核心~結合(易少缺過)~最佳~步驟
一、決策樹分類
決策樹分為兩大類,分類樹和回歸樹
分類樹用於分類標簽值,如晴天/陰天/霧/雨、用戶性別、網頁是否是垃圾頁面
回歸樹用於預測實數值,如明天的溫度、用戶的年齡
兩者的區別:
- 分類樹的結果不能進行加減運算,晴天+晴天沒有實際意義
- 回歸樹的結果是預測一個數值,可以進行加減運算,例如 20 歲+3 歲=23 歲
- GBDT中的決策樹是回歸樹,預測結果是一個數值,在點擊率預測方面常用 GBDT,例如用戶點擊某個內容的概率
二、GBDT
GBDT 的全稱是 Gradient Boosting Decision Tree,梯度提升決策樹,核心在於累加所有樹的結果作為最終結果,因此決定了他用的決策樹是回歸樹
為什么梯度提升方法傾向於選擇決策樹作為基學習器呢?(也就是 GB 為什么要和 DT 結合)
決策樹是 if-then 規則的集合,易於理解,預測速度快。
決策樹算法相比於其他的算法需要更少的特征工程,比如可以不用做特征標准化
決策樹可以很好的處理字段缺失的數據,也可以不用關心特征間是否相互依賴等
不過,單獨使用決策樹算法時,容易過擬合。但通過各種方法,抑制決策樹的復雜性,降低單顆決策樹的擬合能力,再通過梯度提升的方法集成多個決策樹,最終能夠很好的解決過擬合的問題
由此可見,梯度提升方法和決策樹學習算法可以互相取長補短,是一對完美的搭檔
至於抑制單顆決策樹的復雜度的方法有很多,比如限制樹的最大深度、限制葉子節點的最少樣本數量、限制節點分裂時的最少樣本數量、吸收 bagging 的思想對訓練樣本采樣(subsample)
在學習單顆決策樹時只使用一部分訓練樣本、借鑒隨機森林的思路在學習單顆決策樹時只采樣一部分特征、在目標函數中添加正則項懲罰復雜的樹結構等
GBDT的思想可以用一個通俗的例子解釋,假如有個人30歲,我們首先用20歲去擬合,發現損失有10歲,這時我們用6歲去擬合剩下的損失,發現差距還有4 歲,第三輪我們用3歲擬合剩下的差距,差距就只有一歲了
三、簡單講解GBDT
GBDT的核心就在於,每一棵樹學的是之前所有樹結論和的殘差。比如A的真實年齡是18歲,但第一棵樹的預測年齡是12歲,差了6歲,即殘差為6歲
那么在第二棵樹里我們把A的年齡設為6歲去學習,如果第二棵樹真的能把A分到6歲的葉子節點,那累加兩棵樹的結論就是A的真實年齡;如果第二棵樹的結論是5歲,則A仍然存在1歲的殘差,第三棵樹里A的年齡就變成1歲,繼續學
這就是Gradient Boosting在GBDT中的意義
年齡預測為例,簡單起見訓練集只有4個人,A,B,C,D,年齡分別是14,16,24,26。其中A,B分別是高一和高三學生;C,D分別是應屆畢業生和工作兩年的員工。
如果用一棵傳統的回歸決策樹來訓練,會得到如下圖1所示結果:

使用GBDT,由於數據太少,我們限定葉子節點最多有兩個,即每棵樹都只有一個分枝,並且限定只學兩棵樹。我們會得到如下圖2所示結果:

在第一棵樹分枝和圖1一樣,由於A,B年齡較為相近,C,D年齡較為相近,他們被分為兩組,每組用平均年齡作為預測值。此時計算殘差(殘差的意思就是: A的預測值 + A的殘差 = A的實際值),所以A的殘差就是14 - 15 = -1
注意,A的預測值是指前面所有樹累加的和,這里前面只有一棵樹所以直接是15,如果還有樹則需要都累加起來作為A的預測值
進而得到A,B,C,D的殘差分別為-1,1,-1,1。然后拿殘差替代A,B,C,D的原值,到第二棵樹去學習,如果我們的預測值和它們的殘差相等,則只需把第二棵樹的結論累加到第一棵樹上就能得到真實年齡了
這里的數據顯然是我刻意做的,第二棵樹只有兩個值1和-1,直接分成兩個節點。此時所有人的殘差都是0,即每個人都得到了真實的預測值
換句話說,現在A,B,C,D的預測值都和真實年齡一致了:
A: 14歲高一學生,購物較少,經常問學長問題;預測年齡A = 15 – 1 = 14
B: 16歲高三學生;購物較少,經常被學弟問問題;預測年齡B = 15 + 1 = 16
C: 24歲應屆畢業生;購物較多,經常問師兄問題;預測年齡C = 25 – 1 = 24
D: 26歲工作兩年員工;購物較多,經常被師弟問問題;預測年齡D = 25 + 1 = 26
那么哪里體現了Gradient呢?其實回到第一棵樹結束時想一想,無論此時的cost function是什么,是均方差還是均差,只要它以誤差作為衡量標准,殘差向量(-1, 1, -1, 1)都是它的全局最優方向,這就是Gradient
四、算法思想
對於回歸樹算法來說最主要的是尋找最佳的划分點,那么回歸樹中的可划分點包含了所有特征的所有可取的值。在分類樹中最佳划分點的判別標准是熵或者基尼系數,都是用純度來衡量的
但是在回歸樹中的樣本標簽也是連續數值,所以再使用熵之類的指標不再合適,取而代之的是平方誤差,它能很好的評判數據分散程度
我們希望最佳划分節點能夠使得划分得到的兩組數據組內的標簽值相近,如果每組的方差都很小,這就說明每組的組內相似度很高,確實應該被划分
下面看看李航《統計學習方法》回歸樹偽代碼:

從上圖可以看出:利用方差尋找最佳划分點,預測值選擇決策樹的葉子節點中所有樣本的真實值的均值。
負梯度-殘差
GBDT無疑也是Boosting家族的一員,而Adaboost在Boosting家族很出名,但是GBDT並沒有采用Adaboost算法!!!那GBDT中的Boosting是怎么做的呢?
先來個通俗理解:假如有個人30歲,我們首先用20歲去擬合,發現損失有10歲,這時我們用6歲去擬合剩下的損失,發現差距還有4歲,第三輪我們用3歲擬合剩下的差距,差距就只有一歲了。如果我們的迭代輪數還沒有完,可以繼續迭代下面,每一輪迭代,擬合的歲數誤差都會減小。
公式表達:在GBDT的迭代中,假設前一輪迭代得到的強學習器是\(f_{t-1}(x)\),損失函數是\(L(y,f_{t-1}(x))\),我們本輪迭代的目標是找到一個CART回歸樹模型的弱學習器\(f_t(x)\),讓本輪的損失函數\(L(y,f_t(x)) = L(y,f_{t-1}(x)+f_t(x))\)最小
GBDT選取了相對來說容易優化的損失函數——平方損失。GBDT使用的平方損失,經過負梯度擬合得到了\(y-f(x_i)\),這就是我們最終要去擬合的,它的另一個名字叫作殘差

算法流程
1.初始化弱分類器:
\(f_0(x) = argmin_\gamma\sum_{i=1}^{N}L(y_i,\gamma)\)
2.對迭代輪數有:\(m = 1,2,...,M\)
a.對每個樣本\(i = 1,2,...,N\)計算負梯度,即殘差 :
\(\gamma_{im} = -\begin{bmatrix}\partial L(y_i,f(x_i))/ \partial f(x_i)\end{bmatrix}_{f(x) = f_{m-1}(x)}\)
b.將上步得到的殘差作為樣本新的真實值,並將數據\((x_i,\gamma_{im})(i=1,2,...,N)\)作為下棵樹的訓練數據,得到一顆新的回歸樹\(f_m(x)\),其對應的葉子節點區域為\(R_{jm},j=1,2,...,J\),其中J為回歸樹t的葉子節點的個數
c.對葉子區域\(j=1,2,...,J\)計算最佳擬合值:
\(\gamma_{jm} = argmin_\gamma\sum_{x_i\epsilon R_{jm}}L(y_i, f_{m-1}(x_i) + \gamma)\)
d.更新強學習器:
\(f_m(x) = f_{m-1}(x) + \sum_{j=1}^{J}\gamma_{jm}I(x\epsilon R_{jm})\)
3.得到強學習器:
\(f(x) = f_m(x) = f_0(x) + \sum_{m=1}^{M}\sum_{j=1}^{J}\gamma_{jm}I(x\epsilon R_{jm})\)
五、跟着算法來看一個實例
如下表所示:一組數據,特征為年齡、體重,身高為標簽值。共有5條數據,前四條為訓練樣本,最后一條為要預測的樣本

