xgboost原理

基本思想

image.png

xgboost的基本思想就是一种提升的思想,后一个模型在前一个模型的基础上再进行预测,弥补前一个模型做的不好的地方。例如真实值是100,第一颗树的预测值是95,还有5的误差,然后我们再用第二颗树再预测,预测出来3这样两颗树的综合结果就是98,然后依次类推。


image.png

损失函数

image.png

这里预测值就是样本和权重的组合,我们预测出来的是每一个节点的权重,再用这个权重乘以样本的特征。目标函数就是真实值和预测值的均方误差。(这里目标函数也可以换成其他的目标函数,只要能够表明真实值和预测值两者之间的差异就可以)
红框当中的公式用来代表着将每一颗数生成的模型相加,下一个模型等于前面t-1轮模型的和加上第t轮模型生成的树,得到的模型才是最终的模型。


image.png

有了上述的基本知识后我们再来更新我们的基本损失函数:


image.png

这里欧米伽表示的是惩罚项,惩罚项当中包括节点的个数和权重的平方和,这里遵循一个奥卡姆剃刀准则:最简单的就是最好的。所以节点数越多那么模型就越复杂,模型越复杂那么就越有可能过拟合。然后为什么加上权重的平方和呢?因为我们不希望模型给予某些特征过大的权重,当这个特征发生变化时会对整个模型造成很大的影响,我们希望每个特征都具有更加平均的权重。
constant表示的是一个常数项,这里可以将一个化简过程当中的常数放入到这个常数项当中。

最终我们需要优化的损失函数就是这样一个函数。

求解损失函数

image.png

有了这样的一个损失函数l,我们知道我们是在t-1这样一个损失函数的基础上加上了另一个变量f t(x),这样就相当于是在原有的x的基础上加上了一个△x,这里的x表示的是真实值和预测值之间的差,这个差值的变化范围时在实数内,所以当做是一个x就可以了。然后我们就对这个误差用泰勒展开近似的表示这个误差函数。g和h分别表示一阶导和二阶导。我们知道obj(x-1)是已经确定的了的所以我们直接放到常数项当中,这样我们需要求解的就只有损失函数的一阶导和二阶导。


image.png

然后我们知道f-t 是一个用叶子节点上权重和该样本点的一个组合,所以第一个等式和第二个等式是等价的。然后我们将从对样本的遍历转换为对叶子节点上的遍历,因为每一个样本都是会落到一个叶子节点上,我们遍历了每个叶子节点上的所有的点不就相当于我们遍历了所有样本吗。然后我们把惩罚项的w平方也放到对叶子节点的遍历的循环当中。

小总结

看到这里可能有的人有点晕了,我们做一个小总结,xgboost首先根据提升的原理,构造了一个代价函数。这个代价函数表示的总体的代价函数,由于我们新加入的树的模型和原始的模型是相互独立的,原始的那些树模型的代价函数已经是一个定值了,我们需要优化的只有新加入的树的代价函数了,怎么让老的代价函数和新的代价两者分开呢,我们是用了泰勒展开,将新的树的代价函数转为原始代价函数的一个近似值。(只用到了原始代价函数的一阶导和二阶导。)这个新树的代价函数就是我们目前需要优化的这个obj。然后我们就要让这个obj最小,如何最小呢?obj这个函数当中的变量只有w是未知的(并且w的二次项系数是正的),这就是一个一元二次方程,求解过程就很简单了只让obj对w求导等于零,求出的w就是让这个obj最小的w。这个w就是最优的叶节点分数。


image.png

然后我们现在得到了一个代价函数的表达式,这个表达式能够计算的就是在一个给的树的结构下的代价。


image.png

求树结构

现在只要知道树的结构,就能得到一个该结构下的损失值。可是树的结构应该怎么确定呢?没法用枚举,毕竟可能的状态基本属于无穷种。
这种情况,贪婪算法是个好方法。从树的深度为0开始,每一节点都遍历所有的特征。对于某个特征,先按照该特征里的值进行排序,然后线性扫描该特征来决定最好的分割点,最后在所有特征里选择分割后,Gain最高的那个特征。


image.png

这时,就有两种后续。一种是当最好的分割的情况下,Gain为负时就停止树的生长,这样的话效率会比较高也简单,但是这样就放弃了未来可能会有更好的情况。另外一种就是一直分割到最大深度,然后进行修剪,递归得把划分叶子得到的Gain为负的收回。一般来说,后一种要好一些,于是我们采用后一种,完整的算法如下(没有写修剪)


image.png

近似分裂算法

传统的分裂方法虽然精确,但是十分耗时,而且一旦数据较多,非常占用内存,也不利于并行化。xbg提出了一种近似的算法,具体如下:


image.png

对于每个特征,只考察分位点,减少计算复杂度

Global:学习每棵树前,提出候选切分点
Local:每次分裂前,重新提出候选切分点
近似算法举例:三分位数


image.png

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


image.png

为什么用hi加权?
把目标函数整理成以下形式,可以看出hi有对loss加权的作用
image.png

同时,xgb还有处理稀疏数据的算法:

真实数据中,稀疏是比较普遍的,造成稀疏的原因主要有以下几点:

存在缺失值
有很多0
人造特征,比如ont-hot编码

image.png

从该算法中,我们可以看出XGBoost缺失值处理方式是,对于某一个特征,假设所有缺失的样本属于右子树或者左子树,然后分别计算其损失减少量得分,最后取其最高值对应的分裂位和得分值。

你可能感兴趣的:(xgboost原理)