機器學習-梯度降低參數調優小結

在機器學習領域,經過對特徵的參數調優可讓模型的預測值更接近真實值的常見的兩種方法包括最小二乘法和梯度降低方法。目前梯度降低更成爲了一種解決問題的方法和思路,在集成學習和深度學習領域都有較多的應用。html

定義

直觀理解「梯度降低」:咱們在山上想要下山的時候,不知道方向,手頭上只有一個儀器能夠提醒當前的海拔,這時候隨意的走一步能夠知道海拔變大仍是變小,往海拔變小的方向一步一步走,經過順着梯度降低的方向一步步縮小海拔,直到海拔也基本沒有變化爲止,這樣咱們就從山頂走道山下。這就是梯度降低的一個運算思惟。在實際的機器學習中,山頂的海拔高度表明瞭模型的預測值和真實值之間的差距,而梯度降低的方法是經過不斷迭代的方式來縮小這個差距,直到該差距收斂到極小值,從而肯定參數。
以電子商務推薦算法爲例,從建模的角度描述如何經過梯度降低來作參數調優:
用戶對於商品的興趣能夠經過簡單的線性迴歸建模,並設計函數h(x)來表明模型預測用戶對於某個商品的購買興趣,若是購買興趣高,則能夠做爲商品推薦。模型的公式以下:
image
其中X(x1,x2…)是購買行爲的特徵,例如用戶的年齡和喜愛,商品類別和價格,參數組θ(θ0,θ1…)表示特徵對於預測值的影響大小。
機器學習中除了包括數據分析、特徵選擇、模型選擇以外,還有一個步驟是參數調優。假設 模型的X已經肯定,目前須要肯定參數組θ,來評估對於特定用戶對於特定商品的購買興趣而言,到底是商品的價格重要仍是用戶的愛好影響更重要。
咱們須要構建一個損失函數去評估所選擇參數的優劣,簡單的認爲在當前參數組θ,直接比較預測值和真實值差距便可,公式表達爲:
image
梯度學習方法就是經過調整參數組θ從而讓J(θ)取得最小值,調整的方法與從山上順着梯度朝下同樣:python

  1. 首先對θ初始賦值,這個值能夠是隨機的,也可讓θ是一個全零的向量。
  2. 改變θ的值,使得J(θ)按梯度降低的方向進行減小,直到損失函數差減少收斂到極小值或者0爲止。

第二個步驟是關鍵步驟,就是如何讓θi會向着梯度降低的方向進行減小,對於(θ)求偏導J,咱們能夠進一步獲得θ的變化函數:
image
其中α表示步長,h(x)-y表示上次偏差,經過上次偏差、步長和變量來反饋更新θi。更新的圖示以下,其中的兩個黑線都是
Boosting
當參數組θ的每個參數都按照這樣的計算公式進行變化更新的時候,模型的預測值將會以梯度的方向接近真實值,最終獲得一個最優值,這個最優值多是局部最優也多是全局最優,咱們將在後面的章節討論這個問題。算法

關聯概念

在上一章節,咱們舉的建模樣例中提到了一些概念,系統介紹一下:數組

  • 特徵x:建模的輸入變量,例如商品推薦中商品的價格、類別等參數。
  • 預測值:建模h(x)的輸出指標,例如商品推薦中預測用戶對於某商品的興趣程度。
  • 損失函數 J(θ):爲了評估模型擬合的好壞,一般用損失函數來度量擬合的程度。損失函數極小化,意味着擬合程度最好,對應的模型參數即爲最優參數。在線性迴歸中,損失函數一般爲樣本輸出和假設函數的差取平方。
  • 步長:梯度降低過程當中,每一步參數變化的長度大小。步長的設置應該仔細斟酌,若是過小,獲得最優參數組合的速度很慢(須要迭代的輪數次數會不少),若是太大,收斂過早獲得的並不是是最優參數,模型的可靠性不高。
  • 初始賦值:初始值不一樣,得到的最小值也有可能不一樣,所以梯度降低求得的只是局部最小值;固然若是損失函數是凸函數則必定是最優解。因爲有局部最優解的風險,須要屢次用不一樣初始值運行算法,關鍵損失函數的最小值,選擇損失函數最小化的初值。
  • 退出閾值:當梯度降低的降低幅度達到該閾值時,退出梯度降低。該退出閾值應該儘可能接近0(若是有充足的資源進行迭代訓練的話),我我的認爲最低不大於步長的百分之一,即在最大百分之一步長內的變化即認爲收斂到沒法變化了。

