XgBoost算法

一、XgBoost算法简介

        在数据建模中,经常采用Boosting方法通过将成百上千个分类准确率较低的树模型组合起来,成为一个准确率很高的预测模型。这个模型会不断地迭代,每次迭代就生成一颗新的树。但在数据集较复杂的时候,可能需要几千次迭代运算,这将造成巨大的计算瓶颈。

        针对这个问题。华盛顿大学的陈天奇博士开发的XGBoost(eXtreme Gradient Boosting)基于C++通过多线程实现了回归树的并行构建,并在原有梯度提升树(Gradient Boosting)算法基础上加以改进,从而极大地提升了模型训练速度和预测精度。

        xgboost是大规模并行boosted tree的工具,它是目前最快最好的开源boosted tree工具包,比常见的工具包快10倍以上,效率很高。在数据科学方面,有大量kaggle选手选用它进行数据挖掘比赛,其中包括两个以上kaggle比赛的夺冠方案。在工业界规模方面,xgboost的分布式版本有广泛的可移植性,支持在YARN, MPI, Sungrid Engine等各个平台上面运行,并且保留了单机并行版本的各种优化,使得它可以很好地解决于工业界规模的问题。

二、监督学习三要素

        因为Boosting Tree本身是一种有监督学习算法,要讲Boosting Tree,先从监督学习讲起。在监督学习中有几个逻辑上的重要组成部件,粗略地可以分为:模型、参数、目标函数和优化算法。

1、模型   

XgBoost算法_第1张图片

2、参数

XgBoost算法_第2张图片

3、目标函数:误差函数+正则化项

XgBoost算法_第3张图片
XgBoost算法_第4张图片

4、优化算法

三、回归树与树集成

1、回归树模型(regression tree)

        Boosting Tree最基本的组成部分叫做回归树(regression tree),下图就是一个CART的例子。CART会把输入根据输入的属性分配到各个叶子节点,而每个叶子节点上面都会对应一个实数分数。下图预测一个人是否会喜欢电脑游戏的 CART,你可以把叶子的分数理解为有多可能这个人喜欢电脑游戏(分值越大可能性越大)。

XgBoost算法_第5张图片

2、树集成

         上图中的回归树往往过于简单无法有效地预测,因此一个更加强力的模型叫做tree ensemble。

        在下图中使用两个回归树对用户是否喜欢电脑游戏进行了预测,并将两个回归树的预测结果加和得到单个用户的预测结果。在实际的预测模型建立过程中,我们通过不断地增加新的回归树,并给每个回归树赋予合适的权重,在此基础上综合不同的回归树得分获得更为准确的预测结果,这也就是树集成的基本思路。在预测算法中,随机森林和提升树都采用了树集成的方法,但是在具体地模型构造和参数调整的方法有所差别。

XgBoost算法_第6张图片

        在这个树集成模型中,我们可以认为参数对应了树的结构,以及每个叶子节点上面的预测分数。

        那么我们如何来学习这些参数。在这一部分,答案可能千奇百怪,但是最标准的答案始终是一个:定义合理的目标函数,然后去尝试优化这个目标函数。决策树学习往往充满了启发式算法,如先优化基尼系数,然后再剪枝,限制最大深度等等。其实这些启发式算法背后往往隐含了一个目标函数,而理解目标函数本身也有利于我们设计学习算法。

四、XGBoost的推导过程

         对于tree ensemble,我们可以比较严格的把我们的模型写成下图的表示, 其中每个 f 是一个在函数空间(F)里面的函数,而F对应了所有regression tree的集合。

1、XGBoost的目标函数与泰勒展开

        XGBoost的目标函数为:

        第一部分是训练损失,如上面所述的平方损失或者Logistic Loss等,第二部分是每棵树的复杂度的和。因为现在我们的参数可以认为是在一个函数空间里面,我们不能采用传统的如SGD之类的算法来学习我们的模型,因此我们会采用一种叫做additive training的方式。即每次迭代生成一棵新的回归树,从而使预测值不断逼近真实值(即进一步最小化目标函数)。每一次保留原来的模型不变,加入一个新的函数 f 到模型里面:

XgBoost算法_第7张图片

        这里自然就涉及一个问题:如何选择在每一轮中加入的 f(xi) 呢?答案很直接,选取的 f(xi) 必须使得我们的目标函数尽量最大地降低(这里应用到了Boosting的基本思想,即当前的基学习器重点关注以前所有学习器犯错误的那些数据样本,以此来达到提升的效果)。先对目标函数进行改写,表示如下:

XgBoost算法_第8张图片

        如果我们考虑平方误差作为损失函数,公式可改写为:

XgBoost算法_第9张图片

        更加一般的,对于不是平方误差的情况,我们可以采用如下的泰勒展开近似来定义一个近似的目标函数,方便我们进行下一步的计算。

XgBoost算法_第10张图片

        如果移除掉常数项,我们会发现这个目标函数有一个非常明显的特点,它只依赖于每个数据点的在误差函数上的一阶导数和二阶导数。可能有人会问,这个方式似乎比我们之前学过的决策树学习难懂。为什么要花这么多力气来做推导呢?

        这是因为,这样做首先有理论上的好处,它会使我们可以很清楚地理解整个目标是什么,并且一步一步推导出如何进行树的学习。然后这一个抽象的形式对于工程商实现机器学习工具也是非常有帮助的。因为它包含所有可以求到的目标函数,也就是说有了这个形式,我们写出来的代码可以用来求解包括回归、分类和排序的各种问题,正式的推导可以使得机器学习的工具更加一般化。

2、决策树的复杂度

        我们先对于 f 的定义做一下细化,把树拆分成结构部分 q 和叶子权重部分 w 。其中结构部分 q 把输入映射到叶子的索引号上面去,而 w 给定了每个索引号对应的叶子分数是什么。

XgBoost算法_第11张图片
XgBoost算法_第12张图片

3、目标函数的最小化

XgBoost算法_第13张图片
XgBoost算法_第14张图片
该函数对变量 Wj 求导并令其等于0,即得到Wj*的表达式
XgBoost算法_第15张图片
XgBoost算法_第16张图片

4、寻找最优结构树的分割点

(1)贪心法

        在前面分析的基础上,当寻找最优的树结构时,我们可以不断地枚举不同树的结构,利用这个打分函数来寻找一个最优结构的树,加入到我们的模型中,然后再重复这样的操作。不过枚举所有树结构这个操作不太可行,在这里XGBoost采用了常用的贪心法,即每一次尝试去对已有的叶子加入一个分割。为了提高效率,算法必须先对特征的值进行一个排序,然后进行贪心遍历。对于一个具体的分割方案,我们可以获得的增益可以由如下公式计算得到:

XgBoost算法_第17张图片
XgBoost算法_第18张图片
XgBoost算法_第19张图片

(2)近似分割法

        树节点在进行分裂时,我们需要计算每个特征的每个分割点对应的增益,即用贪心法枚举所有可能的分割点。当数据无法一次载入内存或者在分布式情况下,贪心算法效率就会变得很低,所以xgboost还提出了一种可并行的近似算法,用于高效地生成候选的分割点。大致的思想是根据百分位法列举几个可能成为分割点的候选者,然后从候选者中根据上面求分割点的公式计算找出最佳的分割点。(对于每个特征,只考察分位点,减少计算复杂度)

近似算法举例:三分位数

XgBoost算法_第20张图片

        实际上XGBoost不是简单地按照样本个数进行分位,而是以二阶导数值 hi 作为权重(Weighted Quantile Sketch),比如:

XgBoost算法_第21张图片

为什么用hi加权?

        我们要均分的是loss,而不是样本的数量,而每个样本对loss的贡献可能是不一样的,按样本均分会导致loss分布不均匀,取到的分位点会有偏差

XgBoost算法_第22张图片
把目标函数整理成这种形式,可以看出 hi 有对loss加权的作用

补充:分位点和权重分位点差别

分位点:基于特征大小排序,然后根据特征值划分(均分)

权重分位点:基于特征大小排序,然后根据二阶导划分(均分)

五、Xgboost调参

        1、GridSearch

        2、Hyperopt

        3、XGBoost中参数调整的完整指南(包含Python中的代码)

六、Xgboost与传统gbdt有何不同

XgBoost算法_第23张图片
XgBoost算法_第24张图片
XgBoost算法_第25张图片

xgboost代价函数里加入正则项,是否优于cart的剪枝”?

XgBoost算法_第26张图片
XgBoost算法_第27张图片

参考文章:介绍xgboost原理的好文(慕课手记)

                  xgboost相比传统gbdt有何不同  (知乎:wepon)        

                    XGBoost原理简介(看完上面的推导再看这个,一定要看,梳理一遍)

                    机器学习算法系列(8):XgBoost

                    xgboost入门与实战(原理篇)

你可能感兴趣的:(XgBoost算法)