GBDT算法梳理

引言

集成学习中的提升法是一种常见的统计学习方法,通常的思路是改变训练数据的概率分布(即训练数据的权值分布),针对不同训练数据分布调用弱学习方法学习一系列的弱分类器。因此针对Boosting方法,就有两个地方需要注意:

  1. 每一轮训练如何改变训练数据的权值分布和概率分布
  2. 如何将弱分类器组合成一个强分类器

以Boosting算法里常见的AdaBoost算法为例,对于第1个问题,AdaBoost的方法是提升被前一轮弱分类器错误分类的样本的权值,降低被正确分类样本的权值;对于第2个问题,AdaBoost采取加权多数表决的方法,加大分类误差率小的弱分类器的权值,减少分类误差率大的弱分类器的权值

针对这两个问题,大部分Boosting算法都是用**加法模型(additive model)来组合弱分类器,然后用前向分步算法(forward stagewise algorithm)**来训练改变训练数据的权值和概率分布(包括AdaBoost算法)。

前向分步算法

考虑加法模型:

f ( x ) = ∑ m = 1 M β m b ( x ; γ m ) b ( x ; γ m ) 是基函数; γ m 是基函数参数, β m 是基函数的系数 f(x)=\sum_{m=1}^{M} \beta_{m} b\left(x ; \gamma_{m}\right) \\ \text{$b(x;\gamma_{m})$是基函数;$\gamma_m$是基函数参数,$\beta_m$是基函数的系数} f(x)=m=1Mβmb(x;γm)b(x;γm)是基函数;γm是基函数参数,βm是基函数的系数

在给定训练数据以及损失函数 L ( y , f ( x ) ) L(y,f(x)) L(y,f(x))的条件下,学习加法模型 f ( x ) f(x) f(x)就是一个经验风险极小化问题即损失函数极小化问题:

min ⁡ β m , γ m ∑ i = 1 N L ( y i , ∑ m = 1 M β m b ( x i ; γ m ) ) \min _{\beta_{m}, \gamma_{m}} \sum_{i=1}^{N} L\left(y_{i}, \sum_{m=1}^{M} \beta_{m} b\left(x_{i} ; \gamma_{m}\right)\right) βm,γmmini=1NL(yi,m=1Mβmb(xi;γm))
直接求解这个的最小值是个很复杂的优化问题,因此我们采用前向分步算法来解决这一优化问题。

前向分布算法的思路是:因为学习的是加法模型,若能从前到后,每一步只学习一个基函数及其系数,逐步逼近优化目标函数,那么就可以简化复杂度。每步只需要优化如下损失函数

min ⁡ β , γ ∑ i = 1 N L ( y i , β b ( x i ; γ ) ) \min _{\beta, \gamma} \sum_{i=1}^{N} L\left(y_{i}, \beta b\left(x_{i} ; \gamma\right)\right) β,γmini=1NL(yi,βb(xi;γ))

这样的话,原本需要同时求解从 m = 1 m=1 m=1 M M M所有参数 β m , γ m \beta_m, \gamma_m βm,γm的优化问题就简化为逐次求解 β m , γ m \beta_m, \gamma_m βm,γm的优化问题。

负梯度拟合

GBDT也是Boosting算法的一种,但却和Adaboost有很大的不同。

Adaboosting的主要思想是:根据前一轮模型的预测结果,提过对预测结果错误的样本的关注,即改变下一轮训练数据的样本分布,再次进行训练。最后将这些模型结合起来,形成最终的模型。

GBDT的思想:基于前一轮迭代得到的强学习器 f t − 1 ( x ) f_{t-1}(x) ft1(x)(损失函数 L ( y , f t − 1 ( x ) ) L(y, f_{t-1}(x)) L(y,ft1(x))),在不该变前一个模型的基础上,对上一轮模型的残差进行拟合。即这一轮的拟合样本集就办成了 ( x 1 , y 1 − f t − 1 ( x 1 ) ) , ( x 2 , y 2 − f t − 1 ( x 2 ) ) , … ( x n , y n − f t − 1 ( x n ) ) \left(x_{1}, y_{1}-f_{t-1}\left(x_{1}\right)\right),\left(x_{2}, y_{2}-f_{t-1}\left(x_{2}\right)\right), \ldots\left(x_{n}, y_{n}-f_{t-1}\left(x_{n}\right)\right) (x1,y1ft1(x1)),(x2,y2ft1(x2)),(xn,ynft1(xn))( y i − f t − 1 ( x ) y_i - f_{t-1}(x) yift1(x)被称为残差,即上一轮模型没有拟合好的部分)。

