Gradient Boosting 和 AdaBoost 的推导

最近看到集成学习的部分,觉得推导有点难,稍微写一写,推荐看看原论文或李宏毅老师的深度学习2019课程和周志华老师的《机器学习》,这里只关注Gradient Boosting 和 AdaBoost 的推导,综合了三部分内容,理清一下思路。

Gradient Boosting 本身是一个 general 的算法,使用不同的学习器和损失函数可以导出不同的具体的算法。这里换一个角度将整个框架搭建起来。首先,集成学习需要训练 T 个基学习器,然后用某种方法把这些基学习器的结果综合起来作为输出,就会是这样子:

For t = 1 to T:
       \space \space \space \space \space \space       train ft(x)
Output: F( f1(x), f2(x),…,fT(x) )

我们的目标很清晰,最终就是要得到一个强学习器,需要思考的是如何训练基学习器和如何整合起来。我们先略过构造的部分抽象的建模 G(x),这里的 G(x) 有点特别,它是很多个模型的综合,理论上这些模型都可能是不同质的:

Init G(x) = 0
For t = 1 to T:
       \space \space \space \space \space \space       train ft(x)
G(x) = F( f1(x), f2(x),…,fT(x) )
Output: sign(G(x))

从这里出发,或许可以产生许多种集成学习的思路,Gradient Boosting 假设各个学习器是弱学习器,后面训练的弱学习器的目标是校正前面训练的弱学习器的缺点,如果从模型 G(x) 的角度来看,每训练出一个模型,G(x) 的效果就会变好,所以整体上是一种提升算法:

Init G0(x) = 0
For t = 1 to T:
       \space \space \space \space \space \space       train ft(x)
       \space \space \space \space \space \space       update Gt(x) using Gt-1(x) and ft(x)
Output: sign(GT(x))

事实上,Gradient Boosting 采用加性模型,训练后面的基学习器时会固定住前面的基学习器,然后做简单的相加,注意到基学习器的训练过程是有序的,所以 Gradient Boosting 的基学习器的训练不能并行:

Init G0(x) = 0
For t = 1 to T:
       \space \space \space \space \space \space       train ft(x)
       \space \space \space \space \space \space       Gt(x) = Gt-1(x) + at · ft(x)
Output: sign(GT(x))

接下来需要细化提升的过程,所谓的提升一定是相对于某个损失而言的,因此我们需要选择适当的损失函数为整个算法提供方向。注意一下这里是第一个可以选择的地方:

target m i n i m i z e   L ( G ) = ∑ i = 1 N L ( y i , G ( x i ) ) minimize \ \mathcal L(G) = \sum^{N}_{i=1} L(y^i, G(x^i)) minimize L(G)=i=1NL(yi,G(xi))
Init G0(x) = 0
For t = 1 to T:
       \space \space \space \space \space \space       train ft(x)
       \space \space \space \space \space \space       Gt(x) = Gt-1(x) + at · ft(x)
Output: sign(GT(x))

为了做到在 T 个学习器训练完成后整个模型的损失降到最小,我们观察 G(x) 的更新过程。如果训练的基学习器 ft(x) 正好是一个类似负梯度的东西,那就可以保证每一个学习器都有往正确的方向做贡献,再来,如果每一个 at 都选择得恰到好处,那就能达到类似线性搜索的效果,整个优化过程就是最佳的,这正是我们需要构造的两部分:

target m i n i m i z e   L ( G ) = ∑ i = 1 N L ( y i , G ( x i ) ) minimize \ \mathcal L(G) = \sum^{N}_{i=1} L(y^i, G(x^i)) minimize L(G)=i=1NL(yi,G(xi))
Init G0(x) = 0
For t = 1 to T:
       \space \space \space \space \space \space       ft(x) = − ∂ L ( y , G t − 1 ( x ) ) ∂ G t − 1 ( x ) -\frac{ \partial L(y, G_{t-1}(x)) }{\partial G_{t-1}(x)} Gt1(x)L(y,Gt1(x))
       \space \space \space \space \space \space        ρ \rho ρt = a r g m i n ρ ∑ i = 1 N L ( y i , G t − 1 ( x i ) + ρ argmin_\rho \sum^{N}_{i=1}L(y^i,G_{t-1}(x^i)+\rho argminρi=1NL(yi,Gt1(xi)+ρ · ft ( x i ) ) (x^i)) (xi))
       \space \space \space \space \space \space       Gt(x) = Gt-1(x) + ρ \rho ρt · ft(x)
