GBDT即可用于解决回归问题,也能用于解决分类问题。在初步理解GBDT时,最好从回归和分类的角度分别理顺思路,发现其中的不同和关键点,就能初步明白GBDT的算法原理。接下来从回归和分类的角度分别记录下:
1、回归的角度——初步:
GBDT的思想可以用一个通俗的例子解释,假如有个人30岁,我们首先用20岁去拟合,发现损失有10岁,这时我们用6岁去拟合剩下的损失,发现差距还有4岁,第三轮我们用3岁拟合剩下的差距,差距就只有一岁了。如果我们的迭代轮数还没有完,可以继续迭代下面,每一轮迭代,拟合的岁数误差都会减小。
直观的解释:GBDT是一系列回归树(CART)的加法组合,后一颗树拟合之前预测结果与目标的“残差”。具体说明如下:假设样本集 ,第一轮用一个模型,如
去拟合这些数据,使得这批样本的平方损失函数(即
)最小。但是发现虽然模型的拟合效果很好,但仍然有一些差距,比如预测值
,而真实值
,
,
等等。第二轮用一个新的模型
来拟合
未完全拟合真实样本的残差,即
。所以对于每个样本来说,拟合的样本集就变成了:
。依次类推第三轮、第四轮,……,直到满足终止条件,将所有学得的模型相加得到最终的结果,这就是GBDT。
被称为残差,这一部分也就是前一模型
未能完全拟合的部分,所以交给新的模型来完成。GBDT的全称是Gradient Boosting Decision Tree,其中gradient被称为梯度,更一般的理解,可以认为是一阶导,那么这里的残差与梯度是什么关系呢。在第一部分,我们提到了一个叫做平方损失函数的东西,具体形式可以写成
,熟悉其他算法的原理应该知道,这个损失函数主要针对回归类型的问题,分类则是用熵值类的损失函数。具体到平方损失函数的式子,它的一阶导其实就是残差的形式,所以基于残差的GBDT是一种特殊的GBDT模型,它的损失函数是平方损失函数,只能处理回归类的问题。具体形式可以如下表示:
损失函数的一阶导:
正好残差就是负梯度:
1.1为什么基于残差的GBDT不是一个好的选择
首先基于残差的GBDT只能处理回归类的问题,不能处理分类问题,这是损失函数所限制的,所以更一般化的GBDT是基于梯度的算法,这也就意味着只要给出的损失函数是可导的,那么就能用GBDT的思想去解决问题。具体解决的问题就不会仅仅限于回归了。
另外,基于残差的GBDT在解决回归问题上也不算是一个好的选择,一个比较明显的缺点就是对异常值过于敏感。来看一个例子(注:这个和本文要介绍的内容关系不是很大,只是在这个位置涉及到了,举个例子说明下损失函数的优劣对比,证明下基于残差的GBDT不是最好的选择。为啥是残差,其根源是损失函数选择了平方损失函数):
很明显后续的模型会对第4个值关注过多,这不是一种好的现象,所以一般回归类的损失函数会用绝对损失或者huber损失函数来代替平方损失函数:
以上从回归的角度,以特例的方式初步对GBDT进行了解释(平方损失函数)。接下从回归的角度进一步深入解释,得到通用的GBDT(负梯度)
2、回归的角度——深入:
2.1、GBDT的负梯度拟合
GBDT也是集成学习Boosting家族的成员,但是却和传统的Adaboost有很大的不同。回顾下Adaboost,我们是利用前一轮迭代弱学习器的误差率来更新训练集的权重,这样一轮轮的迭代下去。GBDT也是迭代,使用了前向分布算法,但是弱学习器限定了只能使用CART回归树模型,同时迭代思路和Adaboost也有所不同。在GBDT的迭代中,假设我们前一轮迭代得到的强学习器是, 损失函数是
, 本轮迭代的目标是找到一个CART回归树模型的弱学习器
,让本轮的损失函数
最小。也就是说,本轮迭代找到决策树,要让样本的损失尽量变得更小。从上面的例子看这个思想还是蛮简单的,但是有个问题是这个损失的拟合不好度量,损失函数各种各样,怎么找到一种通用的拟合方法呢?
上一段中介绍了GBDT的基本思路,但是没有解决损失函数拟合方法的问题?。针对这个问题,大牛Freidman提出了用损失函数的负梯度来拟合本轮损失的近似值,进而拟合一个CART回归树。第t轮的第i个样本的损失函数的负梯度表示为
利用,可以拟合一颗CART回归树,得到的第t棵回归树,其对应的叶节点区域
。其中J为叶子节点的个数。针对每一个叶子节点里的样本,求出使损失函数最小,也就是拟合叶子节点最好的的输出值
如下(注:这里的c代表的是未知变量,其求得的使损失函数L最小的值是
):
这样就得到了本轮的决策树拟合函数如下:
经过本轮(第 t 轮)学习后得到的强学习器的表达式如下:
通过损失函数的负梯度来拟合,找到了一种通用的拟合损失误差的办法,这样无轮是分类问题还是回归问题,通过其损失函数的负梯度的拟合,就可以用GBDT来解决分类和回归问题。区别仅仅在于损失函数不同导致的负梯度不同而已。
2.2、GBDT回归算法
基于上面的思路,下面总结下GBDT的回归算法。为什么没有加上分类算法一起?因为分类算法的输出是不连续的类别值,需要一些处理才能使用负梯度(定义损失函数时处理,我认为没啥区别,其本质是损失函数的设计,因为分类问题不能一步步拟合“残差”,以LR的对数似然函数作为损失函数来拟合“残差”,其本质是用类别的预测概率值来拟合正确的概率值),下一节讲。输入是训练集样本, 最大迭代次数
, 损失函数
。
输出是强学习器
1) 初始化弱学习器(这里初始化一个c的值,通常为所有样本点的平均值)
2) 对迭代轮数 有:
a)对样本 ,计算负梯度
b)利用,拟合一颗CART回归树,得到第 t 颗回归树,其对应的叶子节点区域为
。其中
为回归树 t 的叶子节点的个数。
c) 对叶子区域,计算最佳拟合值
d) 更新强学习器
3) 得到强学习器的表达式
3、分类的角度:
3.1、GBDT分类算法
接着再看看GBDT分类算法,GBDT的分类算法从思想上和GBDT的回归算法没有区别,但是由于样本输出不是连续的值,而是离散的类别,导致无法直接从输出类别去拟合类别输出的误差。为了解决这个问题,主要有两个方法,一个是用指数损失函数,此时GBDT退化为Adaboost算法。另一种方法是用类似于逻辑回归的对数似然损失函数的方法。也就是说,用的是类别的预测概率值和真实概率值的差来拟合损失。接下来讨论用对数似然损失函数的GBDT。而对于对数似然损失函数,又有二元分类和多元分类的区别。
3.2 二元GBDT分类算法
对于二元GBDT,如果用类似于逻辑回归的对数似然损失函数,则损失函数为:
其中。则此时的负梯度误差为
对于生成的决策树,各个叶子节点的最佳残差拟合值为
由于上式比较难优化,一般使用近似值代替
除了负梯度计算和叶子节点的最佳残差拟合的线性搜索,二元GBDT分类和GBDT回归算法过程相同?。
3.3、多元GBDT分类算法
参见:https://www.cnblogs.com/pinard/p/6140514.html
4、GBDT常用损失函数
对于分类算法,其损失函数一般有对数损失函数和指数损失函数两种:
a) 如果是指数损失函数,则损失函数表达式为
其负梯度计算和叶子节点的最佳残差拟合参见Adaboost原理篇。
b) 如果是对数损失函数,分为二元分类和多元分类两种,参见3.1节和3.2节。
对于回归算法,常用损失函数有如下4种:
a)均方差,这个是最常见的回归损失函数
b)绝对损失,这个损失函数也很常见
对应负梯度误差为:
c)Huber损失,它是均方差和绝对损失的折衷产物,对于远离中心的异常点,采用绝对损失,而中心附近的点采用均方差。这个界限一般用分位数点度量。损失函数如下:
对应的负梯度误差为:
d) 分位数损失。它对应的是分位数回归的损失函数,表达式为
其中θθ为分位数,需要我们在回归前指定。对应的负梯度误差为:
对于Huber损失和分位数损失,主要用于健壮回归,也就是减少异常点对损失函数的影响。
5. GBDT的正则化
和Adaboost一样,也需要对GBDT进行正则化,防止过拟合。GBDT的正则化主要有三种方式。
第一种是和Adaboost类似的正则化项,即步长(learning rate)。定义为νν,对于前面的弱学习器的迭代
如果加上了正则化项(的取值范围为0
。对于同样的训练集学习效果,较小的
意味着需要更多的弱学习器的迭代次数。通常用步长和迭代最大次数一起来决定算法的拟合效果。),则有:
第二种正则化的方式是通过子采样比例(subsample)。取值为(0,1]。注意这里的子采样和随机森林不一样,随机森林使用的是放回抽样,而这里是不放回抽样。如果取值为1,则全部样本都使用,等于没有使用子采样。如果取值小于1,则只有一部分样本会去做GBDT的决策树拟合。选择小于1的比例可以减少方差,即防止过拟合,但是会增加样本拟合的偏差,因此取值不能太低。推荐在[0.5, 0.8]之间。使用了子采样的GBDT有时也称作随机梯度提升树(Stochastic Gradient Boosting Tree, SGBT)。由于使用了子采样,程序可以通过采样分发到不同的任务去做boosting的迭代过程,最后形成新树,从而减少弱学习器难以并行学习的弱点(不理解!不是还是要串行的训练?)。
第三种是对于弱学习器即CART回归树进行正则化剪枝。
6、其他:
1、GBDT有很多简称,有GBT(Gradient Boosting Tree), GTB(Gradient Tree Boosting ), GBRT(Gradient Boosting Regression Tree), MART(Multiple Additive Regression Tree),其实都是指的同一种算法,本文统一简称GBDT。GBDT在BAT大厂中也有广泛的应用。
7、参考文献:
1、https://zhuanlan.zhihu.com/p/29765582
2、https://www.cnblogs.com/pinard/p/6140514.html(主要复制自这篇blog)
8、遗留问题
1、GBDT用于多分类的公式推导。
2、正则化的第二种,不甚理解。
3、损失函数选择为指数函数,退化为Adaboost?