引言
自上节使用了随机森林与adaboost做了kaggle后,我便有一个问题,为什么对于泰坦尼克号来讲随进森林在其里面反而是最优的,同样是集成,为什么adaboost会稍微弱一筹呢?那么本篇,将在我理解的范围内,从理论上推导一下提升算法的过程。
梯度的概念
梯度可以说是一个方向,一个增长最快的方向,梯度的长度是这个最大的变化率.更严格的说,从欧氏空间Rn到R的函数的梯度是在Rn某一点最佳的线性近似.在这个意义上,梯度是雅戈比矩阵的一个特殊情况。而我们最常见的运用梯度的方式,或者就是梯度下降法和梯度下降法了。
梯度下降法是一种迭代算法,在给定初值
x
(
0
)
x^{(0)}
x(0)的情况下,不断迭代,更新
x
x
x的值,从而达到目标函数的极小化,但注意这里只能说明取到了极值,并不能说明拿到了全局最优解。梯度上升法类似,我们可以看下图:
上图不是一个凸函数,所以如果如果运用梯度,很容易陷入局部最优解,这里的收敛速度也很明显不是太快。而关于凸函数的例子,我们可以类比于高中学的二元一次方程,我们一般做法是求导,但不精确,这里我们还可以采用迭代的方式去获取极值,类似于下坡和爬坡,比如说下图:
取自百度图片,上面这张图可以看成是
y
=
x
2
−
2
x
y=x^{2}-2x
y=x2−2x的表达式曲线,那么我们下坡的过程的表达式就可以表示为:
x
i
+
1
=
x
i
−
a
∂
f
(
x
i
)
x
i
x_{i+1}=x_{i}-a\frac{\partial f(x_{i})}{x_{i}}
xi+1=xi−axi∂f(xi)
那么接下来就是如上图那样,小球一直往下滚,不断迭代,那么达到最低的时候,找到最优值。
下面再来复习一下线性回归和逻辑回归的梯度求解,线性回归的方向为:
逻辑回归的梯度方向为:
先在这里放着,不会的可以跳过去,等我有时间会写一个回归总结的。
提升(boosting)
提升是一个机器学习技术,可以用于回归和分类问题,它每一步产生一个弱预测模型,并加权累加到总模型中;如果每一步的弱预测模型生成都是依据损失函数的梯度方向,则称之为梯度提升(Gradient boosting)。可以类比于决策树,它可以看做一个预测模型,可我们并不知道它每一棵树具体的含义,可能是回归的,也可能是分类的,我们只有让它们不断去加权累加,让它逐步逼近于局部最小值,那么这个就可以叫做梯度提升算法。
-
给定输入向量x和输出变量y组成的若干训练样本 ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x n , y n ) (x_{1},y_{1}),(x_{2},y_{2}),...,(x_{n},y_{n}) (x1,y1),(x2,y2),...,(xn,yn),目标是找到近似函数 F ^ ( x ⃗ ) \hat{F}(\vec{x}) F^(x),使得损失函数 L ( y , F ( x ) ) L(y,F(x)) L(y,F(x))的损失值最小
-
L ( y , F ( x ) ) L(y,F(x)) L(y,F(x))的典型定义为:
L ( y , F ( x ⃗ ) ) = 1 2 ( y − F ( x ⃗ ) ) 2 L ( y , F ( x ⃗ ) ) = ∣ y − F ( x ⃗ ) ∣ \begin{matrix} L(y,F(\vec{x}))=\frac{1}{2}(y-F(\vec{x}))^{2} & \\ & \\ L(y,F(\vec{x}))= |y-F(\vec{x})| & \end{matrix} L(y,F(x))=21(y−F(x))2L(y,F(x))=∣y−F(x)∣ -
假定最优函数为 F ∗ ( x ⃗ ) F^{*}(\vec{x}) F∗(x),即:
F ∗ ( x ⃗ ) = a r g m i n F E ( x , y ) [ L ( y , F ( x ) ) ] F^{*}(\vec{x}) = \underset{F}{argmin}E_{(x,y)}[L(y,F(x))] F∗(x)=FargminE(x,y)[L(y,F(x))] -
假定 F ( x ) F(x) F(x)是一组基函数 f i ( x ) f_{i}(x) fi(x)的加权和
F ( x ⃗ ) = ∑ i = 1 M r i f i ( x ) + c o n s t F(\vec{x})=\sum_{i=1}^{M}r_{i}f_{i}(x)+const F(x)=i=1∑Mrifi(x)+const
上述关于 L ( y , F ( x ) ) L(y,F(x)) L(y,F(x))的两个损失函数并没有明确的区别与使用场景,具体情况具体分析,比如说我们上面的线性回归,可以看如下链接:
关于最优函数为 F ∗ ( x ⃗ ) F^{*}(\vec{x}) F∗(x)可以类比于Bayes等算法里的期望风险最小化,在样本空间中对目标函数求期望,当达到最优也就是最小时,F的值是多少。但是从理论角度来讲这个最优函数并不好算,所以我们转而求其次,利用 F ( x ) F(x) F(x)是由一组基函数 f i ( x ) f_{i}(x) fi(x)加权得到的,那么我们的目标也就从 F ( x ) F(x) F(x)转移到了 f i ( x ) f_{i}(x) fi(x)。
梯度提升(gradient boosting)
梯度提升(gradient boosting)算法最初是FreidMan在2000年提出来的,梯度提升算法首先给定一个目标损失函数,它的定义域是所有可行的弱函数集合;提升算法通过迭代的选择一个负梯度方向上的基函数来逐渐逼近局部最小值。
那么针对上面的式子,可以利用梯度提升算法寻找最优解 F ( x ) F(x) F(x),使得损失函数在样本上的期望最小,方法如下:
-
初始化给定模型为常数 F 0 ( x ) F_{0}(x) F0(x):
F 0 ( x ⃗ ) = a r g m i n r ∑ i = 1 m L ( y i , r ) F_{0}(\vec{x}) = \underset{r}{argmin}\sum_{i=1}^{m}L(y_{i},r) F0(x)=rargmini=1∑mL(yi,r) -
然后以贪心的思路扩展得到 F m ( x ) F_{m}(x) Fm(x):
F m ( x ⃗ ) = F m − 1 ( x ⃗ ) + a r g m i n f ϵ H L ( y i , F m − 1 ( x ⃗ i ) + f ( x ⃗ i ) ) F_{m}(\vec{x}) =F_{m-1}(\vec{x})+ \underset{f\epsilon H}{argmin}L(y_{i},F_{m-1}(\vec{x}_{i})+f({\vec{x}_{i}})) Fm(x)=Fm−1(x)+fϵHargminL(yi,Fm−1(xi)+f(xi))
关于贪心算法和梯度近似我也不是很懂,这里留下一个伏笔,留待日后证明,但我知道的一点是,贪心算法的本质是只看当前,那么即使是贪心算法,面对当前未知的样本数据,一样难以找寻到最优的基函数,假如说是很复杂,可能等同于枚举,所以这里可以采用梯度下降和将基函数的样本退化为向量样本去优化它,即
f
(
x
1
)
,
f
(
x
2
)
,
.
.
.
f
(
x
n
)
f(x_{1}),f(x_{2}),...f(x_{n})
f(x1),f(x2),...f(xn)到
L
(
y
1
,
f
(
x
1
)
)
,
L
(
y
2
,
f
(
x
2
)
)
,
.
.
.
,
L
(
y
n
,
f
(
x
n
)
)
L(y_{1},f(x_{1})),L(y_{2},f(x_{2})),...,L(y_{n},f(x_{n}))
L(y1,f(x1)),L(y2,f(x2)),...,L(yn,f(xn))
F
m
(
x
⃗
)
=
F
m
−
1
(
x
⃗
)
+
r
m
∑
i
=
1
n
▽
f
(
y
i
,
F
m
−
1
(
x
⃗
)
+
f
(
x
⃗
i
)
)
F_{m}(\vec{x}) =F_{m-1}(\vec{x})+ r_{m}\sum_{i=1}^{n}\triangledown _{f}(y_{i},F_{m-1}(\vec{x})+f({\vec{x}_{i}}))
Fm(x)=Fm−1(x)+rmi=1∑n▽f(yi,Fm−1(x)+f(xi))
然后在求出上式的权值
r
m
r_{m}
rm为梯度下降的步长,以此为梯度近似。然后再使用线性搜索求最优步长,公式为:
r
m
=
a
r
g
m
i
n
r
∑
i
=
1
n
L
(
y
i
,
F
m
−
1
(
x
⃗
i
)
−
r
⋅
▽
f
L
(
y
i
,
F
m
−
1
(
x
⃗
i
)
)
)
r_{m}= \underset{r}{argmin}\sum_{i=1}^{n}L(y_{i},F_{m-1}(\vec{x}_{i})-r\cdot \triangledown _{f}L(y_{i},F_{m-1}({\vec{x}_{i}})))
rm=rargmini=1∑nL(yi,Fm−1(xi)−r⋅▽fL(yi,Fm−1(xi)))
随机梯度提升(Stochastic gradient boosting)
这个不是重点,所以在这里提一下。
梯度提升的一般步骤
- 初始给定模型模型为常数:
f 0 ( x ) = a r g m i n c ∑ i = 1 N L ( y i , c ) f_{0}(x) = \underset{c}{argmin}\sum_{i=1}^{N}L(y_{i},c) f0(x)=cargmini=1∑NL(yi,c)
对于m=1到M: - 计算伪残差(pseudo residuals):
r m i = − [ ∂ L ( y i , f ( x ⃗ i ) ) ∂ f ( x ⃗ i ) ] f ( x ) = f m − 1 ( x ) r_{mi} = - \Bigg [ \frac {\partial L(y_i, f (\vec{x}_{i}))}{\partial f (\vec{x}_{i})}\Bigg ] _{f (x) = f _{m-1}(x)} rmi=−[∂f(xi)∂L(yi,f(xi))]f(x)=fm−1(x)
为什么叫做伪残差,因为它是负梯度求解产生的,而残差是我们当前的真实值 y y y与预测值 y i y_{i} yi之间的计算值,也就是MSE,它可以看成是平方损失函数求导后的结果,或者说在平方损失函数下的负梯度。在后面介绍提升树与梯度提升树的时候,前者用的是平方损失,后者用的是一般损失,所以也可以说提升树是梯度提升树的一种特例。
- 然后我们就可以以样本 x ⃗ i \vec{x}_{i} xi与伪残差构成 [ x ⃗ i , r i m ] i = 1 m {[\vec{x}_{i},r_{im}]_{i=1}^{m}} [xi,rim]i=1m这样一组新的样本集,然后我们就可以计算拟合残差的基函数 f m ( x ) f_{m}(x) fm(x)
- 计算步长:
r m = a r g m i n r ∑ i = 1 n L ( y i , F m − 1 ( x ⃗ i ) + r ⋅ f ( x ⃗ i ) ) r_{m}= \underset{r}{argmin}\sum_{i=1}^{n}L(y_{i},F_{m-1}(\vec{x}_{i})+r\cdot f({\vec{x}_{i}})) rm=rargmini=1∑nL(yi,Fm−1(xi)+r⋅f(xi)) - 更新模型:
F m ( x ⃗ ) = F m − 1 ( x ⃗ ) − r m ⋅ f m ( x ⃗ ) F_{m}(\vec{x}) =F_{m-1}(\vec{x})-r_{m}\cdot f_{m}(\vec{x}) Fm(x)=Fm−1(x)−rm⋅fm(x)
提升总结
Boosting整体的框架为下面这张图:
我不知道这张图出自哪里,但确实很形象的说明了boosting的机制,蓝线表示训练,绿线表示调整权值,红线则是集成。
Gradient Boost与传统的Boost有着很大的区别,它的每一次计算都是为了减少上一次的残差(residual),而为了减少这些残差,可以在残差减少的梯度(Gradient)方向上建立一个新模型。所以说,在Gradient Boost中,每个新模型的建立是为了使得先前模型残差往梯度方向减少,与传统的Boost算法对正确、错误的样本进行加权有着极大的区别。
References
[1] 机器学习——邹博
[2] 统计学习方法 李航 著
[3] https://en.wikipedia.org/wiki/AdaBoost
[4] AdaBoost 算法原理及推导