GBDT知识整理

来源:互联网 发布:10年选秀体测数据 编辑:程序博客网 时间:2024/06/06 09:41

GBDT算法(Gradient Boosting Decision Tree),由于其出色的非线性拟合能力,被广泛应用在各种回归,分类的机器学习问题中。

除了能在日常工作中调用该算法取得好的结果之外,我们更需要深入理解这个算法的原理,以及其中涉及到的概念。

名词拆解

Boosting

GBDT中Gradient Boosting和Decision Tree是两个独立的概念。Boosting意思是把多个弱分类器组合起来形成一个强分类器。因此这不是某个算法,而一种理念。而和这个理念对应的是直接训练一次性构造一个强分类器,例如SVM,LR等等。

通常通过相加来组合分类器,形式如下:

Fm(x)=f0+α1f1(x)+α2f2(x)++αmfm(x)(1)

其中x表示输入的特征,Fm表示最终得到的分类器,f1,f2,,fm 分别表示m个弱分类器,f0是一个常数, α1,α2,,αm分别表示每个弱分类器对应的权重。

Gradient Boosting Model

Gradient Boosting Model,以下简称GBM。这是一种构造弱分类的方法。同样地,这不是某个具体的算法,仍然是只是一个理念。

先看一个典型的优化问题:

find x̂ =arg minxf(x)

针对这种优化问题,最常用的解决方法是steepest descent(gradient descent),算法逻辑如下:

  • 1.给定一个起始点x0
  • 2.对i=1,2,……K分别做如下迭代:
    • a) xi=xi1+γi1gi1,这里gi1=fxx=xi1表示fxi1 点的梯度
  • 3.直到|gi1|足够小,或者是|xixi1|足够小

以上迭代过程可以这么理解:整个寻优的过程就是个小步快跑的过程,每跑一小步,都往函数当前下降最快的那个方向走一点。

这样寻优得到的结果可以表示成加和形式,即

xk=x0+γ1g1+γ2g2++γkgk

这个等式的形式和前面Eq.(1)弱分类器组合成强分类器Fm如出一辙,Gradient Boosting就是由此启发而来。构造Fm本就是一个寻找最优的过程,只不过我们寻找的不是一个最优点,而是一个最优的函数。优化的目标通常都是通过一个损失函数来定义,即
find Fm=arg minFL(F)=arg minFi=0NLoss(F(xi),yi)(2)

其中Loss(F(xi),yi)表示损失函数在第个样本上的损失值,xiyi分别表示第i个样本的特征和目标值。常见的损失函数如平方差函数
Loss(F(xi),yi)=(F(xi)yi)2

我们可以通过梯度下降法来构造弱分类器f1,f2,,fm ,只不过每次迭代时,令
gi=LFF=Fi1

即对损失函数L,以F为参考求取梯度。

但是,一个函数对函数的求导不好理解。而且通常都无法通过上述公式直接求解到梯度函数gi。为此,采取一个近似的方法,把函数Fi1理解成在所有样本上的离散的函数值,即:

[Fi1(x1),Fi1(x2),,Fi1(xN)]

不难理解,这是一个N维向量,然后计算
gi^(xk)=LF(xk)F=Fi1 k=1,2,,N

这是一个函数对向量的求导,得到的也是一个梯度向量。注意,这里求导时的变量还是函数F,不是样本xk

严格来说gi^(xk)  k=1,2,,N只是描述了gi在某些个别点上的值,并不足以表达gi,但我们可以通过函数拟合的方法从gi^(xk)  k=1,2,,N构造gi,这样我们就通过近似的方法得到了函数对函数的梯度求导。

GBM的过程可以总结如下:

  • 1.选择一个起始常量函数f0
  • 2.对i=1,2,……,K分别做如下迭代:

    • a)计算离散梯度值ĝ i1(xj)=LF(xj)F=Fi1 j=1,2,,N
    • b)对ĝ i1(xj) j=1,2,,N做函数拟合得到gi1
    • c)通过line seach得到γi1=arg min L(Fi1+γi1gi1)
    • d)令Fi=Fi1+γi1gi1
  • 3.直到 |ĝ i1| 足够小,或者迭代次数完毕

常量函数f0通常取样本目标值的均值,即

f0=1Ni=0Nyi

Gradient Boosting Decision Tree

