首页 > 编程语言 >My Task09 Boosting的思路与Adaboost算法 笔记

My Task09 Boosting的思路与Adaboost算法 笔记

时间:2022-12-09 10:34:45浏览次数:62  
标签:分类器 Task09 train Adaboost Boosting test 学习


文章目录

  • 1.导论
  • 2.Boosting方法的基本思路
  • 3. Adaboost算法
  • Zm越小证明分类分得越对 总结:数学家太强了,respect

1.导论

Bagging思想的实质是:通过Bootstrap 的方式对全样本数据集进行抽样得到抽样子集,对不同的子集使用同一种基本模型进行拟合,然后投票得出最终的预测。我们也从前面的探讨知道:Bagging主要通过降低方差的方式减少预测误差。那么,本章介绍的Boosting是与Bagging截然不同的思想,Boosting方法是使用同一组数据集进行反复学习,得到一系列简单模型,然后组合这些模型构成一个预测性能十分强大的机器学习模型。显然,Boosting思想提高最终的预测效果是通过不断减少偏差的形式,与Bagging有着本质的不同。在Boosting这一大类方法中,笔者主要介绍两类常用的Boosting方式:Adaptive Boosting 和 Gradient Boosting 以及它们的变体Xgboost、LightGBM以及Catboost。

  • Bagging是通过降低方差来误差
  • Boosting是通过降低偏差来降低误差

2.Boosting方法的基本思路

能说明Boosting道理的两个例子
第一个例子:不知道大家有没有做过错题本,我们将每次测验的错的题目记录在错题本上,不停的翻阅,直到我们完全掌握(也就是能够在考试中能够举一反三)。
第二个例子:对于一个复杂任务来说,将多个专家的判断进行适当的综合所作出的判断,要比其中任何一个专家单独判断要好。实际上这是一种“三个臭皮匠顶个诸葛亮的道理”。
Boosting的核心思想为串行地训练一系列前后依赖的同类模型,即后一个模型用来对前一个模型的输出结果进行纠正,Boosting算法是可将弱学习器提升为强学习器的算法
Boosting的提出与发展离不开Valiant和 Kearns的努力,历史上正是Valiant和 Kearns提出了"强可学习"和"弱可学习"的概念。那什么是"强可学习"和"弱可学习"呢?在概率近似正确PAC学习的框架下:

**弱学习:**识别错误率小于1/2(即准确率仅比随机猜测略高的学习算法)
**强学习:**识别准确率很高并能在多项式时间内完成的学习算法

非常有趣的是,在PAC 学习的框架下,强可学习和弱可学习是等价的,也就是说一个概念是强可学习的充分必要条件是这个概念是弱可学习的。这样一来,问题便是:在学习中,如果已经发现了弱可学习算法,能否将他提升至强可学习算法。因为,弱可学习算法比强可学习算法容易得多。提升方法就是从弱学习算法出发,反复学习,得到一系列弱分类器(又称为基本分类器),然后通过一定的形式去组合这些弱分类器构成一个强分类器。大多数的Boosting方法都是通过改变训练数据集的概率分布(训练数据不同样本的权值),针对不同概率分布的数据调用弱分类算法学习一系列的弱分类器。

对于Boosting方法来说,有两个问题需要给出答案:
第一个是每一轮学习应该如何改变数据的概率分布,
第二个是如何将各个弱分类器组合起来。
关于这两个问题,不同的Boosting算法会有不同的答案,我们接下来介绍一种最经典的Boosting算法----Adaboost,我们需要理解Adaboost是怎么处理这两个问题以及为什么这么处理的。

3. Adaboost算法

Adaboost的基本原理

