文章目錄
- 1. 集成學習概述
- 2. Boosting算法詳解
- 3. Gradient Boosting算法詳解
- 3.1 基本思想
- 3.2 公式推導
- 4. Python實現
1. 集成學習概述
集成學習(Ensemble Learning)是一種通過結合多個模型的預測結果來提高整體預測性能的技術。相比于單個模型,集成學習通過多個基學習器的“集體智慧”來增強模型的泛化能力,通常能夠提高模型的穩定性和準確性。
常見的集成學習框架有:
- Bagging:通過并行訓練多個模型并對其結果進行平均或投票來減少方差
- Boosting:通過按順序訓練多個模型,每個模型都試圖糾正前一個模型的錯誤,從而減少偏差
- Stacking:通過訓練多個不同類型的基學習器,并將它們的輸出作為特征輸入到一個高層模型中,從而提升預測性能
每種方法都有其獨特的優勢和適用場景。在本文中,我們將重點介紹 Boosting 算法,它主要聚焦于通過提高模型的準確度來減少偏差。
2. Boosting算法詳解
Boosting 是一種迭代加權的集成學習方法,旨在通過多個弱學習器(通常是偏差較大的模型)的組合,構建一個具有較低偏差和較高準確度的強學習器。與 Bagging 不同,Boosting 關注的是減小模型的 偏差,而非僅僅減少方差。
Boosting 算法通過逐步構建和改進模型,使得每個新模型都能夠專注于糾正前一個模型的錯誤。這種方式使得模型的 預測能力 不斷得到提高。Boosting 的核心思想是 順序訓練。每個新的模型都在前一個模型的基礎上進行訓練,重點關注那些被前一個模型錯誤分類的樣本。通過這種方式,Boosting 可以有效地減少偏差,進而提升模型的精度。
3. Gradient Boosting算法詳解
3.1 基本思想
Gradient Boosting 是 Boosting 的一種實現方法,它通過梯度下降的方式,逐步減少模型的偏差。在每一輪迭代中,Gradient Boosting 都會根據上一輪模型的預測誤差(殘差)訓練一個新的弱學習器,最終的預測結果是所有模型預測結果的加權和。
舉個簡單的例子,假設一個樣本真實值為10,若第一個學習器擬合結果為7,則殘差為 10-7=3, 殘差3作為下一個學習器的擬合目標。若第二個學習器擬合結果為2,則這兩個弱學習器組合而成的Boosting模型對于樣本的預測為7+2 = 9,以此類推可以繼續增加弱學習器以提高性能。
Gradient Boosting還可以將其理解為函數空間上的梯度下降。我們比較熟悉的梯度下降是在參數空間上的梯度下降(例如訓練神經網絡,每輪迭代中計算當前損失關于參數的梯度,對參數進行更新)。而在Gradient Boosting中,每輪迭代生成一個弱學習器,這個弱學習器擬合損失函數關于之前累積模型的梯度,然后將這個弱學習器加入累積模型中,逐漸降低累積模型的損失。即 參數空間的梯度下降利用梯度信息調整參數降低損失,函數空間的梯度下降利用梯度擬合一個新的函數降低損失。
3.2 公式推導
假設有訓練樣本 { x i , y i } , i = 1... n \{x_i,y_i\}, i=1...n {xi?,yi?},i=1...n,在第 m ? 1 m-1 m?1 輪獲得的累積模型為 F m ? 1 ( x ) F_{m-1}(x) Fm?1?(x),則第 m m m 輪的弱學習器 h ( x ) h(x) h(x) 可以通過下式得到
F m ( x ) = F m ? 1 ( x ) + arg ? min ? h ∈ H Loss ( y i , F m ? 1 ( x i ) + h ( x i ) ) F_m(x) = F_{m-1}(x) + \arg \min_{h \in H} \, \text{Loss}(y_i, F_{m-1}(x_i) + h(x_i)) Fm?(x)=Fm?1?(x)+argh∈Hmin?Loss(yi?,Fm?1?(xi?)+h(xi?))
其中上式等號右邊第二項的意思是:在函數空間 H H H 中找到一個弱學習器 h ( x ) h(x) h(x),使得加入這個弱學習器之后的累積模型的 l o s s loss loss 最小。那么應該如何找這個 h ( x ) h(x) h(x) 呢?在第 m ? 1 m-1 m?1 輪結束后,我們可以計算得到損失 L o s s ( y , F m ? 1 ( x ) ) Loss(y,F_{m-1}(x)) Loss(y,Fm?1?(x)),如果我們希望加入第 m m m 輪的弱學習器后模型的 l o s s loss loss 最小,根據最速下降法新加入的模型損失函數沿著負梯度的方向移動,即如果第 m 輪弱學習器擬合函數關于累積模型 F m ? 1 ( x ) F_{m-1}(x) Fm?1?(x) 的負梯度,則加上該弱學習器之后累積模型的 l o s s loss loss 會最小。
因此可以得知第 m 輪弱學習器訓練的目標是損失函數的負梯度,即:
g m = ? ? Loss ( y , F m ? 1 ( x ) ) ? F m ? 1 ( x ) g_m = - \frac{\partial \, \text{Loss}(y, F_{m-1}(x))}{\partial F_{m-1}(x)} gm?=??Fm?1?(x)?Loss(y,Fm?1?(x))?
如果 Gradient Boosting中采用平方損失函數 L o s s = ( y ? F m ? 1 ( x ) ) 2 Loss=(y-F_{m-1}(x))^2 Loss=(y?Fm?1?(x))2,損失函數負梯度計算出來剛好是殘差 y ? F m ? 1 ( x ) y-F_{m-1}(x) y?Fm?1?(x),因此也會說Gradient Boosting每一個弱學習器是在擬合之前累積模型的殘差。這樣的說法不具有一般性,如果使用其他損失函數或者在損失函數中加入正則項,那么負梯度就不再剛好是殘差。
由此可得完整的 Gradient Boosting 算法流程:
以上 Gradient Boosting 的算法流程具有一般性,根據其中的損失函數和弱學習器的不同可以演變出多種不同的算法。如果損失函數換成平方損失,則算法變成 L2Boosting;如果將損失函數換成 log-loss,則算法成為 BinomialBoost;如果是指數損失,則算法演變成 AdaBoost;還可以采用 Huber loss 等更加 robust 的損失函數。弱學習器如果使用決策樹,則算法成為 GBDT(Gradient Boosting Decision Tree),使用決策樹作為弱學習器的 GBDT 使用較為普遍。
4. Python實現
python偽代碼實現 GradientBoosting :
class GradientBoosting:def __init__(self, base_learner, n_learner, learning_rate):self.learners = [clone(base_learner) for _ in range(n_learner)]self.lr = learning_ratedef fit(self, X, y):residual = y.copy()for learner in self.learners:learner.fit(X, residual)residual -= self.lr * learner.predict(X)def predict(self, X):preds = [learner.predict(X) for learner in self.learners]return np.array(preds).sum(axis=0) * self.lr
加入學習率 (learning_rate 或 lr) 的目的是為了控制每個基學習器(或弱學習器)對最終模型的貢獻度,從而達到更好的訓練效果和避免過擬合。
具體來說,學習率的作用可以總結為以下幾點(From ChatGPT):
1.防止過擬合
在 Gradient Boosting 中,訓練過程是逐步的,每一輪都會基于前一輪的殘差訓練一個新的基學習器,并將其結果加到已有模型中。假設沒有學習率的話,每個基學習器的預測值將完全被加到累積模型中,可能會使模型快速過擬合訓練數據。
學習率 lr 的引入通過調整每個基學習器的權重,從而控制模型每次更新的幅度。如果學習率過大,可能會使模型在訓練集上快速擬合,導致過擬合;而如果學習率過小,模型訓練速度會變得非常慢,可能需要更多的基學習器來達到同樣的效果。因此,合理的學習率可以在訓練過程中平衡模型的收斂速度和防止過擬合。
2. 控制每個基學習器的貢獻度
Gradient Boosting 的訓練是一個漸進的過程,每個基學習器都會根據前一輪的殘差來進行擬合。沒有學習率的情況下,每個新基學習器的貢獻將會很大,這可能導致模型在早期就對訓練數據過于敏感,無法很好地泛化。
學習率通過縮小每個基學習器的貢獻,避免模型在每輪更新時發生過大的變化。通常來說,較小的學習率需要更多的基學習器(即更多的迭代次數)來收斂,但可以有效減少每個基學習器對最終結果的影響,從而降低過擬合的風險。
3. 控制訓練過程的收斂速度
學習率對模型的收斂速度有很大的影響。較大的學習率可以使模型快速收斂,但可能導致震蕩或過擬合;而較小的學習率使模型收斂較慢,但通常會得到更加平滑和穩健的結果。合理選擇學習率,可以在優化過程的初期實現快速的方向調整,而在后期逐漸精細化模型。
4. 改進模型的穩定性
加入學習率可以幫助模型在訓練過程中避免跳躍式的大幅更新。每個基學習器的調整幅度得到控制,使得模型更新更為平穩,從而使得訓練過程更加穩定,減少了由于每個學習器的過度調整帶來的不穩定性。
數學解釋:
在訓練過程中,每一輪訓練的目標是通過最小化損失函數來擬合前一輪累積模型的殘差。對于每一輪的弱學習器,其目標是擬合當前模型殘差的負梯度。加入學習率 lr 后,訓練過程中的每個弱學習器的輸出會乘以該學習率,從而調節每個學習器對模型更新的貢獻。
具體來說,假設當前模型的輸出為 F m ? 1 ( x ) F_{m-1}(x) Fm?1?(x),而第 m m m 輪的弱學習器的目標是擬合該模型的殘差。使用學習率 lr 后,更新步驟變為:
F m ( x ) = F m ? 1 ( x ) + l r ? h m ( x ) F_m(x) = F_{m-1}(x) + lr*h_m(x) Fm?(x)=Fm?1?(x)+lr?hm?(x)
這里, h m ( x ) h_m(x) hm?(x) 是第 m m m 輪弱學習器的輸出。通過學習率 lr,我們可以控制每個弱學習器的輸出對最終模型的貢獻。
本文參考:
https://borgwang.github.io/ml/2019/04/12/gradient-boosting.html