Output: sign(GT(x))

ρ \rho ρt 的选择不必多讲,在最小化 Gt(x) 损失的过程中选择,就是选择最合适的步长,有问题的是训练 ft(x) 的过程。细心的你可能会发现,ft(x) 要逼近的梯度是一个对函数的偏导,在原论文中称为函数空间的梯度,计算的方法和对参数的偏导相同,简单的将函数看成是 vector 就可以了。但是,之所以说是逼近,是因为 ft(x) 是在有限的样本中训练出来的,只能是对真实函数的估计,一定会有偏差,所以实际上这里不能取等号,我们把它改成逼近的过程(后面略去 target ):

Init G0(x) = a r g m i n ρ ∑ i = 1 N L ( y i , ρ ) argmin_\rho \sum^{N}_{i=1}L(y^i,\rho) argminρi=1NL(yi,ρ)
For t = 1 to T:
       \space \space \space \space \space \space        y ~ i \tilde y^i y~i = [ − ∂ L ( y i , G ( x i ) ) ∂ G ( x i ) ] G ( x ) = G x − 1 ( x )   ,   i = 1 , N [-\frac{ \partial L(y^i, G(x^i)) }{\partial G(x^i)}]_{G(x) =G_{x-1}(x)}\space,\space i=1,N [G(xi)L(yi,G(xi))]G(x)=Gx1(x) , i=1,N
       \space \space \space \space \space \space       ft(x) = a r g m i n f ∑ i = 1 N [ y ~ i   −   f ( x i ) ] 2 argmin_{f}\sum^{N}_{i=1}[\tilde y^i\space-\space f(x^i)]^2 argminfi=1N[y~i  f(xi)]2
       \space \space \space \space \space \space        ρ \rho ρt = a r g m i n ρ ∑ i = 1 N L ( y i , G t − 1 ( x i ) + ρ argmin_\rho \sum^{N}_{i=1}L(y^i,G_{t-1}(x^i)+\rho argminρi=1NL(yi,Gt1(xi)+ρ · ft ( x i ) ) (x^i)) (xi))
       \space \space \space \space \space \space       Gt(x) = Gt-1(x) + ρ \rho ρt · ft(x)
Output: sign(GT(x))

不用担心太复杂。这里的 y ~ \tilde y y~ 就是上面的负梯度,写成带有上标的形式只是为后面的书写方便而已,这里 ft(x) 向负梯度的逼近也是一个最小化损失的过程,损失函数选择平方损失,这里是第二个可以选择的地方,实际上基学习器选择怎么样子的,这里的损失函数要跟着修改,有时还要做一些变换,为了让训练第一个学习器时就能算梯度,修改了一下 G(x) 的初始化。到了这一步,看起来已经非常完善了,只是还有一个细节需要补充。注意到这里 ft(x) 的最小化过程,这里实际上最小化的是 x 和 y ~ \tilde y y~ 的联合概率的期望,与上一段同样的问题,对联合概率的估计只能是在有限的样本中完成,一定会有偏差,为了弥补这一段偏差,我们稍微修改一下最小化的过程:

