一 解决的问题
集成学习,就是把前几章的经典可推导的模型结合起来,将一系列学习器的结果加工一下形成最终结果的学习模型。
为什么将弱学习器结合起来能够提升准确率呢?
其实准确地说,并不是随意将学习器组合起来就有提升准确度的效果,而是要求这些弱学习器要有一定的准确度,并且学习器之间要有差异,这样才能保证组合起来能够减少错误率。而且,基于误差-分歧分解的分析,得出结论,个体学习器准确性越高,多样性越大,则集成效果越好。
怎样保证学习器准确性又好,差异度也大呢?
一种方法是先训练一个模型,然后对于这个模型出错的样本重点关注,再基于这些样本,训练另一个模型,以此迭代,直到最后得到符合要求的准确率,这就是boosting。由此获得的模型之间有强依赖性,模型属于串行生成。这样得到的模型其实是在不断优化失误率,降低偏差。
另一种方法是先把样本空间切分成小的子空间,这样各空间的数据不同,然后每个子空间训练出一个最佳模型,再把这些模型组合起来,得到最终模型。这种训练的方法可以并行处理,模型之间也不存在强依赖关系,称为bagging。Bagging主要关注降低方差,因此,在易受样本扰动的模型上效用更好,比如决策树,神经网络。
怎样增强多样性?
对训练数据来说,就这么一份,怎么训练出多个模型,还让它们具有差异?通常做法是加入扰动。
比如,在样本数据上加入扰动,可以将样本数据划分为多份子空间;
在属性上也可以加入扰动,每次取样仅抽取一定比例的属性;
还可以输出扰动,比如将二分类转化为回归输出构建个体学习器,然后结合的时候再转化为最终分类结果;
对于比较复杂的网络,还可以设置不同的参数,构建不同学习器。
二 概念总结
三 习题简单实践
习题8.3 以不剪枝决策树为基学习器,在3.0α数据上用adaboost训练集成,对比图8.4
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
data = np.loadtxt('./CH3-3watermeleondata.csv', delimiter=',')
X = data[:,0:2]
y = data[:,2]
clf = AdaBoostClassifier(DecisionTreeClassifier(splitter='best'), n_estimators=3,random_state=0)
clf.fit(X,y)
steplength = 0.002 # 将训练出的模型用于高密度的预测,形成一条边界,就是分类的边界线
x_min, x_max = X[:, 0].min() - 0.1, X[:, 0].max() + 0.1
y_min, y_max = X[:, 1].min() - 0.1, X[:, 1].max() + 0.1
xmesh = np.arange(x_min,x_max,steplength)
ymesh = np.arange(y_min, y_max,steplength)
xx, yy = np.meshgrid(xmesh,ymesh)
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()]) #这里预测出来的Z是行向量,也需要重整理成矩阵形式
Z = Z.reshape(xx.shape)
f2 = plt.figure()
plt.title('Classfication boundary output with 3 DecisionTree')
plt.contourf(xx, yy, Z, cmap=plt.cm.Paired)
# Plot also the training points
plt.scatter(X[y == 0,0], X[y == 0,1], marker = 'v', color = 'k', s=100, label = 'bad')
plt.scatter(X[y == 1,0], X[y == 1,1], marker = 'o', color = 'g', s=100, label = 'good')
这里设置3个决策树分类器,得到的结果如下:
可以看到决策树的分类边界的确是线性的,设置5个,11个分类器,得到的结果与3个的没有什么区别。