对于回归问题,一般的损失是平方损失函数: L ( y , F ( x ) ) = 1 2 ( y − F ( X ) ) 2 L(y, F(x))=\frac{1}{2}(y-F(X))^{2} L(y,F(x))=21(yF(X))2,具体形式就是: 1 2 ∑ 0 n ( y i − F ( x i ) ) 2 \frac{1}{2} \sum_{0}^{n}\left(y_{i}-F\left(x_{i}\right)\right)^{2} 210n(yiF(xi))2,这就是我们想最小化的东西。

损失函数的一阶导数是: ∂ J ∂ F ( x i ) = ∂ ∑ i L ( y i , F ( x i ) ) ∂ F ( x i ) = ∂ L ( y i , F ( x i ) ) ∂ F ( x i ) = F ( x i ) − y i \frac{\partial J}{\partial F\left(x_{i}\right)}=\frac{\partial \sum_{i} L\left(y_{i}, F\left(x_{i}\right)\right)}{\partial F\left(x_{i}\right)}=\frac{\partial L\left(y_{i}, F\left(x_{i}\right)\right)}{\partial F\left(x_{i}\right)}=F\left(x_{i}\right)-y_{i} F(xi)J=F(xi)iL(yi,F(xi))=F(xi)L(yi,F(xi))=F(xi)yi
正好残差就是负梯度: y i − F ( x i ) = − ∂ J ∂ F ( x i ) y_{i}-F\left(x_{i}\right)=-\frac{\partial J}{\partial F\left(x_{i}\right)} yiF(xi)=F(xi)J
也就是说,我们对残差的拟合就是对损失函数负梯度的拟合

目标函数

对于普通的机器学习模型而言,其目标函数可以定义为如下:
O b j = ∑ i = 1 n l ( y i , y ^ i ) + ∑ k = 1 K Ω ( f k ) O b j=\sum_{i=1}^{n} l\left(y_{i}, \hat{y}_{i}\right)+\sum_{k=1}^{K} \Omega\left(f_{k}\right) Obj=i=1nl(yi,y^i)+k=1KΩ(fk)
前面是 l o s s loss loss函数,后面 Ω \Omega Ω是正则化项。
结合前向分步算法的原理,在第 t t t步的目标函数是:

O b j ( t ) = ∑ i = 1 n l ( y i , y ^ i t ) + ∑ i = 1 t Ω ( h i ) = ∑ i = 1 n l ( y i , y ^ i t − 1 + h t ( x i ) ) + Ω ( h t ) + constant  \begin{array}{c}{O b j^{(t)}=\sum_{i=1}^{n} l\left(y_{i}, \hat{y}_{i}^{t}\right)+\sum_{i=1}^{t} \Omega\left(h_{i}\right)} \\ {=\sum_{i=1}^{n} l\left(y_{i}, \hat{y}_{i}^{t-1}+h_{t}\left(x_{i}\right)\right)+\Omega\left(h_{t}\right)+\text {constant }}\end{array} Obj(t)=i=1nl(yi,y^it)+i=1tΩ(hi)=i=1nl(yi,y^it1+ht(xi))+Ω(ht)+constant 

最优化该目标函数就是求的 h t ( x ) h_t(x) ht(x)

由泰勒公式的一阶展开式: f ( x + Δ x ) ≈ f ( x ) + f ′ ( x ) Δ x f(x+\Delta x) \approx f(x)+f^{\prime}(x) \Delta x f(x+Δx)f(x)+f(x)Δx
l ( y i , y ^ i t − 1 + h t ( x i ) ) l\left(y_{i}, \hat{y}_{i}^{t-1}+h_{t}\left(x_{i}\right)\right) l(yi,y^it1+ht(xi)) 做一阶泰勒展开得到:

l ( y i , y ^ i t − 1 + h t ( x i ) ) = l ( y i , y ^ i t − 1 ) + g i h t ( x i ) l\left(y_{i}, \hat{y}_{i}^{t-1}+h_{t}\left(x_{i}\right)\right)=l\left(y_{i}, \hat{y}_{i}^{t-1}\right)+g_{i} h_{t}\left(x_{i}\right) l(yi,y^it1+ht(xi))=l(yi,y^it1)+giht(xi)

g i 是 l ( y i , y ^ i t − 1 ) 关于 y ^ t − 1 的一阶导 \text{$g_i$是$l(y_i, \hat y_i^{t-1})$关于$\hat y^{t-1}$的一阶导} gil(yi,y^it1)关于y^t1的一阶导

此时,目标函数(不考虑正则化项)则变成:

O b j ( t ) = ∑ i = 1 n [ l ( y i , y ^ i t − 1 ) + g i h t ( x i ) ] O b j ( t − 1 ) = ∑ i = 1 n [ l ( y i , y ^ i t − 1 ) ] \begin{array}{c}{O b j^{(t)}=\sum_{i=1}^{n}\left[l\left(y_{i}, \hat{y}_{i}^{t-1}\right)+g_{i} h_{t}\left(x_{i}\right)\right]} \\ {O b j^{(t-1)}=\sum_{i=1}^{n}\left[l\left(y_{i}, \hat{y}_{i}^{t-1}\right)\right]}\end{array} Obj(t)=i=1n[l(yi,y^it1)+giht(xi)]Obj(t1)=i=1n[l(yi,y^it1)]

我们肯定希望 O b j Obj Obj 函数每步都减小,即 O b j ( t ) &lt; O b j ( t − 1 ) O b j^{(t)}&lt;O b j^{(t-1)} Obj(t)<Obj(t1),关键就在于 ∑ i = 1 n g i h t ( x i ) \sum_{i=1}^{n}g_{i} h_{t}(x_{i}) i=1ngiht(xi),我们不知道 g i g_i gi 是正是负,那么只需让 h t ( x i ) = − α g i h_{t}\left(x_{i}\right)=-\alpha g_{i} ht(xi)=αgi α \alpha α是我们任取的正常数)就能让 ∑ i = 1 n g i h t ( x i ) \sum_{i=1}^{n}g_{i} h_{t}(x_{i}) i=1ngiht(xi) 恒为负了。而 − g i -g_{i} gi正是负梯度!!!

分类

上面一直在用回归的例子做推导,GBDT的分类算法从思想上和GBDT的回归算法没有区别,但是由于样本输出不是连续的值,而是离散的类别,导致我们无法直接从输出类别去拟合类别输出的误差。

为了解决这个问题,主要有两个方法,一个是用指数损失函数,此时GBDT退化为Adaboost算法。另一种方法是用类似于逻辑回归的对数似然损失函数的方法。也就是说,我们用的是类别的预测概率值和真实概率值的差来拟合损失。本文仅讨论用对数似然损失函数的GBDT分类。而对于对数似然损失函数,我们又有二元分类和多元分类的区别。

二分类

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

L ( y , f ( x ) ) = log ⁡ ( 1 + exp ⁡ ( − y f ( x ) ) ) L(y, f(x))=\log (1+\exp (-y f(x))) L(y,f(x))=log(1+exp(yf(x)))

其中 y ∈ { − 1 , + 1 } y \in\{-1,+1\} y{1,+1},则此时的负梯度为:
r t i = − [ ∂ L ( y , f ( x i ) ) ∂ f ( x i ) ] f ( x ) = f t − 1 ( x ) = y i / ( 1 + exp ⁡ ( y i f ( x i ) ) ) r_{t i}=-\left[\frac{\partial L\left(y, f\left(x_{i}\right)\right) }{\partial f\left(x_{i}\right)}\right]_{f(x)=f_{t-1}(x)}=y_{i} /\left(1+\exp \left(y_{i} f\left(x_{i}\right)\right)\right) rti=[f(xi)L(y,f(xi))]f(x)=ft1(x)=yi/(1+exp(yif(xi)))

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

c t j = arg ⁡ min ⁡ ⎵ c ∑ x i ∈ R t j log ⁡ ( 1 + exp ⁡ ( − y i ( f t − 1 ( x i ) + c ) ) ) c_{t j}=\underbrace{\arg \min }_{c} \sum_{x_{i} \in R_{t j}} \log \left(1+\exp \left(-y_{i}\left(f_{t-1}\left(x_{i}\right)+c\right)\right)\right) ctj=c argminxiRtjlog(1+exp(yi(ft1(xi)+c)))

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

c t j = ∑ x i ∈ R t j r t i / ∑ x i ∈ R t j ∣ r t i ∣ ( 1 − ∣ r t i ∣ ) c_{t j}=\sum_{x_{i} \in R_{t j}} r_{t i} / \sum_{x_{i} \in R_{t j}}\left|r_{t i}\right|\left(1-\left|r_{t i}\right|\right) ctj=xiRtjrti/xiRtjrti(1rti)

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

多分类

