Bootstrap

GBDT原理与Sklearn源码分析-回归篇

摘要:

本文将非常详细的介绍GBDT(Gradient Boosting Decision Tree)的原理以及Sklearn里面具体是如何实现一个GBDT的。本次内容将分为两篇文章,一篇是GBDT用于回归,一篇是GBDT用于分类任务。虽然两者其实本质是一样的,只是loss function不同,但是分成两篇可以帮助更好的对比理解。

注意:本文前半部分是GBDT原理的一个概述,后半步是sklearn中是如何实现的,以及给出一个具体例子一步步和读者分享整个算法的流程(本文也侧重于这一点)

1.GB原理概述

注意:对原理已经熟知或者不想太多了解者可直接跳过看实践部分,另外在学习GBDT前非常建议读者先看一下李航老师的《统计学习方法》中的8.4.1节。

首先,先解释一下所谓的boosting(提升)。提升方法就是从弱学习算法出发,反复学习,得到一系列的弱分类器(基分类器),然后组合这些弱分类器,构成一个强分类器。大多数的提升方法都是改变训练数据的概率分布(训练数据的权值分布)。

所以,对于提升方法来说,需要解决两个问题:一是每一轮学习中,如何改变训练数据的权值或者概率分布;二是如何将弱分类器组合成一个强分类器。

了解了所谓的boosting后,我们得到上面的两个问题,对于第一个问题,在GBDT中,其实就是通过拟合损失函数的负梯度值在当前模型的值,这里需要注意的,在以前的机器学习算法中,我们都是通过直接拟合真实值,而在GBDT里,我们拟合的目标不再是真实值,而是一个梯度值,当然这个梯度值和真实值有关系,后面部分会说明。

对于第二个问题,GBDT中的基分类器当然是决策树。但是决策树有很多比如C4.5、ID3、CART等等。那么用的是哪种树?在GBDT里,用的是CART(分类与回归树),同时Sklearn里面实现GBDT时用的基分类器也是CART。


为了前后连贯,这里简单介绍一下CART。一般的CART是这样的:用于分类任务时,树的分裂准则采用基尼指数,用于回归任务时,用MSE(均方误差)。
注意:当然在回归任务中,分裂准则也不再局限于用MSE,也可以用MAE,还可以用Friedman_mse(改进型的mse)。


上面提到,CART可以用于回归和分类,那么到底用回归还是分类呢?上面我们已经提到了,GBDT拟合的目标是一个梯度值,这个值当然是一个连续值或者说实值,所以在GBDT里,通通都是回归树。

有了基分类器后,如何将这些基分类器组合起来?boosting方法一般是使用加法模型。
即: f M ( x ) = ∑ m = 1 M T ( x , θ m ) \large f_M(x)=\sum_{m=1}^{M}T(x,\theta_m) fM(x)=m=1MT(x,θm)

其实利用GB训练强学习器的思路,总结下来就是下面这个过程:
这里写图片描述


对于算法的第3步: y i ~ = − [ ∂ L ( y i , F ( x i ) ) ∂ F ( x i ) ] F ( x ) = F m − 1 ( x ) \large \tilde{y_i}=-\left[\frac{\partial L(y_i,F(\mathbf{x}_i))}{\partial F(\mathbf{x}_i)}\right]_{F(x)=F_{m-1}(x)} yi~=[F(xi)L(yi,F(xi))]F(x)=Fm1(x),就是我们上面说的损失函数的负梯度在当前模型的值。
也就是说,我们每一个颗回归树拟合的目标是 y i ~ \large \tilde{y_i} yi~

这里这样说可能比较抽象,我们举几个例子:
比如说,损失函数选择使用:
L ( y i , F ( x i ) ) = ( 1 2 ) ∗ ( y i − F ( x i ) ) 2 \large L(y_i,F(x_i))=\left(\frac{1}{2}\right)*(y_i-F(x_i))^2 L(yi,F(xi))=(21)(yiF(xi))2,那么其负梯度值为: − [ ∂ L ( y i , F ( x i ) ) ∂ F ( x i ) ] = ( y i − F ( x i ) ) \large -\left[\frac{\partial L(y_i,F(\mathbf{x}_i))}{\partial F(\mathbf{x}_i)}\right]=(y_i-F(x_i)) [F(xi)L(yi,F(xi))]=(yiF(xi)),再带入当前模型的值 F ( x ) = F m − 1 ( x ) \large {F(x)=F_{m-1}(x)} F(x)=Fm1(x)
则有:
y i ~ = − [ ∂ L ( y i , F ( x i ) ) ∂ F ( x i ) ] F ( x ) = F m − 1 ( x ) = ( y i − F m − 1 ( x i ) ) \large \tilde{y_i}=-\left[\frac{\partial L(y_i,F(\mathbf{x}_i))}{\partial F(\mathbf{x}_i)}\right]_{F(x)=F_{m-1}(x)}=(y_i-F_{m-1}(x_i)) yi~=[F(xi)L(yi,F(xi))]F(x)=Fm1(x)=(yiFm1(xi))
所以我们能看到,当损失函数选用Least-square时,每一次拟合的值就是(真实值-当前模型的值)。

比如说,损失函数选择Least-absolute使用:
L ( y i , F ( x i ) ) = ∣ y i − F ( x i ) ∣ \large L(y_i,F(x_i))=\left|y_i-F(x_i)\right| L(yi,F(xi))=yiF(xi),其梯度值为:
y i ~ = − [ ∂ L ( y i , F ( x i ) ) ∂ F ( x i ) ] F ( x ) = F m − 1 ( x ) = s i g n ( y i − F m − 1 ( x i ) ) \large \tilde{y_i}=-\left[\frac{\partial L(y_i,F(\mathbf{x}_i))}{\partial F(\mathbf{x}_i)}\right]_{F(x)=F_{m-1}(x)}=sign\left(y_i-F_{m-1}(x_i)\right) yi~=[F(xi)L(yi,F(xi))]F(x)=Fm1(x)=sign(yiFm1(xi))
其中 s i g n sign sign是符号函数。

比如说,损失函数选择使用logistic loss时:(二分类任务)
L ( y i , F ( x i ) ) = y i l o g ( p i ) + ( 1 − y i ) l o g ( 1 − p i ) \large L\left(y_i,F(x_i)\right)=y_ilog(p_i)+(1-y_i)log(1-p_i) L(yi,F(xi))=yilog(pi)+(1

;