在GBM的过程中,尚未说清楚如何通过离散值ĝ i1(xj)  j=1,2,,N构造拟合函数gi1。函数拟合是个比较熟知的概念,有很多现成的方法,不过有一种拟合方法广为应用,那就是决策树Decision Tree。理解GBDT重点首先是Gradient Boosting,其次才是Decision Tree。GBDT是Gradient Boosting的一种具体实例,只不过这里的弱分类器是决策树。如果你改用其他弱分类器XYZ,你也可以称之为Gradient Boosting XYZ。只不过Decision Tree很好用,GBDT才如此引人注目。

GBDT的优势得益于Decision Tree本身的一些良好特性,具体可以列举如下:

  • 1) Decision Tree可以很好的处理missing feature,这是他的天然特性,因为决策树的每个节点只依赖一个feature,如果某个feature不存在,这颗树依然可以拿来做决策,只是少一些路径。像逻辑回归,SVM就没这个好处。
  • 2) Decision Tree可以很好的处理各种类型的feature,也是天然特性,很好理解,同样逻辑回归和SVM没这样的天然特性。
  • 3) 对特征空间的outlier有鲁棒性,因为每个节点都是 的形式,至于大多少,小多少没有区别,outlier不会有什么大的影响,同样逻辑回归和SVM没有这样的天然特性。
  • 4) 如果有不相关的feature,没什么干扰,如果数据中有不相关的feature,顶多这个feature不出现在树的节点里。逻辑回归和SVM没有这样的天然特性(但是有相应的补救措施,比如逻辑回归里的L1正则化)。
  • 5) 数据规模影响不大,因为我们对弱分类器的要求不高,作为弱分类器的决策树的深度一般设的比较小,即使是大数据量,也可以方便处理。像SVM这种数据规模大的时候训练会比较麻烦。

当然Decision Tree也不是毫无缺陷,通常在给定的不带噪音的问题上,他能达到的最佳分类效果还是不如SVM,逻辑回归之类的。但是,我们实际面对的问题中,往往有很大的噪音,使得Decision Tree这个弱势就不那么明显了。而且,GBDT通过不断的叠加组合多个小的Decision Tree,他在不带噪音的问题上也能达到很好的分类效果。换句话说,通过GBDT训练组合多个小的Decision Tree往往要比一次性训练一个很大的Decision Tree的效果好很多。因此不能把GBDT理解为一颗大的决策树,几颗小树经过叠加后就不再是颗大树了,它比一颗大树更强。

损失函数

谈到GBDT,常听到一种简单的描述方式:“先构造一个(决策)树,然后不断在已有模型和实际样本输出的残差上再构造一颗树,依次迭代”。其实这个说法不全面,它只是GBDT的一种特殊情况,为了看清这个问题,需要对损失函数的选择做一些解释。

从对GBM的描述里可以看到Gradient Boosting过程和具体用什么样的弱分类器是完全独立的,可以任意组合,因此这里不再刻意强调用决策树来构造弱分类器,转而我们来仔细看看弱分类器拟合的目标值,即梯度ĝ i1(xj),之前我们已经提到过

gi^(xk)=LF(xk)F=Fi1 k=1,2,,N

因此LF(xk)很重要,拿平方差损失函数为例,可以得到
LF(xk)F=Fi1=2(Fi1(xk)yk)

忽略倍数2,这正好是当前已经构造好的函数 Fi1 在样本上和目标值yk之间的差值。
如果我们换一个损失函数,比如绝对差值
Loss(F(xi),yi)=|F(xi)yi|

这个损失函数的梯度是个符号函数
LF(xk)F=Fi1=sign(Fi1(xk)yk)

由此可以看到,只有当损失函数为平方差函数时,才能说GBDT是通过拟合残差来构造弱分类器的。

对比Adaboost

Boosting是一类机器学习算法,在这个家族中还有一种非常著名的算法叫AdaBoost,是Adaptive Boosting的简称,AdaBoost在人脸检测问题上尤其出名。既然也是Boosting,可以想象它的构造过程也是通过多个弱分类器来构造一个强分类器。

