机器学习之Adaboost

来源:互联网 发布:手机淘宝4.6.0下载 编辑:程序博客网 时间:2024/06/05 00:15

主要内容:
1.何为提升学习方法adaboost
2.adaboost算法步骤
3. 代码实现
4. sklearn使用

一、何为提升学习方法

历史上,Kearns和Valiant首先提出了“强可学习(strongly learnable)”和“弱可学习(weakly learnable)”的概念。指出:在概率近似正确(probably approximately correct,PAC)学习框架中,一个概念(一个分类),如果存在一个多项式的学习算法能够学习它,并且正确率很高,那么就称这个概念是强可学习的;一个概念,如果存在一个多项式的学习算法能够学习它,学习的正确率仅比随机猜测略好,那么就称这个概念是弱可学习的。非常有趣的是Schapire后来证明强可学习与弱可学习是等价的,也就是说,在PAC学习的框架下,一个概念是强可学习的充分必要条件是这个概念是弱可学习的。
这样一来,问题便成为,在学习中,如果已经发现了“弱学习算法”,那么能否将它提升(boost)为“强学习算法”。大家知道,发现弱学习算法通常要比发现强学习算法容易得多。那么如何具体实施提升,便成为开发提升方法时所要解决的问题。关于提升方法的研究很多,有很多算法被提出。最具代表性的是AdaBoost算法(AdaBoost algorithm)。
对于分类问题而言,给定一个训练样本集,求比较粗糙的分类规则(弱分类器)要比求精确的分类规则(强分类器)容易得多。提升方法就是从弱学习算法出发,反复学习,得到一系列弱分类器,然后组合这些分类器,构成一个强分类器。

那么问题来了:
1. 在每一轮如何改变训练数据的权值分布?
2. 如何将弱分类器组合成为一个强分类器?
答案是:
1. 提高那些被前一轮弱分类器错误分类样本的权值,而降低那些被正确分类样本的权值
2. 采用加权多数表决的方法
然而,后者好理解,前者呢,为什么要提高错分类样本的权值?对下一次分类器的训练会造成什么影响?

二、Adaboost算法步骤
(1) 初始化训练数据的权值系数

D1=(w11,...,w1i,...,w1N),w1i=1N,i=1,2,...,N(1)

(2)对m=1,2,...,M,这是一个迭代的过程

  • 使用具有权值系数Dm的训练数据集创建弱分类器Gm(x)
  • 计算 Gm(x)在训练数据集上的分类误差率

    em=i=1NwmiI(Gm(xi)yi)(2)

  • 计算Gm(x)的系数

    αm=12log1emem(3)

    由此式可知,当误差率em>1/2时,分类器Gm(x)的系数αm>0
    αm与误差率em成反比,可以看出误差率越小的弱分类器在最终分类器中的作用越大。

  • 更新训练数据的权值系数

    Dm+1=(wm+1,1,wm+1,2,...,wm+1,N)(4)

    wm+1,i=wmiZmexp(αmyiGm(xi))(5)

    Zm=i=1Nwm,iexp(αmyiGm(xi))(6)

    可以看出,正分类样本的权重更新是wmiexp(αm)/Zm,权值变小
    误分类样本的权重更新是wmiexp(αm)/Zm,权值变大

(3)怎么迭代?样本权重更新对分类器的训练有影响吗?貌似并没有啊。。。学习的过程在哪里?目标函数在哪里
对样本的分布有影响,因而对损失函数(交叉熵)有影响。在上一次的训练中错分类的权重增大。新的样本中训练分类器,权重越大的样本对损失函数的影响越大,因而在训练时,这个错分类的样本就会被重视,训练的准确率也会提高。

(4)最终的强分类器公式为

G(x)=sign(m=1MαmGm(x))(7)

三、代码实现

四、sklearn使用

这段非常好的诠释了Adaboost
An AdaBoost [1] classifier is a meta-estimator that begins by fitting a classifier on the original dataset and then fits additional copies of the classifier on the same dataset but where the weights of incorrectly classified instances are adjusted such that subsequent classifiers focus more on difficult cases.

    class sklearn.ensemble.AdaBoostClassifier(base_estimator=None, n_estimators=50, learning_rate=1.0, algorithm=’SAMME.R’, random_state=None)

parameters:

