您的位置:首页 > 大数据

XGBoost设计思路与数学推导

2017-01-21 23:50 274 查看

一. 前言

XGBoost是由陈天奇大神设计的一套基于gbdt的可并行计算的机器学习工具。在kaggle、天池等大数据竞赛有着广泛的应用。通过阅读论文和代码,受益良多,并总结了包括公式推导、并行化设计和源码剖析等一系列笔记。本篇主要梳理了论文中的公式推导,并添加了一些推导的细节和自己的想法。如有错误,还需指正。

二. 从Boosting模型开始

说道GBDT或者XGBoost,就不得不说起Boosting模型,Boosting 是一种将弱分类器转化为强分类器的方法,它的函数模型是具有叠加性的。具体可表示为

                                           


                                           


D代表数据集,m维,数量为n。其中每棵树(每次迭代)都是一个树模型,可表示为

                                                       


q(x)代表样本x到的树模型的叶子节点的映射关系。w是树模型中用来拟合属于各自叶子节点的样本的预测值。第二轮开始,每轮训练输入为上一轮预测与真实值的残差,最后的叶子节点的结果也为残差的预测,最后所有轮加一起即为所求。

三. 目标函数的定义

目标函数是XGBOOST的一个特点,为了防止过拟合,XGBoost的目标函数由损失函数和复杂度组成。复杂度又由叶子数量和L2正则组成。

                                                       


其中i是样本id,k是树id(轮数),由于loss和复杂度项都是凸函数,所以有最小值。

这个也很好理解,w是与真实值的残差,将w的L2正则加在目标函数中,可以有效防止过拟合。(L2正则是很常用的规则化公式,正则的知识请自行补充)

同样叶子数的线性项也加在了目标函数中,一定程度上限制叶子数量,防止过拟合。而传统GDBT方法防止过拟合的手段无论是预剪枝还是后剪枝,都是额外进行交叉验证的步骤。

四.推导出最优估计

目标函数确定了,接下来就是训练的过程了。对于每次迭代过程,可以将一棵树的训练目标函数写成形式如下:

                                                         


输入是t-1轮后预测的值,真实值,用来拟合残差f(x)。对于这个式子,我们不知道loss的具体形式,所以无法对f(x)进行有效的最优估计。于是进行如下推导:

首先将目标函数泰勒二阶展开近似

                                                             


                                                           


去掉常数项即为:

                                                         


正则项展开 

                                                          


首先做一下转换:

                               


                             

公式转化为:

                                                           


这是一个二次项形式,所以最后使得目标函数最小的w为

                                                           


带入原方程最小值为

                                                         


那么最后求得的w就是目标函数在一个样本集合条件下的最优解。

为什么要推导呢?

1. 适应各种损失函数。

2. 正则项的加入对参数估计产生了影响,要具体找出影响是什么。

如果只考虑平方损失的条件下,在没有正则项的情况下参数的最优估计为样本均值。在没有指定损失函数情况下,我们也很容易想到均值是给定样本条件下的误差最小的最优估计。但是损失函数换成绝对值损失,那么最优估计就为中位数。可见不同损失函数下,结果并不想我们想的那么简单。陈天奇大神在博客中也说,推导是为了使得模型更具有一般性。

为什么用泰勒二阶近似展开?

首先我们看一下GBDT的算法流程

                                                               


由于gbdt只用到了一阶信息,如果按照上文中推导,相当于loss只进行了一阶泰勒展开。在没有复杂度项的情况下,无法确定步长,所以只能用常数步长根据一阶梯度方向去逼近。这就是牛顿下降法和梯度下降法的区别。由于二阶展开用二次函数去逼近函数,所以可以利用二阶信息确定更新步长,比只利用一阶信息的gdbt用更少的迭代获得更好的效果。感兴趣可以自己证明牛顿梯度法的二阶收敛性。

五 贪心算法求解

但是满足给定样本属性条件下决策树有很多,找到其中能使目标函数最优的决策树是一个nphard问题,这里使用了贪心算法的策略来近似求解。

假设存在一个游标,先将分支下的样本按照一个属性进行排序,再滑动游标按照这个属性从小到大遍历,分别将样本分为两部分,将两部分的样本带入上一节求得的目标函数最小值公式,再相加,与不分裂的样本的目标函数做差,即为分裂后的“收益”。贪心的策略就是找出收益最大的分裂“游标”的位置。

                                                 


到这里,再来反推一下目标函数的设计思路,如果没有加入复杂度,那么这里的损失函数即为:

                                                


可以预想到,两个参数估计一组样本肯定比一个参数估计一组样本要好,所以树会一直分裂下去。按照传统cart树,会有额外的根据交叉验证的预剪枝或者后剪枝。但是xgboost通过巧妙的设计目标函数,先是在分母上加一个λ,来降低分支的收益“灵敏度”,这个“灵敏度”可以通过修改此参数来控制。当收益小于一个阈值则剪枝,从而达到防止过拟合的目的。(类似的在分母加上常数项的处理,在朴素贝叶斯单个属性条件概率的计算中也有用到)

另外的一个参数γ,从最后每次分割后的收益函数可以看到,这个参数的“物理意义”就是每分裂一次,减去一个视为惩罚的常数。

六.简单的改进方向

这里的贪心算法,是为了提高效率而采取的近似算法。由于是近似算法,所以有一定的改进空间,具体也要结合实际的样本情况。

在参加天池大数据竞赛机场赛的时候,由于有数据在时间上有很强的周期波动性,我自己实现了一个简单的gdbt,只对时间属性上的分支,采用了在每一次分割用两个游标,分割成三个子节点的方法,实际效果,要比相同特征情况下的xgboost准确率高。

 

七. 总结

本文主要是对论文阅读的一个总结,XGBoost的主要特点是并行化的处理,以后整理好笔记会传到博客中。



八. 参考文献

[1]  XGBoost: A Scalable Tree Boosting System
[2]  XGBoost 与 Boosted Tree



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息