当前位置:   article > 正文

AdaBoost.M1 算法原理与python实现:弱模型到强模型——机器学习笔记之集成学习PartⅡ_adaboostm1

adaboostm1

* * * The Machine Learning Noting Series  * * *

导航

  简介

  AdaBoost.M1算法步骤

  Python应用举例

  AdaBoost.M1算法原理的进一步推导

一 简介

之前文章袋装法和随机森林的思路是建立并列的一系列树构成“投票委员会”提高结果的准确性,集成学习的另一个策略是将一系列具有顺序相关的弱模型组成一个强模型,而不会有过拟合的问题。从弱模型到强模型的常见集成学习法有提升法(Boosting)和梯度提升树(Gradient Boosted Decision Tree,GBDT)等。本文主要介绍AdaBoost.M1提升算法。

AdaBoost算法(Adaptive Boosting)又称适应性提升法,主要用于解决输出变量仅有-1和+1两个类别时的分类预测问题。(SAMME算法将输出变量推广到多余2类)抽取训练集的Bootstrap方法点击这里查看

二 AdaBoost.M1算法步骤

开始时,每个样本被抽中的概率一样,即每个样本的权重相同:w_{i}^{(1)}=\frac{1}{N},i=1,2,...,N.,然后进行如下的b=1,2,...,B次迭代,最终形成带有权重的联合委员会,产生最终预测结果:

第一步,基于权重w^{(b)}下的训练集 S_{b} 建立第b个弱模型 G_{b}(X).

说明S_{b} 为Bootstrap训练集,样本量为N。每次迭代产生的训练集中每个样本都会产生自己的权重(这里的权重即下次Bootstrap建立训练集时被抽到的概率)

第二步,计算 G_{b}(X) 的训练误差:

err^{(b)}=\frac{1}{N}\sum_{i=1}^{N}I(y_{i}\neq G_{b}(X_{i}))= \frac{\sum_{i=1}^{N}w_{i}^{(b)}I(y_{i}\neq G_{b}(X_{i}))}{\sum_{i=1}^{N}w_{i}^{(b)}}(< 0.5)

说明:二分类随机猜测误差等于0.5,因此弱模型训练误差小于0.5;从上式可以看出,预测错误的样本,若其权重w_{i}^{(b)}越大,则对误差的贡献也越大。I(·)为示性函数,当括号内条件成立时函数等于1,否则等于0.

第三步,设置联合预测中G_{b}(X)的权重:

\alpha _{b}=log\left ( \frac{1-err^{(b)}}{err^{(b)}} \right )

第四步,基于w_{i}^{(b)}得到更新的下一次Bootstrap抽样权重w_{i}^{(b+1)}

w_{i}^{(b+1)}=w_{i}^{(b)}\cdot e^{\alpha _{b}I(y_{i}\neq G_{b}(X_{i}))},i=1,2,...,N

说明:被G_{b}(X)错误预测的样本观测的权重是正确预测的e^{\alpha _{b}I(y_{i}\neq G_{b}(X_{i}))}= \frac{1-err^{(b)}}{err^{(b)}}倍(若预测正确则权重不变),此外,应满足\frac{1-err^{(b)}}{err^{(b)}} >1,i.e.,err^{(b)}< 0.5G_{b}(X)应是一个弱模型。可以看出,错误预测的而样本观测具有较高权重,在下次加权时有更大几率进入训练集,收到更多关注,因此每次迭代的模型具有顺序相关性

上述每增加一次迭代,就会有一个新的弱模型加入“联合委员会”参与预测,这是向前分步可加建模(Forward Stagewise Additive Modeling)的具体体现,这类建模方法在迭代过程中会有新的成员不断进入“委员会”参与预测,先前进入的模型参数和权重不受后续进入模型的影响,且每次迭代仅需估计当前模型的参数和权重。

迭代结束时会有B 个弱模型组成的“联合委员会”,依据符号sign\left ( \sum_{b}^{B} \alpha _{b}G_{b}(X_{i}))\right )来确定X_{i}的类别。

三 Python 应用举例

