迴歸算法學習筆記——線性迴歸、隨機梯度(SGD、BGD)、邏輯迴歸(牛頓法)、Softmax迴歸算法、L1/L2正則化、Ridge、Lasso、ElasticNet

Python數據分析與挖掘

線性迴歸

  • 迴歸分析
  • 目標函數:線性迴歸方程 y=wx+by = wx + b
  • 一個或多個自變量和因變量之間的關係進行建模(其中θi\theta_i爲權重,θ0\theta_0爲bias偏置值):
    • 一維特徵:hθ(x)=θ0+θ1x1h_\theta(x)=\theta_0+\theta_1x_1
    • 二維特徵:hθ(x)=θ0+θ1x1+θ2x2h_\theta(x)=\theta_0+\theta_1x_1+\theta_2x_2
    • N維特徵:i=0Nθixi=θTX\sum_{i=0}^N\theta_ix_i=\theta^TX

梯度下降算法

構建損失函數

  • 未得到目標線性方程,得到上述公式中的θT\theta^T參數
  • 爲確定所選的θT\theta_T效果好壞使用損失函數(loss function)來評估h(x)h(x)函數的好壞
  • 損失函數如下(MSE誤差平方和):
    J(θ)=12mi=1m(h(θTxi)yi)2(1) J(\theta)=\frac{1}{2m}\sum_{i=1}^m(h(\theta^Tx_i)-y_i)^2 \tag{1}

梯度下降法

  • 使用了導數的概念,對點x0x_0的導數反映了函數在該點處的瞬時變化速率
    f(x0)=limx=yx=limx=f(x0+x)f(x0)x(2) f^\prime(x_0)=\lim_{\vartriangle x \to \infty} =\frac{\vartriangle y}{\vartriangle x}=\lim_{\vartriangle x \to \infty} =\frac{f(x_0+\vartriangle x)-f(x_0)}{\vartriangle x} \tag{2}
  • 推廣到多維函數中,梯度反映了多維圖形中變化速率最快的方向
  • 起始時導數爲正,θ\theta減小後並以新的θ\theta爲基點重新求導,一直迭代就會找到最小的J(θ)J(\theta)
    在這裏插入圖片描述
  • StochasticGradientDescent(SGD)隨機梯度下降
    Repeat{θj=θjα((h(θTxi)yi)xi)} \text{Repeat} \{ \\ \dotsb\\ \theta_j = \theta_j -\alpha((h(\theta^Tx_i)-y_i)x_i)\\ \dotsb\\ \}
    其中:xix_i爲隨機的樣本點
  • 代碼實現
import random
import matplotlib.pyplot as plt

x = [(0.,3), (1.,3) ,(2.,3), (3.,2), (4.,4), (0.,3) , (1.,3.1) ,(2.,3.5), (3.,2.1) , (4.,4.2)]
#y[i] is the output of y = theta0 * x[0] + theta1 * x[1] +theta2 * x[2]
y = [95.364,97.217205,75.195834,60.105519,49.342380, 100.364,100.217205,100.195834,100.105519,12.342380]

epsilon = 0.001
#learning rate
alpha = 0.001
diff = [0,0]
error1 = 0
error0 =0
m = len(x)

#init the parameters to zero
theta0 = 0
theta1 = 0
theta2 = 0
epoch = 0

error_array = []
epoch_array = []
while True:
    #calculate the parameters
    # 線性迴歸:h(x) = theta0  + theta1 * x[i][0] + theta2 * x[i][1] 
    # 損失函數(評測指標MSE):累和 (1/2) *  (y - h(x)) ^ 2
    # d((1/2) *  (y - h(x)) ^ 2) / dtheta0 = (y - h(x)) * (-1) * (1) 
    # theta0 = theta0 - (-alpha * (y - h(x))* 1 )
    # theta1 = theta1 - (-alpha * (y - h(x))* x[i][0])
    # theta2 = theta2 - (-alpha * (y - h(x))* x[i][1])
    # 1. 隨機梯度下降算法在迭代的時候,每迭代一個新的樣本,就會更新一次所有的theta參數。
    i = random.randint(0, m - 1)

    # (y - h(x))
    diff[0] = y[i]-( theta0 * 1 + theta1 * x[i][0] + theta2 * x[i][1] )
    # - (y - h(x))x
    gradient0 = - diff[0]* 1
    gradient1 = - diff[0]* x[i][0]
    gradient2 = - diff[0]* x[i][1]
    # theta = theta - (  - alpha * (y - h(x))x )
    theta0 = theta0 - alpha * gradient0
    theta1 = theta1 - alpha * gradient1
    theta2 = theta2 - alpha * gradient2
    #theta3
    #calculate the cost function
    error1 = 0
    # 此處error爲一個相對的Error值。
    for i in range(len(x)):
        error1 += (y[i]-( theta0 * 1 + theta1 * x[i][0] + theta2 * x[i][1]))**2 
    
    error1 = error1 / m    
    print("delta  error {}".format(abs(error1-error0)))
    error_array.append(error1)
    epoch_array.append(epoch)
    if epoch == 500:
        break
    else:
        error0 = error1
    epoch += 1
    print(' theta0 : %f, theta1 : %f, theta2 : %f, sgd error1 : %f, epoch : % f'%(theta0,theta1,theta2,error1, epoch))

print('Done: theta0 : %f, theta1 : %f, theta2 : %f'%(theta0,theta1,theta2))

plt.plot(epoch_array, error_array, color='blue', linewidth=3)
plt.xlabel('epochs')
plt.ylabel('errors')
plt.show()

在這裏插入圖片描述

  • BatchGradientDescent(BGD)批量隨機梯度下降
    Repeat{θj=θjα(1mi=0m(h(θTxi)yi)xi)} \text{Repeat} \{ \\ \dotsb\\ \theta_j = \theta_j -\alpha(\frac{1}{m}\sum_{i=0}^m(h(\theta^Tx_i)-y_i)x_i)\\ \dotsb\\ \}
  • 代碼實現
import matplotlib.pyplot as plt

#Training data set
#each element in x represents (x0,x1,x2)
x = [(0.,3) , (1.,3) ,(2.,3), (3.,2) , (4.,4), (0.,3) , (1.,3.1) ,(2.,3.5), (3.,2.1) , (4.,4.2)]
#y[i] is the output of y = theta0 * x[0] + theta1 * x[1] +theta2 * x[2]
y = [95.364,97.217205,75.195834,60.105519,49.342380, 100.364,100.217205,100.195834,100.105519,12.342380]


#learning rate
alpha = 0.001 
diff = [0,0]
error1 = 0
error0 =0
m = len(x)

#init the parameters to zero
theta0 = 0
theta1 = 0
theta2 = 0
sum0 = 0
sum1 = 0
sum2 = 0

epoch = 0
error_array = []
epoch_array = []
while True:
    #calculate the parameters
    # 線性迴歸:hi(x) = theta0 + theta1 * x[i][1] + theta2 * x[i][2]  
    # 損失函數:(1/2) 累加 * (y - h(x)) ^ 2
    # theta = theta - 累和(  - alpha * (y - h(x))x )
    # 1. 隨機梯度下降算法在迭代的時候,每迭代一個新的樣本,就會更新一次所有的theta參數。
    #calculate the parameters
    # 2. 批梯度下降算法在迭代的時候,是完成所有樣本的迭代後纔會去更新一次theta參數
    print(m)
    for i in range(m):
        #begin batch gradient descent
        diff[0] = y[i]-( theta0 + theta1 * x[i][0] + theta2 * x[i][1] )
        sum0 = sum0 + ( -alpha * diff[0]* 1)
        sum1 = sum1 + ( -alpha * diff[0]* x[i][0])
        sum2 = sum2 + ( -alpha * diff[0]* x[i][1])
        #end  batch gradient descent
    
    theta0 = theta0 - sum0 / m
    theta1 = theta1 - sum1 / m
    theta2 = theta2 - sum2 / m

    sum0 = 0
    sum1 = 0
    sum2 = 0
    #calculate the cost function
    error1 = 0
    for i in range(m):
        error1 += ( y[i]-( theta0 + theta1 * x[i][0] + theta2 * x[i][1] ) )**2
        
    error1 = error1 / m
    error_array.append(error1)
    epoch_array.append(epoch)
    if epoch == 200:
        break
    else:
        error0 = error1
    epoch += 1
    print(' theta0 : %f, theta1 : %f, theta2 : %f, bgd error1 : %f, epoch: %f'%(theta0,theta1,theta2,error1,epoch))

