原理
XGBoost 的核心原理与之前所讲的提升树是类似的,都是通过学习残差近似来训练模型。不同的是 XGBoost 同时使用了一阶导与二阶导。而且XGBoost 加入了正则项,从某种程度上可以进行预剪枝,所以约束了模型的复杂度。说了这么多,“关键看疗效”,但 XGBoost 真正工程应用上也是非常的棒,陈天奇前辈可谓“华人之光”啊!
对于加法模型与前向分步算法的过程是一样的,那么我们从损失函数来看 XGBoost 的灵性:
我们想构建目标函数,其中包含正则项以及损失函数,那么我就可以先抽象化的定义目标函数:
Obj=∑i=1nl(yi,yi(m1)+fm(xi))+Ω(fm)
其中 l(yi,yi(m+1)+fm(xi)) 为经验损失函数,yi 为真实值,yi(m1) 为第 m-1 次迭代后模型的预测值,Ω(fm) 为正则项。
那么我们该如何具体地表示残差以及正则项呢,XGBoost 选择使用 泰勒公式的二阶展开!
泰勒公式的二阶展开式为:f(x+△x)=f(x)+f′(x)△x+21f′′(x)△x2
根据此,我们将经验损失函数 l(yi,yi(m+1)+fm(xi)) 进行泰勒公式的二阶展开:
我们定义:
一阶导:gi=yim1l(yi,yi(m1)),二阶导:hi=(yim1)22l(yi,yi(m1)),且恰好△x=fm(xi)
所以:
Obj=∑i=1n[l(yi,yi(m1)+fm(x))+gifm(xi)+21hifm2(xi)]
其中 fm(xi) 表示对样本 xi 的预测值。
[l(yi,yi(m1)+fm(x)) 根据上一轮的学习结果计算得到,所以视为常数 C,那么上式转化为:
Obj=∑i=1n[gifm(xi)+21hifmt2(xi)]+C
另外加入正则项 21λ∑t=1Twt2,其中 wt 为第 t 个叶节点的结构分数。并且对于树的复杂度,我们一般还会考虑叶子结点的个数 |T|,所以引入参数 γ,最终得到 XGBoost 模型结构损失函数的完整表达式:
Obj=∑i=1n[gifm(xi)+21hifm2(xi)]+21λ∑t=1Twt2+γ∣T∣+C
其中∑i=1n 表示遍历所有的样本,考虑将 fm(xi) 改写为 wq(xi),遍历每个叶节点进行表示:
Obj==t=1∑T[(i∈x∑gi)wt+21(i∈x∑hi)wt]+21λt=1∑Twt2+γ∣T∣+Ct=1∑T[(i∈x∑gi)wt+21(λ+i∈x∑hi)wt]+γ∣T∣+C
令 ∑igi=Gt,∑ihi=Ht,其中 i 表示 叶节点 t 中的所有样本,得到:
l(yi,yi(m1))=∑t=1T[Gtwt+21(λ+Ht)wt]+γ∣T∣+C
对于中括号内的项,是一个二次函数形式:ax2+bx,其最优解为 x=2ab=λ+HiGi,代入原式并省略常数项得:
obj=21∑t=1T(λ+HtGt2)+γ∣T∣,即结构分数
而后再对 叶节点 进行划分。整体思路相当于先对树的整体结构的损失函数进行正则约束优化,找到最优树结构,而后再对叶节点内部样本求解最优划分方式,是贪心策略的二次规划。
对于叶节点的分裂,我们可以通过推导出来的目标函数 Obj 计算结构分数,通过结构分数计算增益 Gain,Gain 值越大分裂效果越好:
L,RargmaxGain= L,Rargmax21[(λ+HLGL2+λ+HRGR2λ+HL+HR(GL+GR)2)]γ
我们发现在分裂时依赖于损失函数与各样本对于损失函数的一阶二阶导数值,所以我们可以在最开始遍历所有样本对于损失函数的一阶二阶导数值备用,计算分裂时直接取值即可。
xgboost 因为有泰勒二阶展开的存在,所以无论损失函数是怎样的,都可以转换成二次函数,并利用 x=2ab 求得目标函数的最优值。