Init G0(x) = a r g m i n ρ ∑ i = 1 N L ( y i , ρ ) argmin_\rho \sum^{N}_{i=1}L(y^i,\rho) argminρi=1NL(yi,ρ)
For t = 1 to T:
       \space \space \space \space \space \space        y ~ i \tilde y^i y~i = [ − ∂ L ( y i , G ( x i ) ) ∂ G ( x i ) ] G ( x ) = G x − 1 ( x )   ,   i = 1 , N [-\frac{ \partial L(y^i, G(x^i)) }{\partial G(x^i)}]_{G(x) =G_{x-1}(x)}\space,\space i=1,N [G(xi)L(yi,G(xi))]G(x)=Gx1(x) , i=1,N
       \space \space \space \space \space \space       ft(x) = a r g m i n β ⋅ f ∑ i = 1 N [ y ~ i   −   β   ⋅ f ( x i ) ] 2 argmin_{\beta ·f}\sum^{N}_{i=1}[\tilde y^i\space-\space \beta \space·f(x^i)]^2 argminβfi=1N[y~i  β f(xi)]2
       \space \space \space \space \space \space        ρ \rho ρt = a r g m i n ρ ∑ i = 1 N L ( y i , G t − 1 ( x i ) + ρ argmin_\rho \sum^{N}_{i=1}L(y^i,G_{t-1}(x^i)+\rho argminρi=1NL(yi,Gt1(xi)+ρ · ft ( x i ) ) (x^i)) (xi))
       \space \space \space \space \space \space       Gt(x) = Gt-1(x) + ρ \rho ρt · ft(x)
Output: sign(GT(x))

加入 β \beta β 的修正向后,最小化的过程会更准确一些,到这里再换一个更好看的书写方式就得到了与原论文相同的算法流程,非常经典:

Init G0(x) = a r g m i n ρ ∑ i = 1 N L ( y i , ρ ) argmin_\rho \sum^{N}_{i=1}L(y^i,\rho) argminρi=1NL(yi,ρ)
For t = 1 to T:
       \space \space \space \space \space \space        y ~ i \tilde y^i y~i = [ − ∂ L ( y i , G ( x i ) ) ∂ G ( x i ) ] G ( x ) = G x − 1 ( x )   ,   i = 1 , N [-\frac{ \partial L(y^i, G(x^i)) }{\partial G(x^i)}]_{G(x) =G_{x-1}(x)}\space,\space i=1,N [G(xi)L(yi,G(xi))]G(x)=Gx1(x) , i=1,N
       \space \space \space \space \space \space       at = a r g m i n α , β ∑ i = 1 N [ y ~ i   −   β   ⋅ f ( x i ; α ) ] 2 argmin_{\alpha,\beta}\sum^{N}_{i=1}[\tilde y^i\space-\space \beta \space·f(x^i;\alpha)]^2 argminα,βi=1N[y~i  β f(xi;α)]2
       \space \space \space \space \space \space        ρ \rho ρt = a r g m i n ρ ∑ i = 1 N L ( y i , G t − 1 ( x i ) + ρ argmin_\rho \sum^{N}_{i=1}L(y^i,G_{t-1}(x^i)+\rho argminρi=1NL(yi,Gt1(xi)+ρ · ft ( x i , (x^i, (xi,at ) ) )) ))
       \space \space \space \space \space \space       Gt(x) = Gt-1(x) + ρ t ⋅ f t \rho_t · f_t ρtft(x; at)
Output: sign(GT(x))

原论文后面提供了好几种 Gradient Boosting 的具体算法,这里也以最简单的 Least-squares regression 来说明一下用法。还记得 Gradient Boosting 有两个地方可以选择,首先我们选择 L(G) 损失是平方损失,即模型的优化目标是:

target m i n i m i z e   L ( G ) = ∑ i = 1 N L ( y i , G ( x i ) ) = 1 / 2 ∗ ∑ i = 1 N ( y i − G ( x i ) ) 2 minimize \ \mathcal L(G) = \sum^{N}_{i=1} L(y^i, G(x^i)) =1/2 *\sum^{N}_{i=1}(y^i-G(x^i))^2 minimize L(G)=i=1NL(yi,G(xi))=1/2i=1N(yiG(xi))2

由损失函数求得对函数空间的负梯度:

y ~ i \tilde y^i y~i = − ∂ L ( y i , G ( x i ) ) ∂ G ( x i ) = y i − G ( x i )   ,   i = 1 , N -\frac{ \partial L(y^i, G(x^i)) }{\partial G(x^i)} = y^i-G(x^i)\space,\space i=1,N G(xi)L(yi,G(xi))=yiG(xi) , i=1,N

