AdaBoost

本文参考:https://blog.csdn.net/qq_38890412/article/details/120360354

可以直接看这位大佬的文章

 一、概述

1.1 同质与异质

  1. 异质模型:把不同类型的算法集成在一起,基础模型要有足够大差异性(可以找出最适合当前数据的模型)

  2. 同质模型:通过一个基础算法生成的同类型学习器。

 

1.2 并行与串行  

  1. Bagging独立生成N个相同基模型对预测结果进行集成(模型相同,但是训练数据有差异。而且是并行运算)

  2. Boosting持续通过新模型来优化同一个基准模型,新模型的训练,将一直聚焦于之前的模型的误差点(出错样本权重高),目标是不断减少模型的预测误差(串型运算)

 

1.3 基本原理

AdaBoost是Adaptive Boosting(自适应增强)的缩写,

它的自适应在于:被前一个基本分类器误分类的样本的权值会增大,而正确分类的样本的权值会减小,并再次用来训练下一个基本分类器。

同时,在每一轮迭代中,加入一个新的弱分类器,直到达到某个预定的足够小的错误率或预先指定的最大迭代次数再确定最后的强分类器

 

 

 

 

从上图来看,AdaBoost算法可以简化为3个步骤:

首先,是初始化训练数据的权值分布D1。假设有N个训练样本数据,则每一个训练样本最开始时,都会被赋予相同的权值:w1 = 1/N。

训练弱分类器Ci。具体训练过程:如果某个训练样本点,被弱分类器Ci准确地分类,那么再构造下一个训练集中,它对应的权值要减小;相反,如果某个训练样本点被错误分类,那么它的权值就应该增大。权值的更新过的样本被用于训练下一个弱分类器,整个过程如此迭代下去。

最后,将各个训练得到的弱分类器组合成一个强分类器。各个弱分类器的训练过程结束后,加大分类误差率小的弱分类器的权重,使其在最终的分类函数中起着较大的决定作用,而降低分类误差率大的弱分类器的权重,使其在最终的分类函数中起着较小的决定作用。

换而言之,误差率低的弱分类器在最终分类器中占的权重较大,否则较小。

 

二、 AdaBoost算法过程

给定训练数据集:(x1,y1),(x2,y2)···(xn,yn),其中yi属于{1,-1}用于表示训练样本的类别标签,i=1,...,N

Adaboost的目的就是从训练数据中学习一系列弱分类器或基本分类器,然后将这些弱分类器组合成一个强分类器

相关符号定义:

 

Adaboost的算法流程如下:

 

 

 

 

 

 

 

相关说明:

 

 

 

 

 

  综合上面的推导,可得样本分错与分对时,其权值更新的公式为:

 

 

 

 

 三、实际案例

 

例:给定如图所示的训练样本,弱分类器采用平行于坐标轴的直线,用Adaboost算法的实现强分类过程。

 

 

 

数据分析:

 

 将这10个样本作为训练数据,根据 X 和Y 的对应关系,可把这10个数据分为两类,图中用“+”表示类别1,用“O”表示类别-1。

本例使用水平或者垂直的直线作为分类器,图中已经给出了三个弱分类器,即:

 

 

 

 

 初始化:

首先需要初始化训练样本数据的权值分布,每一个训练样本最开始时都被赋予相同的权值:wi=1/N,这样训练样本集的初始权值分布D1(i):

令每个权值w1i = 1/N = 0.1,其中,N = 10,i = 1,2, ..., 10,然后分别对于t= 1,2,3, ...等值进行迭代(t表示迭代次数,表示第t轮),下表已经给出训练样本的权值分布情况:

 

 

 

 

 

第1次迭代t=1:

初试的权值分布D1为1/N(10个数据,每个数据的权值皆初始化为0.1),

D1=[0.1, 0.1, 0.1, 0.1, 0.1, 0.1,0.1, 0.1, 0.1, 0.1]

在权值分布D1的情况下,取已知的三个弱分类器h1、h2和h3中误差率最小的分类器作为第1个基本分类器H1(x)(三个弱分类器的误差率都是0.3,那就取第1个吧)

 

 

在分类器H1(x)=h1情况下,样本点“5 7 8”被错分,因此基本分类器H1(x)的误差率为:  

 

 

 

 

 

 可见,被误分类样本的权值之和影响误差率e,误差率e影响基本分类器在最终分类器中所占的权重α

 

然后,更新训练样本数据的权值分布,用于下一轮迭代,对于正确分类的训练样本“1 2 3 4 6 9 10”(共7个)的权值更新为:

 

 

 

这样,第1轮迭代后,最后得到各个样本数据新的权值分布:

D2=[1/14,1/14,1/14,1/14,1/6,1/14,1/6,1/6,1/14,1/14]

由于样本数据“5 7 8”被H1(x)分错了,所以它们的权值由之前的0.1增大到1/6;反之,其它数据皆被分正确,所以它们的权值皆由之前的0.1减小到1/14,下表给出了权值分布的变换情况:

 

 

 

 

 

可得分类函数:f1(x)= α1H1(x) = 0.4236H1(x)。此时,组合一个基本分类器sign(f1(x))作为强分类器在训练数据集上有3个误分类点(即5 7 8),此时强分类器的训练错误为:0.3

第二次迭代t=2:

在权值分布D2的情况下,再取三个弱分类器h1、h2和h3中误差率最小的分类器作为第2个基本分类器H2(x):

① 当取弱分类器h1=X1=2.5时,此时被错分的样本点为“5 7 8”:

误差率e=1/6+1/6+1/6=3/6=1/2;

② 当取弱分类器h2=X1=8.5时,此时被错分的样本点为“3 4 6”:

误差率e=1/14+1/14+1/14=3/14;

③ 当取弱分类器h3=X2=6.5时,此时被错分的样本点为“1 2 9”:

误差率e=1/14+1/14+1/14=3/14;

 

 

 

 

因此,取当前最小的分类器h2作为第2个基本分类器H2(x)

 

 

 

 

显然,H2(x)把样本“3 4 6”分错了,根据D2可知它们的权值为D2(3)=1/14,D2(4)=1/14, D2(6)=1/14,所以H2(x)在训练数据集上的误差率:

 

 

 

 

这样,第2轮迭代后,最后得到各个样本数据新的权值分布:

D3=[1/22,1/22,1/6,1/6,7/66,1/6,7/66,7/66,1/22,1/22]

下表给出了权值分布的变换情况:

 

 

 

 

可得分类函数:f2(x)=0.4236H1(x) + 0.6496H2(x)。此时,组合两个基本分类器sign(f2(x))作为强分类器在训练数据集上有3个误分类点(即3 4 6),此时强分类器的训练错误为:0.3

第三次迭代t=3:

在权值分布D3的情况下,再取三个弱分类器h1、h2和h3中误差率最小的分类器作为第3个基本分类器H3(x):

① 当取弱分类器h1=X1=2.5时,此时被错分的样本点为“5 7 8”:

误差率e=7/66+7/66+7/66=7/22;

② 当取弱分类器h2=X1=8.5时,此时被错分的样本点为“3 4 6”:

误差率e=1/6+1/6+1/6=1/2=0.5;

③ 当取弱分类器h3=X2=6.5时,此时被错分的样本点为“1 2 9”:

误差率e=1/22+1/22+1/22=3/22;

 

因此,取当前最小的分类器h3作为第3个基本分类器H3(x):

 

 

 

 

这样,第3轮迭代后,得到各个样本数据新的权值分布为:

D4=[1/6,1/6,11/114,11/114,7/114,11/114,7/114,7/114,1/6,1/38]

下表给出了权值分布的变换情况:

 

 

 

 

 

 

 

可得分类函数:f3(x)=0.4236H1(x) + 0.6496H2(x)+0.9229H3(x)。此时,组合三个基本分类器sign(f3(x))作为强分类器,在训练数据集上有0个误分类点。至此,整个训练过程结束。

整合所有分类器,可得最终的强分类器为:

 

 

 

 

这个强分类器Hfinal对训练样本的错误率为0!

 

四、AdaBoost的优点和缺点

优点

  1. Adaboost提供一种框架,在框架内可以使用各种方法构建子分类器。可以使用简单的弱分类器,不用对特征进行筛选,也不存在过拟合的现象。
  2. Adaboost算法不需要弱分类器的先验知识,最后得到的强分类器的分类精度依赖于所有弱分类器。无论是应用于人造数据还是真实数据,Adaboost都能显著的提高学习精度。
  3. Adaboost算法不需要预先知道弱分类器的错误率上限,且最后得到的强分类器的分类精度依赖于所有弱分类器的分类精度,可以深挖分类器的能力,Adaboost可以根据弱分类器的反馈,自适应地调整假定的错误率,执行的效率高。
  4. Adaboost对同一个训练样本集训练不同的弱分类器,按照一定的方法把这些弱分类器集合起来,构造一个分类能力很强的强分类器,即“三个臭皮匠赛过一个诸葛亮”。

缺点:

  1. 串行运算,效率不高。
  2. 且容易受到异常值干扰(数据清洗需要做好)

    

 

五、代码

import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import AdaBoostClassifier


'''
制作样本数据,产生的结果为一个简单的样本数据集,用于可视化聚类算法和分类算法
1. n_samples : 整数型, 可选,默认为100 总的产生的样本点的数量
2. shuffle : 布尔型,可选填 (默认为True) 是否对样本进行重新洗牌
3. noise : 浮点型 or None型 (默认为None) 加到数据里面的高斯噪声的标准差
'''

X, y = datasets.make_moons(n_samples=1000, shuffle=True, noise=0.3, random_state=2)

plt.scatter(X[y == 0, 0], X[y == 0, 1])
plt.scatter(X[y == 1, 0], X[y == 1, 1])
# plt.show()
# 划分数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=2)



X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=2)
dt_clf = DecisionTreeClassifier(max_depth=5, min_samples_leaf=4, random_state=2)
dt_clf.fit(X_train, y_train)
print('决策树的训练集分数:{a:.2%}, 测试集分数:{b:.2%}'.
      format(a=dt_clf.score(X_train, y_train), b=dt_clf.score(X_test, y_test)))



# 以决策树为弱分类器
dt_clf = DecisionTreeClassifier(max_depth=5, min_samples_leaf=4, random_state=2)
ada_clf = AdaBoostClassifier(dt_clf)
ada_clf.fit(X_train, y_train)
print('ada的训练集分数:{a:.2%}, 测试集分数:{b:.2%}'.
      format(a=ada_clf.score(X_train, y_train), b=ada_clf.score(X_test, y_test)))

 

 

 

可以看出,ada算法过拟合了。在选择算法中,能用简单的不要用复杂的,复杂的容易过拟合

     

posted @ 2022-12-18 21:18  qsl_你猜  阅读(55)  评论(0编辑  收藏  举报