集成学习(ensemble learning)之AdaBoost

来源:互联网 发布:离婚率 知乎 编辑:程序博客网 时间:2024/05/01 22:13

个体学习器:通常由一个现有的学习算法从训练数据产生的,例如C4.5决策树算法等。
基学习器:如“决策树集成”中全是决策树,“神经网络集成”中全是神经网络,这样的集成是“同质”的(homogeneous)。同质集成中的个体学习器亦称“基学习器”(base learner),相应的学习算法称为“基学习算法”。

什么是集成学习?
先产生一组“个体学习器”(individual learner),再用某种策略将它们结合起来。
集成学习的结果通过投票法产生,即“少数服从多数”。要获得好的集成,个体学习器应“好而不同”,即个体学习器要有一定的“准确性”,即学习器不能太坏,并且要有“多样性”,即学习器间具有差异,

根据个体学习器的生成方式,目前的集成学习方法大概可以分为以下两类:
1、Boosting算法:在Boosting算法中,个体学习器之间存在强依赖关系,必须串行生成。
2、Bagging算法:在Bagging算法中,个体学习器之间不存在强依赖关系,可同时生成。

Boosting算法
提升方法(Boosting)是一种常见的统计学习方法。提升方法的理论基础是:强可学习与弱可学习是等价的。在概率近似正确(PAC)学习的框架下:
1、强可学习是一种概念(或一个类别),若存在一个多项式的学习算法能够学习它,并且正确率很高,那么称这个概念是强可学习的。
2、弱可学习是一种概念(或一个类别),若存在一个多项式的学习算法能够学习它,学习的正确率仅比随机猜测略好,那么称这个概念是弱可学习的。

对于分类问题而言,求一个比较粗糙的分类规则(弱分类器)要比求精确的分类规则(强分类器)要容易得多。Boosting就是一种可以将弱学习器提升为强学习器的算法。

工作步骤如下:
- 先从初始训练集训练出一个基学习器
- 再根据基学习器的表现对训练样本权重进行调整,使得被先前的基学习器误判的训练样本在后续受到更多关注
- 然后基于调整后的样本权重来训练下一个基学习器
- 如此重复,直到基学习器数量达到给定的值M为止
- 最终将这M个基学习器进行加权组合得到集成学习器

AdaBoost算法
两个核心步骤:
1、权值调整:AdaBoost算法提高那些被前一轮基分类器错误分类样本的权值,而降低那些被正确分类样本的权值。从而使得那些没有得到正确分类的样本,由于权值的加大而受到后一轮基分类器的更大关注。
2、基分类器组合:AdaBoost采用加权多数表决的方法:
(1)加大分类误差率较小的弱分类器的权值,使得它在表决中起较大的作用。
(2)减小分类误差率较大的弱分类器的权值,使得它在表决中起较小的作用。

scikit-learn基于AdaBoost算法提供了两个模型:
AdaBoostClassifier用于分类问题
AdaBoostRegressor用于回归问题

AdaBoostClassifier分类器
ensemble.AdaBoostClassifier()

参数

  • base_estimator:是一个基础分类器。默认为DecisionTreeClassifier,该基础分类器必须支持带样本权重的学习
  • n_estimators:一个整数,指定基础分类器的数量(默认为50)。如果训练集已经完美地训练好了,可能算法会停止,此时基础分类器的数量少于该值
  • learning_rate:浮点数,默认为1.用于减少每一步的步长,防止步长太大而跨过了极值点。通常learning_rate越小,则需要的基础分类器数量会越多。
  • algorithm:一个字符串,指定算法,该算法用于多分类问题,默认为’SAMME.R’

属性

  • estimators_:所有训练过的基础分类器
  • classes_:所有的类别标签
  • n_classes_:类别数量
  • estimator_weights_:每个基础分类器的权重
  • estimator_errors:每个基础分类器的分类器的分类误差
  • feature_importances_:每个特征的重要性

方法

  • score(X,y[,sample_weight]):返回在(X,y)上预测的准确率(accuracy)
  • staged_predict(X):返回一个数组,数组元素依次是每一轮迭代结束时尚未完成的集成分类器的预测值
  • staged_predict_proba(X):返回一个二维数组,数组元素依次是每一轮迭代结束时尚未完成的集成分类器预测X为各个类别的概率值
  • staged_score(X,y[,sample_weight]):返回一个数组,数组元素依次是每一轮迭代结束时尚未完成的集成分类器的预测准确率

AdaBoostRegressor回归器
ensemble.AdaBoostRegressor()

参数

  • loss:一个字符串,指定了损失函数,可以为
    ‘linear’:线性损失函数(默认)
    ‘square’:平方损失函数
    ‘exponential’:指数损失函数