对于Adaboost来说,解决上述的两个问题的方式是:

  1. 提高那些被前一轮分类器错误分类的样本的权重,而降低那些被正确分类的样本的权重。这样一来,那些在上一轮分类器中没有得到正确分类的样本,由于其权重的增大而在后一轮的训练中“备受关注”。
  2. 各个弱分类器的组合是通过采取加权多数表决的方式,具体来说,加大分类错误率低的弱分类器的权重,因为这些分类器能更好地完成分类任务,而减小分类错误率较大的弱分类器的权重,使其在表决中起较小的作用。
    现在,我们来具体介绍Adaboost算法:(参考李航老师的《统计学习方法》)
    假设给定一个二分类的训练数据集:
  3. My Task09 Boosting的思路与Adaboost算法 笔记_权重

  4. ,其中每个样本点由特征与类别组成。特征
  5. My Task09 Boosting的思路与Adaboost算法 笔记_Ada_02

  6. ,类别
  7. My Task09 Boosting的思路与Adaboost算法 笔记_数据_03

  8. My Task09 Boosting的思路与Adaboost算法 笔记_权重_04

  9. 是特征空间,$ \mathcal{Y}
  10. My Task09 Boosting的思路与Adaboost算法 笔记_Ada_05

  11. G(x)
  12. My Task09 Boosting的思路与Adaboost算法 笔记_数据_06

  13. D_{1}=\left(w_{11}, \cdots, w_{1 i}, \cdots, w_{1 N}\right), \quad w_{1 i}=\frac{1}{N}, \quad i=1,2, \cdots, N$
    (2) 对于m=1,2,…,M
  • 使用具有权值分布
  • My Task09 Boosting的思路与Adaboost算法 笔记_数据_07

  • 的训练数据集进行学习,得到基本分类器:
  • My Task09 Boosting的思路与Adaboost算法 笔记_数据_08

  • 计算
  • My Task09 Boosting的思路与Adaboost算法 笔记_Ada_09

  • 在训练集上的分类误差率
  • My Task09 Boosting的思路与Adaboost算法 笔记_Ada_10

  • 计算
  • My Task09 Boosting的思路与Adaboost算法 笔记_Ada_09

  • 的系数
  • My Task09 Boosting的思路与Adaboost算法 笔记_权重_12

  • ,这里的log是自然对数ln
  • 更新训练数据集的权重分布
  • My Task09 Boosting的思路与Adaboost算法 笔记_Ada_13

  • 这里的
  • My Task09 Boosting的思路与Adaboost算法 笔记_Ada_14

  • 是规范化因子,使得
  • My Task09 Boosting的思路与Adaboost算法 笔记_Ada_15

  • 称为概率分布,
  • My Task09 Boosting的思路与Adaboost算法 笔记_Ada_16

(3) 构建基本分类器的线性组合

My Task09 Boosting的思路与Adaboost算法 笔记_权重_17

,得到最终的分类器

My Task09 Boosting的思路与Adaboost算法 笔记_权重_18

下面对Adaboost算法做如下说明:

对于步骤(1),假设训练数据的权值分布是均匀分布,是为了使得第一次没有先验信息的条件下每个样本在基本分类器的学习中作用一样。

对于步骤(2),每一次迭代产生的基本分类器

My Task09 Boosting的思路与Adaboost算法 笔记_Ada_19

在加权训练数据集上的分类错误率

My Task09 Boosting的思路与Adaboost算法 笔记_数据_20

代表了在

My Task09 Boosting的思路与Adaboost算法 笔记_Ada_19

中分类错误的样本权重和,这点直接说明了权重分布

My Task09 Boosting的思路与Adaboost算法 笔记_数据_22


My Task09 Boosting的思路与Adaboost算法 笔记_Ada_19

的分类错误率

My Task09 Boosting的思路与Adaboost算法 笔记_数据_24

有直接关系。同时,在步骤(2)中,计算基本分类器

My Task09 Boosting的思路与Adaboost算法 笔记_Ada_19

的系数

My Task09 Boosting的思路与Adaboost算法 笔记_Ada_26


My Task09 Boosting的思路与Adaboost算法 笔记_权重_27

,它表示了

My Task09 Boosting的思路与Adaboost算法 笔记_Ada_19

在最终分类器的重要性程度,

My Task09 Boosting的思路与Adaboost算法 笔记_Ada_26

的取值由基本分类器

My Task09 Boosting的思路与Adaboost算法 笔记_Ada_19

的分类错误率有直接关系,当

My Task09 Boosting的思路与Adaboost算法 笔记_权重_31

时,

My Task09 Boosting的思路与Adaboost算法 笔记_数据_32

,并且

My Task09 Boosting的思路与Adaboost算法 笔记_Ada_26

随着

My Task09 Boosting的思路与Adaboost算法 笔记_数据_24

