輕鬆玩轉 Scikit-Learn 系列 —— 梯度下降法
接觸過機器學習的小夥伴都應該知道,梯度下降法並不是一個機器學習演算法,而是一種基於搜尋的最優化方法,在機器學習尤其是深度學習的凸優化中使用尤為廣泛。給定一個損失函式,如果該函式是凸函式,在學習率合適的情況下,它能夠快速搜尋到極小值。類似的還有梯度上升法,只是變換下正負號而已,一個是最大化效用函式,一個是最小化損失函式或者成本函式。在求一個函式的最大值或最小值時,沿其梯度方向進行搜尋可能是最有效也是最普遍的方法之一。
我們拿單一變數的凸函式來舉個栗子,如上圖。假如搜尋的初始點在極小值的右邊,其梯度(即導數)為正,則其負梯度方向是從當前位置指向極小值點的方向;假如搜尋的初始點在極小值的左邊,則其負梯度方向也是為從當前的搜尋位置指向區域性極小值的。由相關數學證明也可推得連續凸函式的負梯度方向總是指向區域性極小值點,正梯度方向總是指向其區域性極大值點。同時,也必須控制梯度下降的步長,即需要在梯度之前加上一個係數——學習率,否則可能會導致兩個不良後果。
● 在搜尋極小值的過程中搜索點在極小值點的周圍來回跳動,不斷震盪,但是仍然可以收斂到極小值;
● 在搜尋過程中,所計算的梯度越來越大,甚至導致計算上溢,搜尋失敗。如下圖所示。
所以給梯度下降配上學習率,尤其是選擇合適大小的學習率尤其重要。在深度學習中甚至專門有自適應調整學習率的演算法,例如大名鼎鼎的 Adam,還有 AdaGrad 和 RMSProp 等,感興趣的小夥伴去查閱下花書。
因為搜尋初始點的關係,我們搜尋到的極小值點可能並非是全域性極小值點而只是區域性極小值點,這依賴於搜尋初始點的位置,廣泛採用的解決方案就是進行多次搜尋,每次都隨機的在搜尋域產生初始搜尋點。重複搜尋的次數越多,越有可能找到全域性極小值點。
當在學習的過程中如果訓練樣本非常多的話,因為最終的代價函式是每個樣本代價函式的總和,所以再求梯度的時候每個樣本點都會參與進去,所以以上的梯度下降也叫做批量梯度下降。較大的訓練資料集也意味著較大的計算成本,那我們利用以區域性代替整體的思想,從訓練資料集中隨機抽取出一部分樣本點來代替整個資料集,以減小計算開銷,其實這就是深度學習中廣泛採用的隨機梯度下降法。廢話有點多,接下來上程式碼。
之後例項化一個物件,訓練模型求其準確率。
結果:
CPU times: user 2 ms, sys: 941 µs, total: 2.94 ms
Wall time: 1.38 ms
0.73551631052094557
例項化一個使用隨機梯度下降的線性迴歸模型。
得到結果:
CPU times: user 902 µs, sys: 469 µs, total: 1.37 ms
Wall time: 766 µs
0.74803818104616793
一些細心的小夥伴看到我從 scikit-learn 的 linear_model 直接 import SGDRegressor(),例項化後直接拿去訓練而在這過程中並沒有傳入其他的機器學習模型感到奇怪,因為前面說了梯度下降只是優化演算法,而不是機器學習的模型學習演算法。
的確是這樣,正如註釋裡所說,scikit-learn 之所以可以這樣做是因為它在 SGDRegressor() 中整合的是線性迴歸,在學習模型的過程中使用的隨機梯度下降進行優化搜尋,使用了隨機梯度下降法的預設模型似乎比沒有使用該演算法的模型準確率稍微有所提高,訓練速度也會稍微快了一些。
接下來我們介紹下一些可調整的超引數,並進行調參,順便看下調過參後一些模型的表現。
● loss:用於選擇損失函式,預設 loss=’squared_loss’,表示損失函式為預測值與實際值差的平方和,其他還有 ‘huber’, ‘epsilon_insensitive’等;
● penalty:正則項的懲罰方式,預設 penalty=’l2’, 使用 L2 正則,‘l1’ 和 ‘elasticnet’ ;
● random_state:shuffle 資料時使用其來種隨機種子;
● n_iter:對訓練資料集重複訓練的次數,深度學習中常用 Epoch 表示;
更多超引數請小夥伴們自行查閱官方文件,我就不囉嗦啦!
設定 n_iter 超參如下,得到對應結果 。
CPU times: user 1.7 ms, sys: 659 µs, total: 2.36 ms
Wall time: 1.17 ms
0.74863538201180846
與 sgd_reg 相比只能算是略微的提高,那再變大試試。
CPU times: user 6.8 ms, sys: 789 µs, total: 7.59 ms
Wall time: 6.14 ms
0.73539011191275572
聰明的讀者有沒有發現這個問題,迭代次數增加,精確度並不一定增加 。為啥呢?
已知 n_iter 是訓練資料集重複訓練的次數,當 n_iter 過大時,很可能是在訓練資料集上發生了 過擬合 ,導致模型 sgd_reg3 的準確率與前者相比卻有所下降。而且隨著 n_iter 的變大,訓練時間會延長。
沒有免費的午餐定理表明:在所有可能的資料生成分佈上平均之後,每一個分類演算法在未事先觀測的點上都有相同的錯誤率。換言之,在某種意義上,沒有一個機器學習演算法總是比其他的要好。最先進的演算法和簡單地將所有點歸為同一類的簡單演算法有著相同的平均效能。
今天的分享就到這裡了,關於 SGDRegressor 模型還有很多其他超引數的調整,請小夥伴們自己在下面親手操作下,會收穫更多哦。還是那句話,如果你們中有大神路過,還請高抬貴腳,勿踩勿噴。好了,期待與小夥伴們共同進步!
原文釋出時間為:2018-11-26
本文作者:蜉蝣扶幽
本文來自雲棲社群合作伙伴“ ofollow,noindex">小詹學Python ”,瞭解相關資訊可以關注“ 小詹學Python ”。