学习器的选择这里没有要求,能做回归的弱学习器均可,逼近函数空间梯度的损失也选择平方损失,这里的修正项 β \beta β 正好是我们要学习的步长 ρ \rho ρ(后一个 argmin 的 y ~ \tilde y y~ 代替 y 之后正好与前一个 argmin 相同),于是合并这两个最小化的过程,写成算法就是这样:

Init G0(x) = y ˉ \bar y yˉ
For t = 1 to T:
       \space \space \space \space \space \space        y ~ i \tilde y^i y~i = y i − G t − 1 ( x i )   ,   i = 1 , N y^i- G_{t-1}(x^i)\space,\space i=1,N yiGt1(xi) , i=1,N
       \space \space \space \space \space \space        ( ρ t , a t ) (\rho_t,a_t) (ρt,at) = a r g m i n ρ , a ∑ i = 1 N [ y i ~ − ρ f t ( x i ; a ) ] 2 argmin_{\rho,a} \sum^{N}_{i=1}[\tilde{y^i}-\rho f_t(x^i;a)]^2 argminρ,ai=1N[yi~ρft(xi;a)]2
       \space \space \space \space \space \space       Gt(x) = Gt-1(x) + ρ t ⋅ f t \rho_t · f_t ρtft(x; at)
Output: sign(GT(x))

非常简单,这里再简要分析一下为什么提升算法要选弱学习器。首先一个事实是强学习器与弱学习器是等价的,这使得这种提升变得可行,而训练弱学习器显然要比训练强学习器要快得多,参数也少一些,通过这种提升可以节省不少时间。另外一个是,Gradient Boosting 利用的是残差逼近的想法,我们移项一下:

Gt(x) - Gt-1(x) = ρ t ⋅ f t ( x ) \rho_t · f_t(x) ρtft(x) = rt

忽略修正项,实际上每一个基学习器要学习的梯度是当前模型“残差”(不完全相等,在意义上也不相同,所以称伪残差),从这个角度上讲,只要有足够多的学习器,是可以完全学习出真实函数来的,而这种一步一步拟合残差的过程,交给弱学习器做就足够了。

下面来推导一下 AdaBoost 。首先我们选择 L(G) 损失是指数损失函数,优化目标是这样子的:

target m i n i m i z e   L ( G ) = ∑ i = 1 N L ( y i , G ( x i ) ) = ∑ i = 1 N e x p ( − y i G ( x i ) ) minimize \ \mathcal L(G) = \sum^{N}_{i=1} L(y^i, G(x^i)) =\sum^{N}_{i=1}exp(-y^iG(x^i)) minimize L(G)=i=1NL(yi,G(xi))=i=1Nexp(yiG(xi))

选择这个损失函数是合理的,因为我们需要让模型的预测与真实值同号,而且乘积越大越好,有时这个乘积被称为 margin,由于优化目标需要最大化 margin,这可以用于解释尽管AdaBoost 在训练集上已经学习到 100% 了,继续训练学习器在测试集上仍能继续提升的有趣现象。接下来求对函数空间的负梯度:

y ~ i \tilde y^i y~i = − ∂ L ( y i , G ( x i ) ) ∂ G ( x i ) = e x p ( − y i G ( x i ) ) ( y i ) -\frac{ \partial L(y^i, G(x^i)) }{\partial G(x^i)} = exp(-y^iG(x^i))(y^i) G(xi)L(yi,G(xi))=exp(yiG(xi))(yi)

按照 Gradient Boosting 的思路,这里应该训练基学习器逼近负梯度,用的是平方损失。AdaBoosting 用的是另外一种思路,不需要去逼近,而是让他们方向相同就好(这里的方向相同指的是两个函数的方向相同,有点奇妙,还是看成 vector 处理就好),在这一步可以写成 maximize 的形式:

m a x i m i z e f ∑ i = 1 N e x p ( − y i G ( x i ) ) ( y i )   ⋅ f ( x i ) maximize_f\sum^{N}_{i=1}exp(-y^iG(x^i))(y^i)\ ·f(x^i) maximizefi=1Nexp(yiG(xi))(yi) f(xi)

