xgboost 是集成学习boosting的一种,它的基础分类器是CART,即分类回归树。
下图就是CART树和一堆CART树的示例,用来判断一个人是否会喜欢计算机游戏:
用多棵CART树做预测时,就是将各个树的预测分数相加。
y i ^ = ∑ k = 1 K f k ( x i ) , f k ⊆ K \widehat{y_i}=\sum_{k=1}^{K}f_k(x_i) ,f_k\subseteq \mathcal{K} yi =k=1∑Kfk(xi),fk⊆K
其中 K K K表示有K棵CART树, f k f_k fk函数是第 k k k棵树得到的分数。
定义目标函数为 o b j = ∑ i = 1 n l ( y i , y i ^ ) + ∑ k = 1 K Ω ( f k ) obj=\sum_{i=1}^{n}l(y_i,\widehat{y_i})+\sum_{k=1}^{K}\Omega (f_k) obj=i=1∑nl(yi,yi )+k=1∑KΩ(fk)
目标函数包括第一部分的损失函数和第二部分的正则项。
xgboost在训练时,先优化第一棵树,之后第二棵,第三棵…直到优化完K棵树,真个过程如下图所示:
在第t步时,添加了一棵最优的CART树 f t f_t ft,这棵最优的CART树 f t f_t ft就是在现有的t-1棵树的基础上,使得目标函数最小的那棵CART树,
o b j ( t ) = ∑ i = 1 n l ( y i , y i ^ ( t ) ) + ∑ k = 1 K Ω ( f k ) = ∑ i = 1 n l ( y i , y i ^ ( t − 1 ) + f t ( x i ) ) + Ω ( f t ) + c o n s t a n t \begin{aligned} obj^{(t)}&=\sum_{i=1}^{n}l(y_i,\widehat{y_i}^{(t)})+\sum_{k=1}^{K}\Omega (f_k) \\ & = \sum_{i=1}^{n}l(y_i,\widehat{y_i}^{(t-1)}+f_t(x_i))+\Omega (f_t)+constant \end{aligned} obj(t)=i=1∑nl(yi,yi (t))+k=1∑KΩ(fk)=i=1∑nl(yi,yi (t−1)+ft(xi))+Ω(ft)+constant
这里的
Ω
(
f
t
)
\Omega (f_t)
Ω(ft)是第t步时,当前的CART树的正则项,而
c
o
n
s
t
a
n
t
constant
constant就是前t-1棵树的正则项了。
将损失函数进行泰勒二阶展开,
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 ) + c o n s t a n t obj^{(t)}=\sum_{i=1}^{n}[l(y_i,\widehat{y_i}^{(t-1)})+g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)]+\Omega (f_t)+constant obj(t)=i=1∑n[l(yi,yi (t−1))+gift(xi)+21hift2(xi)]+Ω(ft)+constant
其中
g
i
=
∂
l
(
y
i
,
y
^
i
(
t
−
1
)
)
∂
y
^
i
(
t
−
1
)
,
h
i
=
∂
2
l
(
y
i
,
y
^
i
(
t
−
1
)
)
∂
y
^
i
(
t
−
1
)
g_i=\frac{\partial l(y_i,\hat y_i^{(t-1)})}{\partial \hat y_i^{(t-1)}},h_i=\frac{\partial^2 l(y_i,\hat y_i^{(t-1)})}{\partial \hat y_i^{(t-1)}}
gi=∂y^i(t−1)∂l(yi,y^i(t−1)),hi=∂y^i(t−1)∂2l(yi,y^i(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 ) obj^{(t)}\approx \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)
再看正则项,首先看CART树的另一个定义,
这里的
w
w
w函数是CART树打分的函数,
q
q
q函数是将x定位到哪个叶子节点的函数。xgboost就使用了如下的正则化项,
Ω
(
f
t
)
=
γ
T
+
1
2
λ
∑
j
=
1
T
w
j
2
\Omega (f_t)=\gamma T+\frac{1}{2} \lambda \sum_{j=1}^{T} w_j^2
Ω(ft)=γT+21λj=1∑Twj2
将其带入到目标函数,
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
w
j
2
=
∑
j
=
1
T
[
∑
i
∈
I
j
g
i
+
1
2
(
∑
i
∈
I
j
h
i
+
λ
)
w
j
2
]
+
γ
T
=
∑
j
=
1
T
[
G
j
+
1
2
(
H
j
+
λ
)
w
j
2
]
+
γ
T
\begin{aligned} obj^{(t)}&\approx \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} \lambda \sum_{j=1}^{T} w_j^2\\ &=\sum_{j=1}^{T}[\sum_{i \in I_j}g_i+\frac{1}{2}(\sum_{i \in I_j}hi+\lambda)w_j^2]+\gamma T\\ &=\sum_{j=1}^{T}[G_j+\frac{1}{2}(H_j+\lambda)w_j^2]+\gamma T \end{aligned}
obj(t)≈i=1∑n[gift(xi)+21hift2(xi)]+Ω(ft)=i=1∑n[gift(xi)+21hift2(xi)]+γT+21λj=1∑Twj2=j=1∑T[i∈Ij∑gi+21(i∈Ij∑hi+λ)wj2]+γT=j=1∑T[Gj+21(Hj+λ)wj2]+γT
其中将 ∑ i ∈ I j g i \sum_{i \in I_j}g_i ∑i∈Ijgi简化为 G j G_j Gj,将 ∑ i ∈ I j h i \sum_{i \in I_j}h_i ∑i∈Ijhi简化为 H j H_j Hj。
对于第t棵CART树的某一个确定的结构(可用
q
(
x
)
q(x)
q(x)表示),所有的
G
j
G_j
Gj和
H
j
H_j
Hj都是确定的。而且上式中各个叶子节点的值
w
j
w_j
wj之间是互相独立的。上式其实就是一个简单的二次式,我们很容易求出各个叶子节点的最佳值以及此时目标函数的值。
对 w j ∗ w_j^* wj∗的一个直观的解释是,假设分到 j 这个叶子节点上的样本只有一个,那么
w j ∗ = ( 1 h j + λ ) ∗ ( − g j ) w_j^*=(\frac{1}{h_j+ \lambda})*(-g_j) wj∗=(hj+λ1)∗(−gj)
这个式子告诉我们, w j ∗ w^*_j wj∗的最优值就是负的梯度乘以一个系数,这个系数类似于随机梯度下降中的学习率。 h j h_j hj越大,这个系数越小,也就是学习率越小。 h j h_j hj越大代表在该点附近梯度变化非常剧烈,此时,我们在使用反向梯度更新时步子就要小,也就是权重系数要小。
o b j ∗ obj^* obj∗则是衡量了第t棵树结构的好坏。与叶子节点的值可是无关的。 o b j ∗ obj^* obj∗只和 G j G_j Gj和 H j H_j Hj和 T T T有关,而它们又只和树的结构 ( q ( x ) ) (q(x)) (q(x))有关。
有了评判CART树的标准,我们就可以构造出最优的第t棵树,怎么构造?树的结构有很多,不能每个结构都计算一次
o
b
j
∗
obj^*
obj∗来确定哪个结构做最好。这里就采用逐步学习出最佳的树结构。当样本输入时,先找一个特定的特征j,然后在找该特定的值c,当特征j的值小于c时分到左节点,大于c分到右节点。
问题是怎么决定j和c,xgboost采用的是遍历。
我们以上文提到过的判断一个人是否喜欢计算机游戏为例子。最简单的树结构就是一个节点的树。我们可以算出这棵单节点的树的好坏程度obj*。解设我们先按年龄分,先将这一家五口人按照年龄做个排序
从左至右扫描,找出所有可能的切分点。当切分点确定时,用下列式子作为切分点好坏的标准。
这里的
G
a
i
n
Gain
Gain其实是切分前后的差值。如果是正的,而且值越大说明
o
b
j
∗
obj^*
obj∗下降得越多,如果是负数,也就是说,左边的这一项小于
γ
\gamma
γ项,说明切分后
o
b
j
∗
obj^*
obj∗反而变大了。其实
γ
\gamma
γ是可以自己设定的阈值,也就说这个值越大,对切分点的要求就越严格。
递归地调用这个切分过程,就能获得一个相对较好的树结构。得到了最优的树结构,也就能找到最优的叶子节点,这样就完成了找出第t棵树的目的。之后再进行第t+1棵树,直到K棵树完成。