梯度提升树(GBDT)

集成学习

随机森林

AdaBoost 算法

提升树

梯度提升树(GBDT)

XGBoost



\(GBDT\) 有很多简称,有 \(GBT\ (Gradient\ Boosting\ Tree)\)\(GTB\ (Gradient\ Tree\ Boosting)\)\(GBRT\ (Gradient\ Boosting\ Regression\ Tree)\)\(MART\ (Multiple\ Additive\ Regression\ Tree)\),其实都指同一种算法。\(GBDT\) 是加法模型,学习算法使用前向分步算法,基(弱)学习器只能使用 \(CART\) 回归树

\(GBDT\) 的思想用一个通俗的例子解释,假设有个人 \(30\) 岁,我们首先用 \(20\) 岁去拟合,发现损失有 \(10\) 岁,这时用 \(6\) 岁去拟合,发现损失有 \(4\) 岁,第三轮用 \(3\) 岁去拟合,损失有一岁了。如果迭代次数还没完,可以继续迭代下面,每一轮迭代,拟合的岁数损失都会减小。


1. GBDT 回归算法

提升树用加法模型与前项分布算法实现学习的优化过程。当损失函数是平方误差损失函数和指数损失函数时,每一步优化很简单的。但对一般损失函数而言,每一步并不容易。

\(Freidman\) 提出利用损失函数的负梯度作为残差的近似值,拟合一个回归树。

\[- \begin{bmatrix} \frac{ \partial L(y_i, \ f(x_i))}{ \partial f(x_i)} \end{bmatrix} _{f(x)=f_{m-1} \ \ \ (x)} \]

其中,下标 \({f(x)=f_{m-1}(x)}\) 表示 \(f(x)\) 的取值 \(f_{m-1}(x)\)


梯度提升回归算法:

输入:训练集 \(T=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\}\)\(x_i \in \mathcal{X} \subseteq \pmb{R}^n\)\(y_i \in \mathcal{Y} \subseteq \pmb{R}\)

其中,\(N\) 表示样本个数,\(\mathcal{X}\) 表示输入空间,\(\pmb{R}^n\) 表示 \(n\) 维。

输出:回归树 \(\hat{f}(x)\)

其中,\(\hat{f}(x)\) 表示训练出来的模型。

(1)初始化

\[f_0(x) = arg \ \underset{c}{min} \sum_{i=1}^{N} L(y_i, c) \]

(2)对 \(m=1,2,...,M\)

$\ \ \ \ $(a)对 \(i=1,2,...,N\),计算残差

\[r_{mi} = - \begin{bmatrix} \frac{\partial L(y_i, \ f(x_i))}{\partial f(x_i)} \end{bmatrix} _{f(x)=f_{m-1} \ \ \ (x)} \]

$\ \ \ \ $(b)将所有样本 \((x_i, r_{mi})\) 拟合一个 \(CART\) 回归树,得到第 \(m\) 棵树的叶结点区域 \(R_{mj}\)\(j=1,2,...,J\)
$\ \ \ \ $(c)对 \(j=1,2,...,J\),其中 \(J\) 为叶结点的个数,计算

\[c_{mj} = arg\ \underset{c}{min} \sum_{x_i \in R_{mj}} \ L(y_i,f_{m-1} + c) \]

$\ \ \ \ $(d)更新 \(f_m(x) = f_{m-1}(x) + \sum_{j=1}^{J} c_{mj}I(x \in R_{mj})\)

(3)得到回归树

\[\hat{f}(x) = f_M(x) = \sum_{m=1}^{M} \sum_{j=1}^{J} c_{mj}I(x \in R_{mj}) \]


\((1)\) 步初始化,估计使损失函数极小化的常数值,它只有一个根节点。

\((2a)\)计算损失函数的负梯度在当前模型的值,作为残差的估计。对平方误差损失函数,它就是通常所说的残差;对于一般的损失函数,就是残差的近似值。

\((2b)\)对残差拟合一个回归树,得到回归树叶结点区域

\((2c)\)利用线性搜索估计叶节点区域的值。使损失函数极小化

\((2d)\) 步更新回归树。

\((3)\) 步得到最终模型 \(\hat{f}(x)\)


求证:平方损失函数的负梯度是残差。

证明:为求导方便,在损失函数前乘以 \(\frac{1}{2}\)

\[L(y_i,f(x_i)) = \frac{1}{2} \left( y_i,f(x_i)\right)^2 \]

