Boosting是一类算法的统称,其基本思想很简单,就是”三个臭皮匠顶个诸葛亮”:针对同一个训练集训练不同的分类器(弱分类器),然后把这些弱分类器集合起来,构成一个更强的最终分类器(强分类器)。常见的分类算法,如kNN、线性分类器、决策树等,均可经过特殊约束构造弱分类器。
弱弱联合,变得更强!!!强在准确度上比较好理解,但是怎么提高效率就有点困惑了。因为本来只需训练单个强分类器便可以解决问题,现在却要多个弱分类器组合才能得到结果,计算次数和成本“明显”增加了。其实这块的优化是单个弱分类器的计算开销远远地低于单个强分类器,如判断一个新样本,单个强分类器可能需要对比十个属性才能得到分类结果,但每个弱分类器每次只需要对比一个属性,即使五个弱分类器组合,计算成本也远远小于单个强分类器。
对于Boosting算法,主要存在两个问题:
针对以上两个问题,1995年,Freund and Schapire改进了Boosting算法,取名为Adaboost算法。AdaBoost算法的调整主要是:
AdaBoost算法的具体步骤如下:
1.给定训练样本集S: (x1,y1),(x2,y2),......(xn,yn) ,其中 xi∈X 和 yi∈Y={−1,+1} ;T为训练的最大循环次数;
2.初始化样本权重为 D1=1/n ,即为训练样本的初始概率分布;
3.对于T轮训练,For t =1,2,……,T:
(1)基于当前训练样本的概率分布 Dt ,训练弱分类器 ht ;
(2)计算弱分类器的错误率:
4.经T次循环后,得到T个弱分类器,按更新的权重叠加,最终得到的强分类器:
下面我们举一个简单的例子来看看Adaboost 的实现过程。 图中,“+”和“-”分别表示两种类别,在这个过程中,我们使用水平或者垂直的直线作为弱分类器,来进行分类:
第一步根据分类的正确率,得到一个新的样本分布 D2 ,一个子分离器 h1 .其中画圈的样本表示被分错的。在右边图中,比较大的“+”表示对该样本做了加权。具体过程为算法最开始给了一个均匀的分布 D1 ,所以每个点的值为0.1。当划分后,有三个点被划分错了,根据算法的误差表达式 ϵ1=Pr[h1(xi)≠yi] 得到误差为分错了的三个点的概率值之和,则 ϵ1=0.1+0.1+0.1=0.3 ,而 α1=0.42 ,然后增加分错点的权值。
基于新分布 D2 ,得到一个新的一个子分类器 h2 及样本分布 D3 ,。
再基于新的样本分布 D3 ,得到一个子分类器 h3 。
此时迭代结束,得到3个弱分类器。最终的强分类器由 h1 、 h2 、 h3 线性组合获得。
每个区域是属于哪个属性,由这个区域所在分类器的权值综合决定。比如左下角的区域,属于蓝色分类区的权重为 h1 中的0.42和 h2 中的0.65,其和为1.07;属于淡红色分类区域的权重为 h3 中的0.92;属于淡红色分类区的权重小于属于蓝色分类区的权值,因此左下角属于蓝色分类区。因此可以得到整合的结果如上图所示,从结果图中看,即使是简单的分类器,组合起来也能获得很好的分类效果。
注意到算法最后的表到式为
# -*- coding: utf-8 -*-
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_iris
from sklearn.ensemble import AdaBoostClassifier
#加载iris数据集
irisdata = load_iris()
#调用Adaboost模型,迭代次数为100
numT = 100
clf = AdaBoostClassifier(n_estimators=numT)
#交叉验证
scores = cross_val_score(clf, irisdata.data, irisdata.target)
accres = scores.mean()
print accres
注:AdaBoostClassifier函数介绍:http://scikit-learn.org/stable/modules/generated/sklearn.ensemble.AdaBoostClassifier.html
cross_val_score函数介绍:http://scikit-learn.org/stable/modules/generated/sklearn.cross_validation.cross_val_score.html
正确率: