【Scikit-Learn 中文文檔】隨機梯度下降 - 監督學習 - 用戶指南 | ApacheCN

中文文檔: http://sklearn.apachecn.org/cn/0.19.0/modules/sgd.html

英文文檔: http://sklearn.apachecn.org/en/0.19.0/modules/sgd.html

官方文檔: http://scikit-learn.org/0.19/

GitHub: https://github.com/apachecn/scikit-learn-doc-zh(覺得不錯麻煩給個 Star,我們一直在努力)

貢獻者: https://github.com/apachecn/scikit-learn-doc-zh#貢獻者

關於我們: http://www.apachecn.org/organization/209.html




1.5. 隨機梯度下降

隨機梯度下降(SGD) 是一種簡單但又非常有效的方法,主要用於凸損失函數下對線性分類器的學習,例如(線性) 支持向量機 和 Logistic 迴歸 。 儘管 SGD 在機器學習社區已經存在了很長時間, 但是最近在 large-scale learning (大規模學習)方面 SGD 獲得了相當大的關注。

SGD 已成功應用於文本分類和自然語言處理中經常遇到的大規模和稀疏的機器學習問題。考慮到數據是稀疏的,本模塊的分類器可以輕易的處理超過 10^5 的訓練樣本和超過10^5的特徵。

Stochastic Gradient Descent (隨機梯度下降法)的優勢:

  • 效率。
  • 易於實現 (有大量優化代碼的機會)。

隨機梯度下降法的劣勢:

  • SGD 需要一些超參數,例如 regularization (正則化)參數和 number of iterations (迭代次數)。
  • SGD 對 feature scaling (特徵縮放)敏感。

1.5.1. 分類

Warning

   

在擬合模型前,確保你 permute (重新排列)了( shuffle(打亂))你的訓練數據,或者在每次迭代後用shuffle=True 來打亂。

SGDClassifier 類實現了一個簡單的隨機梯度下降學習程序, 支持不同的 loss functions(損失函數)和 penalties for classification(分類處罰)。

../_images/sphx_glr_plot_sgd_separating_hyperplane_0011.png

作爲其他的 classifiers (分類器), SGD 必須擬合兩個 arrays (數組):保存訓練樣本的 size 爲 [n_samples, n_features] 的數組 X 以及保存訓練樣本目標值(類標籤)的 size 爲 [n_samples] 的數組 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', max_iter=5, n_iter=None,
       n_jobs=1, penalty='l2', power_t=0.5, random_state=None,
       shuffle=True, tol=None, verbose=0, warm_start=False)

擬合後,可以用該模型來預測新值:

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

SGD 通過訓練數據來擬合一個線性模型。成員 coef_ 保存模型參數:

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

成員 intercept_ 保存 intercept(截距) (aka offset or bias(偏移)):

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

模型是否使用 intercept(截距), 即 a biased hyperplane(一個偏置的超平面), 是由參數 fit_intercept 控制的。

使用 SGDClassifier.decision_function 來獲得與超平面的 signed distance (符號距離)

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

具體的 loss function(損失函數) 可以通過 loss 參數來設置。 SGDClassifier 支持以下的 loss functions(損失函數):

  • loss="hinge": (soft-margin) linear Support Vector Machine ((軟-間隔)線性支持向量機),
  • loss="modified_huber": smoothed hinge loss (平滑的hinge損失),
  • loss="log": logistic regression (logistic 迴歸),
  • and all regression losses below(以及所有的迴歸損失)。

前兩個 loss functions(損失函數)是懶惰的,如果一個例子違反了 margin constraint(邊界約束),它們僅更新模型的參數, 這使得訓練非常有效率,即使在使用 L2 penalty(懲罰)也許結果也會是稀疏的模型。

使用 loss="log" 或者 loss="modified_huber" 啓用 predict_proba 方法, 其給出每個樣本 x 的概率估計 P(y|x) 的一個向量:

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

concrete penalty(具體的懲罰)可以通過 penalty 參數來設定。 SGD 支持以下 penalties(懲罰):

  • penalty="l2": L2 norm penalty on coef_.
  • penalty="l1": L1 norm penalty on coef_.
  • penalty="elasticnet": Convex combination of L2 and L1; (1 - l1_ratio) * L2 + l1_ratio * L1.

默認設置爲 penalty="l2" 。 L1 penalty (懲罰)導致稀疏解,使得大多數係數爲零。 Elastic Net(彈性網)解決了在高度相關屬性上 L1 penalty(懲罰)的一些不足。參數 l1_ratio 控制了 L1 和 L2 penalty(懲罰)的 convex combination (凸組合)。

SGDClassifier 通過在將多個 binary classifiers (二分類器)組合在 “one versus all” (OVA) 方案中來支持多類分類。對於每一個 K 類, 學習了一個二進制分類器來區分自身和其他 K-1 個類。在測試階段,我們計算了每個分類的 confidence score(置信度分數)(也就是與超平面的距離)並選擇由最高置信度的類。下圖顯示了在 iris(鳶尾花)數據集上的 OVA 方法。虛線表示三個 OVA 分類器; 背景色顯示了由三個分類器引起的絕策面。