假设类别数为K,则此时我们的对数似然损失函数为:
L ( y , f ( x ) ) = − ∑ k = 1 K y k log ⁡ p k ( x ) p k ( x ) = exp ⁡ ( f k ( x ) ) / ∑ l = 1 K exp ⁡ ( f l ( x ) ) 若样本输出类别为k,则 y k = 1 L(y, f(x))=-\sum_{k=1}^{K} y_{k} \log p_{k}(x) \\ p_{k}(x)=\exp \left(f_{k}(x)\right) / \sum_{l=1}^{K} \exp \left(f_{l}(x)\right)\\ \text{若样本输出类别为k,则$y_{k}=1$} L(y,f(x))=k=1Kyklogpk(x)pk(x)=exp(fk(x))/l=1Kexp(fl(x))若样本输出类别为k,则yk=1

由以上两式,我们可以计算第 t t t轮的第 i i i个样本对应的类别 l l l的负梯度为:
r t i l = − [ ∂ L ( y i , f ( x i ) ) ) ∂ f ( x i ) ] f k ( x ) = f l , t − 1 ( x ) = y i l − p l , t − 1 ( x i ) r_{t i l}=-\left[\frac{\partial L\left(y_{i}, f\left(x_{i}\right)\right) )}{\partial f\left(x_{i}\right)}\right]_{f_{k}(x)=f_{l, t-1}(x)}=y_{i l}-p_{l, t-1}\left(x_{i}\right) rtil=[f(xi)L(yi,f(xi)))]fk(x)=fl,t1(x)=yilpl,t1(xi)

其实这里的误差就是样本 i i i 对应类别的真实概率和 t − 1 t-1 t1轮预测概率的差值。

对于生成的决策树,我们各个叶子节点的最佳负梯度拟合值为:
c t j l = arg ⁡ min ⁡ ⎵ c j l ∑ i = 0 m ∑ k = 1 K L ( y k , f t − 1 , l ( x ) + ∑ j = 0 J c j l I ( x i ∈ R t j ) ) c_{t j l}=\underbrace{\arg \min }_{c_{j l}} \sum_{i=0}^{m} \sum_{k=1}^{K} L\left(y_{k}, f_{t-1, l}(x)+\sum_{j=0}^{J} c_{j l} I\left(x_{i} \in R_{t j}\right)\right) ctjl=cjl argmini=0mk=1KL(yk,ft1,l(x)+j=0JcjlI(xiRtj))

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

c t j l = K − 1 K ∑ x i ∈ R t i l r t i l ∑ x i ∈ R i t ∣ r t i l ∣ ( 1 − ∣ r t i l ∣ ) c_{t j l}=\frac{K-1}{K} \frac{\sum_{x_{i} \in R_{t i l}} r_{t i l}}{\sum_{x_{i} \in R_{i t}}\left|r_{t i l}\right|\left(1-\left|r_{t i l}\right|\right)} ctjl=KK1xiRitrtil(1rtil)xiRtilrtil

损失函数

分类算法

分类算法的损失函数一般有对数损失函数和指数损失函数两种:

  1. 如果是指数损失函数,则损失函数表达式为: L ( y , f ( x ) ) = exp ⁡ ( − y f ( x ) ) L(y, f(x))=\exp (-y f(x)) L(y,f(x))=exp(yf(x))
  2. 如果是对数损失函数,分为二元分类和多元分类两种,见上面。
回归算法

