在集成学习方法之Bagging,Boosting,Stacking篇章中,我们谈论boosting框架的原理,在boosting系列算法中,AdaBoost是著名的算法之一。AdaBoost是英文"Adaptive Boosting"(自适应增强)的缩写,由Yoav Freund和Robert Schapire在1995年提出。
今天我们就来探讨下AdaBoost分类算法的原理,本篇我们先介绍AdaBoost算法;然后通过误差分析探讨AdaBoost为什么能提升模型的学习精度;并且从前向分步加法模型角度解释AdaBoost;最后对AdaBoost的算法优缺点进行一个总结。
1)从boosting到AdaBoost算法
集成原理中,我们提到的boosting框架的思想是选择同质的基分类器,让基分类器之间按照顺序进行训练,并让每个基分类器都尝试去修正前面的分类。既然这样,怎样才能让同质的基分类器能够修正前面的分类?或者说怎样才能让同质的基分类器之间保持“互助”呢?
AdaBoost的做法是,让前一个基分类器ft−1(x)在当前基分类器ft(x)的训练集上的效果很差(和我们随机瞎猜一样),这样ft(x)就能修正ft−1(x)的分类误差,ft(x)和ft−1(x)之间也就产生了“互助”。
AdaBoost的具体做法是,通过提高被前一轮基分类器ft−1(x)分类错误的样本的权值,降低被正确分类样本的权值,使得上一个基分类器ft−1(x)在更新权值后的训练集上的错误率ϵt−1增大到0.5。(再在更新权值后的训练集上训练基分类器ft(x),那ft(x)必能和ft−1(x)产生互助。)
2)AdaBoost算法
下面我们在二分类问题上介绍AdaBoost算法。假如给定训练数据集T={(xi,yi)}i=1n,xi∈Rd,yi∈{−1,1}
样本权值为win,误差率ϵi。在训练数据集T上训练第一个基分类器f1(x),其错误率为ϵ1,ϵ1<0.5(起码比瞎猜要好一些)
ϵ1=Z1∑nw1nδ((f1(xn)=y^n)Z1=n∑w1n
更新样本的权值(权值为w2n)后的训练集为T′,使得f1(x)在T′分类效果等同于随机瞎猜(ϵ=0.5)。用数学语言表示即为
Z2∑nw2nδ((f1(xn)=y^n)=0.5Z2=n∑w2n
那么样本权重如何更新呢?AdaBoost具体做法是,减小f1(x)分类正确的样本的权值,权值除以一个常数d,即d1w1n;增大f1(x)分类错误的样本的权值,权值乘以一个常数d,即w1nd1。用数学语言表示即为
{w2n=w1nd1if f1(xn)=y^n)w2n=d1w1nif f1(xn)=y^n)
下面我们再回到下式中来,
Z2∑nw2nδ((f1(xn)=y^n)=0.5
其中,Z2=∑f1(xn)=y^nw1nd1+∑f1(xn)=y^nd1w1n;当f1(xn)=y^n时,w2n=w1nd1。
将上面两式带入得:
∑f1(xn)=y^nw1nd1+∑f1(xn)=y^nd1w1n∑f1(xn)=y^nw1nd1=0.5
f1(xn)=y^n∑d1w1n=f1(xn)=y^n∑w1nd1
又因为ϵ1=Z1∑f1(xn)=y^nw1n⇒ϵ1Z1=f1(xn)=y^n∑w1n
1−ϵ1=Z1∑f1(xn)=y^nw1n⇒(1−ϵ1)Z1=f1(xn)=y^n∑w1n
因此,
f1(xn)=y^n∑d1w1n=f1(xn)=y^n∑w1nd1
d11f1(xn)=y^n∑w1n=d1f1(xn)=y^n∑w1n
d11(1−ϵ1)Z1=d1ϵ1Z1
d1=ϵ11−ϵ1
其中d1>1(因为ϵ1<0.5)。
因此AdaBoost每次更新权值表达式为:
⎩⎪⎨⎪⎧wt+1n=wtnϵt1−ϵt=wtnexp(Ln(ϵt1−ϵt))if ft(xn)=y^n)wt+1n=ϵt1−ϵtwtn=wtnexp(−Ln(ϵt1−ϵt))if ft(xn)=y^n)
令αt=Ln(ϵt1−ϵt),αt即为基分类器ft(x)的权重系数。当ϵt=0.1时,αt=1.1,当ϵt=0.4时,αt=0.2。这表明,当基分类器分类误差率越小时,基分类器的权重越大,在最终表决时起的作用也越大;当基分类器分类误差率越大时,基分类器的权重越小,在最终表决时起的作用也越小。将αt带入上式,样本权值更新表达式变成:
⎩⎨⎧wt+1n=wtnϵt1−ϵt=wtnexp(αt)if ft(xn)=y^n)wt+1n=ϵt1−ϵtwtn=wtnexp(−αt)if ft(xn)=y^n)
为了方便表示,将上式两项合并成一项得,权值更新的表达式为:
wt+1n=wtnexp(−y^nft(xn)αt)
当ft(xn)=y^n时,y^nft(xn)为+1,当 ft(xn)=y^n时,y^nft(xn)为-1,以上两式为等价变换。
以上就是AdaBoost算法如何做样本权值更新的整个推导过程。
下面对二元分类AdaBoost算法流程进行总结:
输入:训练数据集T={(xi,yi)}i=1N,xi∈Rd,yi∈{−1,1}
输出:最终的分类器H(x)
①初始化训练数据的权值(权值相等)
w1n=1
②for t=1...T:
-
在权值为{wt1,wt2...wtN}的训练机上训练基分类器ft(x)
-
计算ft(x)在训练数据集上的分类误差率ϵt ϵt=P(ft(xn=y^n))=n∑wtnδ(ft(xn=y^n))
-
计算ft(x)的权值系数
αt=Ln(ϵt1−ϵt)
-
for n=1,2....N:
if xn被ft(x)分类错误:
wt+1n=wtnϵt1−ϵt=wtnexp(αt)
else xn 被ft(x)分类正确:
wt+1n=ϵt1−ϵtwtn=wtnexp(−αt)
③构建基分类器线性组合
f(x)=T∑αtft(x)
得到最终的分类器H(x)
H(x)=sign(T∑αtft(x))
3)AdaBoost的训练误差分析
AdaBoost最基本的性质是它能在学习的过程中不断减少训练误差,且训练误差以指数速率下降,且无限逼近于0。具体的数学表达式为:
ErrorRate=N1∑δ(y^ng(x)<0)≤N1n∑exp(−y^ng(x))=N1ZT+1
N1ZT+1=t=1∏T2ϵt(1−ϵt)=t=1∏T(1−4γt2)≤exp(−2t=1∑Tγt2)
其中,γt=21−ϵt。
下面我们就AdaBoost做二元分类的情况,对这一结论分步进行证明。证明过程会涉及较多的数学公式的推导,对证明不感兴趣的小伙伴可以直接跳到第5部分AdaBoost算法总结。
首先我们证明:
ErrorRate=N1∑δ(y^ng(x)<0)≤N1exp(−y^ng(x))
从上一部分内容可知,训练数据集T={(xi,yi)}i=1n,xi∈Rd,yi∈{−1,1},最终的分类器H(x),αt的表达式为
H(x)=sign(t=1∑Tαtft(x))αt=Ln(ϵt1−ϵt)
分类器H(x)的分类误差率为ErrorRate等于分类错误的样本所占总样本的比例,用数学语言表达即为,
ErrorRate=N1∑δ(H(xn)=(y^)n)
其中,H(xn)=(y^)n表示模型的预测值和真实值异号,因此,
ErrorRate=N1∑δ(y^nt=1∑Tαtft(x)<0)
令g(x)=∑t=1Tαtft(x),因此,
ErrorRate=N1∑δ(y^ng(x)<0)
下面我们开始证明:
ErrorRate=N1∑δ(y^ng(x)<0)≤N1exp(−y^ng(x))
其中δ(y^ng(x)<0)为01损失函数,exp(−y^ng(x))为指数损失函数。画出函数图像很容易发现上式不等式成立:
下面我们证明
ErrorRate≤N1n∑exp(−y^ng(x))=N1ZT+1
已知g(x)=∑t=1Tαtft(x)(上面我们定义的等式)。且Zt+1为基分类器ft+1(x)所有训练样本的权重之和,用数学语言表示,
Zt+1=∑nwT+1n
=∑nwTnexp(−y^nft(xn)αt)(权值更新公式)
=∑n∏t=1Texp(−y^nft(xn)αt)
=∑nexp(−y^n∑t=1Tft(xn)αt)(连乘符号∏,放到指数exp中变成求和∑)
=∑nexp(−y^ng(xn))
因此,ErrorRate≤N1n∑exp(−y^ng(x))=N1ZT+1
已知αt=Ln(ϵt1−ϵt),下面我们证明
ErrorRate≤N1ZT+1=t=1∏T2ϵt(1−ϵt)
Zt+1为基分类器ft+1(x)所有训练样本的权重之和,它是由上一轮权值Zt更新而来的,被分类错误的样本权值增大,被分类正确的样本权值减小。
且Z1=N,因此,
ZT+1=Ztϵtexp(αt)+Zt(1−ϵt)exp(−αt)
=Ztϵtϵt1−ϵt+Zt(1−ϵt)1−ϵtϵt
=2Ztϵt(1−ϵt)
=N∏t=1T2ϵt(1−ϵt)
因此,
ErrorRate≤N1ZT+1=t=1∏T2ϵt(1−ϵt)
由于ϵt<0.5,因此2ϵt(1−ϵt)≤1,所以AdaBoost的分类误差率是不断的再减小的。
下面我们证明
t=1∏T2ϵt(1−ϵt)=t=1∏T(1−4γt2)≤exp(−2t=1∑Tγt2)
∏t=1T2ϵt(1−ϵt)
=∏t=1T2(21−(21−ϵt))(21+21−ϵt)
令γt=21−ϵt,γt>0得,
∏t=1T2ϵt(1−ϵt)
=∏t=1T2(21−(21−ϵt))(21+21−ϵt)
=∏t=1T241−γt2
=∏t=1T1−4γt2
最后我们证明,
t=1∏T(1−4γt2)≤exp(−2t=1∑Tγt2)
首先我们构造一个函数f(x)=e−x+x−1,由于f′′(x)=e−x>0,因此f(x)为凸函数,且minf(x)=f(0)=0,所以f(x)≥0。下面我们进入正式证明:
f(x)=e−x+x−1≥0
⇒e−x≥1−x,令x=4γ2,得
⇒e−4γ2≥1−4γ2
⇒e−2γ2≥1−4γ2
因此对于t=1,2...T,都有⎩⎪⎪⎪⎨⎪⎪⎪⎧e−2γ12≥1−4γ12e−2γ22≥1−4γ22...e−2γt2≥1−4γt2
将上式连乘得:
⇒t=1∏Texp(−2γt2)≥t=1∏T1−4γt2
⇒t=1∏T1−4γt2≤t=1∏Texp(−2γt2)
⇒t=1∏T1−4γt2≤exp(−2t=1∑Tγt2)
因此,证明得到下式成立:
ErrorRate=N1∑δ(y^ng(x)<0)≤exp(−2t=1∑Tγt2)
上不等式表明,AdaBoost的训练误差是以指数速率下降且无限逼近于0。(γ>0,−2∑t=1Tγt2<0,小于0的数求指数小于1,小于1的数无限连乘,将无限逼近与0)
4)前向分步加法模型解释AdaBoost
AdaBoost的另外一种解释,认为AdaBoost是加法模型、损失函数为指数函数、学习算法为前向分步算法的分类学习算法。
加法模型比较好理解,最终的分类器是有若干个基分类器加权平均得到。即
H(x)=T∑αtft(x)
其中,ft(x)为基分类器,αt为基分类器的权值。
前向分步学习算法,即利用前一个基分类器的结果更新后一个基分类器的训练权重。
假定第t−1轮后分类器为:
gt−1(x)=t=1∑t−1αtft(x)
而第t轮后分类器为为:
gt(x)=t=1∑tαtft(x)
有上两式可以得:
gt(x)=gt−1(x)+αtft(x)
因此,最终的分类器是通过前向学习算法得到的。
AdaBoost的损失函数为,
α,fargminn∑exp(−y^ngt(x))
利用前向分步学习算法可以得到损失函数为:
(αt,ft(x))=α,fargminn∑exp(−y^n(gt−1(x)+αtft(x))
令wt′n=exp(−y^ngt−1(x)),它的值不依赖αt,ft(x),因此与最小化无关,仅仅依赖于gt−1(x),随着每一轮迭代而改变。将上式子代入损失函数,得
(αt,ft(x))=α,fargminn∑wt′nexp(−y^αtft(x))
我们先求ft∗(x),对于任意的αt>0,使得上式最小的ft(x)由下式得到:
ft∗(x)=fargminwt′nδ(y^n=ft(xn))
其中,wt′n=exp(−y^ngt−1(x))。
基分类器ft∗(x)即为AdaBoost算法的基分类器ft(x),因为它是让第t轮加权训练数据分类误差率最小的基分类器。将ft∗(x)带入损失函数,对αt求导,使其等于0,得
αt=21Lnϵt1−ϵt
其中ϵt为分类误差率:
ϵt=∑nwt′n∑nwt′nδ(y^n=ft(xn))=n∑wtnδ(y^n=ft(xn))
这与我们在第二部分讨论的一致(见下式)。上式的wtn为权值率,下式中的wtn为权值,除以Z1等价于权值率。
ϵ1=Z1∑nw1nδ((f1(xn)=y^n)Z1=n∑w1n
αt=Ln(ϵt1−ϵt)
最后我们来看下每一轮权值的更新,利用以下两式
gt(x)=gt−1(x)+αtft(x)
wt′n=exp(−y^ngt−1(x))
可得到权值更新公式为:
wt+1n=wtnexp(−y^nft(xn)αt)
这与我们在第一部分讨论的权值更新公式也一致。因此,AdaBoost也可以从加法模型、指数损失函数、前向分步学习算法角度来解释。
需要注意的是,是先有了AdaBoost算法之后,人们才发现,通过加法模型、指数损失函数、前向分步学习算法的方式可以解释AdaBoost算法的过程。
5)AdaBoost算法总结
下面我们对AdaBoost算法的优缺点进行总结。
优点:
- 既可以处理分类任务,又可以处理回归任务;
- 不易过拟合;
- AdaBoost训练的分类器,分类精度高;
- 支持各种分类器做基分类器,如逻辑回归,SVM;
缺点:
- 对异常值敏感,异常值的权重在模型训练的过程中可能会越来越大,最终影响整个模型的性能;
终于写完了,这篇写的有点长,涉及的数学推导比较多,我也尽量往详细写了,大家需要一些耐心慢慢看。如果看到数学推导就头晕的小伙伴,可以只看第二部分AdaBoost算法原理部分。本篇涉及的数学公式较多,我也多检查了两遍,尽量减少数学上的表述错误。如果小伙伴发现还有错误,还望指正!
下篇我们探讨Scikit learn中的AdaBoost算法库类,并进行实践。
(欢迎大家在评论区探讨交流,也欢迎大家转载,转载请注明出处!)
上篇:Scikit-learn随机森林算法库总结与调参实践
下篇:持续更新中,敬请关注