这里首先模拟生成800个数据,然后建立树深度为1的弱分类器作为提升法的基础学习器,并迭代500次,然后展示训练误差的变化。代码来自参考文献。

  1. # 需导入的模块
  2. import numpy as np
  3. import pandas as pd
  4. import warnings
  5. warnings.filterwarnings(action = 'ignore')
  6. import matplotlib.pyplot as plt
  7. %matplotlib inline
  8. plt.rcParams['font.sans-serif']=['SimHei'] #解决中文显示乱码问题
  9. plt.rcParams['axes.unicode_minus']=False
  10. from sklearn.model_selection import train_test_split,KFold,cross_val_score
  11. from sklearn import tree
  12. import sklearn.linear_model as LM
  13. from sklearn import ensemble
  14. from sklearn.datasets import make_classification,make_circles,make_regression
  15. from sklearn.metrics import zero_one_loss,r2_score,mean_squared_error,accuracy_score
  16. import xgboost as xgb
  1. # 提升法建模,计算各迭代次数下的训练误差
  2. N=800
  3. X,Y=make_circles(n_samples=N,noise=0.2,factor=0.5,random_state=123)
  4. unique_lables=set(Y)
  5. fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(15,6))
  6. colors=plt.cm.Spectral(np.linspace(0,1,len(unique_lables)))
  7. markers=['o','*']
  8. for k,col,m in zip(unique_lables,colors,markers):
  9. x_k=X[Y==k]
  10. #plt.plot(x_k[:,0],x_k[:,1],'o',markerfacecolor=col,markeredgecolor="k",markersize=8)
  11. axes[0].scatter(x_k[:,0],x_k[:,1],color=col,s=30,marker=m)
  12. axes[0].set_title('%d个样本观测点的分布情况'%N)
  13. axes[0].set_xlabel('X1')
  14. axes[0].set_ylabel('X2')
  15. dt_stump = tree.DecisionTreeClassifier(max_depth=1, min_samples_leaf=1)
  16. B=500
  17. adaBoost = ensemble.AdaBoostClassifier(base_estimator=dt_stump,n_estimators=B,algorithm="SAMME",random_state=123)
  18. adaBoost.fit(X,Y)
  19. adaBoostErr = np.zeros((B,))
  20. for b,Y_pred in enumerate(adaBoost.staged_predict(X)):
  21. adaBoostErr[b] = zero_one_loss(Y,Y_pred)
  22. axes[1].plot(np.arange(B),adaBoostErr,linestyle='-')
  23. axes[1].set_title('迭代次数与训练误差')
  24. axes[1].set_xlabel('迭代次数')
  25. axes[1].set_ylabel('训练误差')
  1. # 图形化展示不同迭代次数下各样本观测的权重变化
  2. fig = plt.figure(figsize=(15,12))
  3. data=np.hstack((X.reshape(N,2),Y.reshape(N,1)))
  4. data=pd.DataFrame(data)
  5. data.columns=['X1','X2','Y']
  6. data['Weight']=[1/N]*N
  7. for b,Y_pred in enumerate(adaBoost.staged_predict(X)):
  8. data['Y_pred']=Y_pred
  9. data.loc[data['Y']!=data['Y_pred'],'Weight'] *= (1.0-adaBoost.estimator_errors_[b])/adaBoost.estimator_errors_[b]
  10. if b in [5,10,20,450]:
  11. axes = fig.add_subplot(2,2,[5,10,20,450].index(b)+1)
  12. for k,col,m in zip(unique_lables,colors,markers):
  13. tmp=data.loc[data['Y']==k,:]
  14. tmp['Weight']=10+tmp['Weight']/(tmp['Weight'].max()-tmp['Weight'].min())*100
  15. axes.scatter(tmp['X1'],tmp['X2'],color=col,s=tmp['Weight'],marker=m)
  16. axes.set_xlabel('X1')
  17. axes.set_ylabel('X2')
  18. axes.set_title("高权重的样本观测点(迭代次数=%d)"%b)

下面左图为模拟样本的情况,其中圆圈和五角星分别代表输出变量的两个类别,在使用树深度为1的弱学习器迭代500次后求出训练误差,右图显示在迭代次数上升时误差急剧下降,而后再缓慢下降,说明算法迭代效率高。

 下图展示了不同迭代次数下高权重样本的分布情况,符号越大,代表下次Bootstrap倍抽样进入训练集的概率也就越大。可以看出:①较大的点都是之前弱模型没有预测正确的点,这些点基本集中在两类的边界处,②随着迭代次数增加,此特点愈发明显。

四 AdaBoost.M1算法原理的进一步推导

 可见,AdaBoost.M1算法是一种最小化指数损失函数的向前分步可加建模方法。指数损失函数对参数估计值变化的敏感程度大于训练误差,应用更广泛。

参考文献

《Python机器学习 数据建模与分析》,薛薇 等/著

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/75539
推荐阅读
相关标签
  

闽ICP备14008679号