../_images/sphx_glr_plot_sgd_iris_0011.png

在 multi-class classification (多類分類)的情況下, coef_ 是 shape=[n_classes, n_features] 的一個二維數組, intercept_ is shape=[n_classes] 的一個一維數組。 coef_ 的第 i 行保存了第 i 類的 OVA 分類器的權重向量;類以升序索引 (參照屬性 classes_ )。 注意,原則上,由於它們允許創建一個概率模型,所以 loss="log" 和 loss="modified_huber" 更適合於 one-vs-all 分類。

SGDClassifier 通過擬合參數 class_weight 和 sample_weight 來支持 weighted classes (加權類)和 weighted instances(加權實例)。更多信息請參照下面的示例和 SGDClassifier.fit 的文檔。

SGDClassifier 支持 averaged SGD (ASGD)。Averaging(平均值)可以通過設置 `average=True` 來啓用。ASGD的工作原理是在一個樣本上的每次迭代上將 plain SGD(平均SGD)的係數平均。當使用 ASGD 時,學習速率可以更大甚至是恆定,主要是在一些數據集上加快訓練時間。

對於一個 logistic loss(logistic 損失)的分類,具有 averaging strategy(平衡策略)的 SGD 的另一變種可用於 Stochastic Average Gradient(隨即平均梯度)(SAG)算法,作爲 LogisticRegression 的 solver (求解器)。

1.5.2. 迴歸

SGDRegressor 類實現了一個簡單的隨即梯度下降學習程序,它支持不同的損失函數和懲罰來擬合線性迴歸模型。 SGDRegressor 是非常適用於有大量訓練樣本(>10.000)的迴歸問題,對於其他問題,我們簡易使用 RidgeLasso,或 ElasticNet

具體的損失函數可以通過 loss 參數設置。 SGDRegressor 支持以下的損失函數:

  • loss="squared_loss": Ordinary least squares,
  • loss="huber": Huber loss for robust regression,
  • loss="epsilon_insensitive": linear Support Vector Regression.

Huber 和 epsilon-insensitive 損失函數可用於 robust regression(穩健迴歸)。不敏感區域的寬度必須通過參數 epsilon 來設定。這個參數取決於目標變量的規模。

SGDRegressor 支持 averaged(平均)SGD 作爲 SGDClassifier。 平均值可以通過設置 `average=True` 來啓用。

對於一個 squared loss(平方損失)和一個 l2 penalty(l2懲罰)的迴歸,具有 averaging strategy(平衡策略)的 SGD 的另一變種可用於 Stochastic Average Gradient(隨即平均梯度)(SAG)算法,作爲 Ridge 中的 solver(求解器)。

1.5.3. 稀疏數據的隨機梯度下降

Note

   

由於一個對於截距是縮小的學習率,稀疏實現與密集實現相比產生的結果略有不同。

在 scipy.sparse 支持的格式中,任意矩陣都有對稀疏數據的內置支持。但是,爲了獲得最好的效率,請使用 scipy.sparse.csr_matrix 中定義CSR矩陣格式.

1.5.4. 複雜度

SGD 主要的優點在於它的效率,在訓練實例的數量上基本是線性的。假如 X 是 size 爲 (n, p) 的矩陣,訓練成本爲 O(k n \bar p),其中 k 是迭代次數, \bar p 是每個樣本非零屬性的平均數。

但是,最近的理論結果表明,在訓練集大小增加時,運行時得到的一些期望的優化精度不會增加。

1.5.5. 實用小貼士

  • 隨機梯度下降法對 feature scaling (特徵縮放)很敏感,因此強烈建議您縮放您的數據。例如,將輸入向量 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

    假如你的 attributes (屬性)有一個內在尺度(例如 word frequencies (詞頻)或 indicator features(指標特徵))就不需要縮放。

  • 最好使用 GridSearchCV 找到一個合理的 regularization term (正則化項) \alpha , 它的範圍通常在 10.0**-np.arange(1,7) 。

  • 經驗性地,我們發現 SGD 在觀察約 10^6 訓練樣本後收斂。因此,對於迭代次數的一個合理的第一猜想是 n_iter = np.ceil(10**6 / n),其中 n 是訓練集的大小。

  • 假如將 SGD 應用於使用 PCA 做特徵提取,我們發現通過常數 c 來縮放特徵值是明智的,這樣,訓練數據的平均 L2 平均值等於 1。

  • 我們發現 Averaged SGD 在一個更大的特徵和一個更高的 eta0 上工作的最好。

參考文獻:

1.5.6. 數學描述

給定一組訓練樣本 (x_1, y_1), \ldots, (x_n, y_n) 其中 x_i \in \mathbf{R}^m , y_i \in \{-1,1\}, 我們的目標是一個線性 scoring function(評價函數) f(x) = w^T x + b ,其中模型參數 w \in \mathbf{R}^m ,截距 b \in \mathbf{R}。爲了做預測, 我們只需要看 f(x) 的符號。找到模型參數的一般選擇是通過最小化由以下式子給出的正則化訓練誤差

