Kaggle Master解釋梯度提升(Gradient Boosting)(譯)
如果說線性回歸算法像豐田凱美瑞的話,那麽梯度提升(GB)方法就像是UH-60黑鷹直升機。XGBoost算法作為GB的一個實現是Kaggle機器學習比賽的常勝將軍。不幸的是,很多從業者都只把這個算法當作黑盒使用(包括曾經的我)。這篇文章的目的就是直觀而全面的介紹經典梯度提升方法的原理。
原理說明
我們先從一個簡單的例子開始。我們想要基於是否打電子遊戲、是否享受園藝以及是否喜歡戴帽子三個特征來預測一個人的年齡。我們的目標函數是最小化平方和,將用於訓練我們模型的訓練集如下:
ID | 年齡 | 喜歡園藝 | 玩電子遊戲 | 喜歡戴帽子 |
1 | 13 | False | True | True |
2 | 14 | False | True | False |
3 | 15 | False | True | False |
4 | 25 | True | True | True |
5 | 35 | False | True | True |
6 | 49 | True | False | False |
7 | 68 | True | True | True |
8 | 71 | True | False | False |
9 | 73 | True | False | True |
我們對數據可能有以下直覺:
- 喜歡園藝的人可能年紀偏大
- 喜歡電子遊戲的人可能更年輕
- 喜歡戴帽子可能跟年紀關系不大
對於這些直覺我們可以很快在數據中檢驗
特征 | False | True |
喜歡園藝 | 「13,14,15,35」 | 「25,49,68,71,73」 |
玩電子遊戲 | 「49,71,73」 | 「13,14,15,25,35,68」 |
喜歡戴帽子 | 「14,15,49,71」 | 「13,25,35,68,73」 |
現在我們嘗試用回歸樹來建模數據。開始時,我們要求每個葉子結點都至少有三個數據點。這樣回歸樹會從喜歡園藝這個特征開始分裂(split),發現滿足條件,分裂結束。結果如下圖:
結果還不錯,不過我們沒有用上玩電子遊戲這個特征。現在我們嘗試將限制條件改為葉子結點要有兩個數據點。結果如下:
這棵樹中我們三個特征都用上了,但喜歡戴帽子這個特征多少與年齡無關,這意味著我們的回歸樹可能過擬合了。
此例中我們可以看出使用單個決策/回歸樹(decision/regression tree)的缺點:它無法疊加兩個有重疊區域的有效特征
ID | 年齡 | Tree1 預測結果 | Tree1 預測殘差(Residual) |
1 | 13 | 19.25 | -6.25 |
2 | 14 | 19.25 | -5.25 |
3 | 15 | 19.25 | -4.25 |
4 | 25 | 57.2 | -32.2 |
5 | 35 | 19.25 | 15.75 |
6 | 49 | 57.2 | -8.2 |
7 | 68 | 57.2 | 10.8 |
8 | 71 | 57.2 | 13.8 |
9 | 73 | 57.2 | 15.8 |
現在我們可以用另一棵樹Tree2來擬合Tree1的預測殘差,結果如下:
現在我們可以註意到這顆回歸樹沒有包括喜歡帽子這個特征(之前過擬合的回歸樹使用了這個特征)。這是因為這棵回歸樹可以在全體樣本上考察特征,而之前過擬合的單棵回歸樹只能在局部考察特征。
現在我們可以在第一棵回歸樹的基礎上加上第二棵“糾錯”的回歸樹,結果如下:
PersonID |
Age | Tree1 Prediction | Tree1 Residual | Tree2 Prediction | Combined Prediction | Final Residual |
---|---|---|---|---|---|---|
1 | 13 | 19.25 | -6.25 | -3.567 | 15.68 | 2.683 |
2 | 14 | 19.25 | -5.25 | -3.567 | 15.68 | 1.683 |
3 | 15 | 19.25 | -4.25 | -3.567 | 15.68 | 0.6833 |
4 | 25 | 57.2 | -32.2 | -3.567 | 53.63 | 28.63 |
5 | 35 | 19.25 | 15.75 | -3.567 | 15.68 | -19.32 |
6 | 49 | 57.2 | -8.2 | 7.133 | 64.33 | 15.33 |
7 | 68 | 57.2 | 10.8 | -3.567 | 53.63 | -14.37 |
8 | 71 | 57.2 | 13.8 | 7.133 | 64.33 | -6.667 |
9 | 73 | 57.2 | 15.8 | 7.133 | 64.33 | -8.667 |
Tree1 SSE | Combined SSE |
---|---|
1994 | 1765 |
梯度提升方案1
受上面“糾錯”樹的啟發,我們可以定義以下梯度提升方法:
- 用一個模型來擬合數據 F1(x)= y
- 用另一個模型來擬合前一個模型預測的殘差 h1(x)= y - F1(x)
- 用殘差模型和原模型之和創建一個新模型 F2(x)= F1(x) + h1(x)
我們可以很容易想到插入更多的模型來糾正之前模型的錯誤(譯註,resnet可以看作一個例子):
FM(x) = FM-1(x) + hM-1(x), F1(x) 為初始模型
因為我們第一步初始化了模型F1(x),我們接下來每一步的任務是擬合殘差: hm(x) = y - Fm(x).
現在我們停下來觀察一下,我們只是說hm是一個“模型”-並沒有說它一定要是一個基於樹的模型。這就是梯度提升的一個優點,我們可以輕松引入任何模型,也就是說梯度提升只是用來叠代提升弱模型的。雖然理論上我們的弱模型可以是任何模型,但是實踐中它幾乎總是基於樹的,所以我們現在把hm就當作回歸樹也沒有什麽問題。
梯度提升方案2
我們現在來嘗試像大多數梯度提升實現一樣初始化-將模型初始化為只輸出單一預測。因為我們的任務目前是最小化平方和誤差,我們可以讓初始化F0為預測訓練樣本的均值:
現在我們可以遞歸的定義我們後續的模型了:
,for
其中hm是基礎模型之一,例如回歸樹。
這時你可能會考慮一個問題:如何選取超參數m。 換句話說,我們該用多少次這種殘差校正過程。一種方法是,最佳的m可以通過使用交叉驗證(cross-validation)來測試不同的m來確定。
梯度提升方案3
到現在為止我們的目標都是最小化方差和(L2),但如果我們想最小化絕對值誤差和呢(L1)?我們很容易想到通過改變我們基礎模型(回歸樹)的目標函數來實現這個,但這麽做有幾個缺點:
- 數據量較大時計算上可能很昂貴(每次分裂我們都需要遍歷以找到中位數)
- 上面所說的GB不限制基礎模型的特性將消失,這樣我們將只能用支持此目標函數的基礎模
讓我們試著找找一個更漂亮的解決方案。回顧一下上面的例子,我們會讓F0預測訓練樣本的中位數,也就是35,來最小化絕對值和。現在我們能計算F0的預測殘差了:
PersonID | Age | F0 | Residual0 |
---|---|---|---|
1 | 13 | 35 | -22 |
2 | 14 | 35 | -21 |
3 | 15 | 35 | -20 |
4 | 25 | 35 | -10 |
5 | 35 | 35 | 0 |
6 | 49 | 35 | 14 |
7 | 68 | 35 | 33 |
8 | 71 | 35 | 36 |
9 | 73 | 35 | 38 |
觀察到第一個和第四個訓練樣本的預測殘差為-22和-10. 假設我們能讓每個預測都離各自的真實值更近1個單位,這樣樣本1和樣本4的平方和誤差將分別減少43和19,而兩者絕對值誤差都將減少1。通過上面的計算我們可以發現,使用平方誤差的回歸樹會主要關註減少第一個訓練樣本的預測殘差,而使用絕對值誤差的回歸樹會同樣關註這兩個樣本。現在我們接著訓練h0來擬合F0的預測殘差,與之前不同的是,我們將使用F0的預測損失函數的導數來訓練h0。使用絕對值誤差時,hm只是考慮Fm預測殘差的符號(平方誤差時還會考慮殘差的大小)。在h中的樣本被分到各個葉子結點之後,每個葉子結點的平均梯度就能被計算出來並加權 用於更新模型: (這樣各葉子結點的損失將減少,實際使用中個葉子結點的權重 可能不同)。
梯度下降 (Gradient Descent)
現在讓我們用GD讓上述想法更形式化一點。考慮如下可導損失函數:
目標是找到一對 來最小化 L。我們可以註意到這個損失函數可以看作計算兩個數據點的均方差,兩個數據點的真實值分別為 15 和 25。雖然我們能解析的找到這個損失函數的最小值,但GD能幫我們優化更復雜的損失函數(也許不能找到解析解)。
初始化:
總叠代數 M = 100
起始預測
步長
For iteration to :
1. 計算 在上次預測點 處的梯度
2. 將預測點向最陡梯度方向移動步長 ,也就是
如果步長 夠小且M足夠大的話, 最終預測sM將會收斂到L的最小值。
利用梯度下降
現在讓我們在梯度提升模型中使用GD。將我們的目標函數記為L,起始模型記為F0(x)。在叠代次數 m = 1時,計算L對F0(x)的梯度。然後我們用一個弱模型擬合梯度,以使用回歸樹為例,葉子結點中有相似特征的樣本中會計算出平均梯度,然後使用平均梯度來更新模型,得到F1。重復此過程直到我們得到Fm。
整理一下利用GD的梯度提升算法,描述如下:
初始化:
For m = 1 to M:
計算偽殘差:
用 擬合偽殘差
計算步長(決策樹的情況可以給每個葉子結點單獨分配步長)
更新模型
為幫助你驗證是否理解梯度提升算法,以下分別給出對例子問題使用L1和L2目標函數的結果。
L2損失函數
Age | F0 |
Pseudo Residual0 | h0 | gamma0 | F1 |
Pseudo Residual1 | h1 | gamma1 | F2 |
---|---|---|---|---|---|---|---|---|---|
13 | 40.33 | -27.33 | -21.08 | 1 | 19.25 | -6.25 | -3.567 | 1 | 15.68 |
14 | 40.33 | -26.33 | -21.08 | 1 | 19.25 | -5.25 | -3.567 | 1 | 15.68 |
15 | 40.33 | -25.33 | -21.08 | 1 | 19.25 | -4.25 | -3.567 | 1 | 15.68 |
25 | 40.33 | -15.33 | 16.87 | 1 | 57.2 | -32.2 | -3.567 | 1 | 53.63 |
35 | 40.33 | -5.333 | -21.08 | 1 | 19.25 | 15.75 | -3.567 | 1 | 15.68 |
49 | 40.33 | 8.667 | 16.87 | 1 | 57.2 | -8.2 | 7.133 | 1 | 64.33 |
68 | 40.33 | 27.67 | 16.87 | 1 | 57.2 | 10.8 | -3.567 | 1 | 53.63 |
71 | 40.33 | 30.67 | 16.87 | 1 | 57.2 | 13.8 | 7.133 | 1 | 64.33 |
73 | 40.33 | 32.67 | 16.87 | 1 | 57.2 | 15.8 | 7.133 | 1 | 64.33 |
L1 損失函數
Age | F0 |
Pseudo
Residual0 | h0 | gamma0 | F1 |
Pseudo Residual1 | h1 | gamma1 | F2 |
---|---|---|---|---|---|---|---|---|---|
13 | 35 | -1 | -1 | 20.5 | 14.5 | -1 | -0.3333 | 0.75 | 14.25 |
14 | 35 | -1 | -1 | 20.5 | 14.5 | -1 | -0.3333 | 0.75 | 14.25 |
15 | 35 | -1 | -1 | 20.5 | 14.5 | 1 | -0.3333 | 0.75 | 14.25 |
25 | 35 | -1 | 0.6 | 55 | 68 | -1 | -0.3333 | 0.75 | 67.75 |
35 | 35 | -1 | -1 | 20.5 | 14.5 | 1 | -0.3333 | 0.75 | 14.25 |
49 | 35 | 1 | 0.6 | 55 | 68 | -1 | 0.3333 | 9 | 71 |
68 | 35 | 1 | 0.6 | 55 | 68 | -1 | -0.3333 | 0.75 | 67.75 |
71 | 35 | 1 | 0.6 | 55 | 68 | 1 | 0.3333 | 9 | 71 |
73 | 35 | 1 | 0.6 | 55 | 68 | 1 | 0.3333 | 9 | 71 |
梯度提升方案4
逐漸縮小步長/學習率(shrinkage),以幫助穩定收斂。
梯度提升方案5
行采樣和列采樣。不同采樣技術之所以有效是因為不同采樣回導致不同的樹分叉-這意味著更多的信息。
實戰中的梯度提升
梯度提升算法在實戰中十分有效。其中最流行的實現 XGBoost 在 Kaggle 的比賽中屢次獲獎。XGBoost 使用了許多小技巧來加速和提高準確率(特別是二階梯度下降)。來自微軟的LigtGBM最近也吸引了不少目光。
梯度提升算法還能做些什麽呢?除了回歸(regression),分類和排名也可以用到-只要損失函數是可微即可。分類應用中二元分類常用logistic function作損失函數,多元分類用softmax作損失函數。
原文鏈接:http://blog.kaggle.com/2017/01/23/a-kaggle-master-explains-gradient-boosting/
Kaggle Master解釋梯度提升(Gradient Boosting)(譯)