1、GBDT简介
- 全称:Gradient Boosting Decison Tree
- 别名:GBT(Gradient Boosting Tree), GTB(Gradient Tree Boosting ), GBRT(Gradient Boosting Regression Tree), MART(Multiple Additive Regression Tree)
- 做者:Friedman
- 所属:boosting迭代型、树类算法
- Boosting Tree 对于每一轮基学习器,拟合的是当前模型与标签值的残差
- GBDT 对于每一轮基学习器,拟合的是当前模型与标签值的残差的负梯度
- 适用范围:分类、回归
- 分类:用Gini系数,越小越好
- 回归:用平方偏差,越小越好
- 回归树与决策树的生成框架是相同的,惟一不一样在于节点的属性选择标准
- 基学习器:CART树(分类回归树)
- 思想:若是样本1的输出真实值为10,树T1针对样本1的预测值为18,而后咱们让树T2去拟合样本1的值为10-18=-8(残差)。若是树T2的输出值为-10,咱们再让树T3去拟合-8-(-10)=2(残差),结果树T3的预测值为1。若是到此迭代结束,在最终对样本1的预测值为:18+(-10)+1=9。经过多轮迭代,每轮迭代产生一个弱模型,每一个模型都是在上一个模型的残差基础上进行训练的,最后将全部树的结果求和得出最终的结果。
- 优势:
- 可以处理连续值/离散值;
- 对异常值的鲁棒性很强,如Huber损失函数和Quantile损失函数
- GBDT的并行主要是针对单棵树特征处理和选择的并行(特征排序),以及在模型完成后进行预测时的并行。
- sklearn连接:https://www.studyai.cn/modules/ensemble.html#gradient-tree-boosting
- 论文连接:
2、GBDT步骤

