XGBOOST(一)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/IamThinker2011/article/details/83501544

轮回Pan  Refinitiv创新实验室ARGO 

“本文作者为Argo特约AI专家, 含有大量有些难度数学公式,预计阅读时间15分钟”


 

XGBoost自2014年由陈天奇博士提出以来,2015年便开始在kaggle的竞赛中频频发力,绝大多数冠军团队都使用了这一算法。它可靠、灵活,而且准确。在大多数的回归和分类问题上,XGBoost的实际表现都十分耀眼,因此在工作中大家可能频繁接触到这一算法。之前作者看了陈天奇博士的XGBoost论文和相应的Slides,翻译和总结了一些内容,所以才有了这篇文章。


 

因为XGBoost的提出基于前辈们对于机器学习算法的不断开拓创新,是分阶段进化的产物,所以本文将从这几个阶段逐层展开:

 

  • 集成算法与Boosting
  • 决策树与CART树
  • Gradient Boosting算法与GBDT
  • XGBOOST


 

一 集成算法与Boosting

 

之前ARGO讲随机森林算法时,我们曾提到过随机森林算法是Bagging算法,是集成算法的一种表现形式。而Boosting算法,则是集成算法的另外一种典型的形式。

 

集成算法的历史可以追溯到Valiant和 Kearns提出了 PAC学习模型,在这个模型中,两人提出了 弱学习器是否可以和强学习器等价的问题。因为一旦等价,就意味着从此以后,人们不必在花费大量的代价去追寻强学习器,而可以依靠某种固定的方式把弱学习器提升为强学习器。1990年, Schap ire构造出一种多项式级的算法 ,对该问题做了肯定的证明,这也是最初的Boosting算法的原型。自此,机器学习领域的提升算法开始繁荣发展。

 

集成算法有两个基本的要求:一 弱学习器不能太弱(低于50%的正确率),二 各个弱学习器不同Bagging和Boosting两种集成算法在训练得到不同的弱学习器上,采用了不同的方法。Bagging对每个弱学习器训练时,使用训练样本的随机放回采样,各个弱学习器使用的训练样本分布类似,但是样本不全相同,最后在使用弱学习器投票产生结果时权重一样,注重的是减少拟合的方差Boosting算法的弱学习器训练不抽样,而且只能顺序进行,其训练依赖上次的弱学习器的结果。比如基于改变样本权重的AdaBoost,每次弱学习器的训练结果里,错分的样本将增加权重,分对的样本减少权重。这样,其投票权重也是按照其正确率各有不同,拟合上注重的是减少其偏差。在Boosting算法中,还有典型的在下文介绍的Gradient Boosting,其基于梯度下降方法计算得到不同的弱学习器。

 

Boosting算法是一种广义加法模型,在Boosting算法里,选择不同的损失函数会有不同的具体的算法:

比如大家熟知的AdaBoost是指数损失函数,而今天所说的XGBoost,则以Gradient Boosting为基础。Boosting算法的弱学习器原则上没有要求,任何的弱学习器都可以跟Boosting算法集成。但是在工程实践中,一般会选用简单的树。XGBoost对于传统GBDT做了优化优化,继承了其选用CART树作为其弱分类器的算法模型。

 

 

二 决策树与CART树

 

决策树之前已经着重讲过ID3, 对于其他类型的树也有了一个初步的介绍,感兴趣的读者可以看看ARGO之前的这篇文章。基于此我们粗略的介绍一下CART树,CART树的不同之处就跟它的命名比较类似,Classifier and Regression Tree,它是一种支持即支持分类又支持回归的树。在李航的《统计机器学习》中,CART树的数学公式有点高深,因此,我们着重讲述一下如何用CART建立回归树。

 

CART建立分类树时,其采用的基尼不纯度作为其是否分裂的参考,这里不再赘述。在建立回归树时,CART树使用的是均方误差。在建立回归树后,其叶子节点的预测值是所有样本总被分类到该叶子节点下的所有样本标签的均值

 

回归树是一棵二叉树,每次分裂都是按某特征下的某个取值划分,内部节点做一次对应特征的判断。其最核心难点在于如何选取最优的切分特征切分特征对应的切分变量。在处理连续特征或离散特征时,切分方法如下(按第 j个特征的取值 s进行切分)。

连续特征:

离散特征:

损失函数:

其中,c1,c2 是被切分后按照分类样本标签计算出的该节点下的样本均值。

 

以连续特征为例,其迭代计算方法如下:

图片来源:https://www.cnblogs.com/ooon/p/5647309.html

 

介绍完CART回归树,我们再看看 Gradient Boosting。Boosting Tree将使用决策树与Boosting算法相结合,弱学习器选用树算法模型。Gradient Boosting算法,基于梯度来构造不同的弱学习器, GBDT算法模型是Boosting CART Tree 和 Gradient Boosting 的结合。

 

 

  Gradient Boosting算法 与 GBDT

 

文初曾经指出,Gradient Boosting不改变样本权重,是广义加法模型的一种。这里简要的介绍一下Gradient Boosting的设计思路。

与之前的机器学习算法学习空间  的权重不一样,梯度提升算法需要学习的是函数Functions。可以这么理解,因为Grandient 是加法模型,所以,其模型可以表示为:

假定确认了基分类器,那么,第m次迭代时,其模型表示方式如下:

设模型损失函数为:

这样,实际上我们要求的是,在引入新的分类器后,损失函数值必须减少,而且是沿着最快的方向减少,而这种要求刚好是梯度下降可以做到的。所以,如果将作为的参数,可以计算得到梯度,以负梯度近似作为更新步长,从而得到下次的分类器函数:

 

