Adaboost算法实例解析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Adaboost算法实例解析
Adaboost 算法实例解析
1 Adaboost的原理
1.1 Adaboost基本介绍
AdaBoost,是英⽂"Adaptive Boosting"(⾃适应增强)的缩写,由Yoav Freund和Robert Schapire在1995年提出。
Adaboost是⼀种迭代,其核⼼思想是针对同⼀个训练集训练不同的分类器(弱分类器),然后把这 Adaboost 些弱分类器集合起来,构成⼀个更强的最终分类器(强分类器)。
其算法本⾝是通过改变数据分布来实现的,它根据每次训练集之中每个样本的分类是否正确,以及上次的总体分类的准确率,来确定每个样本的权值。
将修改过权值的新数据集送给下层分类器进⾏训练,最后将每次训练得到的分类器最后融合起来,作为最后的决策分类器。
使⽤adaboost分类器可以排除⼀些不必要的训练数据特徵,并将关键放在关键的训练数据上⾯。
主要解决的问题
⽬前,对adaBoost算法的研究以及应⽤⼤多集中于分类问题,同时近年也出现了⼀些在回归问题上的应⽤。
就其应⽤adaBoost系列主要解决了: 两类问题、多类单标签问题、多类多标签问题、⼤类单标签问题,回归问题。
它⽤全部的训练样本进⾏学习。
1.2 Adaboost算法介绍
算法分析
该算法其实是⼀个简单的弱分类算法提升过程,这个过程通过不断的训练,可以提⾼对数据的分类能 Adaboost
⼒。
整个过程如下所⽰:
1. 先通过对N个训练样本的学习得到第⼀个弱分类器;
2. 将分错的样本和其他的新数据⼀起构成⼀个新的N个的训练样本,通过对这个样本的学习得到第⼆个弱分类器;
3. 将1和2都分错了的样本加上其他的新样本构成另⼀个新的N个的训练样本,通过对这个样本的学习得到第三个弱分类器;
4. 最终经过提升的强分类器。
即某个数据被分为哪⼀类要通过, ……的多数表决。
Adaboost的⾃适应在于:前⼀个基本分类器分错的样本会得到加强,加权后的全体样本再次被⽤来训练下⼀个基本分类器。
同时,在每⼀轮中加⼊⼀个新的弱分类器,直到达到某个预定的⾜够⼩的错误率或达到预先指定的最⼤迭代次数。
具体说来,整个Adaboost 迭代算法就3步:
1. 初始化训练数据的权值分布。
如果有N个样本,则每⼀个训练样本最开始时都被赋予相同的权重:1/N。
2. 训练弱分类器。
具体训练过程中,如果某个样本点已经被准确地分类,那么在构造下⼀个训练集中,它的权重就被降低;相反,如果
某个样本点没有被准确地分类,那么它的权重就得到提⾼。
然后,权重更新过的样本集被⽤于训练下⼀个分类器,整个训练过程如此迭代地进⾏下去。
3. 将各个训练得到的弱分类器组合成强分类器。
各个弱分类器的训练过程结束后,加⼤分类误差率⼩的弱分类器的权重,使其在最终的
分类函数中起着较⼤的决定作⽤,⽽降低分类误差率⼤的弱分类器的权重,使其在最终的分类函数中起着较⼩的决定作⽤。
换⾔之,误差率低的弱分类器在最终分类器中占的权重较⼤,否则较⼩。
Adaboost算法流程
对于这个算法需要介绍的是:
1. 算法开始前,需要将每个样本的权重初始化为1/m,这样⼀开始每个样本都是等概率的分布,每个分类器都会公正对待。
2. 开始迭代后,需要计算每个弱分类器的分类错误的误差,误差等于各个分错样本的权重和,这⾥就体现了样本权重的作⽤。
如果⼀个分类器正确分类了⼀个权重⼤的样本,那么这个分类器的误差就会⼩,否则就会⼤。
这样就对分类错误的样本更⼤的关注。
3. 获取最优分类器后,需要计算这个分类器的权重,然后再更新各个样本的权重,然后再归⼀化
4. 算法迭代的次数⼀般不超过弱分类器的个数,如果弱分类器的个数⾮常之多,那么可以权衡⾃⼰性价⽐来折中选择。
5. 迭代完成后,最后的分类器是由迭代过程中选择的弱分类器线性加权得到的。
1.3 Adaboost实例解析
例1. 下⾯,给定下列训练样本,请⽤AdaBoost算法学习⼀个强分类器。
求解过程:初始化训练数据的权值分布,令每个权值W1i = 1/N = 0.1,其中,N = 10,i = 1,2, ..., 10,然后分别对于m = 1,2,3, ...等值进⾏迭代。
拿到这10个数据的训练样本后,根据 X 和 Y 的对应关系,要把这10个数据分为两类,⼀类是“1”,⼀类是“-1”,根据数据的特点发现:“0 1 2”这3个数据对应的类是“1”,“3 4 5”这3个数据对应的类是“-1”,“6 7 8”这3个数据对应的类是“1”,9是⽐较孤独的,对应类“-1”。
抛开孤独的9不讲,“0 1 2”、“3 4 5”、“6 7 8”这是3类不同的数据,分别对应的类是1、-1、1,直观上推测可知,可以找到对应的数据分界点,⽐如2.5、5.5、8.5 将那⼏类数据分成两类。
当然,这只是主观臆测,下⾯实际计算下这个过程。
迭代过程1
对于m=1,在权值分布为D1(10个数据,每个数据的权值皆初始化为0.1)的训练数据上,经过计算可得:
1. 阈值v取
2.5时误差率为0.3(x < 2.5时取1,x > 2.5时取-1,则6 7 8分错,误差率为0.3),
2. 阈值v取5.5时误差率最低为0.4(x < 5.5时取1,x > 5.5时取-1,则3 4 5 6 7 8皆分错,误差率0.6⼤于0.5,不可取。
故令x > 5.5时取
1,x < 5.5时取-1,则0 1 2 9分错,误差率为0.4),
3. 阈值v取8.5时误差率为0.3(x < 8.5时取1,x > 8.5时取-1,则3 4 5分错,误差率为0.3)。
所以⽆论阈值v取2.5,还是8.5,总得分错3个样本,故可任取其中任意⼀个如2.5,弄成第⼀个基本分类器为:
上⾯说阈值v取2.5时则6 7 8分错,所以误差率为0.3,更加详细的解释是:因为样本集中
1. 0 1 2对应的类(Y)是1,因它们本⾝都⼩于
2.5,所以被G1(x)分在了相应的类“1”中,分对了。
2. 3 4 5本⾝对应的类(Y)是-1,因它们本⾝都⼤于2.5,所以被G1(x)分在了相应的类“-1”中,分对了。
3. 但6 7 8本⾝对应类(Y)是1,却因它们本⾝⼤于2.5⽽被G1(x)分在了类"-1"中,所以这3个样本被分错了。
4. 9本⾝对应的类(Y)是-1,因它本⾝⼤于2.5,所以被G1(x)分在了相应的类“-1”中,分对了。
从⽽得到G1(x)在训练数据集上的误差率(被G1(x)误分类样本“6 7 8”的权值之和)e1=P(G1(xi)≠yi) = 3*0.1 = 0.3。
然后根据误差率e1计算G1的系数:
这个a1代表G1(x)在最终的分类函数中所占的权重,为0.4236。
接着更新训练数据的权值分布,⽤于下⼀轮迭代:
值得⼀提的是,由权值更新的公式可知,每个样本的新权值是变⼤还是变⼩,取决于它是被分错还是被分正确。
即如果某个样本被分错了,则yi * Gm(xi)为负,负负等正,结果使得整个式⼦变⼤(样本权值变⼤),否则变⼩。
第⼀轮迭代后,最后得到各个数据新的权值分布D2 = (0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.1666, 0.1666, 0.1666, 0.0715)。
由此可以看出,因为样本中是数据“6 7 8”被G1(x)分错了,所以它们的权值由之前的0.1增⼤到0.1666,反之,其它数据皆被分正确,所以它们的权值皆由之前的0.1减⼩到0.0715。
分类函数f1(x)= a1*G1(x) = 0.4236G1(x)。
此时,得到的第⼀个基本分类器sign(f1(x))在训练数据集上有3个误分类点(即6 7 8)。
从上述第⼀轮的整个迭代过程可以看出:被误分类样本的权值之和影响误差率,误差率影响基本分类器在最终分类器中所占的权重。
迭代过程2
对于m=2,在权值分布为D2 = (0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.1666, 0.1666, 0.1666, 0.0715)的训练数据上,经过计算可得:
1. 阈值v取
2.5时误差率为0.1666*3(x < 2.5时取1,x > 2.5时取-1,则6 7 8分错,误差率为0.1666*3),
2. 阈值v取5.5时误差率最低为0.0715*4(x > 5.5时取1,x < 5.5时取-1,则0 1 2 9分错,误差率为0.0715*3 + 0.0715),
3. 阈值v取8.5时误差率为0.0715*3(x < 8.5时取1,x > 8.5时取-1,则3 4 5分错,误差率为0.0715*3)。
所以,阈值v取8.5时误差率最低,故第⼆个基本分类器为:
⾯对的还是下述样本:
很明显,G2(x)把样本“3 4 5”分错了,根据D2可知它们的权值为0.0715, 0.0715, 0.0715,所以G2(x)在训练数据集上的误差率
e2=P(G2(xi)≠yi) = 0.0715 * 3 = 0.2143。
计算G2的系数:
更新训练数据的权值分布:
D3 = (0.0455, 0.0455, 0.0455, 0.1667, 0.1667, 0.01667, 0.1060, 0.1060, 0.1060, 0.0455)。
被分错的样本“3 4 5”的权值变⼤,其它被分对的样本的权值变⼩。
f2(x)=0.4236G1(x) + 0.6496G2(x)
此时,得到的第⼆个基本分类器sign(f2(x))在训练数据集上有3个误分类点(即3 4 5)。
迭代过程3
对于m=3,在权值分布为D3 = (0.0455, 0.0455, 0.0455, 0.1667, 0.1667, 0.01667, 0.1060, 0.1060, 0.1060, 0.0455)的训练数据上,经过计算可得:
1. 阈值v取
2.5时误差率为0.1060*3(x < 2.5时取1,x > 2.5时取-1,则6 7 8分错,误差率为0.1060*3),
2. 阈值v取5.5时误差率最低为0.0455*4(x > 5.5时取1,x < 5.5时取-1,则0 1 2 9分错,误差率为0.0455*3 + 0.0715),
3. 阈值v取8.5时误差率为0.1667*3(x < 8.5时取1,x > 8.5时取-1,则3 4 5分错,误差率为0.1667*3)。
所以阈值v取5.5时误差率最低,故第三个基本分类器为(下图画反了,待后续修正):
依然还是原样本:
此时,被误分类的样本是:0 1 2 9,这4个样本所对应的权值皆为0.0455,
所以G3(x)在训练数据集上的误差率e3= P(G3(xi)≠yi) = 0.0455*4 = 0.1820。
计算G3的系数:
更新训练数据的权值分布:
D4 = (0.125, 0.125, 0.125, 0.102, 0.102, 0.102, 0.065, 0.065, 0.065, 0.125)。
被分错的样本“0 1 2 9”的权值变⼤,其它被分对的样本的权值变⼩。
f3(x)=0.4236G1(x) + 0.6496G2(x)+0.7514G3(x)
此时,得到的第三个基本分类器sign(f3(x))在训练数据集上有0个误分类点。
⾄此,整个训练过程结束。
G(x) = sign[f3(x)] = sign[ a1 * G1(x) + a2 * G2(x) + a3 * G3(x) ],将上⾯计算得到的a1、a2、a3各值代⼊G(x)中,得到最终的分类器为:
G(x) = sign[f3(x)] = sign[ 0.4236G1(x) + 0.6496G2(x)+0.7514G3(x) ]。
------- ---- ⽤图解深⼊浅出的解释adaboost ---—————
也许你看了上⾯的介绍或许还是对adaboost算法云⾥雾⾥的,没关系,百度⼤⽜举了⼀个很简单的例⼦,你看了就会对这个算法整体上很清晰了。
下⾯我们举⼀个简单的例⼦来看看adaboost的实现过程:
图中,“+”和“-”分别表⽰两种类别,在这个过程中,我们使⽤⽔平或者垂直的直线作为分类器,来进⾏分类。
第⼀步:
根据分类的正确率,得到⼀个新的样本分布D2,⼀个⼦分类器h1
其中划圈的样本表⽰被分错的。
在右边的途中,⽐较⼤的“+”表⽰对该样本做了加权。
也许你对上⾯的ɛ1,ɑ1怎么算的也不是很理解。
下⾯我们算⼀下,不要嫌我啰嗦,我最开始就是这样思考的,只有⾃⼰把算法演算⼀遍,你才会真正的懂这个算法的核⼼,后⾯我会再次提到这个。
算法最开始给了⼀个均匀分布 D 。
所以h1 ⾥的每个点的值是0.1。
ok,当划分后,有三个点划分错了,根据算法误差表达式
得到误差为分错了的三个点的值之和,所以ɛ1=(0.1+0.1+0.1)=0.3,⽽ɑ1 根据表达式的可以算出来为0.42.
然后就根据算法把分错的点权值变⼤。
如此迭代,最终完成adaboost算法。
第⼆步:
根据分类的正确率,得到⼀个新的样本分布D3,⼀个⼦分类器h2
第三步:
得到⼀个⼦分类器h3
整合所有⼦分类器:
因此可以得到整合的结果,从结果中看,及时简单的分类器,组合起来也能获得很好的分类效果,在例⼦中所有的。
五 Adaboost 疑惑和思考
到这⾥,也许你已经对adaboost算法有了⼤致的理解。
但是也许你会有个问题,为什么每次迭代都要把分错的点的权值变⼤呢?这样有什么好处呢?不这样不⾏吗? 这就是我当时的想法,为什么呢?我看了好⼏篇介绍adaboost 的博客,都没有解答我的疑惑,也许⼤⽜认为太简单了,不值⼀提,或者他们并没有意识到这个问题⽽⼀笔带过了。
然后我仔细⼀想,也许提⾼错误点可以让后⾯的分类器权值更⾼。
然后看了adaboost算法,和我最初的想法很接近,但不全是。
注意到算法最后的表到式为,这⾥⾯的a 表⽰的权
值,是由得到的。
⽽a是关于误差的表达式,到这⾥就可以得到⽐较清晰的答案了,所有的⼀切都指向了误差。
提⾼错误点的权值,当下⼀次分类器再次分错了这些点之后,会提⾼整体的错误率,这样就导致 a 变的很⼩,最终导致这个分类器在整个混合分类器的权值变低。
也就是说,这个算法让优秀的分类器占整体的权值更⾼,⽽挫的分类器权值更低。
这个就很符合常理了。
到此,我认为对adaboost已经有了⼀个透彻的理解了。
六总结
最后,我们可以总结下adaboost算法的⼀些实际可以使⽤的场景:
1)⽤于⼆分类或多分类的应⽤场景
2)⽤于做分类任务的baseline
⽆脑化,简单,不会overfitting,不⽤调分类器
3)⽤于特征选择(feature selection)
4)Boosting框架⽤于对badcase的修正
只需要增加新的分类器,不需要变动原有分类器
由于adaboost算法是⼀种实现简单,应⽤也很简单的算法。
Adaboost算法通过组合弱分类器⽽得到强分类器,同时具有分类错误率上界随着训练增加⽽稳定下降,不会过拟合等的性质,应该说是⼀种很适合于在各种分类场景下应⽤的算法。
这个是我看过对adaboost写的⽐较容易懂的⽂章了,等有空的时候我⾃⼰运⾏下adaboost的python代码,到时候再把这篇⽂章修改下。
对了,如果看到我的博客后,有意愿和我技术沟通的,可以加我QQ 340217138 讨论。
参考:。