base_estimator : object, optional (default=DecisionTreeClassifier)
弱分类器,默认DecisionTreeClassifier
理论上可以选择任何一个分类或者回归学习器,不过需要支持样本权重。我们常用的一般是CART决策树或者神经网络MLP。默认是决策树,即AdaBoostClassifier默认使用CART分类树DecisionTreeClassifier,而AdaBoostRegressor默认使用CART回归树DecisionTreeRegressor。另外有一个要注意的点是,如果我们选择的AdaBoostClassifier算法是SAMME.R,则我们的弱分类学习器还需要支持概率预测,也就是在scikit-learn中弱分类学习器对应的预测方法除了predict还需要有predict_proba

n_estimators : integer, optional (default=50)
弱分类器的数量,In case of perfect fit, the learning procedure is stopped early

learning_rate : float, optional (default=1.)
Learning rate shrinks the contribution of each classifier by learning_rate. There is a trade-off between learning_rate and n_estimator. 通过学习率缩小每个分类器的贡献。 learning_rate和n_estimator之间存在权衡。
每个弱学习器的权重缩减系数vv,对于同样的训练集拟合效果,较小的νν意味着我们需要更多的弱学习器的迭代次数。通常我们用步长和迭代最大次数一起来决定算法的拟合效果,这两个参数n_estimators和learning_rate要一起调参。一般来说,可以从一个小一点的νν开始调参,默认是1。

algorithm :{‘SAMME’, ‘SAMME.R’}, optional (default=’SAMME.R’)
这个参数只有AdaBoostClassifier有。主要原因是scikit-learn实现了两种Adaboost分类算法,SAMME和SAMME.R。两者的主要区别是弱学习器权重的度量,SAMME使用了和我们的原理篇里二元分类Adaboost算法的扩展,即用对样本集分类效果作为弱学习器权重,而SAMME.R使用了对样本集分类的预测概率大小来作为弱学习器权重。由于SAMME.R使用了概率度量的连续值,迭代一般比SAMME快,因此AdaBoostClassifier的默认算法algorithm的值也是SAMME.R。我们一般使用默认的SAMME.R就够了,但是要注意的是使用了SAMME.R, 则弱分类学习器参数base_estimator必须限制使用支持概率预测的分类器。SAMME算法则没有这个限制。

    from sklearn.ensemble import AdaBoostClassifier    from sklearn.datasets import make_gaussian_quantiles    import numpy as np    import matplotlib.pyplot as plt    def load_data():        ##生成2维正太分布,生成的数据按分位数分成两类,500个样本,2个样本特征,协防差系数为2        x1 , y1 = make_gaussian_quantiles(cov=2.0,n_samples=500,n_features=2,n_classes=2,random_state=1)        ##生成2维正太分布,生成的数据按分位数分成两类,500个样本,2个样本特征,协防差系数为2        x2 , y2 = make_gaussian_quantiles(mean=(3,3),cov=1.5,n_samples=400,n_features=2,n_classes=2,random_state=1)        ##将两组数据合成一组数据        X = np.concatenate((x1,x2))        y = np.concatenate((y1,-y2+1))        plt.scatter(X[:,0],X[:,1],marker='o',c=y)        #plt.show()        return X,y    def plot_decision_boundary(X,y):        X,y = load_data()        x_min,x_max = X[:,0].min()-1, X[:,0].max()+1        y_min,y_max = X[:,1].min()-1, X[:,1].max()-1        xx,yy = np.meshgrid(np.arange(x_min,x_max,0.02),                            np.arange(y_min,y_max,0.02))        z = dbt.predict(np.c_[xx.ravel(),yy.ravel()])        Z = z.reshape(xx.shape)        plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)        plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Spectral)        plt.show()    if __name__=='__main__':        X,y = load_data()        dbt = AdaBoostClassifier(n_estimators=200, learning_rate=0.8)        print(dbt)        clf = dbt.fit(X, y)        print(clf.score(X,y))        plot_decision_boundary(X,y)

运行结果:

    AdaBoostClassifier(algorithm='SAMME.R', base_estimator=None,              learning_rate=0.8, n_estimators=200, random_state=None)    0.895555555556

这里写图片描述
这里写图片描述

参考:

  1. http://blog.csdn.net/sun_shengyun/article/details/54289955
  2. http://www.cnblogs.com/jasonfreak/p/5657196.html
原创粉丝点击