GBDT 梯度提升树 原理总结

梯度提升树(Gradient Boosting Decison Tree)


GBDT有很多简称,有GBT(Gradient Boosting Tree), GTB(Gradient Tree Boosting ), GBRT(Gradient Boosting Regression Tree), MART(Multiple Additive Regression Tree),其实都是指的同一种算法,本文统一简称GBDT。

GBDT作为集成学习的一个重要算法,在被提出之初就和SVM一起被认为是泛化能力较强的算法。具体而言,GDBT是一种迭代的决策树算法,它基于集成学习中的boosting思想,每次迭代都在减少残差的梯度方向新建立一颗决策树,迭代多少次就会生成多少颗决策树。其算法思想使其可以发现数据中有区分性的特征以及特征组合,业界中,Facebook使用其来自动发现有效的特征、特征组合,来作为LR模型中的特征,以提高 CTR预估(Click-Through Rate Prediction)的准确性[1]。随后Kaggle竞赛也有实践此思路[2],GBDT与LR融合开始引起了业界关注。

GBDT 主要结合回归树(Regression Decision Tree)和提升树(Boosting Decision Tree)的思想,并提出利用残差梯度来优化回归树的集成过程。在这里,将首先介绍回归树和提升树,然后在详细阐述GBDT的算法步骤。

1. 回归树(Regression Decision Tree)

关于回归树,推荐参考【李航. 统计学习方法】[5]。
回归树是根据最小化平方误差的准则,递归地构建二叉决策树。假设 \(X\)\(Y\) 分别为输入输出变量,并且 \(Y\) 是连续变量,给定训练数据集

\[D=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\} \]

一个回归树将输入空间(即特征空间)划分为 \(M\) 个单元 \(\{R_1,R_2,...,R_M\}\),回归树的每个叶子节点对应一个单元,其相应的有一个固定的输出值 \(c_m\) 。当输入特征为 \(x\) 时,回归树会将其判定到一个叶子节点,将这个叶子节点对应的输出值 \(c_m\) 作为回归树的输出。这样,回归树模型可以表示为

\[T(x) = \sum_{m=1}^M c_m \mathrm{I}(x\in R_m) \tag{1} \]

其中,\(\mathrm{I}(x \in R_m)\) 为指示函数,当回归树判定 \(x\) 属于 \(R_m\) 时,其值为 \(1\),否则为 \(0\)
建立回归树的目标是针对数据集 \(D\) ,选择合适的空间划分方式(即决策树的生成方式)和相应的输出值,来最小化平方误差

\[\sum\limits_{x_i \in D} (y_i-T(x_i))^2 \]

  • 首先,选择合适的空间划分方式。根据决策树的建立方式,在每一个决策节点处选择变量 \(x\) 的第 \(j\) 维特征(用 \(x\small[ j ]\) 表示 \(x\)\(j\) 维的值) 和相应的阈值 \(s\) ,作为切分特征和切分阈值,则节点将空间划分为两个区域:

    \[R_1(j,s) = \{x|x[j] \leq s \} ~~~和~~~ R_2(j,s) = \{x|x[j] > s \} \tag{2} \]

    该节点处最优的切分特征 \(j\) 和切分阈值 \(s\) 按以下方式寻找

    \[\min_{j,s} \left[ \min_{c_1} \sum_{x_i \in R_1(j,s)}(y_i - c_i)^2 + \min_{c_2} \sum_{x_i \in R_2(j,s)}(y_i - c_2)^2 \right] \tag{3} \]

    该节点根据切分特征 \(j\) 和切分阈值 \(s\)将样本集划分为两个子样本集,式(3)的具体目的是这两个子样本集的方差尽可能小。式(3)中 \(c_1\)\(c_2\) 的取值为各样本的均值,\(j\)\(s\) 的选择则是通过遍历来确定。注意,切分阈值 \(s\) 是连续变量,但其取值可以根据样本的实际分布来选择合适的具体值,而不必连续性遍历。

  • 然后,决定回归树的输出值。针对每个子区域 \(R_m\)(树的叶子节点),其对应的输出值 \(c_m\) 可以直接选取类别均值,即

    \[c_m = \arg \min_c \sum_{x_i \in R_m} (y_i - c)^2 = \mathrm{aver}(y_i|x_i \in R_m) \tag{4} \]

    其中,\(\mathrm{aver}\) 表示取均值。

综上,回归树的具体生成过程如下:

回归树生成算法
输入:训练数据集 $D=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\}$
1 选择最优的切分特征 $j$ 与切分阈值 $s$ ,求解 $$\min_{j,s} \left[ \min_{c_1} \sum_{x_i \in R_1(j,s)}(y_i - c_i)^2 + \min_{c_2} \sum_{x_i \in R_2(j,s)}(y_i - c_2)^2 \right]$$ 遍历所有的特征 $j$ ,对固定的切分特征 $j$ 扫描选取切分阈值 $s$,选择使上式达到最小值的 $(j,s)$.
2 用选定的 $(j,s)$ 划分区域并决定相应的输出值:$$R_1(j,s)=\{x|x[j]\leq s\}, ~ R_2(j,s)=\{x|x[j]>s\} \\ c_m = \frac{1}{N_m} \sum_{x_i \in R_m} y_i, ~ m=1,2$$ 其中, $N_m$ 表示属于 $R_m$ 的样本个数 .
3 继续对两个子区域调用步骤(1),(2),直至区域类样本一致或树的层数达到要求.
4 将输入空间划分为 $M$ 个区域 $R_1,R_2,...,R_M$,生成决策树:$$T(x) = \sum_{m=1}^M c_m \mathrm{I}(x\in R_m)$$
输出:回归树 $T(x)$.

2. 提升树算法(Boosting Decision Tree)

2.1 提升树模型

提升树模型实际是将多个决策树简单的叠加起来,用数学模型可表示为

\[f_M(x) = \sum_{m=1}^M T(x;\Theta_m) \tag{5} \]

其中,\(T(x;\Theta_m)\) 表示决策树,\(\Theta_m\) 表示决策树的参数;\(M\) 为树的个数。
针对样本 \(D=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\}\),提升树模型的训练就是,选择决策树的参数 \(\Theta=\{\Theta_1,\Theta_2,...,\Theta_M\}\) 以最小化损失函数 \(\sum L(y_i,f_M(x_i))\),即

\[\arg \min_\Theta \sum_{i=1}^N L(y_i,f_M(x_i)) = \arg \min_\Theta \sum_{i=1}^N L\left(y_i, \sum_{m=1}^M T(x;\Theta_m)\right) \tag{6} \]

这里,损失函数用来反应“样本标签 \(y_i\) ”与提升树的输出 \(f_M(x_i)\) 之间的差别,这里可以选择平方误差损失函数:

\[L(y, f(x))=\left( y-f(x) \right)^2 \tag{7} \]

2.2 提升树算法

根据式(5),提升树模型也可以表示为迭代过程

\[f_m(x)=f_{m-1}(x)+T(x;\Theta_m),~ m=1,2,...,M \tag{8} \]

因此,提升树的训练也可以按照迭代的过程来完成,在 \(m\) 次迭代中,生成一个新的决策树 \(T(x;\Theta_m)\)
具体而言,首先初始化提升树 \(f_0(x)=0\),第 \(m\) 步确定第 \(m\) 个决策树 \(T(x;\Theta_m)\),即选择合适的决策树参数 \(\Theta_m\),使损失函数最小,即

\[\hat{\Theta}_m = \arg \min_{\Theta_m} \sum_{i=1}^N L(y_i, f_{m-1}(x_i) + T(x_i;\Theta_m)) \tag{9} \]

对于式(9)的求解,即为提升树的关键所在。如果采用平方损失函数,则有

\[\begin{eqnarray*} L(y_i,f_{m-1}(x_i)+T(x_i;\Theta_m)) &=& \left[\,y_i - f_{m-1}(x_i) - T(x_i;\Theta_m)\right]^2 \\ &=& \left[\,r_{m,i} - T(x_i;\Theta_m)\right]^2\tag{10} \end{eqnarray*} \]

这里, $ r_{m,i}=y_i-f_{m-1}(x_i) $ 表示模型 \(f_{m-1}(x)\) 拟合数据 \((x_i,y_i)\) 的残差。

这样对式(9)的求解,就变成了选择合适的决策树参数 \(\Theta_m\) ,使得决策树的输出 \(T(x_i;\Theta_m)\) 与 残差 \(r_{m,i}\) 的误差尽可能小。因此,可以使用 \(\{(x_i,r_{m,i})\}_{i=1,2,...,N}\) 来作为决策树 \(T(x;\Theta_m)\) 的样本集,按照常规的决策树生成过程获得参数的最优值 \(\hat{\Theta}_m\)

综上,我们可以得到提升树算法如下:

提升树算法
输入:训练数据集 $D=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\}$
1 初始化 $f_0(x)=0$
2 For $m=1,2,...,M$
3 $~~~$ 针对每一个样本 $(x_i,y_i)$,计算残差 $$r_{m,i}=y_i - f_{m-1}(x_i),~ i=1,2,...,N$$
4 $~~~$ 利用$\{(x_i,r_{m,i})\}_{i=1,2,...,N}$ 训练一个决策树(回归树),得到 $T(x;\Theta_m)$
5 $~~~$ 更新 $f_m(x)=f_{m-1}(x)+T(x;\Theta_m)$
6 完成以上迭代,得到提升树 $f_M(x) = \sum\limits_{m=1}^M T(x;\Theta_m)$

3. GBDT(Gradient Boosting Decison Tree)

GBDT很好的结合了回归树与提升树的思想,并将它们推广到更一般的情形。例如提升树中第三步计算残差是在损失函数为平方损失函数来计算的,如果损失函数为对数函数,则计算残差 \(r_{m,i}\) 变得不是很方便,以及在第四步训练回归树时,计算节点输出值 \(c_m\) 也变得不容易进行。

GBDT首先使用最速下降的近似方法来计算残差的近似值,即 $$ r_{m,i} = -\left[ \frac{\partial L(y_i,f(x_i))}{\partial f(x_i)} \right]{f(x)=f{m-1}(x)} \tag{11}$$ GBDT 的具体算法过程如下:

GBDT 算法
输入:训练数据集 $D=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\}$;损失函数 $L(y,f(x))$ .
1 初始化 $ f_0(x) = \arg \min\limits_c \sum\limits_{i=1}^N L(y_i, c) $
2 For $m=1,2,...,M$
3 $~~~$ 对于每一个样本$(x_i,y_i)$,计算残差 $$r_{m,i} = -\left[ \frac{\partial L(y_i,f(x_i))}{\partial f(x_i)} \right]_{f(x)=f_{m-1}(x)} ~,~i=1,2,...,N$$
4 $~~~$ 利用$\{(x_i,r_{m,i})\}_{i=1,2,...,N}$ 训练出第 $m$ 棵回归树 $T_m$,其叶节点划分的区域为 $R_{m,j},j=1,2,...,J$
5 $~~~$对于回归树 $T_m$ 的每一个叶节点,计算其输出值 $$ c_{m,j} = \arg \min_c \sum_{x_i\in R_{m,j}} L(y_i, f_{m-1}(x_i)+c) ,~ j=1,2,...,J $$
6 $~~~$ 更新 $f_m(x) = f_{m-1}(x) + \sum\limits_{j=1}^J c_{m,j}I(x \in R_{m,j})$
7 得到最终提升回归树 $$ \hat f(x) = f_M(x) = \sum_{m=1}^M \sum_{j=1}^J c_{m,j} I(x \in R_{m,j}) $$
输出:梯度提升树 $\hat f(x)$

以上算法将回归树和提升树的算法结合起来,在第5步中求解 \(c_{m,j}\) ,如果损失函数为平方损失函数,则解法与前面的回归树一致,直接取均值即可。如果是其他损失函数,则需要具体进行求解。具体而言,就是取导数为零来解等式。

不过对于分类情况,由于样本输出不是连续的值,而是离散的类别,导致我们无法直接从输出类别去拟合类别输出的误差。为了解决这个问题,主要有两个方法,一个是用指数损失函数,此时GBDT退化为Adaboost算法。另一种方法是用类似于逻辑回归的对数似然损失函数的方法。也就是说,我们用的是类别的预测概率值和真实概率值的差来拟合损失。本文仅讨论用对数似然损失函数的GBDT分类。而对于对数似然损失函数,我们又有二元分类和多元分类的区别。

3.1 二元GBDT分类算法

对于二分类问题,比较常用的损失函数为

\[L(y,f(x))=\log (1+\exp (-y \cdot f(x))) \tag{12} \]

其中 \(y \in \{-1,+1\}\),此时的负梯度误差为 $$ r_{m,i} = -\left[ \frac{\partial L(y_i,f(x_i))}{\partial f(x_i)} \right]{f(x)=f{m-1}(x)} = \frac{y_i}{1+\exp (y_i f_{m-1}(x_i))} \tag{14}$$

对于生成决策树,其叶子节点的输出值为

\[c_{m,j} = \arg \min_c \sum_{x_i\in R_{m,j}} \log (1+\exp (-y_i (f_{m-1}(x_i) + c))) \tag{15} \]

由于上式比较难优化,我们一般使用近似值代替

\[c_{m,j} =\left. \sum_{x_i\in R_{m,j}} r_{m,i} \middle / \sum_{x_i\in R_{m,j}} |r_{m,i}|(1-|r_{m,i}|) \right. \tag{16} \]

3.2 多元GBDT分类算法

对于多分类问题,假设类别为 \(K\),一般采用的损失函数为

\[L(y,f(x)) = - \sum_{k=1}^K y_k log p_k(x) \tag{17} \]

其中,如果样本输出类别为 \(k\) ,则 \(y_k=1\)\(p_k(x)\) 表示模型 \(f(x)\) 判定 \(x\) 属于第 \(k\) 类的概率,其表达式为

\[p_k(x) = \frac{\exp (f_k(x))}{ \sum_{l=1}^K \exp(f_l(x))} \tag{18} \]

注意此处,对于多分类问题,回归树训练时,会为每一个类别训练一个决策树。

由此,我们可以计算出第 \(m\) 轮的第 \(i\) 个样本对应类别 \(l\) 的负梯度误差为

\[r_{m,i,l} = -\left[ \frac{\partial L(y_i,f(x_i))}{\partial f(x_i)} \right]_{f(x)=f_{m-1,l}(x)} = y_{i,l} - p_{m,l}(x_i) \tag{19} \]

观察上式可以看出,其实这里的误差就是样本 \(i\) 对应类别 \(l\) 的真实概率和 \(m−1\) 轮预测概率的差值。

对于生成的决策树,对应第 \(l\) 类别的决策树的叶节点输出为

\[c_{m,l,j} = \arg \min_c \sum_{x_i \in R_{m,l,j}} L(y_{i,l}, f_{m-1,l}(x_i) + c) \tag{20} \]

类似的,我们用近似值代替 $$ c_{m,l,j} = \frac{K-1}{K} \frac{\sum\limits_{x_i \in R_{m,l,j}}r_{m,i,l}}{ \sum\limits_{x_i \in R_{m,l,j}} |r_{m,i,l}|(1-|r_{m,i,l}|) } \tag{21}$$