方法

  • staged_predict(X):返回一个数组,数组元素依次是每一轮迭代结束时尚未完成的集成回归器的预测值
  • staged_score(X,y[,sample_weight]):返回一个数字,数组元素依次是每一轮迭代结束时尚未完成的集成回归器的预测性能得分
# -*- coding: utf-8 -*-"""Created on Tue Oct 31 16:45:20 2017@author: Yxm"""import matplotlib.pyplot as pltimport numpy as npfrom sklearn import datasets,cross_validation,ensembledef load_data_regression():    diabetes=datasets.load_diabetes()    return cross_validation.train_test_split(diabetes.data,diabetes.target,test_size=0.25,random_state=0)def load_data_classification():    digits=datasets.load_digits()    return cross_validation.train_test_split(digits.data,digits.target,test_size=0.25,random_state=0)def test_AdaBoostClassifier(*data):    X_train,X_test,y_train,y_test=data    clf=ensemble.AdaBoostClassifier(learning_rate=0.1)    clf.fit(X_train,y_train)    fig=plt.figure()    ax=fig.add_subplot(1,1,1)    estimators_num=len(clf.estimators_)    X=range(1,estimators_num+1)    ax.plot(list(X),list(clf.staged_score(X_train,y_train)),label="Training score")    ax.plot(list(X),list(clf.staged_score(X_test,y_test)),label="Testing score")    ax.set_xlabel("estimator num")    ax.set_ylabel("score")    ax.legend(loc="best")    ax.set_title("AdaBoostClassifier")    plt.show()X_train,X_test,y_train,y_test=load_data_classification()test_AdaBoostClassifier(X_train,X_test,y_train,y_test)test_AdaBoostClassifier_base_classifier(X_train,X_test,y_train,y_test)###考察不同类型的个体分类器的影响def test_AdaBoostClassifier_base_classifier(*data):    from sklearn.naive_bayes import GaussianNB    X_train,X_test,y_train,y_test=data    fig=plt.figure()    ax=fig.add_subplot(2,1,1)    #默认的个体分类器    clf=ensemble.AdaBoostClassifier(learning_rate=0.1)    clf.fit(X_train,y_train)    estimators_num=len(clf.estimators_)    X=range(1,estimators_num+1)    ax.plot(list(X),list(clf.staged_score(X_train,y_train)),label="Training score")    ax.plot(list(X),list(clf.staged_score(X_test,y_test)),label="Testing score")    ax.set_xlabel("estimator num")    ax.set_ylabel("score")    ax.legend(loc="lower right")    ax.set_ylim(0,1)    ax.set_title("AdaBoostClassifier with Decision Tree")    #Gaussian Naive Bayes个体分类器    ax=fig.add_subplot(2,1,2)    clf=ensemble.AdaBoostClassifier(learning_rate=0.1,base_estimator=GaussianNB())    clf.fit(X_train,y_train)    estimators_num=len(clf.estimators_)    X=range(1,estimators_num+1)    ax.plot(list(X),list(clf.staged_score(X_train,y_train)),label="Training score")    ax.plot(list(X),list(clf.staged_score(X_test,y_test)),label="Testing score")    ax.set_xlabel("estimator num")    ax.set_ylabel("score")    ax.legend(loc="lower right")    ax.set_ylim(0,1)    ax.set_title("AdaBoostClassifier with Gaussian Naive Bayes")    plt.show()###考察学习率的影响def test_AdaBoostClassifier_learning_rate(*data):    X_train,X_test,y_train,y_test=data    learning_rates=np.linspace(0.01,1)    fig=plt.figure()    ax=fig.add_subplot(1,1,1)    training_scores=[]    testing_scores=[]    for learning_rate in learning_rates:        clf=ensemble.AdaBoostClassifier(learning_rate=learning_rate,n_estimators=500)        clf.fit(X_train,y_train)        training_scores.append(clf.score(X_train,y_train))        testing_scores.append(clf.score(X_test,y_test))    ax.plot(learning_rates,training_scores,label="Training score")    ax.plot(learning_rates,testing_scores,label="Testing score")    ax.set_xlabel("learning rate")    ax.set_ylabel("score")    ax.legend(loc="best")    ax.set_title("AdaBoostClassifier")    plt.show()test_AdaBoostClassifier_learning_rate(X_train,X_test,y_train,y_test)###考察algorithm的影响def test_AdaBoostClassifier_algorithm(*data):    X_train,X_test,y_train,y_test=data    algorithms=['SAMME.R','SAMME']    fig=plt.figure()    learning_rates=[0.05,0.1,0.5,0.9]    for i,learning_rate in enumerate(learning_rates):        ax=fig.add_subplot(2,2,i+1)        for i,algorithm in enumerate(algorithms):            clf=ensemble.AdaBoostClassifier(learning_rate=learning_rate,algorithm=algorithm)            clf.fit(X_train,y_train)            estimators_num=len(clf.estimators_)            X=range(1,estimators_num+1)            ax.plot(list(X),list(clf.staged_score(X_train,y_train)),label="%s:Training score"%algorithms[i])            ax.plot(list(X),list(clf.staged_score(X_test,y_test)),label="%s:Testing score"%algorithms[i])        ax.set_xlabel("estimator num")        ax.set_ylabel("score")        ax.legend(loc="lower right")        ax.set_title("learning rate:%f"%learning_rate)    fig.suptitle("AdaBoostClassifier")    plt.show()###使用AdaBoostRegressor的函数def test_AdaBoostRegressor(*data):    X_train,X_test,y_train,y_test=data    regr=ensemble.AdaBoostRegressor()    regr.fit(X_train,y_train)    fig=plt.figure()    ax=fig.add_subplot(1,1,1)    estimators_num=len(regr.estimators_)    X=range(1,estimators_num+1)    ax.plot(list(X),list(regr.staged_score(X_train,y_train)),label="Training score")    ax.plot(list(X),list(regr.staged_score(X_test,y_test)),label="Testing score")    ax.set_xlabel("estimator num")    ax.set_ylabel("score")    ax.legend(loc="best")    ax.set_title("AdaBoostRegressor")    plt.show()X_train,X_test,y_train,y_test=load_data_regression()test_AdaBoostRegressor(X_train,X_test,y_train,y_test)###考察不同类型的个体分类器的影响def test_AdaBoostRegressor_base_regr(*data):    from sklearn.svm import LinearSVR    X_train,X_test,y_train,y_test=data    fig=plt.figure()    regrs=[ensemble.AdaBoostRegressor(),ensemble.AdaBoostRegressor(base_estimator=LinearSVR(epsilon=0.01,C=100))]    labels=["Decision Tree Regressor","Linear SVM Regressor"]    for i,regr in enumerate(regrs):        ax=fig.add_subplot(2,1,i+1)        regr.fit(X_train,y_train)        estimators_num=len(regr.estimators_)        X=range(1,estimators_num+1)        ax.plot(list(X),list(regr.staged_score(X_train,y_train)),label="Training score")        ax.plot(list(X),list(regr.staged_score(X_test,y_test)),label="Testing score")        ax.set_xlabel("estimator num")        ax.set_ylabel("score")        ax.legend(loc="lower right")        ax.set_ylim(-1,1)        ax.set_title("Base_Estimator:%s"%labels[i])    plt.suptitle("AdaBoostRegressor")    plt.show()###考察学习率的影响def test_AdaBoostRegressor_learning_rate(*data):    X_train,X_test,y_train,y_test=data    learning_rates=np.linspace(0.01,1)    fig=plt.figure()    ax=fig.add_subplot(1,1,1)    training_scores=[]    testing_scores=[]    for learning_rate in learning_rates:        regr=ensemble.AdaBoostRegressor(learning_rate=learning_rate,n_estimators=500)        regr.fit(X_train,y_train)        training_scores.append(regr.score(X_train,y_train))        testing_scores.append(regr.score(X_test,y_test))    ax.plot(learning_rates,training_scores,label="Training score")    ax.plot(learning_rates,testing_scores,label="Testing score")    ax.set_xlabel("learning rate")    ax.set_ylabel("score")    ax.legend(loc="best")    ax.set_title("AdaBoostRegressor")    plt.show()###考察损失函数的影响def test_AdaBoostRegressor_loss(*data):    X_train,X_test,y_train,y_test=data    losses=['linear','square','exponential']    fig=plt.figure()    ax=fig.add_subplot(1,1,1)    for i,loss in enumerate(losses):        regr=ensemble.AdaBoostRegressor(loss=loss,n_estimators=30)        regr.fit(X_train,y_train)        estimators_num=len(regr.estimators_)        X=range(1,estimators_num+1)        ax.plot(list(X),list(regr.staged_score(X_train,y_train)),label="Training score:loss=%s"%loss)        ax.plot(list(X),list(regr.staged_score(X_test,y_test)),label="Testing score:loss=%s"%loss)        ax.set_xlabel("estimator num")        ax.set_ylabel("score")        ax.legend(loc="lower right")        ax.set_ylim(-1,1)        ax.set_title("AdaBoostRegressor")        plt.show()