回归算法,常用损失函数有如下4种:

  1. 均方差,其表达式为: L ( y , f ( x ) ) = ( y − f ( x ) ) 2 L(y, f(x))=(y-f(x))^{2} L(y,f(x))=(yf(x))2
  2. 平均绝对误差,其表达式为: L ( y , f ( x ) ) = ∣ y − f ( x ) ∣ L(y, f(x))=|y-f(x)| L(y,f(x))=yf(x)
    • 对应负梯度误差为: sign ⁡ ( y i − f ( x i ) ) \operatorname{sign}\left(y_{i}-f\left(x_{i}\right)\right) sign(yif(xi))
  3. Huber损失,它是均方差和绝对损失的折衷产物,对于远离中心的异常点,采用绝对损失,而中心附近的点采用均方差。这个界限一般用分位数点度量,其表达式为: L ( y , f ( x ) ) = { 1 2 ( y − f ( x ) ) 2 ∣ y − f ( x ) ∣ ≤ δ δ ( ∣ y − f ( x ) ∣ − δ 2 ) ∣ y − f ( x ) ∣ &gt; δ L(y, f(x))=\left\{\begin{array}{ll}{\frac{1}{2}(y-f(x))^{2}} &amp; {|y-f(x)| \leq \delta} \\ {\delta\left(|y-f(x)|-\frac{\delta}{2}\right)} &amp; {|y-f(x)|&gt;\delta}\end{array}\right. L(y,f(x))={21(yf(x))2δ(yf(x)2δ)yf(x)δyf(x)>δ
    • 负梯度误差为: r ( y i , f ( x i ) ) = { y i − f ( x i ) ∣ y i − f ( x i ) ∣ ≤ δ δ sign ⁡ ( y i − f ( x i ) ) ∣ y i − f ( x i ) ∣ &gt; δ r\left(y_{i}, f\left(x_{i}\right)\right)=\left\{\begin{array}{ll}{y_{i}-f\left(x_{i}\right)} &amp; {\left|y_{i}-f\left(x_{i}\right)\right| \leq \delta} \\ {\delta \operatorname{sign}\left(y_{i}-f\left(x_{i}\right)\right)} &amp; {\left|y_{i}-f\left(x_{i}\right)\right|&gt;\delta}\end{array}\right. r(yi,f(xi))={yif(xi)δsign(yif(xi))yif(xi)δyif(xi)>δ
  4. 分位数损失,它对应的是分位数回归的损失函数,其表达式为: L ( y , f ( x ) ) = ∑ y ≥ f ( x ) θ ∣ y − f ( x ) ∣ + ∑ y &lt; f ( x ) ( 1 − θ ) ∣ y − f ( x ) ∣ L(y, f(x))=\sum_{y \geq f(x)} \theta|y-f(x)|+\sum_{y&lt;f(x)}(1-\theta)|y-f(x)| L(y,f(x))=yf(x)θyf(x)+y<f(x)(1θ)yf(x),其中 θ \theta θ为分位数,需要我们在回归前指定。
    • 负梯度误差为: r ( y i , f ( x i ) ) = { θ y i ≥ f ( x i ) θ − 1 y i &lt; f ( x i ) r\left(y_{i}, f\left(x_{i}\right)\right)=\left\{\begin{array}{ll}{\theta} &amp; {y_{i} \geq f\left(x_{i}\right)} \\ {\theta-1} &amp; {y_{i}&lt;f\left(x_{i}\right)}\end{array}\right. r(yi,f(xi))={θθ1yif(xi)yi<f(xi)

对于Huber损失和分位数损失,主要用于健壮回归,也就是减少异常点对损失函数的影响。

正则化

GBDT的正则化主要有三种方式:

  1. 第一种是和Adaboost类似的正则化项,即步长(learning rate)。定义 ν \nu ν,对于前面的弱学习器的迭代: f k ( x ) = f k − 1 ( x ) + h k ( x ) f_{k}(x)=f_{k-1}(x)+h_{k}(x) fk(x)=fk1(x)+hk(x),如果我们加上了正则化项,则有: f k ( x ) = f k − 1 ( x ) + ν h k ( x ) f_{k}(x)=f_{k-1}(x)+\nu h_{k}(x) fk(x)=fk1(x)+νhk(x) 0 &lt; ν ≤ 1 0&lt;\nu \leq 1 0<ν1),对于同样的训练集学习效果,较小的 ν \nu ν意味着我们需要更多的弱学习器的迭代次数。通常我们用步长和迭代最大次数一起来决定算法的拟合效果。
  2. 第二种正则化的方式是通过子采样比例(subsample)。取值为(0,1]。注意这里的子采样和随机森林不一样,随机森林使用的是放回抽样,而这里是不放回抽样。如果取值为1,则全部样本都使用,等于没有使用子采样。如果取值小于1,则只有一部分样本会去做GBDT的决策树拟合。选择小于1的比例可以减少方差,即防止过拟合,但是会增加样本拟合的偏差,因此取值不能太低。推荐在[0.5, 0.8]之间。使用了子采样的GBDT有时也称作随机梯度提升树(Stochastic Gradient Boosting Tree, SGBT)。由于使用了子采样,程序可以通过采样分发到不同的任务去做boosting的迭代过程,最后形成新树,从而减少弱学习器难以并行学习的弱点。
  3. 第三种是对于弱学习器即CART回归树进行正则化剪枝。

优缺点

GBDT主要的优点有:

  1. 可以灵活处理各种类型的数据,包括连续值和离散值。
  2. 在相对少的调参时间情况下,预测的准确率也可以比较高。这个是相对SVM来说的。
  3. 使用一些健壮的损失函数,对异常值的鲁棒性非常强。比如 Huber损失函数和Quantile损失函数。

GBDT的主要缺点有:

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

sklearn参数

sklearn官方文档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值