这里的意思就是让负梯度与学习器学习的函数相乘,让它最大当然就是方向相同了。为了思路的清晰,先将算法的流程写出来(这里换了一些字母):

target m i n i m i z e   L ( G ) = ∑ i = 1 N L ( y i , G ( x i ) ) = ∑ i = 1 N e x p ( − y i G ( x i ) ) minimize \ \mathcal L(G) = \sum^{N}_{i=1} L(y^i, G(x^i)) =\sum^{N}_{i=1}exp(-y^iG(x^i)) minimize L(G)=i=1NL(yi,G(xi))=i=1Nexp(yiG(xi))
Init G0(x) = 0
For t = 1 to T:
       θ t \space \space \space \space \space \space \theta_t       θt = a r g m a x θ ∑ i = 1 N e x p ( − y i G t − 1 ( x i ) ) ( y i )   ⋅ f t ( x i , θ ) argmax_\theta \sum^{N}_{i=1}exp(-y^iG_{t-1}(x^i))(y^i)\ ·f_t(x^i,\theta) argmaxθi=1Nexp(yiGt1(xi))(yi) ft(xi,θ)
       \space \space \space \space \space \space        a t a_t at = a r g m i n a ∑ i = 1 N L ( y i , G t − 1 ( x i ) + a argmin_a \sum^{N}_{i=1}L(y^i,G_{t-1}(x^i)+a argminai=1NL(yi,Gt1(xi)+a · ft ( x i , θ t ) ) (x^i,\theta_t)) (xi,θt))
       \space \space \space \space \space \space       Gt(x) = Gt-1(x) + a t ⋅ f t ( x ; θ t a_t · f_t(x; \theta_t atft(x;θt)
Output: sign(GT(x))

我们来继续研究一下这个最大化的过程,我们换一个角度来看这个式子。在第 t 步时,前面 exp() 部分其实是已知的,所以最大化的过程也可以看成是基学习器在拟合带权样本,记成 u t u_t ut ,那么:

u t i u^i_t uti = e x p ( − y i G t − 1 ( x i ) ) exp(-y^iG_{t-1}(x^i)) exp(yiGt1(xi))

     \space\space \space \space      = e x p ( − y i ∑ j = 1 t − 1 a j f j ( x i ) ) exp(-y^i\sum^{t-1}_{j=1}a_jf_j(x^i)) exp(yij=1t1ajfj(xi))

     \space\space \space \space      = ∏ j = 1 t − 1 e x p ( − y i a j f j ( x i ) ) \prod^{t-1}_{j=1}exp(-y^ia_jf_j(x^i)) j=1t1exp(yiajfj(xi))

     \space\space \space \space      = e x p ( − y i a t − 1 f t − 1 ( x i ) )   ⋅ u t − 1 i exp(-y^ia_{t-1}f_{t-1}(x^i))\space·u^i_{t-1} exp(yiat1ft1(xi)) ut1i

     \space\space \space \space      = u t − 1 i ∗ { e x p ( − a t − 1 ) , i f   f t − 1 ( x i ) = y i e x p ( a t − 1 ) , i f   f t − 1 ( x i )    ≠ y i u^i_{t-1}*\begin{cases} exp(-a_{t-1}), & if\space f_{t-1}(x^i)=y^i\\ exp(a_{t-1}), & if\space f_{t-1}(x^i)\space\space \neq y^i \end{cases} ut1i{exp(at1),exp(at1),if ft1(xi)=yiif ft1(xi)  ̸=yi

也就是说,我们不需要真的去执行这个最大化的过程,只需要在每一步让基学习器学习带权样本,而当前训练的基学习器的样本权值,是上一个学习器的样本权值乘上一个式子,这个式子与上一个学习器的“步长” a a a 有关。 a a a 的计算是一个最小化的过程,将损失函数代入再做一些简化:

a t a_t at = a r g m i n a ∑ i = 1 N L ( y i , G t − 1 ( x i ) + a argmin_a \sum^{N}_{i=1}L(y^i,G_{t-1}(x^i)+a argminai=1NL(yi,Gt1(xi)+a · ft ( x i ) ) (x^i)) (xi))

     \space\space \space \space      = a r g m i n a ∑ i = 1 N e x p ( − y i   ⋅   ( G t − 1 ( x i ) + a argmin_a \sum^{N}_{i=1}exp(-y^i\space·\space(G_{t-1}(x^i)+a argminai=1Nexp(yi  (Gt1(xi)+a · ft ( x i ) ) ) (x^i))) (xi)))

     \space\space \space \space      = a r g m i n a ∑ i = 1 N e x p ( − y i ( G t − 1 ( x i ) ) ) e x p ( − y i ⋅ a argmin_a \sum^{N}_{i=1}exp(-y^i(G_{t-1}(x^i)))exp(-y^i·a argminai=1Nexp(yi(Gt1(xi)))exp(yia · ft ( x i ) ) (x^i)) (xi))

接下来求损失对 a a a 的梯度并令为 0,引入学习器的错误率 ϵ \epsilon ϵ

     [   ∑ i = 1 N e x p ( − y i ( G t − 1 ( x i ) ) ) e x p ( − y i ⋅ a \space\space \space \space[\space\sum^{N}_{i=1}exp(-y^i(G_{t-1}(x^i)))exp(-y^i·a     [ i=1Nexp(yi(Gt1(xi)))exp(yia · ft ( x i ) )   ] a ′ (x^i))\space]'_a (xi)) ]a

  \space  =   ∑ i = 1 N e x p ( − y i ( G t − 1 ( x i ) ) e x p ( − y i ⋅ a \space\sum^{N}_{i=1}exp(-y^i(G_{t-1}(x^i))exp(-y^i·a  i=1Nexp(yi(Gt1(xi))exp(yia · ft ( x i ) ) ⋅ ( − y i (x^i))·(-y^i (xi))(yi · ft ( x i ) ) (x^i)) (xi))

  \space  =   ∑ y i = f t ( x i ) − e x p ( − y i ( G t − 1 ( x i ) ) e x p ( − a ) ) \space\sum_{y^i=f_t(x^i)}-exp(-y^i(G_{t-1}(x^i))exp(-a))  yi=ft(xi)exp(yi(Gt1(xi))exp(a)) +

      ∑ y i    ≠ f t ( x i ) e x p ( − y i ( G t − 1 ( x i ) ) e x p ( a ) ) \space\space\space\space\space\sum_{y^i\space\space\neq f_t(x^i)}exp(-y^i(G_{t-1}(x^i))exp(a))      yi  ̸=ft(xi)exp(yi(Gt1(xi))exp(a)) = 令 0 \xlongequal{令}0 0

⇒ ∑ i − e x p ( − a )   ⋅ Ⅰ ( y i = f t ( x i ) ) \Rightarrow\sum_i-exp(-a)\space·Ⅰ(y^i=f_t(x^i)) iexp(a) (yi=ft(xi)) +   ∑ i e x p ( a )   ⋅ Ⅰ ( y i    ≠ f t ( x i ) ) = 0 \space\sum_iexp(a)\space·Ⅰ(y^i \space\space\neq f_t(x^i)) = 0  iexp(a) (yi  ̸=ft(xi))=0

⇒ − ( 1 − ϵ t ) ⋅ e x p ( − a ) \Rightarrow-(1-\epsilon_t)·exp(-a) (1ϵt)exp(a) + ϵ t ⋅ e x p ( a ) = 0 \epsilon_t·exp(a) = 0 ϵtexp(a)=0

⇒ a t = 1 2   l n ( 1 − ϵ t ϵ t ) \Rightarrow a_t = \frac{1}{2}\ ln(\frac{1-\epsilon_t}{\epsilon_t}) at=21 ln(ϵt1ϵt)

所以 a a a 是可以根据当前学习器的错误率计算出来的,我们再整理一下这个过程。首先初始化样本的权值,然后训练一个基学习器,根据基学习器的错误率计算出 a a a 的值,然后调整样本的权值到下一轮训练。由于规定基学习器的错误率要低于 50%(也就是要胜过随机猜测), a a a 的值总大于 0,再代入权值更新的公式,如果当前学习器分类错误的话,要乘上一个大于 1 的数,权值变大,如果分类正确的话,要乘上小于 1 的数,权值变小,从这里可以看到,AdaBoost 后面训练的学习器会更关注前面训练错误的样本,也就是说后面的学习器能校正前面学习器的错误,理论上与 Graient Boosting 一样是可以将错误率降到 0 的。因为整个过程就好像样本会自动适应错误的样子,训练基学习器只用关注带权样本,所以名字就叫做自适应提升算法:

Init u 1 i = 1 / N ,   i = 1 , N u^i_1=1/N,\space i=1,N u1i=1/N, i=1,N
For t = 1 to T:
       \space \space \space \space \space \space        θ t \theta_t θt = a r g m i n θ ∑ i = 1 N l ( u t ⋅ y i , f t ( x i , θ ) ) argmin_\theta\sum^{N}_{i=1}l(u_{t}·y^i,f_t(x^i,\theta)) argminθi=1Nl(utyi,ft(xi,θ))
       ϵ t \space \space \space \space \space \space\epsilon_t       ϵt = ϵ ( u t ⋅ y ,   f t ( x , θ t ) ) \epsilon(u_{t}·y,\space f_t(x,\theta_t)) ϵ(uty, ft(x,θt))

       \space \space \space \space \space \space        a t a_t at = 1 2   l n ( 1 − ϵ t ϵ t ) \frac{1}{2}\ ln(\frac{1-\epsilon_t}{\epsilon_t}) 21 ln(ϵt1ϵt)

       \space \space \space \space \space \space        u t + 1 u_{t+1} ut+1 = u t i ∗ { e x p ( − a t ) , i f   f t ( x i , θ t ) = y i e x p ( a t ) , i f   f t ( x i , θ t )    ≠ y i u^i_{t}*\begin{cases} exp(-a_{t}), & if\space f_{t}(x^i,\theta_t)=y^i\\ exp(a_{t}), & if\space f_{t}(x^i,\theta_t)\space\space \neq y^i \end{cases} uti{exp(at),exp(at),if ft(xi,θt)=yiif ft(xi,θt)  ̸=yi

Output: sign( ∑ t = 1 T a t f t ( x ) \sum^{T}_{t=1}a_tf_t(x) t=1Tatft(x))

上面的权值 u u u 没有经过规范化,我们在更新 u u u 的时候除以一个规范化因子 Z Z Z,再写成分布的形式( D D D 表示训练集, D \frak D D 表示训练集分布, L \frak L L 为训练器):

Init D 1 ( x ) = 1 / N \frak D_1(x)=1/N D1(x)=1/N
For t = 1 to T:
       \space \space \space \space \space \space        f t = L ( D , D t ) f_t = \frak L(D,\frak D_t) ft=L(D,Dt)
       ϵ t \space \space \space \space \space \space\epsilon_t       ϵt = P x ∽ D t ( f t ( x )    ≠ y ) P_{x\backsim\frak D_t}(f_t(x) \space\space\neq y) PxDt(ft(x)  ̸=y)

       \space \space \space \space \space \space        a t a_t at = 1 2   l n ( 1 − ϵ t ϵ t ) \frac{1}{2}\ ln(\frac{1-\epsilon_t}{\epsilon_t}) 21 ln(ϵt1ϵt)
       \space \space \space \space \space \space        D t + 1 ( x ) \frak D_{t+1}(x) Dt+1(x) = D t ( x ) Z t ∗ { e x p ( − a t ) , i f   f t ( x i , θ t ) = y i e x p ( a t ) , i f   f t ( x i , θ t )    ≠ y i \frac{\frak D_{t}(x)}{Z_t}*\begin{cases} exp(-a_{t}), & if\space f_{t}(x^i,\theta_t)=y^i\\ exp(a_{t}), & if\space f_{t}(x^i,\theta_t)\space\space \neq y^i \end{cases} ZtDt(x){exp(at),exp(at),if ft(xi,θt)=yiif ft(xi,θt)  ̸=yi

Output: sign( ∑ t = 1 T a t f t ( x ) \sum^{T}_{t=1}a_tf_t(x) t=1Tatft(x))

写成分布的好处是有些时候学习器不接受带权样本的输入,这时可以依据分布进行采样,替代 re-weighting 的部分。这就是 AdaBoost 的算法流程,整个过程其实相当于在做梯度下降,目的是最小化损失,最后我们来证明一下为什么损失会减小:

L ( G T ) \mathcal L(G_T) L(GT) = ∑ i = 1 N e x p ( − y i G T ( x i ) ) \sum^{N}_{i=1}exp(-y^iG_T(x^i)) i=1Nexp(yiGT(xi))

            \space\space\space\space\space\space\space\space\space\space\space             = ∑ i = 1 N e x p ( − y i ∑ t = 1 T a t f t ( x i ) ) \sum^{N}_{i=1}exp(-y^i\sum^{T}_{t=1}a_tf_t(x^i)) i=1Nexp(yit=1Tatft(xi))

            \space\space\space\space\space\space\space\space\space\space\space             = ∑ i = 1 N ∏ t = 1 T e x p ( − y i a t f t ( x i ) ) \sum^{N}_{i=1}\prod^T_{t=1}exp(-y^ia_tf_t(x^i)) i=1Nt=1Texp(yiatft(xi))

            \space\space\space\space\space\space\space\space\space\space\space             = ∑ i = 1 N u T + 1 i \sum^{N}_{i=1}u^i_{T+1} i=1NuT+1i

            \space\space\space\space\space\space\space\space\space\space\space             = Z T + 1 Z_{T+1} ZT+1

            \space\space\space\space\space\space\space\space\space\space\space             = ∑ i = 1 N u T i   ⋅ e x p ( − y i a t f t ( x i ) ) \sum^N_{i=1}u^i_{T}\space·exp(-y^ia_tf_t(x^i)) i=1NuTi exp(yiatft(xi))

            \space\space\space\space\space\space\space\space\space\space\space             = ∑ y = f ( x ) u T i   ⋅ e x p ( − a t ) \sum_{y=f(x)}u^i_{T}\space·exp(-a_t) y=f(x)uTi exp(at) + ∑ y     ≠ f ( x ) u T i   ⋅ e x p ( a t ) \sum_{y\space\space\space\neq f(x)}u^i_{T}\space·exp(a_t) y   ̸=f(x)uTi exp(at)

            \space\space\space\space\space\space\space\space\space\space\space             = Z T ( 1 − ϵ t ) ⋅ e x p ( − a t ) Z_T(1-\epsilon_t)·exp(-a_t) ZT(1ϵt)exp(at) + Z T ⋅ ϵ t ⋅ e x p ( a t ) Z_T·\epsilon_t·exp(a_t) ZTϵtexp(at)

            \space\space\space\space\space\space\space\space\space\space\space             = Z T ( 1 − ϵ t ) ϵ t / ( 1 − ϵ t ) Z_T(1-\epsilon_t)\sqrt{\epsilon_t/(1-\epsilon_t)} ZT(1ϵt)ϵt/(1ϵt) + Z T ⋅ ϵ t ( 1 − ϵ t ) / ϵ t Z_T·\epsilon_t\sqrt{(1-\epsilon_t)/\epsilon_t} ZTϵt(1ϵt)/ϵt

            \space\space\space\space\space\space\space\space\space\space\space             = Z T ∗ 2 ϵ t ( 1 − ϵ t ) Z_T*2\sqrt{\epsilon_t(1-\epsilon_t)} ZT2ϵt(1ϵt)

            \space\space\space\space\space\space\space\space\space\space\space             < Z T Z_T ZT = L ( G T − 1 ) \mathcal L(G_{T-1}) L(GT1)

从上面这个稍微长一点的推导可以看到,实际上 AdaBoost 每训练一个基学习器,损失就要乘上 2 ϵ t ( 1 − ϵ t ) 2\sqrt{\epsilon_t(1-\epsilon_t)} 2ϵt(1ϵt) ,所以损失会慢慢降低,所以理论上是可以完全学习好训练集的。

你可能感兴趣的:(Gradient Boosting 和 AdaBoost 的推导)