集成学习之AdaBoost算法

集成学习依据个体学习器之间是否存在依赖关系分为两类:一类是个体学习器之间存在强依赖关系,其代表算法是boosting算法;另一类是个体学习器之间不存在强依赖关系,代表算法是bagging算法。AdaBoost是最著名的算法之一,既可以做分类问题,也可以解决回归问题。

AdaBoost算法

Boosting的思想是对于一个复杂模型,每一个学习器是一个弱学习器,其学习能力有限,并不能很好的学习模型中的复杂特征,但是将每一个弱学习器学习的模型组合在一起形成一个强学习器,大大地提升了模型的学习能力,正所谓“三个臭皮匠顶个诸葛亮”。

假设给定一个二类分类的训练集T={(x1,y1),(x2,y2),...,(xN,yN)}T=\left\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\right\}T={(x1,y1),(x2,y2),...,(xN,yN)}
xix_ixi是n维向量,有n个特征,xi∈X⊆Rnx_i\in \mathcal X \subseteq R^nxiXRnyiy_iyi是类别标签,yi∈Y={−1,+1}y_i\in \mathcal {Y}=\left\{-1,+1\right\}yiY={1,+1}X\mathcal XX是实例空间,Y\mathcal YY是标记集合。AdaBoost利用以下算法,从训练数据中学习一系列弱分类器(基分类器),并将这些弱分类器线性组合成一个强分类器。

在介绍AdaBoost算法之前,先思考以下这些问题:

  1. 每一个弱学习器是如何训练得到的
  2. 如何将这些弱学习器组合在一起合成一个强学习器
  3. 如何通过这些组合的强学习器预测最终的结果
算法

输入:训练数据集T={(x1,y1),(x2,y2),...,(xN,yN)}T=\left\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\right\}T={(x1,y1),(x2,y2),...,(xN,yN)},其中xi∈X⊆Rnx_i\in \mathcal X \subseteq R^nxiXRnyi∈Y={−1,+1}y_i\in \mathcal {Y}=\left\{-1,+1\right\}yiY={1,+1};弱分类器;
输出:最终分类器G(x)G(x)G(x)

  1. 初始化训练数据的权值分布D1=(W11,W12,...,W1i,...,W1N),W1i=1N,i=1,2,3,...,ND_1=(W_{11},W_{12},...,W_{1i},...,W_{1N}), W_{1i}=\frac{1}{N},i=1,2,3,...,ND1=(W11,W12,...,W1i,...,W1N),W1i=N1,i=1,2,3,...,N
  2. 对于m=1,2,...,Mm=1,2,...,Mm=1,2,...,M,训练每一个弱分类器Gm(x)G_m(x)Gm(x)
    (a) 使用具有权值分布DmD_mDm的训练数据集学习,得到基分类器Gm(x):X→{−1,+1}G_m(x):\mathcal X\rightarrow\left\{-1,+1\right\}Gm(x):X{1,+1}
    (b) 计算Gm(x)G_m(x)Gm(x)在训练数据集上的分类误差率em=∑i=1NP(Gm(xi)≠yi)=∑i=1NWmiI(Gm(xi)≠yi)e_m=\sum_{i=1}^NP(G_m(x_i) =\not y_i)=\sum_{i=1}^NW_{mi}I(G_m(x_i) =\not y_i)em=i=1NP(Gm(xi)≠yi)=i=1NWmiI(Gm(xi)≠yi)
    (c) 计算Gm(x)G_m(x)Gm(x)的系数,其表示该弱分类器的重要性αm=12log1−emem\alpha_m=\frac{1}{2}log\frac{1-e_m}{e_m}αm=21logem1em
    (d) 更新训练数据集的下一轮的权值分布Dm+1=(Wm+1,1,Wm+2,2,...,Wm+1,i,...,Wm+1,N)D_{m+1}=(W_{m+1,1},W_{m+2,2},...,W_{m+1,i},...,W_{m+1,N})Dm+1=(Wm+1,1,Wm+2,2,...,Wm+1,i,...,Wm+1,N)Wm+1,i=WmiZmexp(−αmyiGm(xi))W_{m+1,i}=\frac{W_{mi}}{Z_m}exp(-\alpha_my_iG_m(x_i))Wm+1,i=ZmWmiexp(αmyiGm(xi))ZmZ_mZm是规划化因子,归一化处理。Zm=∑i=1NWmiexp(−αmyiGm(xi))Z_m=\sum_{i=1}^NW_{mi}exp(-\alpha_my_iG_m(x_i))Zm=i=1NWmiexp(αmyiGm(xi))它使得Dm+1D_{m+1}Dm+1成为一个概率分布。
  3. 构建基分类器的线性组合f(x)=∑m=1MαmGm(x)f(x)=\sum_{m=1}^M\alpha_mG_m(x)f(x)=m=1MαmGm(x)得到最终的分类器G(x)=sign(f(x))=sign(∑m=1MαmGm(x))G(x)=sign(f(x))=sign(\sum_{m=1}^M\alpha_mG_m(x))G(x)=sign(f(x))=sign(m=1MαmGm(x))
AdaBoost算法的解释说明

步骤1:假设训练数据集具有均匀的权值分布,即每个训练样本在基分类器的学习作用相同,数据集样本的权重初始化,这一假设保证能够在原始数据上学习基分类器G1(x)G_1(x)G1(x)
步骤2:AdaBoost迭代学习基分类器,在每一轮m=1,2,...,Mm=1,2,...,Mm=1,2,...,M按顺序执行以下操作:
(a) 使用当前分布DmD_mDm加权的训练数据集,学习基分类器Gm(x)G_m(x)Gm(x)
(b) 计算基分类器Gm(x)G_m(x)Gm(x)在加权训练数据集上的分类错误率:em=∑i=1NP(Gm(xi)≠yi)=∑Gm(xi)≠yiWmie_m=\sum_{i=1}^NP(G_m(x_i)=\not y_i)=\sum_{G_m(x_i)=\not y_i}W_{mi}em=i=1NP(Gm(xi)≠yi)=Gm(xi)≠yiWmiWmiW_{mi}Wmi表示第m轮中第i个实例的权值,∑i=1NWmi=1\sum_{i=1}^NW_{mi}=1i=1NWmi=1,表明Gm(x)G_m(x)Gm(x)在加权的训练数据集上的分类误差率是被Gm(x)G_m(x)Gm(x)误分类样本的权值之和。
(c) 计算基分类器Gm(x)G_m(x)Gm(x)的系数αm\alpha_mαmαm\alpha_mαm表示Gm(x)G_m(x)Gm(x)在最终分类器中的重要性。当em≤12e_m\leq \frac{1}{2}em21时,αm≥0\alpha_m\ge 0αm0,并且αm\alpha_mαm随着eme_mem的减少而增大,所以分类误差率越小的基分类器在最终分类器中的作用越大。
(d) 更新训练数据的权值分布为下一轮做准备
Wm+1,i={WmiZme−αm,Gm(xi)=yiWmiZmeαm,Gm(xi)≠yiW_{m+1,i} = \begin{cases} \frac{W_{mi}}{Z_m}e^{-\alpha_m}, G_m(x_i)=y_i \\ \frac{W_{mi}}{Z_m}e^{\alpha_m},G_m(x_i)=\not y_i \end{cases}Wm+1,i={ZmWmieαm,Gm(xi)=yiZmWmieαm,Gm(xi)≠yi
由此可知,被基分类器Gm(x)G_m(x)Gm(x)误分类样本的权值在扩大,而被正确分类样本的权值在缩小。相比较,误分类样本的权值被放大e2αm=1−ememe^{2\alpha_m}=\frac{1-e_m}{e_m}e2αm=em1em倍。正确分类的样本在下一轮的训练过程中的权重较小,而误分类样本在下一轮的学习权重较大。对于全体训练数据集,在每一轮训练之前更新对应的权重分布,使得训练数据在基分类器的学习中起着不同的作用。
步骤3:线性组合f(x)f(x)f(x)实现M个基分类器的加权表决。系数αm\alpha_mαm表示基分类器Gm(x)G_m(x)Gm(x)的重要程度。f(x)f(x)f(x)的符号决定了实例x的类别。

AdaBoost算法实例

AdaBoost的核心思想在于样本权重的更新和弱分类器权值的生成,样本权重的更新保证了前面的弱分类器重点处理普遍情况,后续的分类器重点处理疑难杂症。最终,弱分类器加权组合保证了前面的弱分类器会有更大的权重,这其实有先抓总体,再抓特例的分而治之思想。

AdaBoost算法的另一种解释

AdaBoost算法的目标是学习每一个弱学习器Gm(x)G_m(x)Gm(x)和对应的权重系数αm\alpha_mαm,然后将这些弱学习器线性组合成一个强学习器。因此,AdaBoost模型是加法模型,学习算法为前向分步算法。其中前向分步算法事实上是通过每一轮的弱学习器学习,利用前N轮的弱学习器的结果来更新后一个弱学习器的训练模型。

例如,前k-1轮的强学习器为:
fk−1(x)=∑i=1k−1αiGi(x)f_{k-1}(x)=\sum_{i=1}^{k-1}\alpha_iG_i(x)fk1(x)=i=1k1αiGi(x)
目标是使前向分步算法得到的αk,Gk(x)\alpha_k,G_k(x)αk,Gk(x)使fk(x)f_{k}(x)fk(x)在训练数据集上的损失最小,即
(αk,Gk(x))=argmin⁡α,G∑i=1NL(yi,fk−1(x)+αG(x))(\alpha_k,G_k(x))=arg\min_{\alpha,G}\sum_{i=1}^NL(y_i,f_{k-1}(x)+\alpha G(x))(αk,Gk(x))=argα,Gmini=1NL(yi,fk1(x)+αG(x))
则第k轮的强学习器为:fk(x)=fk−1(x)+αkGk(x)f_k(x)=f_{k-1}(x)+\alpha_kG_k(x)fk(x)=fk1(x)+αkGk(x)
可见强学习器是通过前向分步学习算法一步步叠加得到的。

AdaBoost实践
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt

print('Loading data...')
# load data
iris = load_iris()
data = iris.data
target = iris.target

print('Plotting scatter...')
# plot
def plot(data,target):
    x0,y0 = [],[]
    x1,y1 = [],[]
    x2,y2 = [],[]
    for i in range(len(data)):
        if target[i] == 0:
            x0.append(data[i][0])
            y0.append(data[i][1])
        elif target[i] == 1:
            x1.append(data[i][0])
            y1.append(data[i][1])
        else:
            x2.append(data[i][0])
            y2.append(data[i][1])

    plt.scatter(x0,y0,c='b',marker='o',label='0')
    plt.scatter(x1,y1,c='r',marker='o',label='1')
    plt.scatter(x2,y2,c='g',marker='o',label='2')
    plt.legend()
    plt.show()

plot(data,target)
iris数据集分布如下图
from sklearn.ensemble import AdaBoostClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.datasets import load_iris 

print('Loading data...')
# load data
iris = load_iris()
data = iris.data
target = iris.target

X_train,X_test,y_train,y_test = train_test_split(data,target,test_size=0.8,random_state=2019)

print('Starting training...')
# train
clf = AdaBoostClassifier(n_estimators=20,
                         learning_rate=0.05,
                         algorithm='SAMME.R',
                         random_state=20)

clf.fit(X_train,y_train)

print('Predicting with the trained model...')
y_pred = clf.predict(X_test)

print('Evaluating model...')
print("the precise of the model's prediction is:",precision_score(y_test,y_pred,average='macro'))
print("the recall of the model is :",recall_score(y_test,y_pred,average='macro'))
print('the f1_score of the model is :',f1_score(y_test,y_pred,average='macro'))
print('the feature importance of model is:',list(clf.feature_importances_))
运行结果如下
Loading data...
Starting training...
Predicting with the trained model...
Evaluating model...
the precise of the model's prediction is: 0.923060391145
the recall of the model is : 0.915363769022
the f1_score of the model is : 0.915824915825
the feature importance of model is: [0.10000000000000001, 0.0, 0.55000000000000004, 0.34999999999999998]
sklearn.ensemble.AdaBoostClassifier
  • algorithm:这个参数只有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算法则没有这个限制。
  • n_estimators: AdaBoostClassifier和AdaBoostRegressor都有,就是我们的弱学习器的最大迭代次数,或者说最大的弱学习器的个数。一般来说n_estimators太小,容易欠拟合,n_estimators太大,又容易过拟合,一般选择一个适中的数值。默认是50。在实际调参的过程中,我们常常将n_estimators和下面介绍的参数learning_rate一起考虑。
  • learning_rate: AdaBoostClassifier和AdaBoostRegressor都有,即每个弱学习器的权重缩减系数ν
  • base_estimator:AdaBoostClassifier和AdaBoostRegressor都有,即我们的弱分类学习器或者弱回归学习器。理论上可以选择任何一个分类或者回归学习器,不过需要支持样本权重。我们常用的一般是CART决策树或者神经网络MLP。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值