集成学习之AdaBoost算法

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

AdaBoost算法

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

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

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

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

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

  1. 初始化训练数据的权值分布 D 1 = ( W 11 , W 12 , . . . , W 1 i , . . . , W 1 N ) , W 1 i = 1 N , i = 1 , 2 , 3 , . . . , N D_1=(W_{11},W_{12},...,W_{1i},...,W_{1N}), W_{1i}=\frac{1}{N},i=1,2,3,...,N D1=(W11,W12,...,W1i,...,W1N),W1i=N1,i=1,2,3,...,N
  2. 对于 m = 1 , 2 , . . . , M m=1,2,...,M m=1,2,...,M,训练每一个弱分类器 G m ( x ) G_m(x) Gm(x)
    (a) 使用具有权值分布 D m D_m Dm的训练数据集学习,得到基分类器 G m ( x ) : X → { − 1 , + 1 } G_m(x):\mathcal X\rightarrow\left\{-1,+1\right\} Gm(x):X{1,+1}
    (b) 计算 G m ( x ) G_m(x) Gm(x)在训练数据集上的分类误差率 e m = ∑ i = 1 N P ( G m ( x i ) = ̸ y i ) = ∑ i = 1 N W m i I ( G m ( x i ) = ̸ y i ) 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) 计算 G m ( x ) G_m(x) Gm(x)的系数,其表示该弱分类器的重要性 α m = 1 2 l o g 1 − e m e m \alpha_m=\frac{1}{2}log\frac{1-e_m}{e_m} αm=21logem1em
    (d) 更新训练数据集的下一轮的权值分布 D m + 1 = ( W m + 1 , 1 , W m + 2 , 2 , . . . , W m + 1 , i , . . . , W m + 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) W m + 1 , i = W m i Z m e x p ( − α m y i G m ( x i ) ) W_{m+1,i}=\frac{W_{mi}}{Z_m}exp(-\alpha_my_iG_m(x_i)) Wm+1,i=ZmWmiexp(αmyiGm(xi)) Z m Z_m Zm是规划化因子,归一化处理。 Z m = ∑ i = 1 N W m i e x p ( − α m y i G m ( x i ) ) Z_m=\sum_{i=1}^NW_{mi}exp(-\alpha_my_iG_m(x_i)) Zm=i=1NWmiexp(αmyiGm(xi))它使得 D m + 1 D_{m+1} Dm+1成为一个概率分布。
  3. 构建基分类器的线性组合 f ( x ) = ∑ m = 1 M α m G m ( x ) f(x)=\sum_{m=1}^M\alpha_mG_m(x) f(x)=m=1MαmGm(x)得到最终的分类器 G ( x ) = s i g n ( f ( x ) ) = s i g n ( ∑ m = 1 M α m G m ( 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:假设训练数据集具有均匀的权值分布,即每个训练样本在基分类器的学习作用相同,数据集样本的权重初始化,这一假设保证能够在原始数据上学习基分类器 G 1 ( x ) G_1(x) G1(x)
步骤2:AdaBoost迭代学习基分类器,在每一轮 m = 1 , 2 , . . . , M m=1,2,...,M m=1,2,...,M按顺序执行以下操作:
(a) 使用当前分布 D m D_m Dm加权的训练数据集,学习基分类器 G m ( x ) G_m(x) Gm(x)
(b) 计算基分类器 G m ( x ) G_m(x) Gm(x)在加权训练数据集上的分类错误率: e m = ∑ i = 1 N P ( G m ( x i ) = ̸ y i ) = ∑ G m ( x i ) = ̸ y i W m i e_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)≠yiWmi W m i W_{mi} Wmi表示第m轮中第i个实例的权值, ∑ i = 1 N W m i = 1 \sum_{i=1}^NW_{mi}=1 i=1NWmi=1,表明 G m ( x ) G_m(x) Gm(x)在加权的训练数据集上的分类误差率是被 G m ( x ) G_m(x) Gm(x)误分类样本的权值之和。
(c) 计算基分类器 G m ( x ) G_m(x) Gm(x)的系数 α m \alpha_m αm α m \alpha_m αm表示 G m ( x ) G_m(x) Gm(x)在最终分类器中的重要性。当 e m ≤ 1 2 e_m\leq \frac{1}{2} em21时, α m ≥ 0 \alpha_m\ge 0 αm0,并且 α m \alpha_m αm随着 e m e_m em的减少而增大,所以分类误差率越小的基分类器在最终分类器中的作用越大。
(d) 更新训练数据的权值分布为下一轮做准备
W m + 1 , i = { W m i Z m e − α m , G m ( x i ) = y i W m i Z m e α m , G m ( x i ) = ̸ y i W_{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
由此可知,被基分类器 G m ( x ) G_m(x) Gm(x)误分类样本的权值在扩大,而被正确分类样本的权值在缩小。相比较,误分类样本的权值被放大 e 2 α m = 1 − e m e m e^{2\alpha_m}=\frac{1-e_m}{e_m} e2αm=em1em倍。正确分类的样本在下一轮的训练过程中的权重较小,而误分类样本在下一轮的学习权重较大。对于全体训练数据集,在每一轮训练之前更新对应的权重分布,使得训练数据在基分类器的学习中起着不同的作用。
步骤3:线性组合 f ( x ) f(x) f(x)实现M个基分类器的加权表决。系数 α m \alpha_m αm表示基分类器 G m ( x ) G_m(x) Gm(x)的重要程度。 f ( x ) f(x) f(x)的符号决定了实例x的类别。

AdaBoost算法实例

集成学习之AdaBoost算法_第1张图片
集成学习之AdaBoost算法_第2张图片
集成学习之AdaBoost算法_第3张图片
集成学习之AdaBoost算法_第4张图片

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

AdaBoost算法的另一种解释

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

例如,前k-1轮的强学习器为:
f k − 1 ( x ) = ∑ i = 1 k − 1 α i G i ( x ) f_{k-1}(x)=\sum_{i=1}^{k-1}\alpha_iG_i(x) fk1(x)=i=1k1αiGi(x)
目标是使前向分步算法得到的 α k , G k ( x ) \alpha_k,G_k(x) αk,Gk(x)使 f k ( x ) f_{k}(x) fk(x)在训练数据集上的损失最小,即
( α k , G k ( x ) ) = a r g min ⁡ α , G ∑ i = 1 N L ( y i , f k − 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轮的强学习器为: f k ( x ) = f k − 1 ( x ) + α k G k ( 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数据集分布如下图
集成学习之AdaBoost算法_第5张图片
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。

你可能感兴趣的:(机器学习)