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通过迭代选择一个目标损失函数的负梯度方向上的基函数来逐渐逼近局部极小值。
还是不太明白?想想在线性回归中,我们希望找到一组参数使得模型的残差最小化。如果只使用一次项来解释二次曲线,那么就会存有大量残差,此时就可以用二次项来继续解释残差,所以可在模型中加入这个二次项。同样的,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包中,采用的是决策树作为基学习器,重要的参数设置如下:
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)
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
# 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