E(w,b) = \frac{1}{n}\sum_{i=1}^{n} L(y_i, f(x_i)) + \alpha R(w)

其中 L 衡量模型(mis)擬合程度的損失函數,R 是懲罰模型複雜度的正則化項(也叫作懲罰); \alpha > 0 是一個非負超平面。

L 的不同選擇需要不同的分類器,例如

  • Hinge: (soft-margin) Support Vector Machines.
  • Hinge: (軟-間隔) 支持向量機。
  • Log: Logistic Regression.
  • Log: Logistic 迴歸。
  • Least-Squares: Ridge Regression.
  • Least-Squares: 嶺迴歸。
  • Epsilon-Insensitive: (soft-margin) Support Vector Regression.
  • Epsilon-Insensitive: (軟-間隔) 支持向量迴歸。

所有上述損失函數可以看作是錯誤分類誤差的上限(0 - 1損失),如下圖所示。

../_images/sphx_glr_plot_sgd_loss_functions_0011.png

正則化項 R 受歡迎的選擇包括:

  • L2 norm: R(w) := \frac{1}{2} \sum_{i=1}^{n} w_i^2,
  • L1 norm: R(w) := \sum_{i=1}^{n} |w_i|, which leads to sparse solutions().
  • Elastic Net: R(w) := \frac{\rho}{2} \sum_{i=1}^{n} w_i^2 + (1-\rho) \sum_{i=1}^{n} |w_i|, a convex combination of L2 and L1, where \rho is given by 1 - l1_ratio.

下圖顯示當 R(w) = 1 時參數空間中不同正則項的輪廓

../_images/sphx_glr_plot_sgd_penalties_0011.png

1.5.6.1. SGD

隨機梯度下降法一種無約束優化問題的優化方法。與(批量)梯度下降法相反,SGD 通過一次只考慮單個訓練樣本來近似 E(w,b) 真實的梯度。

SGDClassifier 類實現了一個 first-order SGD learning routine (一階 SGD 學習程序)。 算法在訓練樣本上遍歷,並且對每個樣本根據由以下式子給出的更新規則來更新模型參數

w \leftarrow w - \eta (\alpha \frac{\partial R(w)}{\partial w}+ \frac{\partial L(w^T x_i + b, y_i)}{\partial w})

其中 \eta 是在參數空間中控制步長的 learning rate (學習速率)。 intercept(截距) b 的更新類似但不需要正則化。

學習率 \eta 可以是常數或者逐漸減小。對於分類來說, 默認學習率 schedule(調度) (learning_rate='optimal')由下式給出。

\eta^{(t)} = \frac {1}{\alpha  (t_0 + t)}

其中 t 是時間步長(總共有 n_samples * n_iter 時間步長), t_0 是由 Léon Bottou 提出的啓發式決定的,這樣,預期的初始更新可以與權重的期望大小相比較(這假設訓練樣本的規範近似1)。在 BaseSGD 中的 _init_t 中可以找到確切的定義。

對於迴歸來說,默認的學習率是反向縮放 (learning_rate='invscaling'),由下式給出

\eta^{(t)} = \frac{eta_0}{t^{power\_t}}

其中 eta_0 和 power\_t 是用戶通過 eta0 和 power_t 分別選擇的超參數。

學習速率常數使用使用 learning_rate='constant' ,並使用 eta0 來指定學習速率。

模型參數可以通過成員 coef_ 和 intercept_ 來訪問:

  • 成員 coef_ holds the weights(控制權重) w
  • 成員 intercept_ holds b

1.5.7. 實現細節

他對 SGD 的實現受到了 Léon Bottou Stochastic Gradient SVM 的影響。類似於 SvmSGD,權值向量表示爲在 L2 正則化的情況下允許有效的權值更新的標量和向量的乘積。 在 sparse feature vectors (稀疏特徵向量)的情況下, intercept (截距)是以更小的學習率(乘以 0.01)更新的,導致了它更頻繁的更新。訓練樣本按順序選取,每次觀察後,學習率降低。 我們從 Shalev-Shwartz 等人那裏獲得了 learning rate schedule ( 學習率計劃表 )。 對於多類分類,使用 “one versus all” 方法。 我們使用 Tsuruoka 等人提出的 truncated gradient algorithm (截斷梯度算法)2009 年爲 L1 正則化(和 Elastic Net )。代碼是用 Cython 編寫的。

參考文獻:




中文文檔: http://sklearn.apachecn.org/cn/0.19.0/modules/sgd.html

英文文檔: http://sklearn.apachecn.org/cn/0.19.0/modules/sgd.html

官方文檔: http://scikit-learn.org/0.19/

GitHub: https://github.com/apachecn/scikit-learn-doc-zh(覺得不錯麻煩給個 Star,我們一直在努力)

貢獻者: https://github.com/apachecn/scikit-learn-doc-zh#貢獻者

關於我們: http://www.apachecn.org/organization/209.html

有興趣的們也可以和我們一起來維護,持續更新中 。。。

機器學習交流羣: 629470233

發佈了25 篇原創文章 · 獲贊 67 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章