對於步長和退出閾值應該基於訓練數據屢次遍歷後判斷得出機器學習

在訓練的時候一個技巧:對特徵值x進行歸一化處理提升迭代的速度。能夠參考博文 的方法。函數

算法版本

批量梯度降低

批量梯度降低法的作法是,當前一步的梯度降低迭代遍歷中參數空間θ的保持不變,當前步結束後,使用更新後的參數θ得到步長大小,而後進行下一步的梯度降低,這就是批量的梯度降低思路。
批量梯度降低的方法須要計算整個數據集纔會更新一次參數θ,對於數據集較大的狀況下,會很是耗時,另外也不適用於在線更新模型的應用狀況,所以應用不太普遍。
代碼示例以下:學習

x = [(1,0.,3) , (1,1.,3) ,(1,2.,3), (1,3.,2) , (1,4.,4)]
y = [95.364,97.217205,75.195834,60.105519,49.342380]
my_break=0.00001
alpha=0.01
diff=0
error1,error0=0,0
theta0,theta1,theta2=0,0,0
sum0,sum1,sum2=0,0,0
while True:
    for i in range(len(x)):
        #批量更新參數
        diff=y[i]-(theta0*x[i][0]+theta1*x[i][1]+theta2*x[i][2])
        sum0=sum0+alpha*diff*x[i][0]
        sum1=sum1+alpha*diff*x[i][1]
        sum2=sum2+alpha*diff*x[i][2]
        count+=1
    theta0,theta1,theta2=sum0,sum1,sum2
    error1=0
    for i in range(len(x)):
        error1+=(y[i]-(theta0*x[i][0]+theta1*x[i][1]+theta2*x[i][2]))**2/2
        count+=1
    if abs(error1-error0)<my_break:
        break
    else:
        error0=error1
print("Done: theta0:{0}, theta1:{1}, theta2:{2}.".format(theta0,theta1,theta2))

隨機梯度降低

隨機梯度降低與批量梯度降低相似,惟一的區別在於在每一步梯度降低的迭代遍歷中,參數空間θ都在變化。也便是說批量梯度降低用全部數據來作梯度降低,隨機梯度降低用的是單條數據來作梯度降低。
隨機梯度降低的優勢是訓練速度快,隨之而來的是所獲得的解並非最優解,準確度沒有批量梯度降低好,尤爲是當訓練數據噪音比較大的狀況。
代碼演示以下:測試

x = [(1,0.,3) , (1,1.,3) ,(1,2.,3), (1,3.,2) , (1,4.,4)]
y = [95.364,97.217205,75.195834,60.105519,49.342380]
my_break=0.00001
alpha=0.01
diff=0
error1,error0=0,0
theta0,theta1,theta2=0,0,0
sum0,sum1,sum2=0,0,0
min_x=2
while True:
    for i in range(len(x)):
        #迭代內參數被單次樣本迭代進行更新
        diff=y[i]-(theta0*x[i][0]+theta1*x[i][1]+theta2*x[i][2])
        theta0=theta0+alpha*diff*x[i][0]
        theta1=theta1+alpha*diff*x[i][1]
        theta2=theta2+alpha*diff*x[i][2]
        count+=1
    error1=0
    for i in range(len(x)):
        error1+=(y[i]-(theta0*x[i][0]+theta1*x[i][1]+theta2*x[i][2]))**2/2
        count+=1
    if abs(error1-error0)<my_break:
        break
    else:
        error0=error1
