1. 程式人生 > >CART迴歸樹和GBDT

CART迴歸樹和GBDT

CART 分為迴歸樹和決策樹。這裡重點講講迴歸樹的特徵選擇。

迴歸樹選擇特徵的方法是:平方誤差最小化。

具體步驟為:

1)依次遍歷每個特徵j,以及該特徵的每個取值s,計算每個切分點(j,s)的損失函式,選擇損失函式最小的切分點。



其中c1,c2分別為R1,R2區間內的輸出平均值。

2)使用上步得到的切分點將當前的輸入空間劃分為兩個部分

3)然後將被劃分後的兩個部分再次計算切分點,依次類推,直到不能繼續劃分。

4)最後將輸入空間劃分為M個區域R1,R2,…,RM,生成的決策樹為:


其中cm為所在區域的輸出值的平均值

總結:此方法的複雜度較高,尤其在每次尋找切分點時,需要遍歷當前所有特徵的所有可能取值,假如總共有F個特徵,每個特徵有N個取值,生成的決策樹有S個內部節點,則該演算法的時間複雜度為:O(F*N*S)。


下面說GBDT

 GBDT(Gradient Boosting Decision Tree) 又叫 MART(Multiple Additive Regression Tree),是一種迭代的決策樹演算法,該演算法由多棵決策樹組成,所有樹的結論累加起來做最終答案。GBDT主要由三個概念組成:Regression Decistion Tree(即DT),Gradient Boosting(即GB),Shrinkage (演算法的一個重要演進分枝)。

一、 DT:迴歸樹 Regression Decision Tree

GDBT是由迴歸樹組成的。

二、 GB:梯度迭代 Gradient Boosting


Boosting,迭代,即通過迭代多棵樹來共同決策。這怎麼實現呢?難道是每棵樹獨立訓練一遍,比如A這個人,第一棵樹認為是10歲,第二棵樹認為是0歲,第三棵樹認為是20歲,我們就取平均值10歲做最終結論?--當然不是!且不說這是投票方法並不是GBDT,只要訓練集不變,獨立訓練三次的三棵樹必定完全相同,這樣做完全沒有意義。之前說過,GBDT是把所有樹的結論累加起來做最終結論的,所以可以想到每棵樹的結論並不是年齡本身,而是年齡的一個累加量。GBDT的核心就在於,每一棵樹學的是之前所有樹結論和的殘差,這個殘差就是一個加預測值後能得真實值的累加量。比如A的真實年齡是18歲,但第一棵樹的預測年齡是12歲,差了6歲,即殘差為6歲。那麼在第二棵樹裡我們把A的年齡設為6歲去學習,如果第二棵樹真的能把A分到6歲的葉子節點,那累加兩棵樹的結論就是A的真實年齡;如果第二棵樹的結論是5歲,則A仍然存在1歲的殘差,第三棵樹裡A的年齡就變成1歲,繼續學。這就是Gradient Boosting在GBDT中的意義,簡單吧。


三、Shrinkage 

Shrinkage(縮減)的思想認為,每次走一小步逐漸逼近結果的效果,要比每次邁一大步很快逼近結果的方式更容易避免過擬合。即它不完全信任每一個棵殘差樹,它認為每棵樹只學到了真理的一小部分,累加的時候只累加一小部分,通過多學幾棵樹彌補不足。用方程來看更清晰,即

沒用Shrinkage時:(yi表示第i棵樹上y的預測值, y(1~i)表示前i棵樹y的綜合預測值)

y(i+1) = 殘差(y1~yi), 其中: 殘差(y1~yi) =  y真實值 - y(1 ~ i)

y(1 ~ i) = SUM(y1, ..., yi) 意思是:前i顆數的預測值的總和為最後預測值。

Shrinkage不改變第一個方程,只把第二個方程改為: 

y(1 ~ i) = y(1 ~ i-1) + step * yi

即Shrinkage仍然以殘差作為學習目標,但對於殘差學習出來的結果,只累加一小部分(step*殘差)逐步逼近目標,step一般都比較小,如0.01~0.001(注意該step非gradient的step),導致各個樹的殘差是漸變的而不是陡變的。直覺上這也很好理解,不像直接用殘差一步修復誤差,而是隻修復一點點,其實就是把大步切成了很多小步。本質上,Shrinkage為每棵樹設定了一個weight,累加時要乘以這個weight,但和Gradient並沒有關係。這個weight就是step。就像Adaboost一樣,Shrinkage能減少過擬合發生也是經驗證明的,目前還沒有看到從理論的證明。

 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的殘差就是16-15=1(注意,A的預測值是指前面所有樹累加的和,這裡前面只有一棵樹所以直接是15,如果還有樹則需要都累加起來作為A的預測值)。進而得到A,B,C,D的殘差分別為-1,1,-1,1。然後我們拿殘差替代A,B,C,D的原值,到第二棵樹去學習,如果我們的預測值和它們的殘差相等,則只需把第二棵樹的結論累加到第一棵樹上就能得到真實年齡了。這裡的資料顯然是我可以做的,第二棵樹只有兩個值1和-1,直接分成兩個節點。此時所有人的殘差都是0,即每個人都得到了真實的預測值。

換句話說,現在A,B,C,D的預測值都和真實年齡一致了。Perfect!:

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。