原文:http://blog.csdn.net/aspirinvagrant/article/details/48415435
GBDT,全稱Gradient Boosting Decision Tree,叫法比較多,如Treelink、 GBRT(Gradient Boost Regression Tree)、Tree Net、MART(Multiple Additive Regression Tree)等。GBDT是決策樹中的回歸樹,決策樹分為回歸樹和分類樹,分類樹的衡量標准是最大熵,而回歸樹的衡量標准是最小化均方差。GBDT可以用來做分類、回歸。GBDT由多棵決策樹構成,通常都是上百棵樹,而且每棵樹規模都較小(即樹的深度會比較淺)。模型預測的時候,對於輸入的一個樣本實例,然后會遍歷每一棵決策樹,每棵樹都會對預測值進行調整修正,最后得到預測的結果。
為了搞明白GBDT,下面先解釋Gradient Boosting(GB,梯度提升)。
Boosting是利用一些弱分類器的組合來構造一個強分類器。與Boosting相比,GB每一次的計算是為了減少上一次的殘差,就可以在殘差減少的梯度方向上建立一個新的模型。在Gradient Boost中,每個新的模型是為了使得之前模型的殘差往梯度方向減少,與Boosting對錯誤的樣本加大加權的做法有着很大的區別。
還是不太明白?想想在線性回歸中,我們希望找到一組參數使得模型的殘差最小化。如果只使用一次項來解釋二次曲線,那么就會存有大量殘差,此時就可以用二次項來繼續解釋殘差,所以可在模型中加入這個二次項。同樣的,GB是先根據初始模型計算偽殘差,之后建立一個學習器來解釋偽殘差,該學習器是在梯度方向上減少殘差。再將該學習器乘上權重系數(學習速率)和原來的模型進行線性組合形成新的模型。這樣反復迭代就可以找到一個使損失函數的期望達到最小的模型。
GBDT的每一棵樹學的是之前所有樹結論和的殘差,這個殘差就是一個加預測值后能得真實值的累加量。比如A的真實年齡是18歲,但第一棵樹的預測年齡是12歲,差了6歲,即殘差為6歲。那么在第二棵樹里我們把A的年齡設為6歲去學習。如果第二棵樹真的能把A分到6歲的葉子節點,那累加兩棵樹的結論就是A的真實年齡。如果第二棵樹的結論是5歲,則A仍然存在1歲的殘差,第三棵樹里A的年齡就變成1歲,繼續學習。
概括GBDT:先構造一個(決策)樹,然后不斷在已有模型和實際樣本輸出的殘差上再構造一顆樹,依次迭代
GBDT的學習過程
ABCD四個人的年齡分別為15,19,23,27,分別為高中生、大學生、運動員和碼農。
決策樹學習過程:

GBDT的學習過程:

現在A,B,C,D的預測值都和真實年齡一致
A: 15歲高中學生,收入較少,天天沒時間玩電腦;預測年齡A = 17– 2 = 15
B: 19歲大學生;收入較少,天天宅在宿舍玩電腦;預測年齡B = 17+ 2 = 19
C: 23歲運動員;收入較多,體育訓練沒時間玩電腦;預測年齡C = 25 – 2 = 23
D: 27歲碼農;收入較多,長時間玩電腦;預測年齡D = 25 + 2 = 27
GBDT的優點:
(1)防止過擬合;
(2)每一步的殘差計算其實變相地增大了分錯instance的權重,而已經分對的instance則都趨向於0;
(3)殘差作為全局最優的絕對方向。
GBDT的兩個版本:
(1)殘差版本把GBDT認為是一個殘差迭代樹,每一棵回歸樹都在學習前N-1棵樹的殘差;
求解方法:殘差----殘差是全局最優值
優化目標:讓結果變成最好
(2)Gradient版本把 GBDT看作一個梯度迭代樹,使用梯度下降法求解,每一棵回歸樹在學習前N-1棵樹的梯度下降值。
求解方法:局部最優方向 * 步長
優化目標:讓結果變成更好
RF和GBDT的對比:


R語言中gbm包用來實現boosting的擴展包。在gbm包中,采用的是決策樹作為基學習器,重要的參數設置如下:
- 損失函數的形式(distribution)
- 迭代次數(n.trees)
- 學習速率(shrinkage)
- 再抽樣比率(bag.fraction)
- 決策樹的深度(interaction.depth)
損失函數的形式容易設定,分類問題一般選擇bernoulli分布,而回歸問題可以選擇gaussian分布。學習速率方面,學習速率是越小越好,但是步子太小的話,步數就得增加,也就是訓練的迭代次數需要加大才能使模型達到最優,這樣訓練所需時間和計算資源也相應加大了。經驗法則是設置shrinkage參數在0.01-0.001之間,而n.trees參數在3000-10000之間。
采用gbm自帶的例子:
1、構造數據集
- # A least squares regression example # create some data
- N <- 1000
- X1 <- runif(N)
- X2 <- 2*runif(N)
- X3 <- ordered(sample(letters[1:4],N,replace=TRUE),levels=letters[4:1])
- X4 <- factor(sample(letters[1:6],N,replace=TRUE))
- X5 <- factor(sample(letters[1:3],N,replace=TRUE))
- X6 <- 3*runif(N)
- mu <- c(-1,0,1,2)[as.numeric(X3)]
- SNR <- 10 # signal-to-noise ratio
- Y <- X1**1.5 + 2 * (X2**.5) + mu
- sigma <- sqrt(var(Y)/SNR)
- Y <- Y + rnorm(N,0,sigma)
- # introduce some missing values
- X1[sample(1:N,size=500)] <- NA
- X4[sample(1:N,size=300)] <- NA
- data <- data.frame(Y=Y,X1=X1,X2=X2,X3=X3,X4=X4,X5=X5,X6=X6)
2、使用gbm函數建模
- library(gbm)
- # fit initial model
- gbm1 <-
- gbm(Y~X1+X2+X3+X4+X5+X6, # formula
- data=data, # dataset
- var.monotone=c(0,0,0,0,0,0), # -1: monotone decrease, +1: monotone increase,
- # 0: no monotone restrictions
- distribution="gaussian", # see the help for other choices
- n.trees=1000, # number of trees
- shrinkage=0.05, # shrinkage or learning rate, 0.001 to 0.1 usually work
- interaction.depth=3, # 1: additive model, 2: two-way interactions, etc.
- bag.fraction = 0.5, # subsampling fraction, 0.5 is probably best
- train.fraction = 0.5, # fraction of data for training, first train.fraction*N used for training
- n.minobsinnode = 10, # minimum total weight needed in each node
- cv.folds = 3, # do 3-fold cross-validation
- keep.data=TRUE, # keep a copy of the dataset with the object
- verbose=FALSE, # don't print out progress
- n.cores=1) # use only a single core (detecting #cores is error-prone, so avoided here)
3、使用交叉驗證確定最佳迭代次數
- # check performance using 5-fold cross-validation
- best.iter <- gbm.perf(gbm1,method="cv")
- print(best.iter)
- [1] 111

4、各解釋變量的重要程度
- # plot the performance # plot variable influence
- summary(gbm1,n.trees=best.iter) # based on the estimated best number of trees
- var rel.inf
- X3 X3 65.28183677
- X2 X2 29.23551102
- X1 X1 4.03158814
- X4 X4 0.77052093
- X6 X6 0.62159781
- X5 X5 0.05894533

參考資料:
Generalized Boosted Regression Modeling(gbm package)
HITSCIR-TM zkli-李澤魁 Bagging & Boosting