这里,两次迭代间分类结果的差值(负梯度)叫做残差,这个残差就是每次迭代训练想拟合的目标,在每次迭代时替换训练样本标签。下面是Grandient Boosting的一般算法流程:

图片来源:https://www.cnblogs.com/ooon/p/5668289.html


 

 

GBDTGradient Boosting Decision Tree,故名思议。就是弱分类器采用的是决策树,而框架采用梯度提升算法的分类器。基本训练方式和上述方式类似,因为CART树的性质,所以分类和回归都支持。GBDT也是一个应用十分广泛的算法,ARGO在将来的文章中将会详细阐述。XGBOOST是基于GBDT的一种从算法到工程的优化。


 

 XGBoost

 

有了前三节的知识储备,这一部分将介绍XGBoost算法,推导遵循的想法与现有的Gradient boosting方法相同,其中的二阶方法来源于Friedman等人。陈天奇博士在正则化目标以及梯度提升方式求解上做了一些改动,而这些改动在实践中被证明是有用的。

 

建立含正则项的损失函数

 

给定一个数据集D,其中包含n个样本,每个样本包含m个特征:

一个由K 个树构成的树集成模型可表示为:

其中,

是所有CART树组成的函数空间。这里 q 表示每个树的结构,它将每一个样本都映射到对应的叶子结点上,T 是树的叶子数。每一个函数对应于一个独立的树结构 q 和叶子结点上的权重。与决策树不一样的是,每一棵回归树的每一个叶子结点上的学习结果都是一个分数。我们用来表示第 i 个叶子结点上的分数。因此,模型的参数包括每棵树的结构和叶子节点的分数,或可以简单的表示


为了学习得到该模型中的函数集合,我们需要定义损失函数,并最优化损失函数:

很明显,Ω项为正则项,当其设置为0,损失函数变回成传统的梯度提升树。知乎 wepon 在回答XGBoost问题时说:“XGBoost在代价函数里加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数、每个叶子节点上输出的score的 L2 模的平方和。从 Bias-variance tradeoff 角度来讲,正则项降低了模型的 variance,使学习出来的模型更加简单,防止过拟合,这也是xgboost优于传统GBDT的一个特性”。

 

损失函数建立好后,下一步要解决的就是怎么去学习和优化。

 

优化GBDT梯度提升方法

 

上面给出的损失函数中,将函数(tree)作为参数,其不能被传统的优化方法,如SGD,在欧式空间中优化。因此,模型以GBDT也就是Gradient Boosting 中提到的方式进行优化,但不同于传统 GBDT 在优化时只用到一阶导数信息,而是同时使用了一阶导数和二阶导数。用来表示第 i 个树在第t次迭代的预测结果,我们将要加上去最小化下面的目标:

这意味着我们贪心的加入去最大化的提升我们的模型。对上式采用二阶近似(泰勒展开)可得:

其中,

是损失函数的一阶和二阶梯度。将上式中的常数项去掉之后可得第t步的简易损失函数:

定义

,


 

是叶子结点 j 的实例集合。将展开可得,

对一个给定的 q(X),上式可以看成是的一元二次函数,求出叶子结点 j 的最优解

和对应的最优值:

这个公式可以当做打分函数来衡量树结构 q 的质量。这个得分与衡量决策树的不纯度分数相似,不同的是它从更广泛的目标函数推导而来。接下来列出所有可能的树结构q,利用这个公式计算出得分,然后从所有的得分中选择最好的树结构,最后代入最优的叶子结点权重就得到了单棵树。但是通常想要列出所有可能的树结构 q 是不可能的,所以在实际中用贪心的思想,从一个结点开始,迭代的增加其分支。假设是分裂后左右分支的结点的实例集。,分裂后损失函数减少可表示为:

剩下的问题是根据这个公式,怎么去寻找一个最优的split。为了实现它,寻找分裂算法需要枚举出所有特征的所有可能分裂,我们称这种为精准贪心算法。对每一结点,列出所有的特征:对每一个特征,根据特征值对数据进行排序;从左到右,线性scan来决定该特征的最佳分裂;对所有的特征应用该最佳分裂方法。现存的很多单机的tree boosting实现,如scikit-learn, R’sgbm都是实现的精准贪心算法。具体算法如下:

 


 

总结

 

到目前为止,我们已经了解到了xgboost的算法模型,参数,目标函数以及怎么选择的最佳分裂,怎么学习得到的每一颗树结构。但是陈天奇博士xgboost的实现中还有很大一部分的算法优化和工程改进,如针对当数据不能完全的被存放到内存中,精准贪心算法不能处理,提出了的近似算法,缩减和列采样,sparsity-awarealgorithm等将会在我的下一篇文章中介绍。


 


 

参考文档:

https://www.cnblogs.com/ooon/p/5668289.html

https://www.cnblogs.com/ooon/p/5647309.html

https://www.cnblogs.com/ooon/p/5663975.html

https://ipvs.informatik.uni-stuttgart.de/mlr/marc/teaching/13-Optimization/04-secondOrderOpt.pdf

BoostedTree slides: https://homes.cs.washington.edu/~tqchen/pdf/BoostedTree.pdf

xgboost paper: https://arxiv.org/pdf/1603.02754.pdf

https://juejin.im/post/5a7eb1f06fb9a0636108710a

https://blog.csdn.net/xierhacker/article/details/64439601

 

好资料推荐:

https://www.cnblogs.com/ooon/ (大神的博客写的特别好)

 

 

猜你喜欢

转载自blog.csdn.net/IamThinker2011/article/details/83501544