GBDT流程图php
1.负梯度拟合
第t棵树的第i个样本的损失函数的负梯度表示为:$r_{ti} = -\bigg[\frac{\partial L(y_i, f(x_i)))}{\partial f(x_i)}\bigg]_{f(x) = f_{t-1}\;\; (x)}$html
负梯度的计算:git
- 对于平方损失函数,拟合的残差就是负梯度;(为何要拟合负梯度,见第三节)
- 对于通常损失函数(梯度降低),拟合的负梯度就是残差的近似值,分裂结点划分时枚举全部特征的值,选取划分点。
利用$(x_i,r_{ti})(i=1,2,...,m)$咱们能够拟合一棵CART回归树,获得了第t棵回归树,其对应的叶节点区域$R_{tj},j=1,2,...,J$其中J为叶子节点的个数。github
GBDT分类回归用的都是CART回归树,选择特征时用均方偏差选择最小的分割点。对于任意划分特征A,对应的任意划分点s两边划分红的数据集D1和D2,求出使D1和D2各自集合的均方差最小,同时D1和D2的均方差之和最小所对应的特征和特征值划分点。表达式为:web
$$\underbrace{min}_{A,s}\Bigg[\underbrace{min}_{c_1}\sum\limits_{x_i \in D_1(A,s)}(y_i - c_1)^2 + \underbrace{min}_{c_2}\sum\limits_{x_i \in D_2(A,s)}(y_i - c_2)^2\Bigg]$$面试
其中,c1为D1数据集的样本输出均值,c2为D2数据集的样本输出均值。算法
针对每个叶子节点里的样本,咱们求出使损失函数最小,也就是拟合叶子节点最好的输出值$c_{tj}$以下:$c_{tj} = \underbrace{arg\; min}_{c}\sum\limits_{x_i \in R_{tj}} L(y_i,f_{t-1}(x_i) +c)$框架
这样获得了本棵决策树拟合函数:$h_t(x) = \sum\limits_{j=1}^{J}c_{tj}I(x \in R_{tj})$函数
从而本轮最终获得的强学习器的表达式以下:$f_{t}(x) = f_{t-1}(x) + \sum\limits_{j=1}^{J}c_{tj}I(x \in R_{tj})$ ,最后预测的结果是每棵树的预测结果相加。post
2.回归问题
给定数据集:$T=\{(x_,y_1),(x_2,y_2), ...(x_m,y_m)\}$
a.MSE(GBDT回归所用)
- $Cost(y,f(x))=\frac{1}{2}\sum(y-f(x))^2$
- 负梯度:$y-f(x)$
- 对异常值很敏感
- 初始模型F0由目标变量的平均值给出
b.绝对损失
- $Cost(y,f(x))=\frac{1}{2}\sum|y-f(x)|$
- 负梯度:$sign(y-f(x))$
- 对异常值不敏感
- 初始模型F0由目标变量的中值给出
c.Huber损失
- $L(y, f(x))= \begin{cases} \frac{1}{2}(y-f(x))^2& {|y-f(x)| \leq \delta}\\ \delta(|y-f(x)| - \frac{\delta}{2})& {|y-f(x)| > \delta} \end{cases}$
- 负梯度:$r(y_i, f(x_i))= \begin{cases} y_i-f(x_i)& {|y_i-f(x_i)| \leq \delta}\\ \delta sign(y_i-f(x_i))& {|y_i-f(x_i)| > \delta} \end{cases}$
- 它是MSE和绝对损失的组合形式,对于远离中心的异常点,采用绝对损失,其余的点采用MSE,这个界限通常用分位数点度量。
- 对异常值不敏感
- 使用alpha参数来控制损失函数对离群点(outliers)的敏感度(sensitivity)
d.Quantile损失
- $L_q(\text{y},\hat{\text{y}})=\frac{1}{n}(1-q)\sum_{i:\hat{y_i}\geq y_i}(\hat{y_i} - y_i)+\frac{1}{n}q\sum_{j:\hat{y_j}< y_j}(y_j-\hat{y_j} )$
- 负梯度:$r(y_i, f(x_i))= \begin{cases} y_i-f(x_i)& {|y_i-f(x_i)| \leq \delta}\\ \delta sign(y_i-f(x_i))& {|y_i-f(x_i)| > \delta} \end{cases}$
- 怎么理解?
- 用于分位数回归
- 对于Huber损失和分位数损失,主要用于健壮回归,也就是减小异常点对损失函数的影响
- 当q>0.5时,目标函数对预测值偏小的结果惩罚更大
- 当q<0.5时,目标函数对预测值偏大的结果惩罚更大
(2)算法
step1
初始化:针对数据集,创建第一个CART回归树$T_1(x)$
- $f_0(x) = \underbrace{arg\; min}_{c}\sum\limits_{i=1}^{m}L(y_i, c)$
- c是针对每个叶子节点里的样本,使得损失函数最小,也就是拟合叶子节点最好的输出值
step2
对迭代次数t=1,2,...,T有:
- a.对样本i=1,2,...,m,计算负梯度$r_{ti} = -\bigg[\frac{\partial L(y_i, f(x_i)))}{\partial f(x_i)}\bigg]_{f(x) = f_{t-1}\;\; (x)}$
- b.利用$(x_i,r_{ti})(i=1,2,3,...m)$拟合一棵CART回归树,获得第t棵回归树,其对应的叶子节点区域为$R_{tj},j=1,2,...,J$其中,J为回归树t的叶子节点的个数
- c.对叶子区域j=1,2,...J,计算最佳拟合值$c_{tj} = \underbrace{arg\; min}_{c}\sum\limits_{x_i \in R_{tj}} L(y_i,f_{t-1}(x_i) +c)$
- d.更新强学习器$f_{t}(x) = f_{t-1}(x) + \sum\limits_{j=1}^{J}c_{tj}I(x \in R_{tj})$
3.分类问题
这里解释下,为何GBDT解决分类问题用的也是回归树。由于GBDT的根本就是在不断地拟合残差,残差的加减能够逐渐减少误差。而分类树输出的是类别,他们之间的加减是没有意义的。分类问题和回归问题的最大不一样在于损失函数的定义以及节点输出值的肯定,其余都是同样的。
(1)损失函数
- 对数似然损失函数:
- 二元:$L(y, f(x)) = log(1+ exp(-yf(x)))$
- 多元:$L(y, f(x)) = - \sum\limits_{k=1}^{K}y_klog\;p_k(x)$
- 指数损失函数:
- 与adaboost的损失函数同样,与log loss相比,对于误标记的样本的鲁棒性较差,只能用于二元分类
- $L(y, f(x)) = exp(-yf(x))$
(2)二分类
- 损失函数:$L(y, f(x)) = log(1+ exp(-yf(x)))$,标签y属于{-1,+1}
- 负梯度:$r_{ti} = -\bigg[\frac{\partial L(y, f(x_i)))}{\partial f(x_i)}\bigg]_{f(x) = f_{t-1}\;\; (x)} = y_i/(1+exp(y_if(x_i)))$
- 生成的决策树每一个叶子节点最佳负梯度拟合值为:$c_{tj} = \underbrace{arg\; min}_{c}\sum\limits_{x_i \in R_{tj}} log(1+exp(-y_i(f_{t-1}(x_i) +c)))$
- 上式比较难优化,通常用近似值替代:$c_{tj} = \sum\limits_{x_i \in R_{tj}}r_{ti}\bigg / \sum\limits_{x_i \in R_{tj}}|r_{ti}|(1-|r_{ti}|)$
(3)多分类
- 损失函数:$L(y, f(x)) = - \sum\limits_{k=1}^{K}y_klog\;p_k(x)$
- 其中若是样本输出类别为k,则yk=1。第k类的几率pk(x)的表达式为:
- 负梯度:第t轮的第i个样本对应类别l的负梯度偏差$r_{til} = -\bigg[\frac{\partial L(y_i, f(x_i)))}{\partial f(x_i)}\bigg]_{f_k(x) = f_{l, t-1}\;\; (x)} = y_{il} - p_{l, t-1}(x_i)$
- 生成的决策树每一个叶子节点的最佳负梯度拟合值为:$$c_{tjl} = \underbrace{arg\; min}_{c_{jl}}\sum\limits_{i=0}^{m}\sum\limits_{k=1}^{K} L(y_k, f_{t-1, l}(x) + \sum\limits_{j=0}^{J}c_{jl} I(x_i \in R_{tjl}))$$
- 上式比较难优化,通常用近似值代替:$c_{tjl} = \frac{K-1}{K} \; \frac{\sum\limits_{x_i \in R_{tjl}}r_{til}}{\sum\limits_{x_i \in R_{til}}|r_{til}|(1-|r_{til}|)}$(怎么获得的?)
- 除了负梯度计算和叶子节点的最佳负梯度拟合的线性搜索,多元GBDT分类和二元GBDT分类以及GBDT回归算法过程相同。
4.GBDT用到的技巧
4.1 shrinkage

