sklearn文檔 — 1.5. 隨機梯度下降

原文章為scikit-learn中"用戶指南"-->"監(jiān)督學習的第五節(jié):Stochastic Gradient Descent"######

**隨機梯度下降(SGD) 是一個既有效又簡單的方法去用于在諸如(線性)支持向量機Logistic回歸中溺森,"凸"代價函數(shù)下的線性分類器的辨別學習梯澜。盡管 SGD **已經(jīng)在機器學習社區(qū)存在了很長一段時間了岳服,但是在最近的大規(guī)模學習的浪潮下它還是得到了很多人的關(guān)注类早。

SGD 已經(jīng)很成功的應用在了大規(guī)模下和稀疏機器學習問題上谎砾,主要是用于進行文本分類和自然語言處理蕊退。對給定一個稀疏的數(shù)據(jù)坪它,(Sklearn)中的分類器能夠很容易的擴展為能夠處理超過105個訓練樣本和超過105個特征的問題营曼。

**SGD **的優(yōu)點有:

  • 極其效率。
  • 易于實施(有大量調(diào)整代碼的余地)尿贫。

但是其缺點有:

  • 需要許多超參數(shù)电媳,例如正則化參數(shù)和迭代次數(shù)。
  • 對數(shù)據(jù)縮放很敏感庆亡。

1.5.1. 分類#

注意:請確保在每次擬合模型之前都對數(shù)據(jù)進行重新排序匾乓,不然則設置 shuffle=True 使得在每次迭代中都會重排數(shù)據(jù)。

SGDClassifier
實現(xiàn)了一個常規(guī)的樸素梯度下降學習又谋,其對分類問題支持許多不同的代價函數(shù)和懲罰項拼缝。

一個SGD分類的實例

跟其他分類器一樣,**SGD 同樣需要擬合兩個數(shù)組:一個保存著訓練樣本彰亥,尺寸為 [n_samples, n_features] 的數(shù)組 X 和一個保存著結(jié)果標簽咧七,尺寸為 [n_samples] 的數(shù)組 y **:

>>> from sklearn.linear_model import SGDClassifier
>>> X = [[0., 0.], [1., 1.]]
>>> y = [0, 1]
>>> clf = SGDClassifier(loss="hinge", penalty="l2")
>>> clf.fit(X, y)
SGDClassifier(alpha=0.0001, average=False, class_weight=None, epsilon=0.1,
       eta0=0.0, fit_intercept=True, l1_ratio=0.15,
       learning_rate='optimal', loss='hinge', n_iter=5, n_jobs=1,
       penalty='l2', power_t=0.5, random_state=None, shuffle=True,
       verbose=0, warm_start=False)

在擬合之后,這個模型就可以用來預測了:

>>> clf.predict([[2., 2.]])
array([1])

**SGD 使用訓練集擬合了一個線性模型任斋,其成員 coef_ **保存著模型參數(shù):

>>> clf.coef_                                         
array([[ 9.9...,  9.9...]])

然后成員** intercept_ **保存著截距(也稱為偏移值或偏差)

>>> clf.intercept_                                    
array([-9.9...])

不用關(guān)心模型是不是用了截距继阻,其超平面截距,都是由** fit_intercept **參數(shù)控制废酷。

可以通過 SGDClassifier.decision_function
來獲得超平面的帶符號距離:

>>> clf.decision_function([[2., 2.]])                 
array([ 29.6...])

可以通過** loss **參數(shù)來選擇具體是要使用哪個代價函數(shù)瘟檩。SGDClassifier
支持以下幾種代價函數(shù):

  • loss="hinge": (軟邊際) 線性支持向量機,
  • loss="modified_huber": 平滑的 hinge 代價函數(shù),
  • loss="log": logistic回歸,
  • 和下方"回歸"一節(jié)中的代價函數(shù).

前面兩種代價函數(shù)是懶惰的,他們只在樣本違反了邊際的約束(即出現(xiàn)意外值時)才會更新模型參數(shù)澈蟆,也因為如此在訓練的時候很執(zhí)行效率很高墨辛,但也同樣會使得產(chǎn)生出不同稀疏模型,即便是使用了L2懲罰項趴俘。

設置** loss="log" ** 或 ** loss="modified_huber" 來啟用 predict_proba 函數(shù)睹簇,這個函數(shù)對于每個樣本 x 都會給出估計概率( P(y | x) **)矩陣。

>>> clf = SGDClassifier(loss="log").fit(X, y)
>>> clf.predict_proba([[1., 1.]])                      
array([[ 0.00...,  0.99...]])