的减少而增大,因此分类错误率越小的基本分类器在最终分类器的作用越大!

**最重要的,对于步骤(2)中的样本权重的更新: **

My Task09 Boosting的思路与Adaboost算法 笔记_权重_35


因此,从上式可以看到:被基本分类器

My Task09 Boosting的思路与Adaboost算法 笔记_Ada_19

错误分类的样本的权重扩大,被正确分类的样本权重减少,二者相比相差

My Task09 Boosting的思路与Adaboost算法 笔记_数据_37

倍。

对于步骤(3),线性组合

My Task09 Boosting的思路与Adaboost算法 笔记_Ada_38

实现了将M个基本分类器的加权表决,系数

My Task09 Boosting的思路与Adaboost算法 笔记_Ada_26

标志了基本分类器

My Task09 Boosting的思路与Adaboost算法 笔记_Ada_19

的重要性,值得注意的是:所有的

My Task09 Boosting的思路与Adaboost算法 笔记_Ada_26

之和不为1。

My Task09 Boosting的思路与Adaboost算法 笔记_Ada_38

的符号决定了样本x属于哪一类。

Zm越小证明分类分得越对 总结:数学家太强了,respect

# 引入数据科学相关工具包:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.style.use("ggplot")
%matplotlib inline
import seaborn as sns
# 加载训练数据:         
wine = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data",header=None)
wine.columns = ['Class label', 'Alcohol', 'Malic acid', 'Ash', 'Alcalinity of ash','Magnesium', 'Total phenols','Flavanoids', 'Nonflavanoid phenols',
'Proanthocyanins','Color intensity', 'Hue','OD280/OD315 of diluted wines','Proline']
# 数据查看:
print("Class labels",np.unique(wine['Class label']))
wine.head()
Class labels [1 2 3]

Class label

Alcohol

Malic acid

Ash

Alcalinity of ash

Magnesium

Total phenols

Flavanoids

Nonflavanoid phenols

Proanthocyanins

Color intensity

Hue

OD280/OD315 of diluted wines

Proline

0

1

14.23

1.71

2.43

15.6

127

2.80

3.06

0.28

2.29

5.64

1.04

3.92

1065

1

1

13.20

1.78

2.14

11.2

100

2.65

2.76

0.26

1.28

4.38

1.05

3.40

1050

2

1

13.16

2.36

2.67

18.6

101

2.80

3.24

0.30

2.81

5.68

1.03

3.17

1185

3

1

14.37

1.95

2.50

16.8

113

3.85

3.49

0.24

2.18

7.80

0.86

3.45

1480

4

1

13.24

2.59

2.87

21.0

118

2.80

2.69

0.39

1.82

4.32

1.04

2.93

735

下面对数据做简单解读:

  • Class label:分类标签
  • Alcohol:酒精
  • Malic acid:苹果酸
  • Ash:灰
  • Alcalinity of ash:灰的碱度
  • Magnesium:镁
  • Total phenols:总酚
  • Flavanoids:黄酮类化合物
  • Nonflavanoid phenols:非黄烷类酚类
  • Proanthocyanins:原花青素
  • Color intensity:色彩强度
  • Hue:色调
  • OD280/OD315 of diluted wines:稀释酒OD280 OD350
  • Proline:脯氨酸

# 数据预处理
# 仅仅考虑2,3类葡萄酒,去除1类
wine = wine[wine['Class label'] != 1]
y = wine['Class label'].values
X = wine[['Alcohol','OD280/OD315 of diluted wines']].values

# 将分类标签变成二进制编码:
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
y = le.fit_transform(y)

