Boosting思路
类似于bagging集成学习,boosting也是通过重采样得到多个弱分类器,最后得到一个强分类器。区别是boosting是基于权值的弱分类器集成。
Boosting流程图
1.e表示某个弱分类器的错误分类率,计算用来作为这个分类器的可信度权值a,以及更新采样权值D。
2.D表示原始数据的权值矩阵,用来随机采样。刚开始每个样本的采样概率都一样,为1/m。在某个弱分类器分类时,分类错误或对,则D就会根据e相应地增加或减少,那么分错的样本由于D增大,在下一次分类采样时被采样的概率增加了,从而提高上次错分样本下次分对的概率。
3.α为弱分类器的可信度,bagging中隐含的α为1,boosting中,根据每个弱分类器的表现(e较低),决定这个分类器的结果在总的结果中所占的权重,分类准的自然占较多的权重。
最后根据可信度α,以及各个弱分类器的估计h(x),得到最后的结果。
Bagging与Boosting的区别:
二者的主要区别是取样方式不同。Bagging采用均匀取样,而Boosting根据错误率来取样,因此Boosting的分类精度要优于Bagging。
Bagging的训练集的选择是随机的,各轮训练集之间相互独立,而Boostlng的各轮训练集的选择与前面各轮的学习结果有关;
Bagging的各个预测函数没有权重,而Boosting是有权重的;
Bagging的各个预测函数可以并行生成,而Boosting的各个预测函数只能顺序生成。
对于象神经网络这样极为耗时的学习方法。Bagging可通过并行训练节省大量时间开销。
bagging和boosting都可以有效地提高分类的准确性。在大多数数据集中,boosting的准确性比bagging高。在有些数据集中,boosting会引起退化— Overfit。
原文链接:https://blog.csdn.net/u014114990/article/details/50948079
以上内容出自bagging和boosting 总结,较全。
AdaBoost算法
以下出自Boosting方法详解。
算法的输入:一个训练数据集还有诸多弱学习算法。
训练数据集如下:
y有1和-1两类。
输出:一个最终分类器G(x)。
算法的执行步骤如下:
(1)初始化训练数据的权值分布。假设训练数据有均匀的权值分布,即每个训练样本在基本分类器的学习中作用相同,这样就保证了第一步是在原始数据上学习基本分类器
G
1
(
x
)
G_1(x)
G1(x).
(2)训练,反复学习基本分类器,在每一轮m执行下列操作,共循环M轮。
使用当前分布
D
(
m
)
D(m)
D(m)
- 加权的训练数据集,学习基本分类器 G m ( x ) G_m(x) Gm(x)。
- 计算基本分类器
G
m
(
x
)
G_m(x)
Gm(x)在加权训练数据集上的分类误差率:
w m i w_{mi} wmi表示第 m m m轮中第 i i i个实例的权值,权值之和为1。这表明 G m ( x ) G_m(x) Gm(x)在加权的训练数据集上的分类误差率是被 G m ( x ) G_m(x) Gm(x)误分类样本的权值之和。
-
计算基本分类器 G m ( x ) G_m(x) Gm(x)的系数,该系数表示了 G m ( x ) G_m(x) Gm(x)在最终分类器中的重要性。
当 e m ≤ 1 2 e_m \le \frac{1}{2} em≤21时, α ≥ 0 \alpha \ge 0 α≥0,并且 α m \alpha_m αm随着KaTeX parse error: Undefined control sequence: \e at position 1: \̲e̲_m的减小而增大,所以分类误差率越小的基本分类器在最终分类器中的作用越大。 -
更新训练数据的权值分布为下一轮作准备:
Z m Z_m Zm是规范化因子,使得 D m D_m Dm成为一个概率分布
权值还可以写成:
基本分类器 G m ( x ) G_m(x) Gm(x)误分类样本的权值扩大了,被正确分类样本的权值缩小了,扩大和缩小的幅度和 G m ( x ) G_m(x) Gm(x)在最终分类器中的作用直接相关。也就是这个分类器越重要,下一个分类器就要越关注到这个分类器的缺点。
3)构建基本分类器的线性组合,这个线性组合实现的是 M M M个基本分类器的加权表决,这个权重之和并不为1。这个函数的符号决定了实例 x x x的类,其绝对值表示了分类的确信度。
得到最终分类器:
使用sklearn对Adaboost算法进行建模
以下代码出自team-learning-data-mining/EnsembleLearning/CH4-集成学习之boosting/。详细代码分析和结果对比分析同样可看原文。
# 引入数据科学相关工具包:
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']
# 数据预处理
# 仅仅考虑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))
# 使用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 accuracies %.3f/%.3f' % (ada_train,ada_test))
# 画出单层决策树与Adaboost的决策边界:
x_min = X_train[:, 0].min() - 1
x_max = X_train[:, 0].max() + 1
y_min = X_train[:, 1].min() - 1
y_max = X_train[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.1),np.arange(y_min, y_max, 0.1))
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)
axarr[idx].contourf(xx, yy, Z, alpha=0.3)
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='OD280/OD315 of diluted wines',ha='center',va='center',fontsize=12,transform=axarr[1].transAxes)
plt.show()