XGBoost算法学习记录

XGBoost算法梳理

你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

XGBoost原理

  1. XGBoost目标函数定义为: 3
    constant 为一个常数,正则项 Ω ( f t ) \Omega(f_t) Ω(ft)如下:
    在这里插入图片描述
    其中, T T T表示叶子节点树, w j w_j wj表示第 j j j个叶子节点的权重。
    例如下图,叶子节点数为3,每个叶子节点的权重分别为2,0.1,-1,正则项计算见图:
    在这里插入图片描述
    泰勒展开式:
    利用泰勒展开式
    利用泰勒展开式对式目标函数进行展开:
    在这里插入图片描述
    其中, g i g_i gi表示 L ( y i , y ^ t − 1 ) L(y_i,\hat{y}^{t-1}) L(yi,y^t1) y ^ t − 1 \hat{y}^{t-1} y^t1的一阶导数, h i h_i hi表示 L ( y i , y ^ t − 1 ) L(y_i,\hat{y}^{t-1}) L(yi,y^t1) y ^ t − 1 \hat{y}^{t-1} y^t1的二阶导数。
    L ( y i , y ^ t − 1 ) L(y_i,\hat{y}^{t-1}) L(yi,y^t1)为真实值与前一个函数计算所得残差是已知的(都是在已知前一个树的情况下计算下一棵树的),同时,在同一个叶子节点上的数的函数值是相同的,可以做合并,于是:
    在这里插入图片描述
    解释下在同一个叶子节点上的数的函数值是相同的:
    I I I被定义为每个叶子上面的样本集合 I j = { i ∣ q ( x i ) = j } I_j=\left\{i|q(x_i)=j\right\} Ij={iq(xi)=j}, T T T表示叶子节点树, w j w_j wj表示第 j j j个叶子节点的权重。如下图所示 T = 2 T=2 T=2, I j = 1 I_{j=1} Ij=1为男孩和爷爷的集合, w j = 1 = 0.9 w_{j=1}=0.9 wj=1=0.9, I j = 2 I_{j=2} Ij=2为女孩,妈妈和奶奶的集合 w j = 2 = − 0.9 w_{j=2}=-0.9 wj=2=0.9.
    在这里插入图片描述
    此时目标函数是关于叶节点分数 w w w的一个一元二次函数,求解最优的 w w w和目标函数值就变得很简单了,通过求导等于0,可以得到:
    在这里插入图片描述
    w j w_j wj带入得目标函数的简化公式如下:
    在这里插入图片描述
    O b j ( t ) Obj(t) Obj(t)越小越好
    目标函数简化后,可以看到xgboost的目标函数是可以自定义的,计算时只用到了它的一阶导二阶导

分裂节点算法

在上面的推导中,我们知道了如果我们一棵树的结构确定了,如何求得每个叶子节点的分数。如何确定树的结构,即每次特征分裂怎么寻找最佳特征,怎么寻找最佳分裂点。
贪心法:每次尝试分裂一个叶节点,计算分裂前后的增益,选择增益最大的。
常见的几种回归树,分裂前后增益的计算方式:

算法前后增益计算方式
ID3算法信息增益
C4.5算法信息增益比
CART算法Gini系数
XGBoost打分函数

打分函数计算举例

目标函数 O b j Obj Obj代表了当我们指定一个树的结构的时候,我们在目标上面最多减少多少。我们可以把它叫做结构分数,可以看成类似于基尼系数一样更加一般的对于树结构进行打分的函数,下面是一个具体的打分函数计算的例子:在这里插入图片描述

枚举所有不同树结构的贪心法

贪心法:每一次尝试去对已有的叶子节点加入一个分割。对于一个具体的分割方案,我们可以获得的增益可以由如下公式计算:
在这里插入图片描述

Gain的值越大,分裂后目标函数减少越多。所以对一个叶节点分割时,计算所有特征值对应的Gain,选取Gain最大进行分裂。

对于每次扩展,分割某个特定的分割a,我们要计算a左边和右边的导数和。计算过程如下图所示:
在这里插入图片描述
对于所有的特征值,我们只需要做一遍从左到右的扫描,就可以枚举出所有分割的梯度和 G L G_L GL G R G_R GR。然后再用上面的公式计算每个分割方案的分数就可以了。

近似方法

对于每个特征,只考察分位点,减少计算复杂度。
具体内容参看这篇文章知乎

缺失值处理

xgboost模型能够处理缺失值,该模型允许缺失值存在。作者将缺失值的处理看成与稀疏矩阵的处理一样,不会对该特征为missing的样本进行遍历统计,只对该列特征值为non-missing的样本上对于的特征值进行遍历,通过这个技巧来减少稀疏离散特征寻找splot point的时间开销。在每个结点上都会将对应变量是缺失值的数据往左右分支各导流一次,然后计算两种导流方案对Objective的影响,最后认为对Objective降低更明显的方向(左或者右)就是缺失数据应该流向的方向,在预测时在这个结点上将同样变量有缺失值的数据都导向训练出来的方向。
在这里插入图片描述

XGBoost参数解释

这篇博文写的很详细XGBoost参数

优缺点

优点

1.XGBoost 支持线性分类器,此时相当于L1和L2正则化的逻辑斯蒂回归(分类)或者线性回归
2.XGBoost在代价函数中加入了正则项,用于控制模型的复杂度。从权衡方差偏差来看,它降低了模型的方差,降低了过拟合性
3.shrinkage(缩减),相当于学习速率(XGBoost中的eta)。XGBoost在进行完一次迭代时,会将叶子节点的权值乘上该系数,主要是为了削弱每棵树的影响,让后面有更大的学习空间。
4.对有缺失值的样本可以进行处理,学习出它的分裂方向。
5.列抽样。借鉴了随机森林的做法,支持列抽样,不仅防止过拟合,还能进行减少计算。
6.XGBoost工具支持并行。Boosting不是一种串行的结构吗?怎么并行 的?注意XGBoost的并行不是tree粒度的并行,XGBoost也是一次迭代完才能进行下一次迭代的(第t次迭代的代价函数里包含了前面t-1次迭代的预测值)。XGBoost的并行是在特征粒度上的。我们知道,决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点),XGBoost在训练之前,预先对数据进行了排序,然后保存为block结构,后面的迭代 中重复地使用这个结构,大大减小计算量。这个block结构也使得并行成为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。

缺点

1.每轮迭代,都需要遍历整个训练数据多次
2.预排序方案:首先空间消耗大。这样的算法需要保存数据的特征值,还保存了特征排序的结果。其次时间上有较大的开销,在遍历每一个分割点的时候,都要进行分裂增益的计算,消耗代价大
3.对cache优化不友好。在预排序后,特征对梯度的访问是一种随机访问,并且不同的特征访问的顺序不一样,无法对cache进行优化。同时,在每一层长树的时候,需要随机访问一个行索引到叶子索引的数组,并且不同特征访问的顺序也不一样,也会造成较大的cache miss

参考资料

1.https://blog.csdn.net/qq_28031525/article/details/70207918
2.https://zhuanlan.zhihu.com/p/52211079
3.https://zhuanlan.zhihu.com/p/40129825
4.缺失值处理
5.http://wepon.me/2016/05/07/XGBoost浅入浅出/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值