机器学习笔记10-梯度提升树(GBDT)

机器学习笔记10-梯度提升树(GBDT)

上一节中讲到了集成学习的Boosting方法,并详细解释了其中的代表性算法AdaBoost算法。除了AdaBoost算法外,Boosting中还有另一个非常常用的算法:提升树和梯度提升树(GBDT)。

  1. 提升树
    提升树是以分类树或回归树为基本分类器的提升方法,可以表示为加法模型: f M ( x ) = m = 1 M T ( x ; θ m ) {f_M}(x) = \sum\limits_{m = 1}^M {T(x;{\theta _m})} ,其中 T ( x ; θ m ) {T(x;{\theta _m})} 表示决策树, θ m \theta _m 表示决策树的参数,M为决策树的个数。提升树算法采用前向分步算法。首先确定 f 0 ( x ) = 0 f_0(x)=0 ,第m步的模型是
    f m ( x ) = f m 1 ( x ) + T ( x ; θ m ) {f_m}(x) = {f_{m - 1}}(x) + T(x;{\theta _m}) 其中, f m 1 ( x ) f_{m-1}(x) 为当前模型,通过极小化损失函数确定下一棵决策树的参数 θ m \theta_m
    θ ^ m = arg m i n θ m i = 1 N L ( y i , f m 1 ( x i ) + T ( x i ; θ m ) ) {{\hat \theta }_m} = \arg {\rm{ }}\mathop {{\rm{min}}}\limits_{{\theta _m}} \sum\limits_{i = 1}^N {L({y_i},{f_{m - 1}}({x_i}) + T({x_i};{\theta _m}))} 针对不同问题的提升树学习算法,其主要区别在于使用的损失函数不同。包括用平方误差损失函数的回归问题,用指数损失函数的分类问题,以及用一般损失函数的一般决策问题。对于二类分类问题,提升树算法只需要将上一节中的AdaBoost算法中的基分类器限制为二类分类树。以下叙述回归问题的提升树:
    此时损失函数为:
    L ( y , f m 1 ( x ) + T ( x ; θ m ) ) = ( y f m 1 ( x ) T ( x ; θ m ) ) 2 = ( r T ( x ; θ m ) ) 2 L(y,{f_{m - 1}}(x) + T(x;{\theta _m})) = {(y - {f_{m - 1}}(x) - T(x;{\theta _m}))^2} = {(r - T(x;{\theta _m}))^2} 这里 r = y f m 1 ( x ) r=y-f_{m-1}(x) ,是当前模型拟合数据的残差。具体地,其算法可表述为:
    (1)初始化 f 0 ( x ) = 0 f_0(x)=0
    (2)对 m = 1 , 2 , . . . , M m=1,2,...,M
    (i)计算残差 r m i = y i f m 1 ( x ) r_{mi}=y_i-f_{m-1}(x)
    (ii)拟合残差 r m i r_{mi} 学习一个回归树,得到 T ( x ; θ m ) T(x; {\theta}_m) ,这一步可参考决策树那一节;
    (iii)更新 f m ( x ) = f m 1 ( x ) + T ( x ; θ m ) {f_m}(x) = {f_{m - 1}}(x) + T(x;{\theta _m})
    (3)得到回归树模型 f M ( x ) = m = 1 M T ( x ; θ m ) {f_M}(x) = \sum\limits_{m = 1}^M {T(x;{\theta _m})}

  2. 梯度提升树(GBDT)
    提升树当损失函数是平方损失或指数损失函数时,每一步优化都很简单。但对于一般损失函数是,每一步优化都不容易。利用梯度提升树可以解决这个问题。它利用了最速下降法的近似方法,其关键是利用损失函数的负梯度在当前模型的值
    [ L ( y , f ( x i ) ) f ( x i ) ] f ( x ) = f m 1 ( x ) - {\left[ {\frac{{\partial L(y,f({x_i}))}}{{\partial f({x_i})}}} \right]_{f(x) = {f_{m - 1}}(x)}} 作为回归问题提升树算法中的残差的近似值,拟合一个回归树。其具体算法如下:
    (1)初始化 f 0 ( x ) = arg m i n c i = 1 N L ( y i , c ) f_0(x)=\arg {\rm{ }}\mathop {{\rm{min}}}\limits_c \sum\limits_{i = 1}^N {L({y_i},c)}
    (2)对 m = 1 , 2 , . . . , M m=1,2,...,M
    (i)对i=1,2,…,N,计算
    r m i = [ L ( y i , f ( x i ) ) f ( x i ) ] f ( x ) = f m 1 ( x ) {r_{mi}} = - {\left[ {\frac{{\partial L({y_i},f({x_i}))}}{{\partial f({x_i})}}} \right]_{f(x) = {f_{m - 1}}(x)}}
    (ii)对 r m i r_{mi} 拟合一个回归树,得到第m棵树的叶结点区域 R m j R_{mj} ,j=1,2,…,J
    (iii)对j=1,2,…,J,计算
    c m j = arg m i n c x i R m j L ( y i , f m 1 ( x i ) + c ) {c_{mj}} = \arg {\rm{ }}\mathop {{\rm{min}}}\limits_c \sum\limits_{{x_i} \in {R_{mj}}} {L({y_i},{f_{m - 1}}({x_i}) + c)}
    (iv)更新 f m ( x ) = f m 1 ( x ) + j = 1 J c m j I ( x R m j ) {f_m}(x) = {f_{m - 1}}(x) + \sum\limits_{j = 1}^J {{c_{mj}}I(x \in {R_{mj}})}
    (3)得到回归树 f M ( x ) = m = 1 M j = 1 J c m j I ( x R m j ) {f_M}(x) = \sum\limits_{m = 1}^M {\sum\limits_{j = 1}^J {{c_{mj}}I(x \in {R_{mj}})} }
    GBDT也能用于分类,GBDT的分类算法从思想上和GBDT的回归算法没有区别,但是由于样本输出不是连续的值,而是离散的类别,导致无法直接从输出类别去拟合类别输出的误差。为了解决这个问题,主要有两个方法,一个是用指数损失函数,此时GBDT退化为Adaboost算法。另一种方法是用类似于逻辑回归的对数似然损失函数的方法。也就是说,我们用的是类别的预测概率值和真实概率值的差来拟合损失。

    GBDT常用损失函数:对于分类算法,其损失函数一般有对数损失函数和指数损失函数两种;对于回归算法,常用损失函数有如下4种:均方差、绝对损失、Huber损失、分位数损失。对于Huber损失和分位数损失,主要用于健壮回归,也就是减少异常点对损失函数的影响。

    GBDT正则化:GBDT的正则化主要有三种方式:第一种是添加步长系数,对于若学习器 f m ( x ) = f m 1 ( x ) + A {f_m}(x) = {f_{m - 1}}(x) + A ,正则化后会变为 f m ( x ) = f m 1 ( x ) + v A {f_m}(x) = {f_{m - 1}}(x) + vA v v 取值在[0,1]之间。较小的ν意味着需要更多的弱学习器的迭代次数;第二种是通过子采样比例。这里的子采样和随机森林不一样,随机森林使用的是放回抽样,而这里是不放回抽样。如果取值为1,则全部样本都使用,等于没有使用子采样。如果取值小于1,则只有一部分样本会去做GBDT的决策树拟合。使用了子采样的GBDT有时也称作随机梯度提升树(SGBT);第三种是对于弱学习器即CART回归树进行正则化剪枝。

    GBDT与随机森林的关系:随机森林和梯度提升树两者之间主要差别在于每棵树训练的顺序。随机森林通过对数据随机采样来单独训练每一棵树。这种随机性也使得模型相对于单决策树更健壮,且不易在训练集上产生过拟合。GBDT则一次只训练一棵树,后面每一棵新的决策树逐步矫正前面决策树产生的误差。随着树的添加,模型的表达力也愈强。因此,随机森林可以并行运算。对于GBDT和随机森林这两者而言,增加树的数量都会增加训练的时间,同时树的数量增加也提高了预测精度。但是随机森林训练的时间更短,但是要达到和GBDT同样的预测精度则需要更深的树。GBDT则能在每次迭代时显著地减少误差,但是经过过多的迭代,它又太容易过拟合(增加了测试误差)。随机森林则不太容易过拟合,测试误差也趋于稳定。