- Shrinkage的思想认为,每次走一小步逐渐逼近结果的效果,要比每次迈一大步很快逼近结果的方式更容易 获得精确值,即它不彻底信任每一棵残差树,认为每棵树只学到了真理的一部分累加的时候只累加了一小部分多学几棵树来弥补不足。 这个技巧相似于梯度降低里的学习率
- $f_{k}(x) = f_{k-1}(x) + \nu h_k(x)$,其中v被称之为learning rate,它能够控制梯度降低的步长,而且能够经过learning_rate参数来设置,$\gamma$是人为设置的参数,用来调整学习的快慢和精度
- 选择小于1的比例能够减小泛化时的方差(测试集的方差),即防止过拟合,可是会增长样本拟合的误差,所以取值不能过低。推荐在[0.5, 0.8]之间。
4.2 重复使用属性
在GBDT的每一棵树中,一个属性能够在多个节点用到
4.3 子采样
GBDT学习了RF里的样本采样方法,每一棵树基于原始本来的一个子集进行训练,达到防止过拟合和提高训练速度的目的。
- 样本子采样subsample,经过无放回采样得到(RF是有放回采样)
- 减小方差的策略是特征子采样,这种相似于随机森林中的随机分割,子采样的特征数量能够经过参数max_features来控制,使用一个小的max_features值可以显著下降计算时间。
4.4 剪枝
对于弱学习器即CART回归树进行正则化剪枝
5.对结果的解释
- 特征重要性
- 若是一个特征在树的分割节点中用的越频繁,则这个特征的重要性就越高。 这种特征重要性的概念能够 经过简单的平均一下每棵树上的特征重要性扩展到决策树集合。
- 部分依赖性
- 部分依赖图(Partial dependence plots (PDP))展现了目标响应和一系列目标特征的依赖关系, 同时边缘化了其余全部特征的取值(候选补充特征)。 直觉上,咱们能够将部分依赖解释为做为目标特征函数 的预期目标响应 。
3、GBDT面试总结
1.优缺点
优势:
缺点:因为弱学习器之间存在依赖关系,难以并行训练数据。不过能够经过自采样的SGBT来达到部分并行。
2.GBDT 和 随机森林/Adaboost/LR的区别与联系
-
GBDT和随机森林
- 相同点:
- 都是由多棵树组成
- 最终的结果都是由多棵树一块儿决定
- 不一样点:
- 组成随机森林的树能够并行生成;而GBDT只能是串行生成 ;
- 对于最终的输出结果而言,随机森林采用多数投票等;而GBDT则是将全部结果累加起来,或者加权累加起来 ;
- 随机森林对异常值不敏感,GBDT对异常值很是敏感 ;
- 随机森林对训练集一视同仁,GBDT是基于权值的弱分类器的集成 ;
- 随机森林是经过减小模型方差提升性能,GBDT是经过减小模型误差提升性能;
- 随机森林既可使用决策树也可使用回归树,可是gbdt采用的都是CART回归树。
和AdaBoost同样,Gradient Boosting也是重复选择一个表现通常的模型而且每次基于先前模型的表现进行调整。不一样的是,AdaBoost是经过提高错分数据点的权重来定位模型的不足而Gradient Boosting是经过算梯度(gradient)来定位模型的不足。所以相比AdaBoost, Gradient Boosting可使用更多种类的目标函数,而当目标函数是均方偏差时,计算损失函数的负梯度值在当前模型的值即为残差。
从决策边界来讲,线性回归的决策边界是一条直线,逻辑回归的决策边界是一条曲线,而GBDT的决策边界多是不少条线。
3. 为何拟和负梯度能够下降集成模型的损失,即为何拟合负梯度是可行的?
参考连接