\(f(x_i)\) 求导,则有:

\[\frac{\partial L(y_i, \ f(x_i))}{\partial f(x_i)} = f(x_i) - y_i \]

残差是梯度相反数,即:

\[r_{mi} = y_i - f_{m-1}(x_i) = - \begin{bmatrix} \frac{\partial L(y_i, \ f(x_i))}{\partial f(x_i)} \end{bmatrix} _{f(x)=f_{m-1}\ \ \ (x)} \]



2. GBDT 分类算法

\(GBDT\) 分类算法从思想上和 \(GBDT\) 回归算法没区别,但是由于样本输出不是连续的值,而是离散的类别,导致无法直接从输出类别去拟合类别输出的误差。

两种方法解决:

  • 指数损失函数,此时 \(GBDT\) 退化为 \(AdaBoost\) 算法。
  • 类似逻辑回归的对数似然损失函数方法。即用类别的预测概率值和真实概率值的差来拟合损失。本文仅讨论用对数似然损失函数的 \(GBDT\) 分类。而对于对数似然损失函数,我们又有二元分类和多元分类的区别。

2.1 二元 GBDT 分类算法

对于二元 \(GBDT\),如果用类似逻辑回归的对数似然损失函数,则损失函数为

\[L(y,f(x)) = log(1+e^{-yf(x)}) \]

其中,\(y \in \{-1,1\}\),则此时的负梯度误差

