xgboost是由k个基模型组成的一个加法运算式。
模型的预测精度由模型的偏差和方差共同决定,我们追求偏差小方差小的模型。
损失函数代表了模型的偏差,提升模型复杂度可以减小偏差。
但模型过于复杂时容易过拟合,使用正则项抑制模型复杂度。选用抑制模型复杂度的正则项 Ω \Omega Ω 来衡量。
其中
y i t ^ \hat{y_i^{t}} yit^ 为 t t t 步的模型预测值,
y i t − 1 ^ \hat{y_i^{t-1}} yit−1^ 为 t − 1 t-1 t−1 步的模型预测值,
f t ( x i ) f_t(x_i) ft(xi)为这次需要加入的新模型的预测值。
此时目标函数可写成:
由于在第 t t t步时, y i t − 1 ^ \hat{y_i^{t-1}} yit−1^即上一步的预测值是一个已知的值。
每轮加入什么 f t ( x i ) f_t(x_i) ft(xi) 决定了最终目标函数的大小。需要选取使目标函数尽量低的 f f f。
(在下方公式中,
将 l ( y i , y i t − 1 ^ ) l(y_i,\hat{y_i^{t-1}}) l(yi,yit−1^) 视作泰勒的 f(x) ,
将 y i t − 1 ^ \hat{y_i^{t-1}} yit−1^ 视作 x x x ,
而第t步的模型 f t ( x i ) f_t(x_i) ft(xi) 视作 Δ \Delta Δ x x x)
(注意泰勒的f(x)和我们目标函数中的 f t ( x i ) f_t(x_i) ft(xi) 不是同一个函数,只是他们恰好都叫f;泰勒展开是为了将常数项剔除掉,最终简化目标函数)
定义 g i g_i gi 为损失函数的一阶导,
定义 h i h_i hi 为损失函数的二阶导,
(导数是对
y i t − 1 ^ \hat{y_i^{t-1}} yit−1^求导)
?为何需要做泰勒展开
因为损失函数为平方误差时,求目标函数最优解还好求,但对于其他损失函数将变得很复杂,通过二阶泰勒展开使求解其他损失函数时的目标函数最优解变得可行。
?为何是二阶不是一阶
https://www.zhihu.com/question/277638585/answer/522272201
损失函数是MSE时, O b j Obj Obj展开是一阶项(残差)+二阶项的形式,而其他的损失函数(如log loss)的展开式没有这样的形式。为了有一个统一的形式,选择二阶展开,就可以把MSE推导的过程直接复用到其他自定义损失函数上(简单说就是为了统一损失函数的形式以支持自定义损失函数)。
二阶信息本身就能让梯度收敛更快更准确。这一点在优化算法里的牛顿法里已经证实了。可以简单认为一阶导指引梯度方向,二阶导指引梯度方向如何变化。这是从二阶导本身的性质,也就是为什么要用泰勒二阶展开的角度来说的
?为什么要在形式上与MSE统一
因为MSE是最普遍常用的损失函数,且求导最容易。
?xgboost和GBDT的区别
- GBDT在决策树构建完成后再进行剪枝,而xgboost在决策树构建阶段就加入了正则项。
- GBDT在模型训练时只使用了代价函数的一阶导数信息,xgboost对代价函数进行二阶泰勒展开。同时用到了一阶和二阶导数。
- 传统的GBDT采用CART作为基模型,xgboost支持多种类型的基模型,比如线性分类器。
x x x为某一样本
q ( x ) q(x) q(x)代表了该样本在哪个节点上(叶子的索引)
w q w_q wq代表了叶子节点的取值(即每个叶子的分数)
w q ( x ) w_{q(x)} wq(x)代表了每个样本的取值
需提前了解L2正则化
叶子节点不该含有过高的权重 w w w 怎么理解叶子节点的权重?叶子节点的权重和该叶子上样本的取值的关系?
基模型为决策树的xgboost的目标函数中的正则项可定义为:
这种复杂度的定义不是唯一的一种定义方式,只是这种方式简单并且有效。
外层循环:从第 j = 1 j=1 j=1 个叶子节点遍历至第 T T T 个叶子节点。
内层循环:
为属于第j个叶子节点上所有样本的 g g g (一阶导)求和。 w j w_j wj为第 j j j个叶子节点取值。
G G G 和 H H H 是前一步t-1步得到的结果,可以视为常数,只有最后一棵树(第t步加入的基模型)的各叶子节点的值 w j w_j wj 不确定。
将 w j w_j wj 代入后 O b j Obj Obj 化简为
上图给出目标函数计算的例子,求每个节点每个样本的一阶导数 g 和二阶导数 h ,然后针对每个节点对所含样本求和得到的 G 和 H ,最后遍历决策树的节点即可得到目标函数。
O b j Obj Obj 表示在某个确定的树结构下的结构分数(structure score)
a.从深度为0的树开始,每个叶节点枚举所有的可用特征;
b.对每个特征,把属于该节点的训练样本根据该特征值进行升序排序,通过线性枚举,决定该特征的最佳分裂点;
c.选择增益最大的特征作为分裂特征(增益:分裂前的目标函数值-分裂后的目标函数值)
(因为随着不断分裂,我们希望目标函数越小越好),用该特征的最佳分裂点作为分裂位置。
在该节点上分裂出左右两个新的叶子节点,并为每个新节点关联对应的样本集。
d.回到第a步,递归执行到满足特定条件为止。
上图为论文原图,外层循环为从第1个特征遍历到第m个特征;内层循环为遍历 I I I(即当前叶子节点的样本集合,且样本集合是按该特征值进行排序后的)
该特征增益Gain也可作为特征重要性的依据。
引入分割不一定会使结果更好, 当引入的分割带来的增益大于该设定的阈值时,才进行分裂。
(这种阈值限制是为了限制树深度,因为新增一次分割,模型的复杂度就会增大)
设定的阈值:
xgboost的切分操作和普通的决策树切分过程是不一样的。普通的决策树在切分的时候并不考虑树的复杂度,所以才有了后续的剪枝操作。而xgboost在切分的时候就已经考虑了树的复杂度(obj里面看到那个了吗)。所以,它不需要进行单独的剪枝操作。https://mp.weixin.qq.com/s/NC9CwR4cfDUJ26WpHsvkPQ
遍历完所有特征后,我们就可以确定应该在哪个特征的哪个点进行切分。对切分出来的两个节点,递归地调用这个过程,我们就能获得一个相对较好的树结构, 有了树结构就比较容易找最优的叶子节点,这样就能对上面的样本进行预测了。当然,特征与特征之间的收益计算是互不影响的,所以这个遍历特征的过程其实可以并行运行。
贪婪算法可以得到最优解,但当数据量太大时,无法完全读入内存,贪婪算法的效率就很低;或分布式场景下想应用此算法不好应用。
近似算法:对于每个特征,只考察分位点,可以减少计算复杂度。
在选取候选切分点时有两种策略:
local策略需要更多的计算步骤,而globa策略因为节点没有划分所以需要更多的候选点。
两种近似策略以及贪婪算法的 AUC曲线:
Globa策略在候选点多时(eps小),可以和Local策略在候选点少时(eps大)具有相似的准确度。
在eps取值合理时,近似算法能取得和贪婪算法(exact greedy)相同的AUC。几种evaluation metric的区别
上方论文原图,第一个循环,遍历特征,根据每个特征的分布找到候选切分点集合 S k S_k Sk。
第二个循环,遍历每个特征,将样本映射到上一步根据对应切分点划分出的分桶区间中。并对每个桶统计G、H,根据统计量选择最佳分裂点。
实际上xgboost不是简单地按样本个数分位,而是以二阶导数值 h i h_i hi 作为样本的权重进行分位。
1/3分位点 :(0.1×6)/(0.1×6+0.4+0.2+0.6)=1/3
https://www.youtube.com/watch?v=oRrKeUCEbq8
纯分位数分桶:
xgboost only uses the 【Approximate Greedy Algorithm】,【Parallel Learning】 and the 【Weighted Quantile Sketch】 when the Training Dataset is huge;
When the Training Datasetes are small ,xgboost just uses a noemal,every day 【Greedy Algorithm】。
为什么用 $h_i$ 作为样本权重?
目的是找使本次分裂的增益最大的分裂点;
增益最大 意味着 目标函数减小得最多,目标函数由损失函数、抑制复杂度组成,即损失函数下降得更多,那加权分位数相较于 直接单纯的分位数,优点在哪呢,我看到有文章说能加速这个找最佳分裂点的过程?怎么加速的呢?(待解决)
xgboost在应对数据缺失时的分裂策略
xgboost在构建树的节点过程中只考虑非缺失值的数据遍历,但为每个节点增加了一个缺省方向,当样本相应的特征值缺失时,分别将该样本归为左右分支,计算归为两边各自的增益,选增益最大的那一边作为最优缺省方向。
注意:xgboost在构建树的过程中只考虑了特征未缺失的样本的遍历,而特征值缺失的样本直接被分配到左右节点。
因此遍历的样本量减少,稀疏感知算法比basic算法速度快得多。
树何时停止分裂?
1、当本次分裂引入的增益小于设定阈值时,本次分裂不进行。
2、设定超参数max_depth,即当树的深度大于该值时停止分裂。
3、设定超参数min_child_weight,当某个叶子节点的权重 H j H_j Hj(该叶子上所有样本的权重 h i h_i hi , i i i∈ I j I_j Ij 之和)小于该值时停止分裂。
参考:
https://zhuanlan.zhihu.com/p/87885678
20道XGBoost面试题