可以通過** penalty 參數(shù)來選擇需要使用哪種懲罰項哮幢,SGD **支持下列幾種:

  • penalty="l2": 使用L2范數(shù)對** coef_ **進行懲罰。
  • penalty="l1": 使用L1范數(shù)對** coef_ **進行懲罰志珍。
  • penalty="elasticnet": 使用L2和L1的凸組合: (1 - l1_ratio) * L2 + l1_ratio * L1 對** coef_ **進行懲罰橙垢。

**SGD 的默認懲罰項是 penalty="l2" ,使用L1懲罰項會生成出一個大多數(shù)系數(shù)為零的稀疏模型伦糯。若使用彈性網(wǎng)絡則會解決一些L1懲罰在高度相關(guān)屬性中存在的缺陷柜某。參數(shù) l1_ratio **控制著L2與L2懲罰項的凸組合。

SGDClassifier
能夠在“一對多” (OVA)方案下敛纲,通過組合多個二元分類器來進行多類分類喂击。對于每一個K類,二元分類器會比較其與** K-1 **類的區(qū)別進行學習淤翔。在測試階段翰绊,我們?yōu)槊恳粋€分類器計算其置信度(即到超平面的帶符號距離),然后選擇具有高置信度的類。下方的圖表表現(xiàn)了OVA在鳶尾花數(shù)據(jù)集中的表現(xiàn)监嗜。虛線代表著三種OVA分類器谐檀;背景顏色則表現(xiàn)了這三個分類器的決策邊界。

三種OVA分類器在iris數(shù)據(jù)集的表現(xiàn)

在多類分類情況裁奇,**coef_ 是一個形狀為 [n_classes, n_features] 的二維數(shù)組桐猬,然后 intercept_ 是一個形狀為 [n_classes] 的一維數(shù)組。然后對第 i 行的 coef_ 而言刽肠,其保存著第 i 類的分類器的權(quán)重向量溃肪。然后類是按升序來索引的(可以查看 classes_ 屬性)。但要注意的是音五,因為在原則上這個多類分類器是允許創(chuàng)建出一個概率模型的惫撰,所以最好設置代價函數(shù)為 loss="log" loss="modified_huber" **,這樣做比使用默認的代價函數(shù)要更適合這個一對多分類放仗。

SGDClassifier
能通過** fit 參數(shù) class_weight sample_weight **支持權(quán)重類和權(quán)重實例润绎。要了解更多的內(nèi)容可以查看下面的例子或是這個類的說明文檔 SGDClassifier.fit

示例

SGDClassifier
支持平均SGD(ASGD)诞挨±蚱玻可以通過設置** average=True **來開啟平均化。ASGD的工作原理是通過在每個樣本的迭代中惶傻,分別平均化其平面SGD的系數(shù)棍郎。當使用ASGD時,學習率可能會變得很大(耗時下降)银室,甚至會不斷地導致一些數(shù)據(jù)集在訓練的耗時減少涂佃。

對于使用** logistic 代價函數(shù)的分類,另一種 SGD **的變體是在隨機平均梯度(SAG)算法中啟用平均化策略蜈敢,其包含在 LogisticRegression
中辜荠,同樣可以作為一個求解器使用。

1.5.2. 回歸#

SGDRegressor
類實現(xiàn)了一個常規(guī)的樸素梯度下降學習抓狭,其支持對擬合線性模型設置許多不同的代價函數(shù)和懲罰項伯病。SGDRegressor
是一個適合用來對有大量訓練樣本(> 10,000)回歸問題,若是對其他回歸問題否过,則建議使用Ridge
午笛,Lasso
,或 ElasticNet
苗桂。

可以通過** loss **參數(shù)來選擇具體是要使用哪個代價函數(shù)药磺。SGDRegressor
支持以下幾種代價函數(shù):

  • loss="squared_loss":最小二乘法。
  • loss="huber":穩(wěn)健回歸中的Huber損失煤伟。
  • loss="epsilon_insensitive":線性支持向量回歸癌佩。

**huber epsilon_insensitive 代價函數(shù)都是能夠在穩(wěn)健回歸中使用的木缝。不敏感區(qū)的寬度只能通過 epsilon **參數(shù)來設置,并且這個參數(shù)取決于目標變量的規(guī)模驼卖。

SGDRegressor
類似 SGDClassifier
氨肌,都是支持平均 SGD的。

對帶有平方損失和L2懲罰項的回歸來說酌畜,另一種SGD的可選方案是使用隨機平均梯度(SAG)算法怎囚,其包含在 Ridge
,同樣能夠單獨作為求解器來使用桥胞。

1.5.3. 對稀疏數(shù)據(jù)使用隨機梯度下降#

注意:因為在截距上收縮了學習速率恳守,所以稀疏實現(xiàn)與密集實現(xiàn)的結(jié)果會有所不同。

對符合格式要求的任意稀疏矩陣都在 scipy.sparse 中存在內(nèi)置支持贩虾。但是如果要追求最大效率的話催烘,可以使用 scipy.sparse.csr_matrix 內(nèi)所定義CSR矩陣格式。

示例

1.5.4. 復雜度#

SGD的主要優(yōu)點就在于其執(zhí)行效率缎罢,根據(jù)訓練樣本的數(shù)量基本上是呈線性的伊群。如果** X 是一個尺寸為 (n, p) 的矩陣,根據(jù)代價函數(shù) O(k·n·p) 進行訓練策精,其中 k 是迭代數(shù)量舰始,而 p **則是每個樣本非零屬性的平均值。

但是近期的研究結(jié)果顯示咽袜,獲得期望的最優(yōu)準確度所需的時間并不是隨著訓練集大小的增加而增加丸卷。

1.5.5. 實用技巧#

  • SGD對特征縮放很敏感,所以在這里高度建議對數(shù)據(jù)進行縮放询刹。舉例來說谜嫉,對輸入向量** X 的每個特征縮放為值域是[0, 1]或[-1, +1],又或者是將其標準化為均值為0凹联,方差為1的值域沐兰。當然也要對測試集做相同的縮放操作。
    這些操作可以使用
    StandardScaler **來簡單的完成:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)  # Don't cheat - fit only on training data
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)  # apply same transformation to test data

如果你的參數(shù)存在內(nèi)在尺度(例如單詞出現(xiàn)頻率或指標特征)蔽挠,那么就不應該對其進行縮放住闯。

  • 使用** GridSearchCV 來尋找一個合理的 α 項,通常限制的范圍是 10.0**-np.arrage(1, 7)**象泵。
  • 通常來說寞秃,當我們觀察了大約的訓練結(jié)果后(觀察學習曲線或模型圖)就會認為SGD已經(jīng)收斂了斟叼。
    以數(shù)量為10^6的訓練樣本為例偶惠,鑒于此一個對迭代數(shù)量的初步合理的猜想是** n_iter = np.ceil(10**6 / n) ,其中 n **是訓練集的數(shù)量朗涩。
  • 如果你講SGD應用在使用PCA提取出的特征上忽孽,一般的建議是通過尋找某個常數(shù)** c **來縮放特征,使得訓練數(shù)據(jù)的平均L2范數(shù)等于1。
  • 平均SGD(ASGD)最適合應用在有超大數(shù)量的特征與很高的** eta0 **的樣本上兄一。

引用

1.5.6. 數(shù)學公式#

給定一個訓練集(x1, y1),...,(xn, yn)厘线,其中** xi ∈ R^n yi ∈ {-1, 1} 出革。我們的目標是在使用模型參數(shù) ω ∈ R^m 和截距 b ∈ R 的情況下造壮,學習線性評分函數(shù) f(x) = ω^T·x + b 。為了做出預測骂束,我們簡單的將這個函數(shù)用 f(x) 來代替耳璧。然后通常是使用最小化正規(guī)訓練誤差來找到適合的模型參數(shù)(ω b**)。

最小化代價函數(shù)

其中** L 是測量模型(mis)擬合用的代價函數(shù)展箱, R 是懲罰模型復雜性的正則化項(也成為懲罰項)旨枯。α > 0 **是一個非負超參數(shù)。

對不同的分類使用不同的** L **混驰,例如:

  • Hinge:(軟邊界) 支持向量機攀隔。
  • Log:Logistic回歸。
  • Least-Squares:嶺回歸栖榨。
  • Epsilon-Insensitive:(軟邊界)支持向量回歸昆汹。

上述的損失函數(shù)都可以被認為是誤分類誤差(0-1)的上限,即下圖所示:


損失函數(shù)圖

常用的正則項** R **有:

  • L2范數(shù)
  • L1范數(shù)治泥,產(chǎn)生稀疏結(jié)果
  • 彈性網(wǎng)絡筹煮,L2與L1的凸組合,其中** p **由** 1 - l1_ratio **得出

下面的圖顯示了在** R(ω) = 1 **的情況下居夹,使用各種正規(guī)化后函數(shù)的輪廓:


三種正規(guī)化的輪廓

1.5.6.1. SGD##

隨機梯度下降是無約束最優(yōu)化問題的一種優(yōu)化方式败潦。比較與(批)梯度下降,SGD的方式是分別考慮單個樣本來逼近** E(ω准脂, b) **的真實梯度劫扒。

SGDClassifier
實現(xiàn)了一個一階SGD學習。這個算法迭代訓練樣本并對每一個樣本根據(jù)下面的公式來更新模型參數(shù):

ω參數(shù)

其中** n 是控制著步進的學習速率狸膏。截距 b **也是以類似的方式更新沟饥,除了不需要正則化。

學習速率** n 可以是一個恒定值或是衰減值湾戳。對分類問題而言贤旷,默認的學習速率(learning_rate='optimal'**)是通過下面的公式給出:

分類的學習速率公式

上式的** t 是間隔時間(此處是 n_samples * n_iter 的總和),而t0是基于Léon Bottou提出的啟發(fā)式來確定的砾脑,默認是跟權(quán)重的初始值一致(這是在假設訓練樣本的范數(shù)是近似為1的情況下)幼驶。關(guān)于這個的確切定義可以在 BaseSGD _init_t **中找到。

對回歸問題而言韧衣,默認的學習速率(learning_rate='invscaling')是通過下面的公式給出:

回歸的學習速率公式

其中** eta0 power_t 是通過用戶在 eta0 power_t **輸入的超參數(shù)盅藻。

如果要使用恒定的學習速率則設置** learning_rate='constant' 购桑,固定值則是設置 eta0 **了。

可以通過** coef_ intercept_ **來訪問模型參數(shù):

  • coef_成員保存著權(quán)重** ω **氏淑。
  • intercept_成員保存著** b **勃蜘。

引用

1.5.7. 實現(xiàn)細節(jié)#

SGD的實現(xiàn)受Léon Bottou的 隨機梯度SVM 影響。與SvmSGD相似假残,權(quán)重向量代表著標量和向量的乘積缭贡,而這允許在L2正則化下能夠有效地對權(quán)重進行更新。在稀疏特征向量的情況下辉懒,截距是參照更小的學習速率(更新頻率為 學習速率乘以0.01)來更新的匀归,而這說明了會很頻繁的對截距進行更新。訓練樣本被順序挑出耗帕,并且在"觀察"每個樣本后就將降低學習速率穆端。在該類中我們是采用了Shalev-Shwartz 等人在2007年所提出的學習速率。對于多類分類問題則是采用了"一對多"仿便。然后再正則化方面則是采用了由 Tsuruoka 等人在2009年提出的裁斷梯度算法來為L1正則化(彈性網(wǎng)絡也包括在內(nèi))体啰。最后則是使用了Cython來進行代碼實現(xiàn)。

引用


(在嘗試翻譯這篇文檔的時候難免會因為各種問題而出現(xiàn)錯翻嗽仪,如果發(fā)現(xiàn)的話荒勇,煩請指出,謝謝> <)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末闻坚,一起剝皮案震驚了整個濱河市沽翔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌窿凤,老刑警劉巖仅偎,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異雳殊,居然都是意外死亡橘沥,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門夯秃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來座咆,“玉大人,你說我怎么就攤上這事仓洼〗樘眨” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵色建,是天一觀的道長哺呜。 經(jīng)常有香客問我,道長镀岛,這世上最難降的妖魔是什么弦牡? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮漂羊,結(jié)果婚禮上驾锰,老公的妹妹穿的比我還像新娘。我一直安慰自己走越,他們只是感情好椭豫,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著旨指,像睡著了一般赏酥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谆构,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天裸扶,我揣著相機與錄音,去河邊找鬼搬素。 笑死呵晨,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的熬尺。 我是一名探鬼主播摸屠,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼粱哼!你這毒婦竟也來了季二?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤揭措,失蹤者是張志新(化名)和其女友劉穎胯舷,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绊含,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡需纳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了艺挪。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片不翩。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖麻裳,靈堂內(nèi)的尸體忽然破棺而出口蝠,到底是詐尸還是另有隱情,我是刑警寧澤津坑,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布妙蔗,位于F島的核電站,受9級特大地震影響疆瑰,放射性物質(zhì)發(fā)生泄漏眉反。R本人自食惡果不足惜昙啄,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望寸五。 院中可真熱鬧梳凛,春花似錦、人聲如沸梳杏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽十性。三九已至叛溢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間劲适,已是汗流浹背楷掉。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留霞势,地道東北人靖诗。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像支示,于是被迫代替她去往敵國和親刊橘。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容