提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
boosting方法主要是对同一组数据进行反复训练,通过调整数据权重,得到一系列弱学习器,最后使用一些决策方式将这些弱学习器结合,组成一个强学习器。这种集成方法主要是通过降低模型偏差、增高模型复杂度的方式来提升预测效果。
以一个例子来说明boosting方式。三个同班学生(弱学习器)完成三道数学应用题,每个人都只对了两道题,且每个人做错的题目并不一致,如果这时他们三人互相教授经验,那么不需要教授该课的老师(强学习器)出面,他们就能将这三道题目全部解出。
大多数的boosting方法都是通过改变训练数据集的概率分布(数据权重),来调用弱分类算法从而得到弱分类器的。因此,有两个问题需要解决,一是改变数据集的概率分布,二是将弱分类器组合起来。
adaboost对两个问题进行了回答,这个回答是诸多答案中比较有代表性的一个。
(1)提高前一轮被分类错误样本的权重(更重视被分错的样本),降低被正确分类样本的权重。
(2)各个弱分类器的组合则是对经过加权后各基模型进行投票表决的方式完成的。
详细公式推导可以参考此文
代码如下(示例):
import numpy as np
import pandas as pd
from sklearn import datasets
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
from sklearn.ensemble import AdaBoostClassifier
import matplotlib.pyplot as plt
plt.style.use('ggplot')
wine = pd.read_csv('wine.data', header=None)
wine.columns = ['class label', 'alcohol','malic acid', 'ash','alcalinity of ash', 'magnesium',
'total phenols', 'flavanoids', 'nonflacanoid phenols','proanthocyanins',
'color intensity', 'hue', 'delubuted wine', 'proline']
print('class label', np.unique(wine['class label']))
wine.head()
wine = wine[wine['class label'] != 1]
y = wine['class label'].values
x = wine[['alcohol', 'delubuted wine']].values
le = LabelEncoder()
y = le.fit_transform(y)
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2,
random_state=1, stratify=y)
# 单棵决策树
tree = DecisionTreeClassifier(criterion='entropy', random_state=1, max_depth=1)
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))
# 以决策树为基模型的adaboost
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, 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='delubuted wine', ha='center', va='center', fontsize=12,
transform=axarr[1].transAxes)
plt.show()
Adaboost模型的决策边界比单层决策树的决策边界要复杂的多。也就是说,Adaboost试图用增加模型复杂度而降低偏差的方式去减少总误差。但是过程中引入了方差,可能出现过拟合现象,因此这时在训练集和测试集之间的性能存在较大的差距。