print("Done: theta0:{0}, theta1:{1}, theta2:{2}.".format(theta0,theta1,theta2))

小批量梯度降低

小批量梯度降低結合了批量梯度降低準確度高和隨機梯度降低訓練速度快的特色,對於訓練集m的迭代中,選擇x(1<x<m)次迭代後,參數空間θ進行更新。優化

x = [(1,0.,3) , (1,1.,3) ,(1,2.,3), (1,3.,2) , (1,4.,4)]
y = [95.364,97.217205,75.195834,60.105519,49.342380]
my_break=0.00001
alpha=0.01
diff=0
error1,error0=0,0
theta0,theta1,theta2=0,0,0
sum0,sum1,sum2=0,0,0
count=0
min_x=2
while True:
    count_x=0
    for i in range(len(x)):
        diff=y[i]-(theta0*x[i][0]+theta1*x[i][1]+theta2*x[i][2])
        sum0=sum0+alpha*diff*x[i][0]
        sum1=sum1+alpha*diff*x[i][1]
        sum2=sum2+alpha*diff*x[i][2]
        count_x+=1
        #在迭代內部小批量迭代更新參數
        if count_x%min_x==0:
            theta0,theta1,theta2=sum0,sum1,sum2
        count+=1

    error1=0
    for i in range(len(x)):
        error1+=(y[i]-(theta0*x[i][0]+theta1*x[i][1]+theta2*x[i][2]))**2/2
        count+=1
    if abs(error1-error0)<my_break:
        break
    else:
        error0=error1
print("Done: theta0:{0}, theta1:{1}, theta2:{2}.".format(theta0,theta1,theta2))

過分擬合

梯度降低的目標是在下降預測值和真實值之間的差距從而得到最優的參數空間,基於已有的數據進行迭代訓練,須要特別注意」過分擬合「的現象。
防止過分擬合的方法能夠參考這篇博文機器學習:防止過擬合的方法
這裏參考wiki使用Early Stopping的方法來作防止過擬合:.net

  1. 將訓練數據分隔成訓練集和測試集,80%:20%或者2:1的比例都行;
  2. 只基於訓練集進行訓練,每輪訓練集迭代後記錄並記爲一次EPOCH,每隔N(N=5,8…)個epoch在測試集上運行validation metric進行計算獲得validation accuracy並,validation metric能夠是模型表現的評估函數;
  3. 當連續M(M=10)次EPOCH沒有達到最佳的validation accuracy,中止在訓練集上的迭代;
  4. 記錄最佳validation accuracy所對應的參數。

上述的方法是與梯度降低結合使用的,也能夠認爲在梯度降低的退出條件中增長了一個過渡擬合。除此以外,還能夠選擇交叉驗證、拓展數據集數據等方法來進行過擬合。

局部最優VS全局最優

在不考慮模型過擬合的狀況下,梯度降低獲得的最優解不必定是全局最優解,也有多是局部最優解,注意本文第三章節的代碼示例中,梯度降低的退出條件:

if abs(error1-error0)<my_break:
    break

在降低過程當中,咱們找到了一個數據無變化的點(不動點),這個不動點可能有三個含義:極大值、極小值和鞍點。在梯度降低中,極大值基本上可能性沒有,只有多是極小值和鞍點。當前僅當梯度降低是凸函數時,梯度降低會收斂到最小值。
也就是在使用梯度降低中,咱們最大可能獲得是局部最優解。
爲了確保不動點是局部最優解,能夠設置更小的退出閾值,進行屢次比較看看參數是否變化,若是變化了,說明能夠再次調試。
總的來講,梯度降低時一種得到最優解的參數組合的思路,實際應用過程當中會結合多種優化方法一塊兒使用。

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

相關文章
相關標籤/搜索