4. 即使拟合负梯度是可行的,为何不直接拟合残差? 拟合负梯度好在哪里?
参考连接
Boosting Tree 和 GBDT 二者的相同之处在于,都是迭代回归树,都是累加每棵树的结果做为最终结果,每棵树都在学习前m-1棵树尚存的不足,从整体流程和输入输出上二者是没有区别的.
二者的主要区别就在于每步迭代的时候是否使用残差的负梯度做为树的拟合对象,前者不用残差的负梯度而是使用残差,是全局最优值,后者使用的是 局部最优方向(负梯度)*步长(𝛽),即前者是每一步都试图让结果变成最好,后者则每步试图让结果更好一点.
Boosting Tree的最大问题在于,它依赖残差进行优化,损失函数通常固定为反应残差的均方差损失函数,所以 当均方差损失函数失效(该损失函数对异常值敏感)的时候,换了其余通常的损失函数,便很可贵到优化的结果。同时,由于损失函数的问题,Boosting Tree也很难处理回归以外问题。 然后者使用梯度降低的方法,对于任意能够求导的损失函数它均可以处理.
GBDT本质上是以梯度降低和参数搜索(𝛽)的办法简化了Boosting Tree对于损失函数的优化求解问题.
5.gbdt在分类时,当以指数损失做为损失函数时,为何等价于adaboost?
参考(109楼)
若是采用指数函数,那么Adaboost每一步就在拟合指数损失的梯度。也就是第t轮要依据$(x_i, -y_i exp(-y_if_{t-1}x)$拟合一颗决策树。
$\sum\limits_{i=1}^{m}Loss(f_{t-1}(x)+\alpha_tG_t(x) , y_i) = \sum\limits_{i=1}^{m}exp(-y_i(f_{t-1}(x)+\alpha_tG_t(x))) = \sum\limits_{i=1}^{m}exp(-y_i(f_{t-1}(x)) exp(-y_i\alpha_tG_t(x)) = \sum\limits_{i=1}^{m} w_{ti}^{’}exp(-y_i\alpha G(x))$
最后这个式子就是咱们Adaboost的须要极小化的损失函数公式,它能够从第一步的GBDT的残差思路递推出来。
参考文献: