参考网址:

1. GBDT(MART) 迭代决策树入门教程 | 简介

2. Wikipedia: Gradient boosting

 


一般Gradient Boosting

 

先用原函数值拟合一个模型,而后计算残差,再构建新的基(弱)学习器,不断重复,最后将这些基模型的结果加权相加,得到最后的结果。

 

输入:训练集$\{(x_{i}, y_{i})\}_{i=1}^{n}$,可导损失函数$L(y, F(x))$,迭代次数$M$

算法:

1. 用常数值初始化模型

\[F_{0}=\arg\underset{\gamma}{\min} \sum_{i=1}^{n} L(y_{i}, \gamma)\]

 

2. 从m=1到M:

  1)计算“伪残差”:

\[ r_{im}=-[\frac{\partial L(y_{i}, F(x_{i}))}{\partial F(x_{i})}]|_{F(x)=F_{m-1}(x)},i=1, ..., n\]

        当$L(y, F(x))$是$\frac{1}{2} (y-F(x))^{2})$时,$\frac{\partial L(y, F(x))}{\partial F(x)}=-(y-F(x))$,即为残差

  2)拟合基学习器(如:树)$h_m(x)$,使用训练集为$\{(x_i, r_{im})\}_{i=1}^{n}$
  3)通过一维优化问题计算乘子$\gamma_m$:

\[\gamma_m=\arg\underset{\gamma}{\min} \sum_{i=1}^{n} L(y_i, F_{m-1}(x_i)+\gamma h_m(x_i))\] 
  4)更新模型:

\[F_m(x)=F_{m-1}(x)+\gamma_mh_m(x)\]

 

3. 输出$F_m(x)$

 

注意,就算是两个同类基学习器的加权效果累加,也不一定能通过该类学习器单个实现。例如,如果是多项式为基学习器,那么能找到一个多项式实现另外两个多项式的任意加权叠加效果;但当基学习器为树的时候,两棵简单的树的效果叠加,也是不一定能通过另一棵树(无论层次多深)去实现的。这是这个算法会产生和原学习器不同效果的一个基础。


 Gradient Tree Boosting(包括了Gradient boosting decision tree:GBDT)

Gradient Tree Boosting一般是用决策树(尤其是CART树)作为基学习器。树的大小一般是固定的。对于这特定的以树作为基学习器的情形,Friedman作了一些修正来提升它的效果。

主要体现在第2点,在第m步迭代时,用决策树$h_m(x)$拟合伪残差。

记$J_m$为该树的叶子结点数目,则输入空间被划分为$J_m$个不相交的区域:$R_{1m},R_{2m}, ..., R_{J_{m} m}$。每个区域的预测值为一个常数,记为$b_{jm}$。

则\[h_m(x)=\sum_{j=1}^{J_m}b_{jm}1_{R_{jm}} (x).\]

$1_{R_{jm}}$为示性函数。


如果是原本的Gradient boosting算法,系数$b_{jm}$和$\gamma_m$相乘,并通过用线性搜索的方法对loss function求小值解来确定这些系数。模型更新的步骤如下:

\[F_m(x)=F_{m-1}(x)+\gamma_m h_m(x), \gamma_m=\arg\underset{\gamma}{\min} \sum_{i=1}^{n}L(y_i, F_{m-1}(x_i)+\gamma h_m(x_i))\]

Friedman提出的修正方法是为树的每一个区域$\{R_{jm}\}_1^{J_m}$都选择一个最优的$\gamma_{jm}$,而不是整棵树只用一个$\gamma_m$。

Friedman称修正后的算法为"TreeBoost“。通过这样的方式,实际上$b_{jm}$可以直接移除,模型更新变为:

\[F_m(x)=F_{m-1}(x)+\sum_{j=1}^{J_m}\gamma_{jm} 1_{R_{jm}}(x)\]

\[\gamma_{jm}=\arg\underset{\gamma}{\min} \sum_{x_i\in R_{jm}}L(y_i,F_{m-1}(x_i)+\gamma)\]

 

记J为树的叶子节点个数,可以根据数据集做调整,它控制的是模型中不同变量的交互作用(interaction)。

例如当J=2时,变量间不存在交互作用,而如果J=3,则至多有两个变量之间存在交互作用。

Hastie等人认为一般$4\leq J \leq8$对于boosting来说效果较好,并且当$J$处于这个范围的时候,效果受$J$变化的影响不敏感。$J=2$在多数应用场景都不太够,而一般也不需要用到$J=10$的情形。

 


 Regularization:正则化减小过拟合风险


如果模型太贴合训练集,可能会导致模型的泛化能力变差。

有几种正则化方法可以减少过拟合的发生可能。

控制迭代次数M(例如GBDT中的树的棵树)是其中一种十分自然的想法。M增大时训练误差减小,但过大时就会导致过拟合发生。最优的M通常是通过控制独立的验证集的预测误差来确定的。

其他的方法如下:

1. Shrinkage收缩 :引入学习率learning rate

\[F_m(x)=F_{m-1}(x)+v\cdot \gamma_mh_m(x),0\leq v\leq1\]

v称为学习率。在学习率低时(例如$v<0.1$),相比于没有收缩(即v=1)时,模型泛化能力会有显著提高,但由于迭代次数会增加,也造成了计算时间变长.

 

2.Stochastic gradient boosting随机梯度提升

受Breiman的启发,Friedman在Gradient boosting提出来后不久就提出了一个小的修改方案:每一次迭代构建基学习器时,不用所有的训练集样本,而用其子集。这种改进的效果提升很明显。

在每次构建时,子集的占比(子集样本数/训练集样本总数)$f$是确定的,当$f=1$时,就是原来的算法。$f$设置得小时,是把随机性引入到模型当中,有助于减轻过拟合的现象。而由于每次迭代计算时计算需要的样本数减小了,模型训练的速度也得到提升。

$f$一般设为0.5(也就是每次建树用了一半的训练样本),Friedman认为$0.5\leq f \leq0.8$对于中小型数据集的效果都不错。

在这种改进的算法里,有一种out-of-bag的误差会被计算(out-of-bag error),我理解里,指的是用没有在下一个基学习器里训练用到的样本,去计算这个(指前面的"下一个“)的预测误差,衡量其预测效果。但和用验证集相比,这种估计会低估实际的效果提升,以及最优的迭代次数。

 

3.Number of observations in the tree

限制每棵树叶子节点最小的样本数,这可以降低预测值的方差。

 

4. Penalized complexity of Tree

对模型复杂度进行惩罚。模型复杂度可以定义为叶子数的某个比例。

损失函数和模型复杂度的联合优化对应着,在一定阈值限定内,减小损失函数的后剪枝算法。另外,对叶子节点加上$l2$惩罚项,也可以避免过拟合。

 

 Multiple Additive Regression Trees" (MART)也是指的这个算法。

 

posted on 2017-11-06 19:35  RRRRecord  阅读(396)  评论(0编辑  收藏  举报