1.XGBoost算法原理
XGBoost(Extreme Gradient Boosting)全名极端梯度提升树,在绝大多数回归和分类问题上表现突出,因此,在集成算法中,XGBoost是公认的王牌算法。
最优模型构建方法
通过之前的算法学习,我们知道:一般构建最优算法模型,其实就是最小化训练数据的损失函数,我们用字母L表示损失,如下式:
min
f
∈
F
1
N
∑
i
=
1
N
L
(
y
i
,
f
(
x
i
)
)
\min _{f \in F} \ \ \ \frac{1}{N} \sum_{i=1}^{N} L\left(y_{i}, f\left(x_{i}\right)\right)
f∈Fmin N1i=1∑NL(yi,f(xi))
预测值和真实值经过函数计算出损失,并求出所有函数的平均损失,使得损失最小。上面的式子叫经验风险最小化,训练得到的模型复杂度较高,很容易出现过拟合现象。因此,为了降低模型复杂度,通常采用下式:
min
f
∈
F
1
N
∑
i
=
1
N
L
(
y
i
,
f
(
x
i
)
)
+
Ω
J
(
f
)
\min _{f \in F} \ \ \ \frac{1}{N} \sum_{i=1}^{N} L\left(y_{i}, f\left(x_{i}\right)\right)+\Omega J(f)
f∈Fmin N1i=1∑NL(yi,f(xi))+ΩJ(f)
上面的式子叫结构风险最小化。结构风险最小化通常对训练集和未知的测试集有很好的预测性。
XGBoost生成决策树是结构风险最小化的结果
2.XGBoost目标函数推导
2.1 目标函数确定
目标函数,即损失函数,通过最小化损失函数构建最优模型。XGBoost是对梯度提升树的改进,并在损失函数中加入了正则化项。其目标函数如下:
obj
(
θ
)
=
∑
i
n
L
(
y
i
,
y
^
i
)
+
∑
k
=
1
K
Ω
(
f
k
)
\operatorname{obj}(\theta)=\sum_{i}^{n} L\left(y_{i}, \hat{y}_{i}\right)+\sum_{k=1}^{K} \Omega\left(f_{k}\right)
obj(θ)=i∑nL(yi,y^i)+k=1∑KΩ(fk)
目标函数第一项表示整个强学习器的损失函数,第二项表示强学习器中K个弱学习器的复杂度。
2.2 树的复杂度定义
2.2.1 每棵树的复杂度定义
XGBoost每一个弱学习器的复杂度由两方面考量:
Ω
(
f
)
=
γ
T
+
1
2
λ
∥
w
∥
2
\Omega(f)=\gamma T+\frac{1}{2} \lambda\|w\|^{2}
Ω(f)=γT+21λ∥w∥2
-
γT 中的 T 表示一棵树的叶子节点数量,一般来说,叶子节点数量越多,则树越高,越大,越复杂。γ是对该项的调节函数。
-
λ||w||2 中的 w 表示叶子节点输出值组成的向量,这一项考量的是弱学习器的预测值的复杂度。
-
比如:我们有两棵只有两个叶子结点的树,其中一个树的叶子结点值为:50、50,另一棵树的叶子结点值为:0、100,这两棵树我们应该怎么衡量呢?
-
第一棵树叶子结点组成的 w 向量为:(50, 50),其模的值为:5000,第二棵树为:(0, 100),其模的值为 1000,我们更强于选择叶子向量模较小的树,这是因为其值输出更为平稳一些。
-
2.2.2 树的复杂度举例
假设我们要预测一家人对电子游戏的喜好程度,考虑到年轻和年老相比,年轻更可能喜欢电子游戏,以及男性和女性相比,男性更喜欢电子游戏,故先根据年龄大小区分小孩和大人,然后再通过性别区分开是男是女,逐一给各人在电子游戏喜好程度上打分,如下图所示:
通过上述步骤,训练出两棵树tree1和tree2,同之前的GBDT原理,最终的结论就是两棵树结论加起来,因此可得:
- 小男孩的预测分数就是两棵树中小孩所落到的结点的分数相加:2 + 0.9 = 2.9。
- 爷爷的预测分数同理:-1 + 0.9 = -0.1。
如下图所示:
树的复杂度可表示为:
2.3 目标函数推导
2.3.1 目标问题转换
根据上述的目标函数的推导式:
o
b
j
(
t
)
=
∑
i
=
1
n
L
(
y
i
,
y
^
i
(
t
)
)
+
∑
k
=
1
t
Ω
(
f
k
)
o b j^{(t)}=\sum_{i=1}^{n} L\left(y_{i}, \hat{y}_{i}^{(t)}\right)+\sum_{k=1}^{t} \Omega\left(f_{k}\right)
obj(t)=i=1∑nL(yi,y^i(t))+k=1∑tΩ(fk)
可转化为前t-1次加上t次的目标函数:
o
b
j
(
t
)
=
∑
i
=
1
n
L
(
y
i
,
y
^
i
(
t
−
1
)
+
f
t
(
x
i
)
)
+
Ω
∑
k
=
1
t
−
1
(
f
k
)
+
Ω
(
f
t
)
obj^{(t)}=\sum_{i=1}^nL(y_i,\hat y_i^{(t-1)}+f_t(x_i))+\Omega \sum_{k=1}^{t-1}(f_k)+\Omega(f_t)
obj(t)=i=1∑nL(yi,y^i(t−1)+ft(xi))+Ωk=1∑t−1(fk)+Ω(ft)
-
Boosting 使用的加法模型。所以,强学习器的预测值 yi(t) 就等于:当前树预测值 ft(xi) 与前一棵树的预测值 yi(t-1) 的和 。
-
我们正则化部分也变成了当前树的复杂度 Ω(ft) 和前面所有树的复杂度之和。
2.3.2 泰勒公式展开
泰勒公式二阶导公式:
f
(
x
0
+
Δ
x
)
≈
f
(
x
0
)
+
f
′
(
x
0
)
⋅
Δ
x
+
1
2
f
′
′
(
x
0
)
⋅
(
Δ
x
)
2
f(x_0+\Delta x)\approx f(x_0)+f'(x_0)\cdot \Delta x+\frac{1}{2}f''(x_0)\cdot(\Delta x)^2
f(x0+Δx)≈f(x0)+f′(x0)⋅Δx+21f′′(x0)⋅(Δx)2
因此,目标函数可转化为:
o
b
j
(
t
)
≈
∑
i
=
1
m
[
L
(
y
i
,
y
^
i
(
t
−
1
)
)
+
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
]
+
∑
k
=
1
t
−
1
Ω
(
f
k
)
+
Ω
(
f
t
)
o b j^{(t)} \approx \sum_{i=1}^{m}\left[L\left(y_{i}, \hat{y}_{i}^{(t-1)}\right)+g_{i} f_{t}\left(x_{i}\right)+\frac{1}{2} h_{i} f_{t}^{2}\left(x_{i}\right)\right]+\sum_{k=1}^{t-1} \Omega\left(f_{k}\right)+\Omega\left(f_{t}\right)
obj(t)≈i=1∑m[L(yi,y^i(t−1))+gift(xi)+21hift2(xi)]+k=1∑t−1Ω(fk)+Ω(ft)
其中,gi 和 hi 的分别为损失函数的一阶导、二阶导:
g
i
=
∂
y
^
t
−
1
L
(
y
i
,
y
^
(
t
−
1
)
)
h
i
=
∂
y
^
(
t
−
1
)
2
L
(
y
i
,
y
^
(
t
−
1
)
)
\begin{array}{l} g_{i}=\partial_{\hat{y}^{t-1}} L\left(y_{i}, \hat{y}^{(t-1)}\right) \\ \\ h_{i}=\partial_{\hat{y}^{(t-1)}}^{2} L\left(y_{i}, \hat{y}^{(t-1)}\right) \end{array}
gi=∂y^t−1L(yi,y^(t−1))hi=∂y^(t−1)2L(yi,y^(t−1))
2.3.3 化简目标函数
通过观察目标函数,发现以下两项都是常数项,可以去掉:
为什么说是常数项呢?这是因为当前学习器之前的学习器都已经训练完了,可以直接通过样本得出结果。化简之后的结果为:
o
b
j
(
t
)
≈
∑
i
=
1
m
[
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
]
+
Ω
(
f
t
)
o b j^{(t)} \approx \sum_{i=1}^{m}\left[g_{i} f_{t}\left(x_{i}\right)+\frac{1}{2} h_{i} f_{t}^{2}\left(x_{i}\right)\right]+\Omega\left(f_{t}\right)
obj(t)≈i=1∑m[gift(xi)+21hift2(xi)]+Ω(ft)
我们再将 Ω(ft) 展开,结果如下:
o
b
j
(
t
)
≈
∑
i
=
1
m
[
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
]
+
γ
T
+
1
2
λ
∥
w
∥
2
o b j^{(t)} \approx \sum_{i=1}^{m}\left[g_{i} f_{t}\left(x_{i}\right)+\frac{1}{2} h_{i} f_{t}^{2}\left(x_{i}\right)\right]+\gamma T+\frac{1}{2} \lambda\|w\|^{2}
obj(t)≈i=1∑m[gift(xi)+21hift2(xi)]+γT+21λ∥w∥2
2.3.4 再次问题转换
我们再次理解公式表示的含义:
- gi表示每个样本的一阶导数,hi表示每个样本的二阶导数
- ft(xi)表示样本的预测值
- T表示叶子节点的数目
- ||w||2表示由叶子节点值组成向量的模
现在,我们发现公式的各部分考虑的角度不同,有的从样本角度来看,例如 ft(xi),有的从叶子节点的角度来看,例如T,||w||2。我们要将转换为相同的角度,这样方便下一步合并、化简公式。下面我们统一从叶子节点的角度进行转换:
例如:10个样本,落在D节点的有3个,落在E节点的有2个,落在F节点的有2个,落在G节点的有3个
-
D 结点计算: w1 * gi1 + w1 * gi2 + w1 * gi3 = (gi1 + gi2 + gi3) * w1
-
E 结点计算: w2 * gi4 + w2* gi5 = (gi4 + gi5) * w2
-
F 结点计算: w3 * gi6 + w3 * gi6 = (gi6 + gi7) * w3
-
G 节点计算:w4 * gi8 + w4 * gi9 + w4* gi10 = (gi8 + gi9 + gi10) * w4
gi ft(xi) 可以转换为如下形式:
∑
i
=
1
m
g
i
f
t
(
x
i
)
=
∑
j
=
1
T
(
∑
i
∈
I
j
g
i
)
w
j
\sum_{i=1}^{m} g_{i} f_{t}\left(x_{i}\right)=\sum_{j=1}^{T}\left(\sum_{i \in I_{j}} g_{i}\right) w_{j}
i=1∑mgift(xi)=j=1∑T⎝⎛i∈Ij∑gi⎠⎞wj
-
wj 表示第 j 个叶子结点的值
-
gi 表示每个样本的一阶导
hift2(xi) 从叶子结点的问题,转换如下:
∑
i
=
1
m
1
2
h
i
f
t
2
(
x
i
)
=
1
2
∑
j
=
1
T
(
∑
i
∈
I
j
h
i
)
w
j
2
\sum_{i=1}^{m} \frac{1}{2} h_{i} f_{t}^{2}\left(x_{i}\right)=\frac{1}{2} \sum_{j=1}^{T}\left(\sum_{i \in I_{j}} h_{i}\right) w_{j}{ }^{2}
i=1∑m21hift2(xi)=21j=1∑T⎝⎛i∈Ij∑hi⎠⎞wj2
λ||w||2 由于本身就是从叶子角度来看,我们将其转换一种表示形式:
1
2
λ
∣
∣
w
∥
2
=
1
2
λ
∑
i
=
1
T
w
i
2
\frac{1}{2} \lambda|| w \|^{2}=\frac{1}{2} \lambda \sum_{i=1}^{T} w_{i}{ }^{2}
21λ∣∣w∥2=21λi=1∑Twi2
通过以上替换,我们重新整理公式为:
o
b
j
(
t
)
=
∑
j
=
1
m
(
g
j
f
t
(
x
j
)
+
1
2
h
j
f
t
2
(
x
j
)
)
+
γ
T
+
1
2
λ
∣
∣
w
∣
∣
2
o
b
j
(
t
)
=
∑
j
=
1
T
[
(
∑
i
∈
I
j
g
i
)
w
i
+
1
2
(
∑
i
∈
I
j
h
i
)
w
j
2
]
+
γ
T
+
1
2
λ
∑
i
=
1
T
w
j
2
o
b
j
(
t
)
=
s
u
m
j
=
1
T
[
(
∑
i
∈
I
j
g
i
)
w
j
+
1
2
(
∑
i
∈
I
j
h
i
)
w
j
2
+
1
2
λ
w
j
2
]
+
γ
T
o
b
j
(
t
)
=
∑
j
=
1
T
[
(
∑
i
∈
I
j
g
i
)
w
j
+
1
2
(
∑
i
∈
I
j
h
i
+
λ
)
w
j
2
]
+
γ
T
obj^{(t)}=\sum_{j=1}^{m}\left(g_jf_t(x_j)+\frac{1}{2}h_jf_t^2(x_j)\right)+\gamma T+\frac{1}{2}\lambda ||w||^2 \\ \\ \\ obj^{(t)}=\sum_{j=1}^T \left[\left(\sum_{i\in I_j}g_i\right)w_i+\frac{1}{2}\left(\sum_{i\in I_j}h_i\right)w_j^2 \right] +\gamma T+\frac{1}{2}\lambda \sum_{i=1}^{T} w_{j}{ }^{2} \\ \\ \\obj^{(t)} = sum_{j=1}^{T}\left[\left(\sum_{i \in I_{j}} g_{i}\right) w_{j}+\frac{1}{2}\left(\sum_{i \in I_{j}} h_{i}\right) w_{j}^{2}+\frac{1}{2} \lambda w_{j}^{2}\right]+\gamma T \\ \\ \\obj^{(t)} =\sum_{j=1}^{T}\left[\left(\sum_{i \in I_{j}} g_{i}\right) w_{j}+\frac{1}{2}\left(\sum_{i \in I_{j}} h_{i}+\lambda\right) w_{j}^{2}\right]+\gamma T
obj(t)=j=1∑m(gjft(xj)+21hjft2(xj))+γT+21λ∣∣w∣∣2obj(t)=j=1∑T⎣⎡⎝⎛i∈Ij∑gi⎠⎞wi+21⎝⎛i∈Ij∑hi⎠⎞wj2⎦⎤+γT+21λi=1∑Twj2obj(t)=sumj=1T⎣⎡⎝⎛i∈Ij∑gi⎠⎞wj+21⎝⎛i∈Ij∑hi⎠⎞wj2+21λwj2⎦⎤+γTobj(t)=j=1∑T⎣⎡⎝⎛i∈Ij∑gi⎠⎞wj+21⎝⎛i∈Ij∑hi+λ⎠⎞wj2⎦⎤+γT
我们令:
G
i
=
∑
i
∈
I
j
g
i
H
i
=
∑
i
∈
I
j
h
i
G_i=\sum_{i\in I_j}g_i \\ \\H_i=\sum_{i\in I_j}h_i
Gi=i∈Ij∑giHi=i∈Ij∑hi
Gi表示所有样本的一阶导之和,Hi表示所有样本的二阶导之和,当确定损失函数时,我们可以通过计算得到结果。
因此,公式可以转化为:
o
b
j
(
t
)
=
∑
i
=
1
T
[
G
i
w
j
+
1
2
(
H
i
+
λ
)
w
i
2
]
+
γ
T
obj^{(t)}=\sum_{i=1}^T\left[G_iw_j+\frac{1}{2}\left(H_i+\lambda\right)w_i^2\right]+\gamma T
obj(t)=i=1∑T[Giwj+21(Hi+λ)wi2]+γT
2.3.5 对叶子节点求导
此时,公式可以看作是关于叶子节点w的一元二次函数,对w求导并令其等于0,可得到w的最优值:
w
i
=
−
G
i
H
i
+
λ
w_i=-\frac{G_i}{H_i+\lambda}
wi=−Hi+λGi
将wj代入到公式中,可得:
o
b
j
(
t
)
=
∑
i
=
1
T
[
G
i
(
−
G
i
H
i
+
λ
)
+
1
2
(
H
i
+
λ
)
(
−
G
i
H
i
+
λ
)
2
]
+
γ
T
o
b
j
(
t
)
=
∑
i
=
1
T
[
(
−
G
i
2
H
i
+
λ
)
+
1
2
(
−
G
i
2
H
i
+
λ
)
]
+
γ
T
o
b
j
(
t
)
=
−
1
2
∑
i
=
1
T
(
G
i
2
H
i
+
λ
)
+
γ
T
obj^{(t)} =\sum_{i=1}^{T}\left[G_{i}\left(-\frac{G_{i}}{H_{i}+\lambda}\right)+\frac{1}{2}\left(H_{i}+\lambda\right)\left(-\frac{G_{i}}{H_{i}+\lambda}\right)^{2}\right]+\gamma T \\ \\ \\obj^{(t)}=\sum_{i=1}^T\left[\left(-\frac{G_i^2}{H_i+\lambda}\right)+\frac{1}{2}\left(-\frac{G_i^2}{H_i+\lambda}\right)\right]+\gamma T \\ \\obj^{(t)}=-\frac{1}{2}\sum_{i=1}^T\left(\frac{G_i^2}{H_i+\lambda}\right)+\gamma T
obj(t)=i=1∑T[Gi(−Hi+λGi)+21(Hi+λ)(−Hi+λGi)2]+γTobj(t)=i=1∑T[(−Hi+λGi2)+21(−Hi+λGi2)]+γTobj(t)=−21i=1∑T(Hi+λGi2)+γT
该公式也叫打分函数(scoring function),它可以从树的损失函数,树的复杂度两个角度来衡量一棵树的优劣。
3.XGBoost的回归树构建方法
当我们构建回归树的时候,可以用来选择树的最佳划分点:
Gain
=
O
b
j
L
+
R
−
(
O
b
j
L
+
O
b
j
R
)
=
[
−
1
2
(
G
L
+
G
R
)
2
H
L
+
H
R
+
λ
+
γ
T
]
−
[
−
1
2
(
G
L
2
H
L
+
λ
+
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
+
λ
]
−
γ
\begin{aligned} \text { Gain } &=O b j_{L+R}-\left(O b j_{L}+O b j_{R}\right) \\ &=\left[-\frac{1}{2} \frac{\left(G_{L}+G_{R}\right)^{2}}{H_{L}+H_{R}+\lambda}+\gamma T\right]-\left[-\frac{1}{2}\left(\frac{G_{L}^{2}}{H_{L}+\lambda}+\frac{G_{R}^{2}}{H_{R}+\lambda}\right)+\gamma(T+1)\right] \\ &=\frac{1}{2}\left[\frac{G_{L}^{2}}{H_{L}+\lambda}+\frac{G_{R}^{2}}{H_{R}+\lambda}-\frac{\left(G_{L}+G_{R}\right)^{2}}{H_{L}+H_{R}+\lambda}\right]-\gamma \end{aligned}
Gain =ObjL+R−(ObjL+ObjR)=[−21HL+HR+λ(GL+GR)2+γT]−[−21(HL+λGL2+HR+λGR2)+γ(T+1)]=21[HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2]−γ
其过程如下:
- 对树中的每个叶子节点尝试进行分裂
- 计算分裂前-分类后的分数:
- 如果分数>0,则分列之后分树的结构损失更小,进行此次分裂
- 如果分数<0,说明分裂后的分数比分裂前的分数大,不进行分裂
- 当触发以下条件时停止分裂:
- 达到最大深度
- 叶子节点数量低于某个阈值
- 所有的节点再分裂不能降低损失
XGBoost还可以通过降低叶子节点的输出值的贡献,以便能够训练出更多的基学习器。
4.XGBoost和GBDT的区别
- 区别一:
- XGBoost生成树时考虑了树的复杂度
- GBDT未考虑,GBDT在树的剪枝步骤中考虑了树的复杂度
- 区别二:
- XGBoost拟合上一轮损失函数的二阶导展开,GBDT拟合上一轮损失函数的一阶导展开,因此,XGBoost的准确性更高,且满足相同的训练效果,需要迭代的次数更少。
- 区别三
- XGBoost和GBDT都是逐次迭代来提高模型的性能,但是XGBoost在最佳切分点时可以开启多线程进行,大大提高了运行的速度。