序言
xgboost一直在数学科学比赛中是一个强有力的大杀器,然而其数学原理对于数学小白来说,是比较晦涩难懂的。
本文主要目的是带领机器学习的小白,以一种简单的方式来理解xgboost,而具体详情请翻阅陈天奇大佬的论文。论文链接:https://dl.acm.org/citation.cfm?id=2939785
一、回归树是什么
xgboost是基于弱学习器的一种集成算法。而论文中的弱学习器选用的是回归树。因此在学习xgboost之前,我们先来讨论下什么是回归树。
我们知道在决策树算法中主要解决的是分类问题,而回归树就是用来解决回归问题的。与决策树不同的是,决策树的叶子结点的预测值是分类标签,而回归树的叶子结点的预测值则是实数值。
比如图中的案例,我们要预测一个人是否喜欢电脑游戏,给定的特征值为年龄,性别,职业,而我们要预测的是是否喜欢计算机的打分值,是个实数值。
- 如果样本是符合高斯分布的,因此我们选择的损失函数是均方误差损失函数,则叶子结点的预测值则选取该结点样本预测值的平均值。
- 如果样本是符合拉普拉斯分布的,我们选择的目标函数则是绝对值损失函数,那么叶子结点的预测值则为该结点样本的中位数。
在理解xgboost之前,我们必须在牢记把回归树看成是一个函数。这个函数的作用就是根据特征空间向量来进行标签的预测。
我们接下来的推倒都是基于函数空间来进行推导的。
二、xgboost的算法过程
xgboost的算法通俗来说就是不断地添加树,不断地进行特征分裂来生长一棵树,每次添加一个树,其实是学习一个新函数,去拟合上次预测的残差。
当我们训练完成得到k棵树,我们要预测一个样本的分数,其实就是根据这个样本的特征,在每棵树中会落到对应的一个叶子节点,每个叶子节点就对应一个分数,最后只需要将每棵树对应的分数加起来就是该样本的预测值。
三、公式推导
3.1目标函数
xgboost的目标函数为:
J
(
f
t
)
=
∑
i
=
1
n
L
(
y
i
,
y
i
^
(
t
−
1
)
+
f
t
(
x
i
)
)
+
Ω
(
f
t
)
+
c
o
n
s
t
(
式
①
)
J(f_t)=\sum_{i=1}^{n}L(y_i,\hat{y_i}^{(t-1)}+f_t(x_i))+\Omega(f_t)+const(式①)
J(ft)=i=1∑nL(yi,yi^(t−1)+ft(xi))+Ω(ft)+const(式①)
损失函数: ∑ i = 1 n L ( y i , y i ^ t − 1 + f t ( x i ) ) ( 式 ② ) \sum_{i=1}^{n}L(y_i,\hat{y_i}^{t-1}+f_t(x_i)) (式②) ∑i=1nL(yi,yi^t−1+ft(xi))(式②)
正则项: Ω ( f t ) ( 式 ③ ) \Omega(f_t)(式③) Ω(ft)(式③)
常数:
c
o
n
s
t
const
const
在这里需要注意的是:
目标函数是在函数空间而并不是在参数空间进行的数值优化的。而我们之前已经提到过回归树从本质上来说其实也是属于一个函数,实际上是一定的特征空间到预测值之间的映射。因此,目标函数,实际上是自变量为
f
t
f_t
ft的函数。
3.2泰勒公式化简目标函数
关于目标函数,我们可以对其进行二阶展开。
由泰勒公式
f
(
x
+
Δ
x
)
≈
f
(
x
)
+
f
′
(
x
)
Δ
x
+
1
2
f
′
′
(
x
)
Δ
x
2
f(x+\Delta{x})\approx f(x)+f^{'}(x)\Delta{x}+\frac{1}{2}f^{''}(x)\Delta{x}^2
f(x+Δx)≈f(x)+f′(x)Δx+21f′′(x)Δx2
在这里,我们令
一阶导为
g
i
=
∂
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)}}}
gi=∂yi^(t−1)∂L(yi,yi^(t−1))
二阶导为
h
i
=
∂
2
L
(
y
i
,
y
i
^
(
t
−
1
)
)
∂
2
y
i
^
(
t
−
1
)
h_i = \frac{\partial{^2L(y_i,\hat{y_i}^{(t-1)})}}{\partial{^2\hat{y_i}^{(t-1)}}}
hi=∂2yi^(t−1)∂2L(yi,yi^(t−1))
其中在式②中
x
=
y
i
^
t
−
1
x = \hat{y_i}^{t-1}
x=yi^t−1,
Δ
x
=
f
t
(
x
i
)
\Delta{x} =f_t(x_i)
Δx=ft(xi)
因此,式②则为
J
(
f
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
(
式
③
)
J(f_t)=\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)+const(式③)
J(ft)=i=1∑n[L(yi,yi^(t−1))+gift(xi)+21hift2(xi)]+Ω(ft)+const(式③)
因为,我们的第t颗回归树是根据前面的t-1颗回归树的残差得来的,因此,前面t-1颗树的值
y
i
^
t
−
1
\hat{y_i}^{t-1}
yi^t−1是已知的。则
L
(
y
i
,
y
i
^
(
t
−
1
)
)
L(y_i,\hat{y_i}^{(t-1)})
L(yi,yi^(t−1))也是已知的,因此可放到常数项
c
o
n
s
t
const
const中去。
因此,我们的目标函数则可以化为
J
(
f
t
)
=
∑
i
=
1
n
[
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
]
+
Ω
(
f
t
)
+
c
o
n
s
t
(
式
④
)
J(f_t)=\sum_{i=1}^{n}[g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)]+\Omega(f_t)+const(式④)
J(ft)=i=1∑n[gift(xi)+21hift2(xi)]+Ω(ft)+const(式④)
3.3正则项的解释说明
我们已经知道,关于回归树的对样本进行回归预测,落在相同叶子结点处的预测值是一样的,一般情况下取该结点样本的标签值的平均数。
我们假设第t颗树的叶子结点数为
T
T
T,每个叶子结点的权值为
w
q
(
x
i
)
w_q(xi)
wq(xi)。回归树的构建过程实际上就是根据样本属性的划分,得到权值的过程。
我们将样本落在结点q可以定义为
f
(
x
i
)
=
w
q
(
x
i
)
式
⑤
f(x_i)=w_q(xi)式⑤
f(xi)=wq(xi)式⑤
而我们的正则项的目的则是对回归树的模型的简化,
一颗决策树的核心则是叶子结点的权重
w
q
w_q
wq和叶子结点的数量
T
T
T
因此,第t颗树的正则项则为
Ω
(
f
t
)
=
γ
T
+
λ
.
1
2
∑
j
=
1
T
(
w
j
2
)
(
式
⑥
)
\Omega(f_t)=\gamma T+\lambda.\frac{1}{2}\sum_{j=1}^{T}(w_j^2)(式⑥)
Ω(ft)=γT+λ.21j=1∑T(wj2)(式⑥)
3.4目标函数化简
将式⑤⑥代入式④中,可得目标函数为:
J
(
f
t
)
=
∑
i
=
1
n
[
g
i
w
q
(
x
i
)
+
1
2
h
i
w
q
2
(
x
i
)
]
+
λ
.
1
2
∑
j
=
1
T
(
w
j
2
)
+
γ
T
+
c
o
n
s
t
J(f_t)=\sum_{i=1}^{n}[g_iw_q(x_i)+\frac{1}{2}h_iw_q^2(x_i)]+\lambda.\frac{1}{2}\sum_{j=1}^{T}(w_j^2)+\gamma T+const
J(ft)=i=1∑n[giwq(xi)+21hiwq2(xi)]+λ.21j=1∑T(wj2)+γT+const
=
∑
j
=
1
T
[
(
∑
i
ϵ
I
j
g
i
)
w
j
+
1
2
(
∑
i
ϵ
I
j
h
i
)
w
j
2
]
+
λ
.
1
2
∑
j
=
1
T
(
w
j
2
)
+
γ
T
+
c
o
n
s
t
=\sum_{j=1}^{T}[(\sum_{i\epsilon I_j }{g_i})w_j+\frac{1}{2}(\sum_{i\epsilon I_j }h_i)w_j^2]+\lambda.\frac{1}{2}\sum_{j=1}^{T}(w_j^2)+\gamma T+const
=j=1∑T[(iϵIj∑gi)wj+21(iϵIj∑hi)wj2]+λ.21j=1∑T(wj2)+γT+const
=
∑
j
=
1
T
[
(
∑
i
ϵ
I
j
g
i
)
w
j
+
1
2
(
∑
i
ϵ
I
j
h
i
)
w
j
2
]
+
λ
.
1
2
∑
j
=
1
T
(
w
j
2
)
+
γ
T
+
c
o
n
s
t
=\sum_{j=1}^{T}[(\sum_{i\epsilon I_j }{g_i})w_j+\frac{1}{2}(\sum_{i\epsilon I_j }h_i)w_j^2]+\lambda.\frac{1}{2}\sum_{j=1}^{T}(w_j^2)+\gamma T+const
=j=1∑T[(iϵIj∑gi)wj+21(iϵIj∑hi)wj2]+λ.21j=1∑T(wj2)+γT+const
=
∑
j
=
1
T
[
(
∑
i
ϵ
I
j
g
i
)
w
j
+
1
2
(
∑
i
ϵ
I
j
h
i
+
λ
)
w
j
2
]
+
γ
T
+
c
o
n
s
t
=\sum_{j=1}^{T}[(\sum_{i\epsilon I_j }{g_i})w_j+\frac{1}{2}(\sum_{i\epsilon I_j }h_i+\lambda)w_j^2]+\gamma T+const
=j=1∑T[(iϵIj∑gi)wj+21(iϵIj∑hi+λ)wj2]+γT+const
我们定义
G
j
=
(
∑
i
ϵ
I
j
g
i
)
G_j=(\sum_{i\epsilon I_j }{g_i})
Gj=(∑iϵIjgi),
H
j
=
(
∑
i
ϵ
I
j
h
i
)
H_j=(\sum_{i\epsilon I_j }{h_i})
Hj=(∑iϵIjhi)
则目标函数则最终化简为:
J
(
f
t
)
=
∑
j
=
1
T
[
G
j
w
j
+
1
2
(
H
j
+
λ
)
w
j
2
]
+
γ
T
+
c
o
n
s
t
(
式
⑦
)
J(f_t)=\sum_{j=1}^{T}[G_jw_j+\frac{1}{2}(H_j+\lambda)w_j^2]+\gamma T+const(式⑦)
J(ft)=j=1∑T[Gjwj+21(Hj+λ)wj2]+γT+const(式⑦)
3.5 目标函数的优化
我们要让目标函数最小,那么只要让目标函数关于
w
j
w_j
wj的偏导为0即可,
因此
∂
J
(
f
t
)
∂
w
j
=
G
j
+
(
H
j
+
λ
)
w
j
=
0
\frac{\partial{J(f_t)}}{\partial{{w_j}}}=G_j+(H_j+\lambda)w_j=0
∂wj∂J(ft)=Gj+(Hj+λ)wj=0
则
w
j
=
−
G
j
H
j
+
λ
(
式
⑧
)
w_j=- \frac{G_j}{H_j+\lambda}(式⑧)
wj=−Hj+λGj(式⑧)
将式⑧代入式⑦,化简目标函数,最终为
J
(
f
t
)
=
−
1
2
∑
j
=
1
T
(
G
j
2
H
j
+
λ
)
+
γ
T
(
式
⑨
)
J(f_t)=- \frac{1}{2}\sum_{j=1}^{T}( \frac{G_j^2}{H_j+\lambda})+\gamma T(式⑨)
J(ft)=−21j=1∑T(Hj+λGj2)+γT(式⑨)
四、推导的公式在做什么
目标函数表示了这棵树的结构有多好,值越小,代表这样结构越好!也就是说,它是衡量第t棵CART树的结构好坏的标准。注意注意注意~,这个值仅仅是用来衡量结构的好坏的,与叶子节点的值可是无关的。为什么?请再仔细看一下obj的推导过程。obj只和Gj和Hj和T有关,而它们又只和树的结构(q(x))有关,与叶子节点的值可是半毛关系没有。
五.找出最优的树结构
好了,有了评判树的结构好坏的标准,我们就可以先求最佳的树结构,这个定出来后,最佳的叶子结点的值实际上在上面已经求出来了。
问题是:树的结构近乎无限多,一个一个去测算它们的好坏程度,然后再取最好的显然是不现实的。所以,我们仍然需要采取一点策略,这就是逐步学习出最佳的树结构。这与我们将K棵树的模型分解成一棵一棵树来学习是一个道理,只不过从一棵一棵树变成了一层一层节点而已。如果此时你还是有点蒙,没关系,下面我们就来看一下具体的学习过程。
我们以上文提到过的判断一个人是否喜欢计算机游戏为例子。最简单的树结构就是一个节点的树。我们可以算出这棵单节点的树的好坏程度obj*。假设我们现在想按照年龄将这棵单节点树进行分叉,我们需要知道:
1、按照年龄分是否有效,也就是是否减少了obj的值
2、如果可分,那么以哪个年龄值来分。
为了回答上面两个问题,我们可以将这一家五口人按照年龄做个排序。如下图所示:
按照这个图从左至右扫描,我们就可以找出所有的切分点。对每一个确定的切分点,我们衡量切分好坏的标准如下:
这个Gain实际上就是单节点的obj减去切分后的两个节点的树obj,Gain如果是正的,并且值越大,表示切分后obj越小于单节点的obj,就越值得切分。同时,我们还可以观察到,Gain的左半部分如果小于右侧的γ,则Gain就是负的,表明切分后obj反而变大了。γ在这里实际上是一个临界值,它的值越大,表示我们对切分后obj下降幅度要求越严。这个值也是可以在xgboost中设定的。
扫描结束后,我们就可以确定是否切分,如果切分,对切分出来的两个节点,递归地调用这个切分过程,我们就能获得一个相对较好的树结构。
注意:xgboost的切分操作和普通的决策树切分过程是不一样的。普通的决策树在切分的时候并不考虑树的复杂度,而依赖后续的剪枝操作来控制。xgboost在切分的时候就已经考虑了树的复杂度,就是那个γ参数。所以,它不需要进行单独的剪枝操作。
六、大功告成
最优的树结构找到后,确定最优的叶子节点就很容易了。我们成功地找出了第t棵树!撒花!!!