\[\begin{aligned} r_{mi} & = - \begin{bmatrix} \frac{\partial L(y_i, \ f(x_i))}{\partial f(x_i)} \end{bmatrix} _{f(x)=f_{m-1} \ \ \ (x)} \\ \\ & = -\left[ln \frac{e^{y_if(x_i)}+1}{e^{y_if(x_i)}} \right]' = -\frac{e^{y_i f(x_i)}}{e^{y_i f(x_i)}+1} \left[\frac{e^{y_i f(x_i)}+1}{e^{y_i f(x_i)}} \right]' = -\frac{e^{y_i f(x_i)}}{e^{y_i f(x_i)}+1} \left[1+e^{-y_i f(x_i)} \right]' = -\frac{e^{y_i f(x_i)}}{e^{y_i f(x_i)}+1} \left[-y_i e^{-y_i f(x_i)} \right] \\ \\ & = y_i / (1+exp(y_if(x_i))) \end{aligned} \]

对于生成的决策树,各个叶子结点的最佳负梯度拟合值为

\[c_{mj} = arg \underset{c}{min} \sum_{x_i \in R_{mj}} log(1+exp(-y_i(f_{m-1} (x_i) + c))) \]

由于上式比较难优化,所以一般用近似值代替

\[c_{mj} = \sum_{x_i \in R_{mj}}r_{mi} \ / \sum_{x_i \in R_{mj}} |r_{mi}|(1-|r_{mi}|) \]

除了负梯度计算和叶子结点的最佳负梯度拟合的线性搜索,二元 \(GBDT\) 分类和 \(GBDT\) 回归算法过程相同 。


2.2 多元 GBDT 分类算法

多元 \(GBDT\) 比二元 \(GBDT\) 复杂一些,对应的是多元逻辑回归和二元逻辑回归的复杂度差别。假设类别为 \(K\),则对数似然损失函数为

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

其中如果样本输出类别为 \(k\),则 \(y_k=1\)。第 \(k\) 类的概率 \(p_k(x)\)​ 的表达式为

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

集合上两式,可以计算出第 \(m\) 轮的第 \(i\) 个样本对应对应类别 \(l\) 的负梯度误差为

\[\begin{aligned} r_{mil} & = -\left[ \frac{\partial L(y_i,f(x_i))}{\partial f(x_i)} \right]_{f_k(x) = f_{l,\ m-1}\ \ \ \ (x)} \\ \\ & = y_{il} - p_{l,\ m-1}\ (x_i) \end{aligned} \]

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

对于生成的决策树,各个叶子结点的最佳负梯度拟合值为

\[c_{mjl} = arg \underset{c_{jl}}{min} \sum_{i=0}^{N} \sum_{k=1}^{K} L(y_k,f_{m-1,l} \ (x) + \sum_{j=0}^{J}c_{jl} I(x_i \in R_{tjl})) \]

由于上式比较难优化,所以一般用近似值代替

\[c_{tjl} = \frac{K-1}{K} \left[\sum_{x_i \in R_{mjl}} r_{mil} \ / \sum_{x_i \in R_{mil}} |r_{mil}|(1-|r_{mil}|)\right] \]

除了负梯度计算和叶子结点的最佳负梯度拟合的线性搜索,多元 \(GBDT\) 分类、二元 \(GBDT\) 分类和 \(GBDT\) 回归算法过程相同 。



3. GBDT 损失函数

分类算法:对数似然损失函数、指数损失函数。

① 对数似然损失函数。分为二元分类、多元分类,详见 \(2.1、2.2\) 节。

② 指数损失函数。损失函数表达式为

\[L(y,f(x)) = e^{-yf(x)} \]

回归算法:均方差、绝对损失、\(Huber\) 损失、分位数损失。

① 均方差。

\[L(y,f(x)) = (y-f(x))^2 \]

② 绝对损失。

\[L(y,f(x)) = |y-f(x)| \]

对应负梯度为

\[sign(y_i - f(x_i)) \]

\(Huber\) 损失。它是均方差和绝对损失的折中产物,对远离中心的异常点,采用绝对损失,对中心附近的点采用均方差。这个界限一般用分位数度量。损失函数为

\[L(y,f(x)) = \begin{cases} \frac{1}{2} (y-f(x))^2 & |y-f(x)| \leqslant \delta \\ \\ \delta (|y-f(x)| - \frac{\delta}{2}) & |y-f(x)| > \delta \end{cases} \]

对应负梯度为

\[r(y_i,f(x_i)) = \begin{cases} y_i - f(x_i) & |y-f(x)| \leqslant \delta \\ \\ \delta sign(y_i-f(x_i)) & |y-f(x)| > \delta \end{cases} \]

④ 分位数损失。对应的是分位数回归的损失,表达式为

\[L(y,f(x)) = \sum_{y \geqslant f(x)} \theta |y-f(x)| + \sum_{y<f(x)} (1-\theta) |y-f(x)| \]

其中,\(\theta\) 为分位数,需要在回归前指定。

对应的负梯度为

\[r(y_i,f(x_i)) = \begin{cases} \theta & y_i \geqslant f(x_i) \\ \theta-1 & y_i < f(x_i) \end{cases} \]

\(Huber\) 损失、分位数损失,主要用于健壮回归,即减少异常点对损失函数的影响。



4. GBDT 正则化

为防止过拟合,需要对 \(GBDT\) 进行正则化。\(GBDT\) 正则化主要有三种:

① 与 \(AdaBoost\) 类似,定义步长 \(\nu\)

对于弱学习器的迭代,

\[f_m(x) = f_{m-1}(x) + \alpha_m G_m(x) \]

加上正则化项,

\[f_m(x) = f_{m-1}(x) + \nu \alpha_m G_m(x) \]

其中 \(0< \nu \leqslant 1\)

对于同样的训练集,较小的 \(\nu\) 意味需要更多的迭代次数。通常我们用步长和迭代最大次数一起来决定算法的拟合效果。

通过子采样比例。取值为 \((0,1]\)。注意这里的子采样是不放回抽样,与随机森林不一样。

如果取值为 \(1\),则全部样本都使用,等于没使用子采样;

如果取值小于 \(1\),则只有一部分样本做 \(GBDT\) 决策树拟合。选择小于 \(1\) 的比例可以减少方差,即防止过拟合。但会增加样本拟合的偏差,因此取值不能太低。推荐 \([0.5,0.8]\) 之间。

使用子采样的 \(GBDT\) 也称随机梯度提升树(\(Stochastic\ Gradient\ Boosting\ Tree,SGBT\))。由于使用了子采样,程序可以通过采样分发到不同的任务去做 \(Boosting\) 的迭代过程,最后形成新树,从而减少弱学习器难以并行学习的弱点。

对弱学习器 \(CART\) 回归树进行正则化剪枝。



5. GBDT 总结

\(GBDT\) 优点:

① 可以处理各种类型数据,包括连续值、离散值。

② 在相对较少的调参下,预测准确率就可以比较高(相比 \(SVM\))。

③ 使用一些健壮的损失函数,对异常值的鲁棒性非常强。比如 \(Huber\) 损失函数、\(Quantile\) 损失函数。

\(GBDT\) 缺点:

① 由于弱学习器之间存在依赖关系,难以并行训练数据。不过可以通过子采样的 \(SGBT\) 来达到部分并行。



来自:刘建平

posted @ 2019-08-14 11:05  做梦当财神  阅读(753)  评论(1编辑  收藏  举报