目前GBDT的算法比较好的库是xgboost。当然scikit-learn也可以。但是xgboost并不是GBDT,它与GBDT的区别如下:
(1)传统GBDT以CART作为基分类器,xgboost还支持线性分类器,这个时候xgboost相当于带L1和L2正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题)。
(2)传统GBDT在优化时只用到一阶导数信息,xgboost则对代价函数进行了二阶泰勒展开,同时用到了一阶和二阶导数。顺便提一下,xgboost工具支持自定义代价函数,只要函数可一阶和二阶求导。
(3)xgboost在代价函数里加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数、每个叶子节点上输出的score的L2模的平方和。从Bias-variance tradeoff角度来讲,正则项降低了模型的variance,使学习出来的模型更加简单,防止过拟合,这也是xgboost优于传统GBDT的一个特性。
(4)xgboost工具支持并行。
(5)具体可参考这几位up主的博客:xgboost入门与实战(原理篇)XGBoost原理介绍机器学习算法中 GBDT 和 XGBOOST 的区别有哪些?

参考:
李航《统计学习方法》
https://blog.csdn.net/u013361361/article/details/45032627
https://www.cnblogs.com/pinard/p/6140514.html
https://blog.csdn.net/sb19931201/article/details/52557382
https://blog.csdn.net/yinyu19950811/article/details/81079192
https://www.zhihu.com/question/41354392/answer/98658997

猜你喜欢

转载自blog.csdn.net/zhennang1427/article/details/85264876
今日推荐