print('Done: theta0 : %f, theta1 : %f, theta2 : %f'%(theta0,theta1,theta2))
plt.plot(epoch_array, error_array, color='blue', linewidth=3)
plt.xlabel('epochs')
plt.ylabel('errors')
plt.show()

在這裏插入圖片描述

對比兩類梯度下降法各有利弊,SGD的計算量小,但隨機性強,有時可以快速收斂,有時則收斂的很慢,loss曲線抖動下降;MGD的計算量大,但包含批量的樣本,收斂效果比較好,loss曲線平滑下降。

Logistic Regression算法

  • 針對分類問題,利用迴歸問題的思路,解決分類問題。

sigmoid函數

  • sigmoid函數是一個s形的曲線
  • 取值在(0, 1)之間
  • 在遠離0的地方函數的值會很快接近0或1
  • g(z)=11+ezg(z)=\frac{1}{1+e^{-z}}

在這裏插入圖片描述

構造目標函數

  • θ0+θ1x1++θnxn=i=0nθixi=θTX\theta_0+\theta_1x_1+\dotsc+\theta_nx_n=\sum_{i=0}^n\theta_ix_i=\theta^TX
  • hθ(x)=g(θTX)=11+eθTXh_\theta(x)=g(\theta^TX)=\frac{1}{1+e^{-\theta^TX}}
  • p(y=1x,θ)=hθ(x)p(y=0x,θ)=1hθ(x)(3) p(y=1|x,\theta)=h_\theta(x) \\ p(y=0|x,\theta)=1-h_\theta(x) \tag{3}
  • 將預測結果轉化成預測某類別的概率公式(3)中y爲真實的類別

構造損失函數-極大似然估計

  • 根據上述公式構建損失函數,目的:通過θT\theta^T的取值使預測正確類別的概率最大化
  • p(yx,θ)=(hθ(x))y(1hθ(x))1yp(y|x,\theta)=(h_\theta(x))^y(1-h_\theta(x))^{1-y}
  • Lossfunction: L(θ)=i=0mp(yixi,θ)=i=0m(hθ(xi))yi(1hθ(xi))1yiL(\theta)=\prod_{i=0}^mp(y_i|x_i,\theta)=\prod_{i=0}^m(h_\theta(x_i))^{y_i}(1-h_\theta(x_i))^{1-y_i}
  • 由於累乘的式子難以求導,因此對上式進行對數處理,轉化爲累加
  • l(θ)=logL(θ)=i=0m(yi(loghθ(xi)+(1yi)log(1hθ)))l(\theta)=\log L(\theta)=\sum_{i=0}^m(y_i(\log h_\theta(x_i)+(1-y_i)\log (1-h_\theta)))
  • 轉化爲類似線性迴歸問題中求最小損失函數的問題:
    • J(θ)=1ml(θ)J(\theta)=-\frac{1}{m}l(\theta)

梯度下降

  • 首先求解損失函數梯度
    θjJ(θ)=1mi=1m[yi1hθ(xi)θjhθ(xi)(1yi)11hθ(xi)θjhθ(xi)]=1mi=1m(hθ(xi)yi)xij \begin{aligned} \frac{\partial}{\partial \theta_j}J(\theta) & = -\frac{1}{m}\sum_{i=1}^m\left[y_i\frac{1}{h_\theta(x_i)}\frac{\partial}{\partial \theta_j}h_\theta(x_i)-(1-y_i)\frac{1}{1-h_\theta(x_i)}\frac{\partial}{\partial \theta_j}h_\theta(x_i)\right] \\ & = \frac{1}{m} \sum_{i=1}^m\left(h_\theta(x_i)-y_i\right)x_i^j\\ \end{aligned}
  • 使用梯度下降求解最優參數
    θj=θjα1mi=1m(hθ(xi)yi)xij \theta_j = \theta_j - \alpha\frac{1}{m} \sum_{i=1}^m\left(h_\theta(x_i)-y_i\right)x_i^j

多分類問題

優化算法:牛頓法

  • 牛頓法比梯度下降法收斂的要快(迭代次數更少)
    • 梯度下降法每次只從當前位置選一個上升速度最大的方向走一步
    • 牛頓法在選擇方向時,不僅會考慮上升速度是否夠大,還會考慮你走了一步之後,上升速度是否會變得更大(即二階導數,類似物理上的加速度)
  • 紅色的牛頓法的迭代路徑,綠色的是梯度下降法的迭代路徑。
    在這裏插入圖片描述
  • 由於最速梯度下降收斂速度並不“最速”,局部搜索中最速下降的方向和全局的最小值方向並不一致,所以就有後來改進的方法,包括牛頓法以及擬牛頓法。