# 按8:2分割训练集和测试集
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=1,stratify=y) # stratify参数代表了按照y的类别等比例抽样
# 使用单一决策树建模
from sklearn.tree import DecisionTreeClassifier
tree = DecisionTreeClassifier(criterion='entropy',random_state=1,max_depth=1)
from sklearn.metrics import accuracy_score
tree = tree.fit(X_train,y_train)
y_train_pred = tree.predict(X_train)
y_test_pred = tree.predict(X_test)
tree_train = accuracy_score(y_train,y_train_pred)
tree_test = accuracy_score(y_test,y_test_pred)
print('Decision tree train/test accuracies %.3f/%.3f' % (tree_train,tree_test))
Decision tree train/test accuracies 0.916/0.875
# 使用sklearn 实现Adaboost(基分类器为决策树)
'''
AdaboostClassifier 相关参数
base_estimator :基本分类器,默认为DecisionTreeClassifier(max_depth=1)
n_estimators : 终止迭代的次数
learning_rate:学习率
algorithm:训练的相关算法,{'SAMME','SAMME.R'},默认='SAMME.R'
random_state:随机种子
'''
from sklearn.ensemble import AdaBoostClassifier
ada = AdaBoostClassifier(base_estimator=tree,n_estimators=500,learning_rate=0.1,random_state=1)
ada = ada.fit(X_train,y_train)
y_train_pred = ada.predict(X_train)
y_test_pred = ada.predict(X_test)
ada_train = accuracy_score(y_train,y_train_pred)
ada_test = accuracy_score(y_test,y_test_pred)
print('Adaboost train/test accurancies %.3f/%.3f' % (ada_train,ada_test))
Adaboost train/test accurancies 1.000/0.917

结果分析:单层决策树似乎对训练数据欠拟合,而Adaboost模型正确地预测了训练数据的所有分类标签,而且与单层决策树相比,Adaboost的测试性能也略有提高。然而,为什么模型在训练集和测试集的性能相差这么大呢?我们使用图像来简单说明下这个道理!

  • Python zip() 函数 https://www.runoob.com/python/python-func-zip.html
  • Numpy中的meshgrid()函数 Python的reshape的用法python中ravel()用法numpy中np.c_和np.r_ matplotlib.pyplot contourf()函数的使用 plt.tight_layout()
# 画出单层决策树与Adaboost的决策边界
x_min = X_train[:,0].min() - 1 # 10.03
x_max = X_train[:,0].max() + 1 # 15.34
y_min = X_train[:,1].min() - 1 # 0.27
y_max = X_train[:,1].max() + 1 # 4.68
xx,yy = np.meshgrid(np.arange(x_min,x_max,0.1),np.arange(y_min,y_max,0.1)) # 相当于在弄了很多点(x,y)出来
f,axarr = plt.subplots(nrows=1,ncols=2,sharex='col',sharey='row',figsize = (12,6))
for idx,clf,tt in zip([0,1],[tree,ada],['Decision tree','Adaboost']):
clf.fit(X_train,y_train)
Z = clf.predict(np.c_[xx.ravel(),yy.ravel()])
Z = Z.reshape(xx.shape) # alpha 介于0(透明)和1(不透明)之间。
axarr[idx].contourf(xx, yy, Z, alpha=0.38)
axarr[idx].scatter(X_train[y_train==0,0],X_train[y_train==0,1],c='blue',marker='^')
axarr[idx].scatter(X_train[y_train==1,0],X_train[y_train==1,1],c='red',marker='o')
axarr[idx].set_title(tt)
axarr[0].set_ylabel('Alcohol',fontsize=12)
plt.tight_layout()
plt.text(0,-0.2,s='0D280/0D315 of diluted wines',ha='center',va='center',fontsize=12,transform=axarr[1].transAxes)
plt.show()

My Task09 Boosting的思路与Adaboost算法 笔记_数据_43

从上面的决策边界图可以看到:Adaboost模型的决策边界比单层决策树的决策边界要复杂的多。也就是说,Adaboost试图用增加模型复杂度而降低偏差的方式去减少总误差,但是过程中引入了方差,可能出现过拟合,因此在训练集和测试集之间的性能存在较大的差距,这就简单地回答的刚刚问题。值的注意的是:与单个分类器相比,Adaboost等Boosting模型增加了计算的复杂度,在实践中需要仔细思考是否愿意为预测性能的相对改善而增加计算成本,而且Boosting方式无法做到现在流行的并行计算的方式进行训练,因为每一步迭代都要基于上一部的基本分类器。

这个图挺难画的,终究还是太菜了

My Task09 Boosting的思路与Adaboost算法 笔记_权重_44

参考 :​GitHub开源集成学习(上) Datawhale​

标签:分类器,Task09,train,Adaboost,Boosting,test,学习
From: https://blog.51cto.com/u_15796263/5923946

相关文章