4. GBDT 的正则化

  • 第一种是和Adaboost类似的正则化项,即使用步长(learning rate),定义为 \(\alpha\) 。常规的提升回归树的迭代为

\[f_m(x) = f_{m-1}(x) + T(x;\Theta_m)$$ 引入正则化后,其迭代过程为 $$ f_m(x) = f_{m-1}(x) + \alpha T(x;\Theta_m) \]

其中,\(0<\alpha \leq 1\)。对于同样的训练集学习效果,较小的 \(\alpha\) 意味着我们需要更多的弱学习器的迭代次数。通常我们用步长和迭代最大次数一起来决定算法的拟合效果。

  • 第二种正则化的方式是通过子采样比例(subsample)。取值为(0,1]。注意这里的子采样和随机森林不一样,随机森林使用的是放回抽样,而这里是不放回抽样。如果取值为1,则全部样本都使用,等于没有使用子采样。如果取值小于1,则只有一部分样本会去做GBDT的决策树拟合。选择小于1的比例可以减少方差,即防止过拟合,但是会增加样本拟合的偏差,因此取值不能太低。推荐在[0.5, 0.8]之间。
    使用了子采样的GBDT有时也称作随机梯度提升树(Stochastic Gradient Boosting Tree, SGBT)。由于使用了子采样,程序可以通过采样分发到不同的任务去做boosting的迭代过程,最后形成新树,从而减少弱学习器难以并行学习的弱点。

  • 第三种称为 Regularized Learning Objective,将树模型的复杂度作为正则项显式地加进优化目标里,这也是XGBoost实现的独到之处。其具体实现可以参考文献[7],在这里列出其加入正则化后的优化目标

\[L_{r}(y,f(x)) = L(y,f(x)) + \sum_{m} \Omega(T(x;\Theta_m)) \\ \mathrm{where} ~~ \Omega(T(x;\Theta_m)) = \gamma T_{leaf} + \frac12 \lambda \| w \|^2 \]

其中,\(L(y,f(x))\) 为常规的损失函数;\(\Omega(T(x;\Theta_m))\) 表示决策树的复杂度,\(T_{leaf}\) 为树叶节点个数,\(w\) 为叶节点的固定输出值\(c_m\)组成的向量;\(\gamma, \lambda\) 为相应的系数。

  • 最后还有一种就是类 似DeepLearning 的 Dropout ,其具体可以参考文献[8]。通俗地讲,每次新加一棵树,这棵树要拟合的并不是之前全部树ensemble后的残差,而是随机抽取的一些树ensemble。

以上为作者暂时了解到的,其它的正则化方法如果日后学习到,会继续添加。

[1]. He X, Pan J, Jin O, et al. Practical lessons from predicting clicks on adsat facebook[C]. Proceedings of 20th ACM SIGKDD Conference on KnowledgeDiscovery and Data Mining. ACM, 2014: 1-9.
[2]. guestwalk. kaggle-2014-criteo. https://github.com/guestwalk/Kaggle-2014-criteo
[3]. SiyueLin. GBDT: 梯度提升决策树. https://www.jianshu.com/p/005a4e6ac775
[4] 玉心sober. CTR预估中GBDT与LR融合方案. https://blog.csdn.net/lilyth_lilyth/article/details/48032119
[5] 李航. 统计学习方法.
[6] 刘建平Pinard. 梯度提升树(GBDT)原理小结.https://www.cnblogs.com/pinard/p/6140514.html
[7] Chen T, Guestrin C. XGBoost: A Scalable Tree Boosting System[J]. 2016:785-794. https://arxiv.org/pdf/1603.02754.pdf
[8] Rashmi K V, Gilad-Bachrach R. DART: Dropouts meet Multiple Additive Regression Trees[J]. Computer Science, 2015:489-497.
[9] 知识天地. Regularization on GBDT. https://www.cnblogs.com/mfryf/p/6015713.html

posted @ 2018-04-08 14:59  子龙丨风  阅读(7199)  评论(0编辑  收藏  举报