切線法

  • 牛頓法的幾何意義
    在這裏插入圖片描述
  • 從上圖可以總結出如下公式:
    θj=θjJ(θj)J(θj) \theta_j = \theta_j - \frac{J'(\theta_j)}{J''(\theta_j)}
    其中分母上的二階導函數可以理解爲正則項,當一階導數下降方向不是最優方向,進行修改,而且由於二階導數包含數值,因此也不用設置學習率,下降的步長是最優的。

另一種理解方式

  • 隨時函數最小值 = 損失函數導數爲0
  • 將損失函數進行泰勒展開:
    f(x)f(x(k))+gkT(xx(k))+12(xx(k))TH(x(k))(xx(k))(4) f(x) \approx f\left(x^{(k)}\right) + g^T_k\left(x-x^{(k)}\right)+\frac{1}{2}\left(x-x^{(k)}\right)^TH\left(x^{(k)}\right)\left(x-x^{(k)}\right) \tag{4}
    其中g(x)g(x)爲一階導數,HH爲二階導數
  • 對(4)式等式兩端進行求導,轉化爲梯度下降:
    f(x)=gk+Hk(xx(k))gk+Hk(xx(k))=0x(x+1)=x(x)Hk1gk \triangledown f(x)=g_k +H_k \left( x-x^{(k)}\right)\\ g_k +H_k \left( x-x^{(k)}\right) = 0 \\ x^{(x+1)} = x^{(x)} - H_k^{-1}g_k

    最終的結果與切線法得到的結果表達式是一樣的

改進:擬牛頓法

  • 牛頓法中需要計算HkH_k二階導數矩陣,其尺寸爲N×NN\times N的,其中N爲特徵的數量,計算代價很大
  • 而擬牛頓法不在使用HkH_k二階導數矩陣,而是選取相似矩陣

Softmax Regression算法

  • Softmax解決多分類的分類器,即類標籤y的取值大於等於2
  • 類標記爲: y(i){1,2,,k}y(i) \in \left\{ 1,2,\cdots,k \right\}
  • 假設函數爲對於每一個樣本估計其所屬的類別的概率p(y=jx)p(y=j∣x)
  • 每一個樣本估計所屬類別概率爲:
    p(y(i)x(x);θ)=eθjTx(i)l=1keθlTx(i)p\left(y^{(i)}|x^{(x)};\theta\right)=\frac{e^{\theta^T_jx^{(i)}}}{\sum_{l=1}^ke^{\theta^T_lx^{(i)}}}
    即對預測數的各類別的值取loglog後除以所有類別概率值取loglog的總和

Softmax迴歸代價函數

  • 類似於Logistic迴歸,在Softmax的代價函數中引入指示函數I{}I\{⋅\},其具體形式爲:
    I{expression}={0if expression=false1if expression=true I\left \{ \text{expression}\right\} = \begin{cases} 0 \quad \text{if}\ \text{expression}=\text{false}\\ 1 \quad \text{if}\ \text{expression}=\text{true} \end{cases}
  • 那麼,對於Softmax迴歸的代價函數爲交叉熵:
    J(θ)=1m[i=1mj=1kI{yi=j}logeθjTx(i)l=1keθlTx(i)] J(\theta)=-\frac{1}{m}\left[\sum_{i=1}^m\sum_{j=1}^kI\{y^{i}=j \}\log \frac{e^{\theta^T_jx^{(i)}}}{\sum_{l=1}^ke^{\theta^T_lx^{(i)}}} \right]
  • Sofrmax迴歸求解
    • 對上述的代價函數,可以使用梯度下降法進行求解,首先對其進行求梯度:
      θjJ(θ)=1mi=1m[θjj=1kI{y(i)=j}logeθjTx(i)l=1keθlTx(i)]=1mi=1m[I{y(i)=j}l=1keθlTx(i)eθjTx(i)eθjTx(i)x(i)l=1keθlTx(i)eθjTx(i)x(i)eθjTx(i)(l=1keθlTx(i))2]=1mi=1m[I{y(i)=j}l=1keθlTx(i)eθjTx(i)l=1keθlTx(i)x(i)] \begin{aligned} \triangledown_{\theta_j}J(\theta) & =-\frac{1}{m}\sum_{i=1}^m\left[\triangledown_{\theta_j}\sum_{j=1}^kI\left\{y^{(i)}=j \right\}\log \frac{e^{\theta^T_jx^{(i)}}}{\sum_{l=1}^ke^{\theta^T_lx^{(i)}}} \right]\\ & =-\frac{1}{m}\sum_{i=1}^m\left[I\left\{y^{(i)}=j \right\} \frac{\sum_{l=1}^ke^{\theta^T_lx^{(i)}}}{e^{\theta^T_jx^{(i)}}}\cdot \frac{e^{\theta^T_jx^{(i)}}\cdot x^{(i)}\cdot \sum_{l=1}^ke^{\theta^T_lx^{(i)}}-e^{\theta^T_jx^{(i)}}\cdot x^{(i)}\cdot e^{\theta^T_jx^{(i)}}}{\left( \sum_{l=1}^ke^{\theta^T_lx^{(i)}}\right)^2}\right]\\ & = -\frac{1}{m}\sum_{i=1}^m \left[ I\left\{y^{(i)}=j \right\} \cdot \frac{\sum_{l=1}^ke^{\theta^T_lx^{(i)}}- e^{\theta^T_jx^{(i)}}}{\sum_{l=1}^ke^{\theta^T_lx^{(i)}}} \cdot x^{(i)}\right] \end{aligned}
      θj=θjθjJ(θ) \theta_j = \theta_j - \triangledown_{\theta_j}J(\theta)

L1/L2正則化

  • 爲了防止過擬合,擬合過程中通常都傾向於讓權值儘可能小,最後構造一個所有參數都比較小的模型
  • 參數值小的模型比較簡單,能適應不同的數據集,也在一定程度上避免了過擬合現象
  • 對於一個線性迴歸方程,若參數很大,那麼只要數據偏移一點點,就會對結果
    造成很大的影響
  • 但如果參數足夠小,數據偏移得多一點也不會對結果造成什麼影響

L1

  • L1正則化是指權值向量ww中各個元素的絕對值之和,通常表示爲w1\left\|w \right\|_1
  • 如下圖所示,圖中等值線是J0的等值線,黑色方形是L函數的圖形。在圖中,當J0等值線與L首次相交的地方就是最優解。上圖中J0與L在L的一個頂點處相交,這個頂點就是最優解。
    在這裏插入圖片描述
  • 正則化和“帶約束的目標函數”是等價的對L1正則化建立數學模型如下:
    J(θ)=i=1n(yiθTxi)2s.t.θ1m J(\theta)=\sum_{i=1}^n\left(y_i - \theta^T x_i \right)^2\\ s.t.\quad \left\|\theta \right\|_1\leqslant m
  • 通過拉格朗日乘子法,可以變爲如下形式:
    J(θ)=i=1n(yiθTxi)2+λ(θ1m) J(\theta)=\sum_{i=1}^n\left(y_i - \theta^T x_i \right)^2 + \lambda \left(\left\|\theta \right\|_1-m\right)

L2

  • L2正則化是指權值向量ww中各個元素的平方和然後再求平方根(在Ridge迴歸的L2正則化項有平方符號),通常表示爲w2\left\|w \right\|_2
  • 如下圖所示,二維平面下L2正則化的函數圖形是個圓,與方形相比,被磨去了棱角。
    在這裏插入圖片描述
  • 對比L1和L2兩圖,採用L1範數時平方誤差項等值線與正則化項等值線的交點出現在座標軸上,即w1w_1w2w_2爲0,而採用L2範數時,兩者的交點常出現在某個象限中,即w1w_1w2w_2均非0;換而言之,採用L1範數比L2範數更容易於得到稀疏解。
  • 正則化和“帶約束的目標函數”是等價的對L1正則化建立數學模型如下:
    J(θ)=i=1n(yiθTxi)2s.t.θ22m J(\theta)=\sum_{i=1}^n\left(y_i - \theta^T x_i \right)^2\\ s.t.\quad \left\|\theta \right\|_2^2\leqslant m
  • 通過拉格朗日乘子法,可以變爲如下形式:
    J(θ)=i=1n(yiθTxi)2+λ(θ22m) J(\theta)=\sum_{i=1}^n\left(y_i - \theta^T x_i \right)^2 + \lambda \left(\left\|\theta \right\|_2^2-m\right)

L1和L2對比

在這裏插入圖片描述

其中c爲超參數,控制L1和L2的限制區域大小,c越小對損失函數的約束越大;圖中像素點表示[0, 1]的取值,0爲白色1爲黑色。可以看出L1下是很多權值爲0,做到了稀疏性。

參考資料:L1與L2範數

正則化目的

  • 預防或修復過擬合情況
  • 其他方式:
    • 數據層面:
      • 增加數據(行上擴展)
      • 減少feature,特徵選擇
    • 模型層面:
      • 模型融合

Ridge與Lasso

  • L1正則化和L2正則化可以看做是損失函數的懲罰項
  • Lasso迴歸
    • 對於線性迴歸模型,使用L1正則化的模型建叫做Lasso迴歸
    • Lasso迴歸的損失函數,式中加號後面一項即爲L1正則化項
  • Ridge
    • Ridge迴歸的損失函數,式中加號後面一項αθ22\alpha \left\|\theta \right\|_2^2即爲L2正則化項

ElasticNet

對於ElasticNet迴歸,可以看做是Lasso和ridge迴歸的組合
J(θ)=i=1n(yiθTxi)2+λ1(θ1)+λ2(θ22)minθJ(θ) J(\theta)=\sum_{i=1}^n\left( y_i - \theta^Tx_i\right)^2+\lambda_1(\left\|\theta \right\|_1)+\lambda_2(\left\|\theta \right\|_2^2)\\ \min_\theta J(\theta)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章