梯度提升树
梯度提升树是一种集成学习方法率属于Boosting家族,本质基于回归树。通过构造多个弱学习器为基学习器,结果累加作为输出。
一、原理
训练的时候采用前向分步算法,首先确定第一棵树拟合的结果,然后基于之前所有的树的误差来进行更新并且训练下一棵树,逐步迭代直至模型构建完毕。在训练时候,我们可以首先确定初始提升树为:
f
(
x
)
=
0
f(x)=0
f(x)=0
然后在后续训练时第m步骤的模型就是:
f
m
(
x
)
=
f
m
−
1
(
x
)
+
T
(
x
;
θ
m
)
f_m(x)=f_{m-1}(x)+T(x;\theta_m)
fm(x)=fm−1(x)+T(x;θm)
其中, f m − 1 ( x ) f_{m-1}(x) fm−1(x)是当前模型,通过经验风险最小化确定下一棵树的参数 θ m \theta_m θm
其中, θ m = a r g m i n ∑ i = 1 N L ( y i , f m − 1 ( x i ) + T ( x ; θ m ) ) \theta_m=argmin\sum_{i=1}^{N}\mathfrak{L}(y_i,f_{m-1}(x_i)+T(x;\theta_m)) θm=argmini=1∑NL(yi,fm−1(xi)+T(x;θm))
那么我们就可以使用梯度下降法对上式进行求解,并且得到梯度提升树的算法。
二、算法
输入:训练数据集为
T
=
{
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
.
.
.
,
(
x
N
,
y
N
)
}
,
x
1
∈
X
⊆
R
n
,
y
1
∈
Y
⊆
R
n
;
损
失
函
数
为
C
o
s
t
(
y
,
f
(
x
)
)
.
T = \{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\},x_1\in\mathcal{X}\subseteq{R^n},y_1\in\mathcal{Y}\subseteq{R^n};损失函数为Cost(y,f(x)).
T={(x1,y1),(x2,y2),...,(xN,yN)},x1∈X⊆Rn,y1∈Y⊆Rn;损失函数为Cost(y,f(x)).
输出:回归树
f
^
(
x
)
\widehat{f}(x)
f
(x)。
(1)初始化:
f
0
(
x
)
=
a
r
g
m
i
n
∑
i
=
1
N
L
(
y
i
,
c
)
f_0(x)=argmin\sum_{i=1}^{N}\mathfrak{L}(y_i,c)
f0(x)=argmini=1∑NL(yi,c)
(2)对于 m = 1 , 2 , . . . , M m=1,2,...,M m=1,2,...,M
a.对于
i
=
1
,
2
,
.
.
.
,
N
i=1,2,...,N
i=1,2,...,N,计算:
γ
m
i
=
−
[
∂
L
(
y
i
,
f
(
x
i
)
)
∂
f
(
x
i
)
]
f
(
x
)
=
f
m
−
1
(
x
)
\gamma_{mi}=-{[\cfrac{\partial\mathfrak{L}(y_i,f(x_i))}{\partial{f(x_i)}}]}_{f(x)=f_m-1(x)}
γmi=−[∂f(xi)∂L(yi,f(xi))]f(x)=fm−1(x)
b.对 γ m i \gamma_{mi} γmi拟合一个回归树,得到第 m m m棵树的叶节点区域 R m j , j = 1 , 2 , . . . , J R_{mj},j=1,2,...,J Rmj,j=1,2,...,J;
c.对 j = 1 , 2 , . . . , J j=1,2,...,J j=1,2,...,J,计算: c m j = = a r g m i n c ∑ x i ∈ R m j L ( y i , f m − 1 ( x i ) + c ) c_{mj}==argmin_{c}\sum_{x_i\in{R_{mj}}}L(y_i,f_{m-1}(x_i)+c) cmj==argmincxi∈Rmj∑L(yi,fm−1(xi)+c)
d.得到回归树: f ^ ( x ) = f M ( x ) = ∑ m = 1 M ∑ j = 1 J c m j I ( x ∈ R m j ) \widehat{f}(x)=f_M(x)=\sum_{m=1}^{M}\sum_{j=1}^{J}c_{mj}I(x\in{R_{mj}}) f (x)=fM(x)=m=1∑Mj=1∑JcmjI(x∈Rmj)
接下来介绍XGBoost,这是梯度提升树非常优秀的实现。
三、XGBoost 和GBDT的效果区别?是什么原因导致了这个区别
XGBoost的精度要比GBDT高而且效率也要高。我认为精度高的最大原因是大部分的CTR特征中,我们会将一些高基类别的离散值转化为连续值,会产生很多含有缺失值的稀疏特征,而XGBoost会对缺失值做一个特殊的处理。效率高是因为建树时采用了更好的分割点估计算法。
Xgboost是GBDT算法的一种很好的工程实现,并且在算法上做了一些优化,主要的优化在一下几点。首先Xgboost加了一个衰减因子,相当于一个学习率,可以减少加进来的树对于原模型的影响,让树的数量变得更多;其次是在原GBDT模型上加了个正则项,对于树的叶子节点的权重做了一个约束;还有增加了在随机森林上常用的col subsample的策略;然后使用二阶泰勒展开去拟合损失函数,加快优化的效率;然后最大的地方在于不需要遍历所有可能的分裂点了,它提出了一种估计分裂点的算法。在工程上做了一个算法的并发实现,具体我并不了解如何实现的。
四、XGBoost对缺失值的处理?
在普通的GBDT策略中,对于缺失值的方法是先手动对缺失值进行填充,然后当做有值的特征进行处理,但是这样人工填充不一定准确,而且没有什么理论依据。而Xgboost采取的策略是先不处理那些值缺失的样本,采用那些有值的样本搞出分裂点,然后在遍历每个分裂点的时候,尝试将缺失样本划入左子树和右子树,选择使损失最优的情况。
五、XGBoost数学原理:
XGBoost 是由
k
k
k个基模型组成的一个加法运算式:
y
^
i
=
∑
t
=
1
k
f
t
(
x
i
)
\widehat{y}_{i}=\sum_{t=1}^{k}f_t(x_i)
y
i=t=1∑kft(xi)
其中,
f
k
f_k
fk为第
k
k
k个基模型,
y
^
i
\widehat{y}_{i}
y
i为第
i
i
i个样本的预测值。损失函数可以由预测值
y
^
i
\widehat{y}_i
y
i和真实值
y
i
y_i
yi进行表示:具体如下:
L
=
∑
i
=
1
n
ℓ
(
y
i
,
y
^
i
)
L=\sum_{i=1}^{n}\ell\left(y_i,{\hat{y}}_i\right)
L=i=1∑nℓ(yi,y^i)
其中
n
n
n为样本数量。模型的预测精度由模型的偏差和方差共同决定,损失函数代表了模型的偏差,想要方差小则需要简单的模型,所以目标函数由模型的损失函数
ℓ
\ell
ℓ 与抑制模型复杂度的正则项
Ω
\Omega
Ω组成,所以有:
O
b
j
=
∑
i
=
1
n
ℓ
(
y
i
,
y
^
i
)
+
∑
t
=
1
k
Ω
(
f
t
)
Obj=\sum_{i=1}^{n}\ell\left(y_i,{\hat{y}}_i\right)+\sum_{t=1}^{k}\Omega\left(f_t\right)
Obj=i=1∑nℓ(yi,y^i)+t=1∑kΩ(ft)
其中
Ω
\Omega
Ω为模型的正则项,用于抑制模型的复杂度。同时boosting模型是前向加法,以第
t
t
t步的模型为例,模型对第
i
i
i个样本
x
i
x_i
xi的预测为:
y
^
i
t
=
y
^
i
t
−
1
+
f
t
(
x
i
)
{\hat{y}}_i^t={\hat{y}}_i^{t-1}+f_t\left(x_i\right)
y^it=y^it−1+ft(xi)
其中,
y
^
i
t
−
1
{\hat{y}}_i^{t-1}
y^it−1是由第
t
−
1
t-1
t−1步的模型给出的预测值,是已知常数,
f
t
(
x
i
)
f_t\left(x_i\right)
ft(xi)是这次要加入的新模型的预测值,此时目标函数就可以写成:
O
b
j
t
=
∑
i
=
1
n
ℓ
(
y
i
,
y
^
i
t
)
+
∑
i
=
1
t
Ω
(
f
i
)
=
∑
i
=
1
n
ℓ
(
y
i
,
y
^
i
t
−
1
+
f
t
(
x
i
)
)
+
∑
i
=
1
t
Ω
(
f
i
)
Obj^t=\sum_{i=1}^{n}\ell\left(y_i,{\hat{y}}_i^t\right)+\sum_{i=1}^{t}\Omega\left(f_i\right) =\sum_{i=1}^{n}\ell\left(y_i,{\hat{y}}_i^{t-1}+f_t\left(x_i\right)\right)+\sum_{i=1}^{t}\Omega\left(f_i\right)
Objt=i=1∑nℓ(yi,y^it)+i=1∑tΩ(fi)=i=1∑nℓ(yi,y^it−1+ft(xi))+i=1∑tΩ(fi)
求此时最优化目标函数,就相当于求解
f
t
(
x
i
)
f_t\left(x_i\right)
ft(xi)。
泰勒公式是将一个在
x
=
x
0
x=x_0
x=x0处具有
n
n
n阶导数的函数
f
(
x
)
f\left(x\right)
f(x)利用关于
x
−
x
0
x-x_0
x−x0的
n
n
n次多项式来逼近函数的方法。如若函数
f
(
x
)
f\left(x\right)
f(x)在包含
x
0
x_0
x0的某个闭区间
[
a
,
b
]
[a,b]
[a,b]上具有
n
n
n阶导数,且在开区间
(
a
,
b
)
\left(a,b\right)
(a,b)上具有
n
+
1
n+1
n+1阶导数,则对于闭区间
[
a
,
b
]
\left[a,b\right]
[a,b]上任意一点
x
x
x有:
f
(
x
)
=
∑
i
=
0
n
f
(
i
)
x
0
i
!
(
x
−
x
0
)
i
+
R
n
(
x
)
f\left(x\right)=\sum_{i=0}^{n}\frac{f^{\left(i\right)}x_0}{i!}\left(x-x_0\right)^i+R_n\left(x\right)
f(x)=i=0∑ni!f(i)x0(x−x0)i+Rn(x)
其中的多项式称之为函数在
x
0
x_0
x0处的泰勒展开式,
R
n
(
x
)
R_n\left(x\right)
Rn(x)是泰勒公式的余项而且是
(
x
−
x
0
)
n
\left(x-x_0\right)^n
(x−x0)n的高阶无穷小。
根据泰勒公式,将函数
f
(
x
+
Δ
x
)
f\left(x+\Delta x\right)
f(x+Δx)在
x
x
x处进行泰勒的二阶展开,得到等式如下:
f
(
x
+
Δ
x
)
≈
f
(
x
)
+
f
′
(
x
)
Δ
x
+
1
2
f
′
′
(
x
)
Δ
x
2
f\left(x+\Delta x\right)\approx f\left(x\right)+f^\prime(x)\Delta x+\frac{1}{2}f^{\prime\prime}\left(x\right)\Delta x^2
f(x+Δx)≈f(x)+f′(x)Δx+21f′′(x)Δx2
这里将
y
^
i
t
−
1
{\hat{y}}_i^{t-1}
y^it−1视为
x
x
x,同时将
f
t
(
x
i
)
f_t\left(x_i\right)
ft(xi)视为
Δ
x
\Delta x
Δx,则可以将目标函数写成:
O
b
j
(
t
)
=
∑
i
=
1
n
[
ℓ
(
y
i
,
y
^
i
t
−
1
)
+
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
+
∑
i
=
1
t
Ω
(
f
i
)
]
Obj^{\left(t\right)}=\sum_{i=1}^{n}\left[\ell\left(y_i,{\hat{y}}_i^{t-1}\right)+g_if_t{(x}_i)+\frac{1}{2}h_if_t^2\left(x_i\right)+\sum_{i=1}^{t}\Omega\left(f_i\right)\right]
Obj(t)=i=1∑n[ℓ(yi,y^it−1)+gift(xi)+21hift2(xi)+i=1∑tΩ(fi)]
其中,
g
i
g_i
gi为损失函数的一阶导数,
h
i
h_i
hi为损失函数的二阶导数,这里的求导是对
y
^
i
t
−
1
{\hat{y}}_i^{t-1}
y^it−1求导。
这里以平方损失函数为例:
∑
i
=
1
n
(
y
i
−
(
y
^
i
t
−
1
+
f
t
(
x
i
)
)
)
2
{\sum_{i=1}^{n}\left(y_i-\left({\hat{y}}_i^{t-1}+f_t\left(x_i\right)\right)\right)}^2
i=1∑n(yi−(y^it−1+ft(xi)))2
一阶导数为,二阶导数分别为:
g
i
=
∂
(
y
^
i
t
−
1
−
y
i
)
2
∂
y
^
i
t
−
1
=
2
(
y
^
i
t
−
1
−
y
i
)
g_i=\frac{\partial\left({\hat{y}}_i^{t-1}-y_i\right)^2}{\partial{\hat{y}}_i^{t-1}}\ =2\left({\hat{y}}_i^{t-1}-y_i\right)
gi=∂y^it−1∂(y^it−1−yi)2 =2(y^it−1−yi)
h
i
=
∂
g
i
∂
y
^
i
t
−
1
=
2
h_i=\frac{\partial g_i}{\partial{\hat{y}}_i^{t-1}}=2
hi=∂y^it−1∂gi=2
由于在第
t
t
t步的时候,
y
^
i
t
−
1
{\hat{y}}_i^{t-1}
y^it−1其实已经是已知的,所以
ℓ
(
y
i
,
y
^
i
t
−
1
)
\ell\left(y_i,{\hat{y}}_i^{t-1}\right)
ℓ(yi,y^it−1)是一个常数,它对于函数的优化不会产生影响,所以进一步可以将目标函数写成:
O
b
j
(
t
)
≈
∑
i
=
1
n
[
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
+
∑
i
=
1
t
Ω
(
f
i
)
]
Obj^{\left(t\right)}\approx\sum_{i=1}^{n}\left[g_if_t{(x}_i)+\frac{1}{2}h_if_t^2\left(x_i\right)+\sum_{i=1}^{t}\Omega\left(f_i\right)\right]
Obj(t)≈i=1∑n[gift(xi)+21hift2(xi)+i=1∑tΩ(fi)]
所以,只需要求出每一步损失函数的一阶导数和二阶导数的值(由于前一步的
y
^
i
t
−
1
{\hat{y}}_i^{t-1}
y^it−1已知,所以就这两个值是常数),最后优化目标函数,就可以得到每一步的
f
(
x
)
f\left(x\right)
f(x),再根据加法模型得到一个整体模型。