首先看下Adaboost算法,Adaboost的核心在于Adaptive,它的自适应体现在:前一个基本分类器分错的样本会得到加强,加权后的全体样本再次被用来训练下一个基本分类器。同时,在每一轮中加入一个新的弱分类器,直到达到某个预定的足够小的错误率或达到预先指定的最大迭代次数。以下是它的算法迭代步骤:

  • 1.初始化训练数据的权值分布。如果有N个样本,则每一个训练样本最开始时都被赋予相同的权值:1N
  • 2.训练弱分类器。具体训练过程中,如果某个样本点已经被准确地分类,那么在构造下一个训练集中,它的权值就被降低;相反,如果某个样本点没有被准确地分类,那么它的权值就得到提高。然后,权值更新过的样本集被用于训练下一个分类器,整个训练过程如此迭代地进行下去。
  • 3.将各个训练得到的弱分类器组合成强分类器。各个弱分类器的训练过程结束后,加大分类误差率小的弱分类器的权重,使其在最终的分类函数中起着较大的决定作用,而降低分类误差率大的弱分类器的权重,使其在最终的分类函数中起着较小的决定作用。换言之,误差率低的弱分类器在最终分类器中占的权重较大,否则较小。

那AdaBoost和GBDT有什么区别呢?两者最大的区别在于,AdaBoost不属于Gradient Boosting,即它在构造弱分类器时并没有利用到梯度下降法的思想,而是用的Forward Stagewise Additive Modeling (FSAM)。为了理解FSAM,在回过头来看看Eq.(2)中的优化问题。从可以表达成一个迭代的形式

Fm(x)=Fm1(x)+αmfm(x)

严格来说Eq.(2)描述的优化问题要求我们同时找出α1,α2,,αmf1,f2,,fm,这个问题很难。为此我们把问题简化为分阶段优化,每个阶段找出一个合适的αifi。假设我们已经得到前m-1个弱分类器,即Fm1,下一步在保证Fm1不变的前提下,寻找合适的αmfm。按照损失函数的定义,我们可以得到
L(Fm)=i=0NLoss(Fm(xi),yi)=i=0NLoss(Fm1(xi)+αmfm(xi),yi)

如果Loss是平方差函数,则我们有
i=0NLoss(Fm1(xi)+αmfm(xi),yi)=i=0N(yiFm1(xi)αmfm(xi))2

这里yiFm1(xi)就是当前模型在数据上的残差,可以看出,求解合适的αmfm(x)当前的残差上拟合一个弱分类器,且损失函数还是平方差函数。这和GBDT选择平方差损失函数时构造弱分类器的方法恰好一致。
如果Loss是指数形式,即:
Loss(Fm(xi),yi)=exp(yiFm(xi))


i=0NLoss(Fm1(xi)+αmfm(xi),yi)=i=0Nexp(yi(Fm1(xi)+αmfm(xi)))=i=0Nexp(yiFm1(xi))exp(yiαmfm(x))=i=0Nωm1iexp(yiαmfm(x))

其中ωm1i=exp(yiFm1(xi))和要求解的αmfm无关,可以当成样本的权重,因此在这种情况下,构造弱分类器就是在对样本设置权重后的数据上拟合,且损失函数还是指数形式。
这个就是AdaBoost,不过AdaBoost最早并不是按这个思路推出来的,相反,是在AdaBoost提出5年后,人们才开始用Forward Stagewise Additive Modeling来解释AdaBoost背后的原理。

为什么要把平方差和指数形式Loss函数单独拿出来说呢?这是因为对这两个损失函数来说,按照Forward Stagewise Additive Modeling的思路构造弱分类器时比较方便。如果是平方差损失函数,就在残差上做平方差拟合构造弱分类器; 如果是指数形式的损失函数,就在带权重的样本上构造弱分类器。但损失函数如果不是这两种,问题就没那么简单,比如绝对差值函数,虽然构造弱分类器也可以表示成在残差上做绝对差值拟合,但这个子问题本身也不容易解,因为我们是要构造多个弱分类器的,所以我们当然希望构造弱分类器这个子问题比较好解。因此 FSAM思路无法推广到其他一些实用的损失函数上。相比而言,Gradient Boosting Modeling (GBM) 有什么优势呢?GBM每次迭代时,只需要计算当前的梯度,并在平方差损失函数的基础上拟合梯度。虽然梯度的计算依赖原始问题的损失函数形式,但这不是问题,只要损失函数是连续可微的,梯度就可以计算。至于拟合梯度这个子问题,我们总是可以选择平方差函数作为这个子问题的损失函数,因为这个子问题是一个独立的回归问题。

因此 FSAM和GBM得到的模型虽然从形式上是一样的,都是若干弱模型相加,但是他们求解弱分类器的思路和方法有很大的差别。只有当选择平方差函数为损失函数时,这两种方法等同。