1 XGBoost目标函数
XGBoost的目标函数由训练损失和正则化项两部分组成,其表达式为:
O
b
j
=
∑
i
=
1
n
l
(
y
i
,
y
i
^
)
+
∑
k
=
1
K
Ω
(
f
k
)
Obj=\sum_{i=1}^{n}l(y_i,\hat{y_i})+\sum_{k=1}^K\Omega(f_k)
Obj=i=1∑nl(yi,yi^)+k=1∑KΩ(fk)
其中第一项就是训练损失,第二项就是树的复杂度。
-
l
(
y
i
,
y
i
^
)
l(y_i,\hat{y_i})
l(yi,yi^)表示损失函数,常见的损失函数有:
平方损失函数: l ( y i , y i ^ ) = ( y i − y i ^ ) 2 l(y_i,\hat{y_i})=(y_i-\hat{y_i})^2 l(yi,yi^)=(yi−yi^)2
逻辑回归损失函数: 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,yi^)=yiln(1+e−yi^)+(1−yi)ln(1+eyi^) -
y
i
^
\hat{y_i}
yi^是第
i
i
i个样本
x
i
x_i
xi的预测值,由于XGBoost是加法模型,
y
i
^
\hat{y_i}
yi^的表达式为:
y i ^ = ∑ k = 1 K f k ( x i ) , f k ∈ ϝ \hat{y_i}=\sum_{k=1}^Kf_k(x_i),\ \ f_k\in \digamma yi^=k=1∑Kfk(xi), fk∈ϝ
其中 k ∈ K k\in K k∈K,代表第 k k k棵树, i i i代表第 i i i个样本, f k f_k fk是第 k k k棵树的函数。 -
∑
k
=
1
K
Ω
(
f
k
)
\sum_{k=1}^K\Omega(f_k)
∑k=1KΩ(fk)就是将全部
k
k
k棵树的复杂度求和,添加到目标函数中作为正则化项,用于防止模型过拟合,
Ω
(
f
k
)
\Omega(f_k)
Ω(fk)的表达式为:
Ω ( f k ) = γ T + 1 2 λ ∣ ∣ ω ∣ ∣ 2 \Omega(f_k)=\gamma T+\frac{1}{2}\lambda||\omega||^2 Ω(fk)=γT+21λ∣∣ω∣∣2
复杂度由叶子节点数量和叶子节点权重向量的L2范数组成。其中, T T T为树叶子节点数量, ω \omega ω为叶子权重, γ \gamma γ为叶子树惩罚正则项,具有剪枝作用, λ \lambda λ为叶子权重惩罚正则项,可以防止过拟合。 - 树的定义:
XGboost是由很多的CART回归树定义的,而CART回归树实质上就是在某特征维度对样本空间进行划分,这就有:
f ( x ) = ω q ( x ) f(x)=\omega_{q(x)} f(x)=ωq(x)
其中 ω q ( x ) \omega_{q(x)} ωq(x)就是叶子节点 q q q的分数, q ( x ) q(x) q(x)是叶子节点的编号, f ( x ) f(x) f(x)就是一棵回归树,即对于任意一个样本 x x x其最后会落在树的某个叶子节点上,其值为 ω q ( x ) \omega_{q(x)} ωq(x)。
2 学习第 t t t棵树
前文提到,XGBoost是一个加法模型,有:
y
i
^
(
t
)
=
∑
k
=
1
t
f
k
(
x
i
)
=
y
i
^
(
t
−
1
)
+
f
t
(
x
i
)
\hat{y_i}^{(t)}=\sum_{k=1}^tf_k(x_i)=\hat{y_i}^{(t-1)}+f_t(x_i)
yi^(t)=k=1∑tfk(xi)=yi^(t−1)+ft(xi)
其中
y
i
^
(
t
)
\hat{y_i}^{(t)}
yi^(t)表示第
t
t
t次迭代后样本
i
i
i的预测结果,
y
i
^
(
t
−
1
)
\hat{y_i}^{(t-1)}
yi^(t−1)表示前
t
−
1
t-1
t−1棵树的预测结果,
f
t
(
x
i
)
f_t(x_i)
ft(xi)表示第
t
t
t棵树的函数。
将上式代入目标函数,可以得到:
O
b
j
(
t
)
=
∑
i
=
1
n
l
(
y
i
,
y
i
^
(
t
)
)
+
∑
i
=
1
t
Ω
(
f
i
)
=
∑
i
=
1
n
l
(
y
i
,
y
i
^
(
t
−
1
)
+
f
t
(
x
i
)
)
+
Ω
(
f
t
)
+
c
o
n
s
t
a
n
t
Obj^{(t)}=\sum_{i=1}^nl(y_i,\hat{y_i}^{(t)})+\sum_{i=1}^t\Omega(f_i) \\ =\sum_{i=1}^nl(y_i, \hat{y_i}^{(t-1)}+f_t(x_i))+\Omega(f_t)+constant
Obj(t)=i=1∑nl(yi,yi^(t))+i=1∑tΩ(fi)=i=1∑nl(yi,yi^(t−1)+ft(xi))+Ω(ft)+constant
不用考虑常量,第
t
t
t棵树要学习的目标函数为:
O
b
j
(
t
)
=
∑
i
=
1
n
l
(
y
i
,
y
i
^
(
t
−
1
)
+
f
t
(
x
i
)
)
+
Ω
(
f
t
)
Obj^{(t)}=\sum_{i=1}^nl(y_i, \hat{y_i}^{(t-1)}+f_t(x_i))+\Omega(f_t)
Obj(t)=i=1∑nl(yi,yi^(t−1)+ft(xi))+Ω(ft)
实际上,除了
f
t
(
x
i
)
f_t(x_i)
ft(xi),其他的都是已知量或者可以通过已知量计算得到。
3 泰勒形式展开
泰勒公式的二阶展开形式如下:
f
(
x
+
Δ
x
)
≃
f
(
x
)
+
f
′
(
x
)
Δ
x
+
1
2
f
′
′
(
x
)
Δ
x
2
f(x+\Delta x)\simeq f(x)+f^{\prime}(x)\Delta x+\frac{1}{2}f^{\prime \prime}(x)\Delta x^2
f(x+Δx)≃f(x)+f′(x)Δx+21f′′(x)Δx2
对应到:
l
(
y
i
,
y
i
^
(
t
−
1
)
+
f
t
(
x
i
)
)
l(y_i, \hat{y_i}^{(t-1)}+f_t(x_i))
l(yi,yi^(t−1)+ft(xi)),其中
f
(
x
)
f(x)
f(x)对应到损失函数
l
l
l,
x
x
x对应到前
t
−
1
t-1
t−1棵树的预测值
y
i
^
(
t
−
1
)
\hat{y_i}^{(t-1)}
yi^(t−1),
Δ
x
\Delta x
Δx对应于我们正在训练的第
t
t
t棵树,损失函数可以转化为:
l
(
y
i
,
y
i
^
(
t
−
1
)
+
f
t
(
x
i
)
)
=
l
(
y
i
,
y
i
^
(
t
−
1
)
)
+
∂
l
(
y
i
,
y
^
(
t
−
1
)
)
∂
y
^
(
t
−
1
)
f
t
(
x
i
)
+
1
2
∂
2
l
(
y
i
,
y
^
(
t
−
1
)
)
∂
2
y
^
(
t
−
1
)
f
t
2
(
x
i
)
l(y_i, \hat{y_i}^{(t-1)}+f_t(x_i))=l(y_i, \hat{y_i}^{(t-1)})+\frac{\partial l(y_i, \hat{y}^{(t-1)})}{\partial \hat{y}^{(t-1)}}f_t(x_i)+\frac{1}{2}\frac{\partial ^2 l(y_i, \hat{y}^{(t-1)})}{\partial ^2 \hat{y}^{(t-1)}}f_t^2(x_i)
l(yi,yi^(t−1)+ft(xi))=l(yi,yi^(t−1))+∂y^(t−1)∂l(yi,y^(t−1))ft(xi)+21∂2y^(t−1)∂2l(yi,y^(t−1))ft2(xi)
令损失函数
l
l
l关于
y
^
(
t
−
1
)
\hat{y}^{(t-1)}
y^(t−1)的一阶导数和二阶导数分别表示为:
g
i
=
∂
l
(
y
i
,
y
^
(
t
−
1
)
)
∂
y
^
(
t
−
1
)
h
i
=
∂
2
l
(
y
i
,
y
^
(
t
−
1
)
)
∂
2
y
^
(
t
−
1
)
g_i=\frac{\partial l(y_i, \hat{y}^{(t-1)})}{\partial \hat{y}^{(t-1)}} \\ h_i=\frac{\partial ^2 l(y_i, \hat{y}^{(t-1)})}{\partial ^2 \hat{y}^{(t-1)}}
gi=∂y^(t−1)∂l(yi,y^(t−1))hi=∂2y^(t−1)∂2l(yi,y^(t−1))
则
l
(
y
i
,
y
i
^
(
t
−
1
)
+
f
t
(
x
i
)
)
l(y_i, \hat{y_i}^{(t-1)}+f_t(x_i))
l(yi,yi^(t−1)+ft(xi))化简为:
l
(
y
i
,
y
i
^
(
t
−
1
)
+
f
t
(
x
i
)
)
=
l
(
y
i
,
y
i
^
(
t
−
1
)
)
+
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
l(y_i, \hat{y_i}^{(t-1)}+f_t(x_i))=l(y_i, \hat{y_i}^{(t-1)})+g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)
l(yi,yi^(t−1)+ft(xi))=l(yi,yi^(t−1))+gift(xi)+21hift2(xi)
带入到式子
O
b
j
(
t
)
=
∑
i
=
1
n
l
(
y
i
,
y
i
^
(
t
−
1
)
+
f
t
(
x
i
)
)
+
Ω
(
f
t
)
Obj^{(t)}=\sum_{i=1}^nl(y_i, \hat{y_i}^{(t-1)}+f_t(x_i))+\Omega(f_t)
Obj(t)=∑i=1nl(yi,yi^(t−1)+ft(xi))+Ω(ft)中,得到:
O
b
j
(
t
)
≃
∑
i
=
1
n
[
l
(
y
i
,
y
i
^
(
t
−
1
)
)
+
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
]
+
Ω
(
f
t
)
Obj^{(t)}\simeq \sum_{i=1}^n[l(y_i, \hat{y_i}^{(t-1)})+g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)] + \Omega(f_t)
Obj(t)≃i=1∑n[l(yi,yi^(t−1))+gift(xi)+21hift2(xi)]+Ω(ft)
式中
l
(
y
i
,
y
i
^
(
t
−
1
)
)
l(y_i, \hat{y_i}^{(t-1)})
l(yi,yi^(t−1))是可以计算得到的常量,因此,上式进一步化简为:
O
b
j
(
t
)
≃
∑
i
=
1
n
[
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
]
+
Ω
(
f
t
)
+
C
Obj^{(t)}\simeq \sum_{i=1}^n[g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)] + \Omega(f_t) + C
Obj(t)≃i=1∑n[gift(xi)+21hift2(xi)]+Ω(ft)+C
3 叶子节点归组
我们将属于第
j
j
j个叶子结点的所有样本
x
i
x_i
xi , 划入到一个叶子结点样本集中,数学表示如下:
I
j
=
{
i
∣
q
(
x
i
)
=
j
}
I_j=\{i|q(x_i)=j\}
Ij={i∣q(xi)=j}
将复杂度公式代入
O
b
j
(
t
)
≃
∑
i
=
1
n
[
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
]
+
Ω
(
f
t
)
Obj^{(t)}\simeq \sum_{i=1}^n[g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)] + \Omega(f_t)
Obj(t)≃i=1∑n[gift(xi)+21hift2(xi)]+Ω(ft)
并运用节点归组的思想,得到:
O
b
j
(
t
)
≃
∑
i
=
1
n
[
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
]
+
Ω
(
f
t
)
=
∑
i
=
1
n
[
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
]
+
γ
T
+
1
2
∑
j
=
1
T
λ
∣
∣
ω
∣
∣
2
=
∑
j
=
1
T
[
(
∑
i
∈
I
j
g
i
)
ω
j
+
1
2
(
∑
i
∈
I
j
h
i
+
λ
)
ω
j
2
]
+
γ
T
Obj^{(t)}\simeq \sum_{i=1}^n[g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)] + \Omega(f_t) \\ =\sum_{i=1}^n[g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)]+\gamma T+\frac{1}{2}\sum_{j=1}^T\lambda||\omega||^2 \\ =\sum_{j=1}^T[(\sum_{i\in I_j}g_i)\omega_j+\frac{1}{2}(\sum_{i\in I_j}h_i+\lambda)\omega_j^2]+\gamma T
Obj(t)≃i=1∑n[gift(xi)+21hift2(xi)]+Ω(ft)=i=1∑n[gift(xi)+21hift2(xi)]+γT+21j=1∑Tλ∣∣ω∣∣2=j=1∑T[(i∈Ij∑gi)ωj+21(i∈Ij∑hi+λ)ωj2]+γT
进一步,给出如下定义:
G
j
=
∑
i
∈
I
j
g
i
H
j
=
∑
i
∈
I
j
h
i
G_j=\sum_{i\in I_j}g_i \\ H_j=\sum_{i\in I_j}h_i
Gj=i∈Ij∑giHj=i∈Ij∑hi
其中,
G
j
G_j
Gj是叶子节点
j
j
j所包含样本的一阶偏导数累加之和,是一个常数;
H
j
H_j
Hj是叶子节点
j
j
j所包含的二阶偏导数累加之和,同样也是一个常量。得到最终的目标函数:
O
b
j
(
t
)
≃
∑
i
=
1
n
[
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
]
+
Ω
(
f
t
)
=
∑
j
=
1
T
[
(
∑
i
∈
I
j
g
i
)
ω
j
+
1
2
(
∑
i
∈
I
j
h
i
+
λ
)
ω
j
2
]
+
γ
T
=
∑
j
=
1
T
[
G
j
ω
j
+
1
2
(
H
j
+
λ
)
ω
j
2
]
+
γ
T
Obj^{(t)}\simeq \sum_{i=1}^n[g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)] + \Omega(f_t) \\ =\sum_{j=1}^T[(\sum_{i\in I_j}g_i)\omega_j+\frac{1}{2}(\sum_{i\in I_j}h_i+\lambda)\omega_j^2]+\gamma T \\ = \sum_{j=1}^T[G_j\omega_j+\frac{1}{2}(H_j+\lambda)\omega_j^2]+\gamma T
Obj(t)≃i=1∑n[gift(xi)+21hift2(xi)]+Ω(ft)=j=1∑T[(i∈Ij∑gi)ωj+21(i∈Ij∑hi+λ)ωj2]+γT=j=1∑T[Gjωj+21(Hj+λ)ωj2]+γT
4 最优化
上面得到最终的目标函数:
O
b
j
(
t
)
≃
∑
j
=
1
T
[
G
j
ω
j
+
1
2
(
H
j
+
λ
)
ω
j
2
]
+
γ
T
Obj^{(t)}\simeq \sum_{j=1}^T[G_j\omega_j+\frac{1}{2}(H_j+\lambda)\omega_j^2]+\gamma T
Obj(t)≃j=1∑T[Gjωj+21(Hj+λ)ωj2]+γT
实际上,对于每个叶子结点
j
j
j , 都可以将其从目标式
O
b
j
Obj
Obj中拆解出来,并且各个叶子结点的目标子式是相互独立的,也就是说,当每个叶子结点的子式都达到最值点时,整个目标函数式
O
b
j
(
t
)
Obj^{(t)}
Obj(t)才达到最值点。
O
b
j
=
G
j
ω
j
+
1
2
(
H
j
+
λ
)
ω
j
2
Obj = G_j\omega_j+\frac{1}{2}(H_j+\lambda)\omega_j^2
Obj=Gjωj+21(Hj+λ)ωj2
因为
G
j
G_j
Gj和
H
j
H_j
Hj对于第
t
t
t棵树来说都是可以计算的,因此上式就只包含一个变量
ω
j
\omega_j
ωj,令
O
b
j
Obj
Obj对
ω
j
\omega_j
ωj的导数为
0
0
0,很容易得到最优的
ω
j
\omega_j
ωj:
ω
j
∗
=
−
G
j
H
j
+
λ
\omega_j^*=-\frac{G_j}{H_j+\lambda}
ωj∗=−Hj+λGj
得到最优的目标函数(最小损失):
O
b
j
=
−
1
2
∑
j
=
1
T
G
j
2
H
j
+
λ
+
γ
T
Obj=-\frac{1}{2}\sum_{j=1}^T\frac{G_j^2}{H_j+\lambda}+\gamma T
Obj=−21j=1∑THj+λGj2+γT
5 树的生长
如何分裂
为什么我们之前一直讨论目标函数
O
b
j
Obj
Obj,在GBDT中,启发式的方法让分裂准则不总是和损失函数相关,我们可以使用多种损失函数评价分裂质量。但在XGBoost中的分裂准则是直接跟损失函数挂钩的一种分裂准则,这是XGBoost跟GBDT不一样的一个点。
具体来讲,XGBoost选择这个准则,计算增益Gain :
G
a
i
n
=
−
1
2
(
G
L
+
G
R
)
2
H
L
+
H
R
+
λ
+
γ
T
0
−
(
−
1
2
G
L
2
H
L
+
λ
−
1
2
G
R
2
H
R
+
λ
)
−
γ
T
1
=
1
2
[
G
L
2
H
L
+
λ
+
G
R
2
H
R
+
λ
−
(
G
L
+
G
R
)
2
H
L
+
H
R
+
λ
]
+
γ
(
T
0
−
T
1
)
Gain=-\frac{1}{2}\frac{(G_L+G_R)^2}{H_L+H_R+\lambda} + \gamma T_0 - (-\frac{1}{2}\frac{G_L^2}{H_L+\lambda}-\frac{1}{2}\frac{G_R^2}{H_R+\lambda})-\gamma T_1 \\ =\frac{1}{2}[\frac{G_L^2}{H_L+\lambda}+\frac{G_R^2}{H_R+\lambda}-\frac{(G_L+G_R)^2}{H_L+H_R+\lambda}] + \gamma (T_0-T_1)
Gain=−21HL+HR+λ(GL+GR)2+γT0−(−21HL+λGL2−21HR+λGR2)−γT1=21[HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2]+γ(T0−T1)
其中,
T
0
=
1
T_0=1
T0=1,
T
1
=
2
T_1=2
T1=2。
其实选择这个作为准则的原因很简单也很直观,由最优损失易知,对于一个节点,假设我们不分裂的话,那么对于左叶子节点和右叶子节点而言其包含样本点的一阶二阶导的和就不是单独来算了,而是合在一起算的。
因为此时所有样本都存在于未分裂的节点中,所以此时该节点中一阶导的和就相当于
(
G
L
+
G
R
)
(G_L+G_R)
(GL+GR),未分裂节点上的二阶导为
(
H
L
+
H
R
)
(H_L+H_R)
(HL+HR),将其代入
O
b
j
=
−
1
2
∑
j
=
1
T
G
j
2
H
j
+
λ
+
γ
T
Obj=-\frac{1}{2}\sum_{j=1}^T\frac{G_j^2}{H_j+\lambda}+\gamma T
Obj=−21∑j=1THj+λGj2+γT中,即可得到不分裂情况下的损失值:
(
G
L
+
G
R
)
2
H
L
+
H
R
+
λ
\frac{(G_L+G_R)^2}{H_L+H_R+\lambda}
HL+HR+λ(GL+GR)2
假设在这个节点分裂的话,分裂之后左右叶子节点的损失分别为:
G
L
2
H
L
+
λ
和
G
R
2
H
R
+
λ
\frac{G_L^2}{H_L+\lambda}和\frac{G_R^2}{H_R+\lambda}
HL+λGL2和HR+λGR2
所以选择分裂后预期损失减少得最多,即:
m
a
x
(
G
L
2
H
L
+
λ
+
G
R
2
H
R
+
λ
−
(
G
L
+
G
R
)
2
H
L
+
H
R
+
λ
)
max(\frac{G_L^2}{H_L+\lambda}+\frac{G_R^2}{H_R+\lambda}-\frac{(G_L+G_R)^2}{H_L+H_R+\lambda})
max(HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2)
寻找最优分裂
上一节介绍了如何分裂,但在一个结点分裂时,可能有很多个分裂点,每个分裂点都会产生一个增益,寻找最优分裂点就非常重要了。寻找最优分裂点一般步骤如下:
- 遍历每个结点的每个特征;
- 对每个特征,按特征值大小将特征值排序;
- 线性扫描,找出每个特征的最佳分裂特征值;
- 在所有特征中找出最好的分裂点(分裂后增益最大的特征及特征值)。
这是一般方法,每次进行分裂尝试都要遍历一遍全部候选分裂点,如果数据量较大,内存无法承载或在分布式的情况下,这种方法就不再适用。因此就有了XGBoost算法的改进:
- 特征预排序+缓存
XGBoost在训练之前,预先对每个特征按照特征值大小进行排序,然后保存为block结构,后面的迭代中会重复地使用这个结构,使计算量大大减小。 - 分位点近似法
对每个特征按照特征值排序后,采用类似分位点选取的方式,仅仅选出常数个特征值作为该特征的候选分割点,在寻找该特征的最佳分割点时,从候选分割点中选出最优的一个。 - 并行查找
由于各个特性已预先存储为block结构,XGBoost支持利用多个线程并行地计算每个特征的最佳分割点,这不仅大大提升了结点的分裂速度,也极利于大规模训练集的适应性扩展。
停止生长
常见的让树停止生长的条件包括:
- Gain控制
我们知道,分裂前后的Gain值为:
G a i n = 1 2 [ G L 2 H L + λ + G R 2 H R + λ − ( G L + G R ) 2 H L + H R + λ ] − γ Gain=\frac{1}{2}[\frac{G_L^2}{H_L+\lambda}+\frac{G_R^2}{H_R+\lambda}-\frac{(G_L+G_R)^2}{H_L+H_R+\lambda}] - \gamma Gain=21[HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2]−γ
其中式子前半部分表示训练损失的减少量, γ \gamma γ表示叶子节点惩罚正则项。当 G a i n Gain Gain值小于0时,表明分裂失败。 - 深度停止
当树的深度达到一定值时,停止分裂,时一种防止过拟合的措施。 - 权重阈值
分裂后重新计算新生成的左、右两个叶子结点的样本权重和。如果任一个叶子结点的样本权重低于某一个阈值,也会放弃此次分裂。这涉及到一个超参数:最小样本权重和,是指如果一个叶子节点包含的样本数量太少也会放弃分裂,防止树分的太细,是防止过拟合的一种措施。
其他
手动还原参考:XGBoost详解