1.初始化弱學習器:\(f_0(x) = argmin_\gamma\sum_{i=1}^{N}L(y_i,\gamma)\)
由於此時只有根節點,樣本1,2,3,4都在根節點,此時要找到使得平方損失函數最小的參數\(\gamma\),怎么求呢?平方損失顯然是一個凸函數,直接求導,倒數等於零,得到\(\gamma\):
\(\sum_{i=1}^{N}\partial L(y_i,\gamma)/\partial \gamma = \sum_{i=1}^{N}\partial (y_i-\gamma)^2/\partial \gamma = 2(y_1 - \gamma) + 2(y_2 - \gamma) + 2(y_3 - \gamma) + 2(y_4 - \gamma) = 0\)
所以初始化時,\(\gamma\)取值為所有訓練樣本標簽值的均值。\(\gamma = (1.1 + 1.3 + 1.7 + 1.8) / 4 = 1.475 \),此時得到初始學習器:\(f_0(x) = \gamma = 1.475\)
2.對迭代輪數\(m=1\):
a.對每個樣本\(i = 1,2,...,N\)計算負梯度,即殘差 :
\(\gamma_{i1} = -\begin{bmatrix}\partial L(y_i,f(x_i))/ \partial f(x_i)\end{bmatrix}_{f(x) = f_0(x)}\)
說白了,就是殘差(上面已經解釋過了),在此例中,殘差在下表列出:

b.將上步得到的殘差作為樣本新的真實值,並將數據\((x_i,\gamma_{im})(i=1,2,...,N)\)作為下棵樹的訓練數據,得到一顆新的回歸樹\(f_1(x)\),其對應的葉子節點區域為\(R_{j1},j=1,2,...,J\),其中J為回歸樹t的葉子節點的個數(這里J=2)

接着,尋找回歸樹的最佳划分節點,遍歷每個特征的每個可能取值。從年齡特征的5開始,到體重特征的70結束,分別計算方差,找到使方差最小的那個划分節點即為最佳划分節點。
例如:以年齡7為划分節點,將小於7的樣本划分為一類,大於等於7的樣本划分為另一類。樣本1為一組,樣本2,3,4為一組,兩組的方差分別為0,0.047,兩組方差之和為0.047。所有可能划分情況如下表所示

以上划分點是的總方差最小為0.0125有兩個划分點:年齡21和體重60,所以隨機選一個作為划分點,這里我們選年齡21。 此時還需要做一件事情,給這兩個葉子節點分別賦一個參數,來擬合殘差。
c.對葉子區域\(j=1,2,...,J\)計算最佳擬合值:
\(\gamma_{j1} = argmin_\gamma\sum_{x_i\epsilon R_{j1}}L(y_i, f_0(x_i) + \gamma)\)
這里其實和上面初始化學習器是一個道理,平方損失,求導,令導數等於零,化簡之后得到每個葉子節點的參數\(\gamma\),其實就是標簽值的均值。 根據上述划分節點:
樣本1,2為左葉子節點,\((x_1,x_2 \epsilon R_{11})\),所以\(\gamma_{11} = (-0.375 - 0.175) / 2 = -0.275\)
樣本3,4為右葉子節點,\((x_3,x_4 \epsilon R_{21})\),所以\(\gamma_{21} = (0.225 + 0.325) / 2 = 0.275\)
d.更新強學習器:
\(f_1(x) = f_0(x) + \sum_{j=1}^{2}\gamma_{j1}I(x\epsilon R_{j1})\)
此時可以獲得每個樣本在下輪循環M=2時的值,即將得到的殘差作為樣本新的真實值,參與到下一顆回歸樹的構建,如下:

3.對迭代輪數\(m = 1,2,...,M\),循環迭代M次,M是人為控制的參數,迭代結束生成M棵樹
4.得到最后的強學習器:
為了方別展示和理解,我們假設M=1,根據上述結果得到強學習器:
\(f(x) = f_m(x) = f_0(x) + \sum_{m=1}^{M}\sum_{j=1}^{J}\gamma_{jm}I(x\epsilon R{jm}) = f_0(x) + \sum_{j=1}^{2}\gamma_{j1}(x\epsilon R_{j1})\)
如圖所示得到只迭代一次,只有一顆樹的GBDT:

5.預測樣本5:
樣本5在根節點中(即初始學習器)被預測為1.475,樣本5的年齡為25,大於划分節點21歲,所以被分到了右邊的葉子節點,同時被預測為0.275。此時便得到樣本5的最總預測值為1.75。
六、小結
既然圖1和圖2 最終效果相同,為何還需要GBDT呢?答案是過擬合。我們發現圖1為了達到100%精度使用了3個feature(上網時長、時段、網購金額)相對來說圖2的boosting雖然用了兩棵樹 ,但其實只用了2個feature就搞定
GBDT幾乎可用於所有回歸問題(線性/非線性),相對logistic regression僅能用於線性回歸,GBDT的適用面非常廣。亦可用於二分類問題(設定閾值,大於閾值為正例,反之為負例)
七、參考文獻
李航 《統計學習方法》
博客:https://blog.csdn.net/zpalyq110/article/details/79527653
