目标函数
Xgboost与GBDT比较大的不同就是目标函数的定义,xgboost的目标函数如下图所示:
其中,
红色箭头所指向的
l
l
l即为损失函数,比如平方损失函数:
l
(
y
i
,
y
^
i
)
=
(
y
i
−
y
^
i
)
2
l(y_i,\hat{y}_i) = (y_i-\hat{y}_i)^2
l(yi,y^i)=(yi−y^i)2,或logistic损失函数
l
(
y
i
,
y
^
i
)
=
y
i
l
n
(
1
+
e
−
y
^
i
)
+
(
1
−
y
i
)
l
n
(
1
+
e
y
^
i
)
l(y_i,\hat{y}_i) =y_iln(1+e^{-\hat{y}_i}) +(1-y_i)ln(1+e^{\hat{y}_i})
l(yi,y^i)=yiln(1+e−y^i)+(1−yi)ln(1+ey^i)。
红色方框所框起来的是正则项(包括
L
1
L1
L1正则、
L
2
L2
L2正则)
红色圆圈所圈起来的为常数项
对于损失函数
l
l
l,xgboost利用泰勒展开三项,做一个近似,最终的目标函数只依赖于每个数据点的在误差函数上的一阶导数和二阶导数。
模型训练误差
具体来说,目标函数第一部分中
i
i
i表示第
i
i
i样本,
l
(
y
i
,
y
^
i
)
l (y_i,\hat{y}_i)
l(yi,y^i) 表示第
i
i
i个样本的预测误差,我们的目标当然是误差越小越好。
在当前步,
y
i
,
y
^
i
(
t
−
1
)
y_i,\hat{y}_i^{(t-1)}
yi,y^i(t−1)都是已知值,模型学习的是
f
t
f_t
ft。
那接下来,我们如何选择每一轮加入什么
f
f
f?答案是非常直接的,选取
f
f
f 来使得我们的目标函数尽量最大地降低。
这个公式可能有些过于抽象,我们可以考虑
l
l
l 是平方误差的情况,这个时候我们的目标可以被写成下面这样的二次函数,注意
(
y
i
−
y
^
i
t
−
1
)
2
(y_i-\hat{y}_i^{t-1})^2
(yi−y^it−1)2为常数项,所以归到
c
o
n
s
t
const
const中
更加一般的,损失函数不是二次函数咋办?泰勒展开,不是二次的想办法近似为二次。
且把常数项移除之后,我们会发现如下一个比较统一的目标函数。
这时,目标函数只依赖于每个数据点的在误差函数上的一阶导数和二阶导数
树的复杂度
首先,梳理下几个规则:
- 树的复杂度用叶子节点集合以及叶子节点得分表示
- 每个样本都落在一个叶子节点上
- q ( x ) q(x) q(x)表示样本x在某个叶子节点上, w q ( x ) w_{q(x)} wq(x)是该节点的得分,即该样本的模型预测值
所以树的结构就可以用如下式表示
树的复杂度可以用下式表示,即包含了一棵树里面节点的个数,以及每个树叶子节点上面输出分数的模平方
L
2
L2
L2。
目标函数进一步改写
通过以上模型训练误差和树的复杂度分步理解后,我们可以得到最终目标函数,并改写如下:
其中
I
j
I_j
Ij被定义为每个叶节点
j
j
j 上面的样本集合:
I
j
=
{
i
∣
q
(
x
i
)
=
j
}
I_j=\{i|q(x_i)=j\}
Ij={i∣q(xi)=j}
以上目标包含了
T
T
T个相互独立的单变量二次函数。我们可以定义
最终公式可以化简为
通过
w
j
w_j
wj对求导等于0,可以得到
然后把
w
j
wj
wj最优解代入得到:
最优计算
结构分数:
O
b
j
Obj
Obj代表了当我们指定一个树的结构的时候,我们在目标上面最多减少多少。我们可以把它叫做结构分数(structure score)(下图
H
4
H_4
H4应该为
H
2
H_2
H2)
分裂节点
xgboost的原始论文中给出了两种分裂节点的方法
(1)枚举所有不同树结构的贪心法
不断地枚举不同树的结构,利用这个打分函数来寻找出一个最优结构的树,加入到我们的模型中,再重复这样的操作。不过枚举所有树结构这个操作不太可行,所以常用的方法是贪心法,每一次尝试去对已有的叶子加入一个分割。对于一个具体的分割方案,我们可以获得的增益可以由如下公式计算。
此目标代表了增益,越大越好,优化这个目标对应了树的剪枝,当引入的分割带来的增益小于一个阀值的时候,我们可以剪掉这个分割。
对于每次扩展,我们还是要枚举所有可能的分割方案,如何高效地枚举所有的分割呢?假设我们要枚举所有
x
<
a
x < a
x<a这样的条件,对于某个特定的分割
a
a
a我们要计算
a
a
a左边和右边的导数和。
我们可以发现对于所有的
a
a
a,我们只要做一遍从左到右的扫描就可以枚举出所有分割的梯度和
G
L
G_L
GL和
G
R
G_R
GR。然后用上面的公式计算每个分割方案的分数就可以了。
(2)近似算法
主要针对数据太大,不能直接进行计算,本文略
参考:
1.https://blog.csdn.net/weixin_41358871/article/details/81541482
2.https://blog.csdn.net/a819825294/article/details/51206410