1、第07章 集成学习p集成学习p投票法p挂袋法p提升法7.1 引言n 集成学习(Ensemble Learning)是指利用多个独立的基学习器来进行学习,组合某输入样例在各个基学习器上的输出,并由他们按照某种策略共同决定输出。n 集成学习的基本思想是先通过一定的规则生成一定数量的基学习器(Base Estimator),再采用某种集成策略将这些基学习器的预测结果组合起来,形成最终的结论。n 集成学习中,弱学习器(Weak Learner)是错误概率小于0.5的学习器;而强学习器(Strong Learner)则具有任意小的错误概率。n 集成学习主要包括三个部分:个体的生成方法、个体学习器(基学习
2、器)和结论的合(集)成方法。n 集成学习中的基学习器可以是同质的“弱学习器”,也可以是异质的“弱学习器”。目前,同质个体学习器的应用最为广泛,同质个体学习器使用最多的模型是CART决策树和神经网络。7.1.1 集成学习的概念7.1 引言n 集成学习主要包括三个部分:个体的生成方法个体学习器(基学习器)结论的合(集)成方法。n 集成学习需要很好地解决如下两个问题。(1)如何通过有效地训练,获得若干个基学习器?(2)如何选择一个组合策略,将这些基学习器集合成为一个强学习器?7.1.2 集成学习的组成7.1 引言n 同质个体学习器按照个体学习器之间是否存在依赖关系又可以分为两类:个体学习器之间存在着
3、强依赖关系其代表算法是Boosting算法;个体学习器之间不存在强依赖关系,可以并行生成这些个体学习器,其代表算法是Bagging和随机森林(Random Forest)算法。n 根据集成学习的用途不同,结论合成的方法也各不相同。集成的输出通常由各个体学习器的输出投票产生。通常采用绝对多数投票法或相对多数投票法。当集成学习用于回归估计时,集成的输出通常由各学习器的输出通过简单平均或加权平均产生。7.1.3 同质个体学习器的分类及算法7.2 Votingn 假设某机器学习模型有L个基学习器 ,用dj表示基学习器Mj在给定的任意输入向量x上的估计值,即 (注:若输入向量存在多种表示 ,也就是说每个
4、基学习器的输入各不相同,那么Mj在输入xj上的预测 ),那么最终的预测值可由各个基学习器的预测计算得出:若每个基学习器有K个输出,即基学习器Mj的输出当它们组合时,得到预测值11Ljjw0jw 1Lijjijyw d7.2 Votingn 组合函数是投票法组合函数还可以是取平均值的简单投票法(Simple Voting)、中位数(Median)、最大值(Maxmize)等,如图7-1所示。图7-1 多个基学习器通过投票方法组合而成的集成学习方式示意图7.2 Votingn 对于回归,可以使用简单平均、加权平均或中位数来融合基回归器的输出。中位数对噪声比平均值更加棒。n 分类器组合函数规则组合函
5、数说明平均和 相对多数表决,直观加权和 考虑学习器的投票权重中位数 对离群点的鲁棒性好最小值 悲观估计最大值 乐观估计乘积 每个学习器都有否决权7.2 Votingn 假定dj是独立同分布的,其期望值为E(dj),方差为Var(dj),那么当wj=1/L时,输出的期望值和方差分别为:从上述推导过程可以看到,期望值没有改变,因而偏倚也不会改变。但是方差随着独立投票数量的增加而下降。对于一般情况,有可以看出,如果学习器是正相关的,则方差增加。因此,在实践中,需要使用不同算法和输入特征来减少其正相关性。如果投票者不独立,但是负相关的,那么进一步降低方差也是可能的。7.2 Votingn sklear
6、n提供了一种软投票/多数规则分类器(Soft Voting/Majority Rule Classifier),其原型如下:class sklearn.ensemble.VotingClassifier(estimators,voting=hard,weights=None,n_jobs=1,flatten_transform=None)n 主要参数如下estimators:指定的估计器,该估计器必须有.fit方法进行训练。voting:字符串,可选项为“soft”和“hard”,其默认值为“hard”。如果voting取值“hard”,那么使用多数规则表决预测的类标签。否则,基于各个基学习器
7、的预测概率之和预测类标签。weights:数组,大小等于n_classifiers(基学习器的数量),缺省值为None。权值序列表示预测类标签出现(hard voting),或者平均化之前的类概率(soft voting)。n 示例from itertools import productimport numpy as npimport matplotlib.pyplot as pltfrom sklearn import datasetsfrom sklearn.tree import DecisionTreeClassifierfrom sklearn.neighbors import K
8、NeighborsClassifierfrom sklearn.svm import SVCfrom sklearn.ensemble import VotingClassifier#加载鸢尾花数据集iris=datasets.load_iris()X=iris.data:,0,2y=iris.target7.2 Voting#构造三个基学习器和一个集成学习器clf1=DecisionTreeClassifier(max_depth=4)clf2=KNeighborsClassifier(n_neighbors=7)clf3=SVC(kernel=rbf,probability=True)ec
9、lf=VotingClassifier(estimators=(dt,clf1),(knn,clf2),(svc,clf3),voting=soft,weights=3,2,1)#训练学习器clf1.fit(X,y)clf2.fit(X,y)clf3.fit(X,y)eclf.fit(X,y)7.2 Voting#生成数据网格x_min,x_max=X:,0.min()-1,X:,0.max()+1y_min,y_max=X:,1.min()-1,X:,1.max()+1xx,yy=np.meshgrid(np.arange(x_min,x_max,0.1),np.arange(y_min,y
10、_max,0.1)#绘图f,axarr=plt.subplots(2,2,sharex=col,sharey=row,figsize=(10,8)for idx,clf,tt in zip(product(0,1,0,1),clf1,clf2,clf3,eclf,Decision Tree(depth=4),KNN(k=7),Kernel SVM,Soft Voting):Z=clf.predict(np.c_xx.ravel(),yy.ravel()Z=Z.reshape(xx.shape)7.2 Voting axarridx0,idx1.contourf(xx,yy,Z,alpha=0.
11、4)axarridx0,idx1.scatter(X:,0,X:,1,c=y,s=20,edgecolor=k)axarridx0,idx1.set_title(tt)plt.show()7.2 Votingn 首先构造三个不同的基学习器:决策树、k近邻和支持向量机,然后用软投票(soft voting)策略,将上述三个基学习器集成为一个新的学习器,使用sklearn 中的鸢尾花数据集训练上述各个学习器。7.2 Votingn 运行结果如下7.3 Bagging7.3 Baggingn 一个学习算法是稳定的,如果该算法在相同训练数据集的再抽样版本上多次运行导致具有高正相关性的学习器。决策树和多
12、层感知器是不稳定的,最近邻算法是稳定的,但是精简的最近邻算法是不稳定的。n一个学习算法是不稳定的,如果训练集的微小变化引起由其训练得到的学习器的很大差异,即学习算法具有高方差。nBagging的组合策略是:分类任务采取简单投票法,即每个基学习器一票;回归任务使用简单平均法,即每个基学习器的预测值取平均值。nsklearn提供了典型的Bagging分类器,其原型如下:class sklearn.ensemble.BaggingClassifier(base_estimator=None,n_estimators=10,max_samples=1.0,max_features=1.0,bootst
13、rap=True,bootstrap_features=False,oob_score=False,warm_start=False,n_jobs=1,random_state=None,verbose=0)source7.3 Baggingn 主要参数l base_estimator:对象,默认值为None。如果是None,则默认的基学习器是决策树。l n_estimator:整型,默认值为10。基学习器的数量。l max_samples:整型或浮点型,默认值为1.0。从X中抽取指定的样本数来训练每个基学习器。如果是整型,抽取max_samples个样本作为训练数据集;否则,抽取max_sa
14、mples*X.shape0样本作为训练数据集。l max_features:整型或浮点型,默认值为1.0。从X中抽取指定的属性数量来训练每个基学习器。如果是整型,抽取max_featuress个属性;否则,抽取max_features*X.shape1属性。l warm_start:布尔值,默认值为False。当设置为True时,训练是在前一次集成学习的基础上,继续训练并添加更多基学习器到集成学习中来,否则,只是训练一个全新的集成学习。7.3 Baggingn采取与前一节示例中一样的基学习器,分别构造三个不同的基学习器以及它们相对应的挂袋集成学习器,然后使用sklearn中的鸢尾花数据集训练
15、上述各个学习器。挂袋法比单个基学习器的效果稍好一点。7.3 Baggingn 随机森林(Random Froest,RF)的基学习器是决策树。对于一个输入样本,N棵决策树就会有N个分类结果,随机森林集成了所有分类投票结果,将投票次数最多的类别作为最终的输出。(1)抽样产生每棵决策树的训练数据集。RF采用Bagging抽样技术从原始训练数据集中产生N个训练子集。(2)构建N棵决策树(基学习器)。每一个训练子集生成一棵决策树,从而产生N棵决策树形成森林,每棵决策树不需要剪枝处理。(3)生成随机森林,以简单多数的原则决定该样本是哪个类别。使用N棵决策树对测试样本进行分类,随机森林将每棵子树的结果汇总
16、,以简单多数的原则决定该样本是哪个类别。n 随机森林的生成过程如下:7.3 Bagging(4)从原始训练集中随机产生N个训练子集用于随机生成N颗决策树。(5)在构建具体的决策树过程中随机地选择m个属性,随机森林的生成过程中这两个随机性,可以确保不会出现过拟合(over-fitting)。n sklearn提供了RF分类器,其原型如下:class sklearn.ensemble.RandomForestClassifier(n_estimators=10,criterion=gini,max_depth=None,min_samples_split=2,min_samples_leaf=1,
17、min_weight_fraction_leaf=0.0,max_features=auto,max_leaf_nodes=None,min_impurity_decrease=0.0,min_impurity_split=None,bootstrap=True,oob_score=False,n_jobs=1,random_state=None,verbose=0,warm_start=False,class_weight=None)7.4 Boostingn 1990年,R.Schapire给出了肯定的答案,通过组合三个弱学习器实现了一个强学习器,促进了提升(Boosting)算法的极大发
18、展。Boosting算法分为如下两个阶段。n 训练阶段。给定一个大训练集X,随机地将其划分为3个子集X=X1,X2,X3。首先,使用X1训练的d1;接着,提取X2并将它作为d1的输入,将d1错误分类的所有实例以及X2中被d1正确分类的一些实例一起作为d2的训练集;然后,提取X3并将它输入给d1和d2,其中用d1和d2输出不一致的实例作为d3的训练集。n 检验阶段。给定一个实例,首先将其提供给d1和d2,如果二者输出一致,这就是输出结果,否则d3的输出作为输出结果。7.4 Boosting7.4.1 AdaBoostn 尽管Boosting非常成功,但是需要一个非常大的训练样本集,将样本集一分为
19、三。()n 1996年,Yoav Freund和Robert Schapire提出了提升的一个变种,即自适应提升(Adaptive Boosting,AdaBoost),它重复使用相同的训练集,而不再要求很大的数据集。n AdaBoost算法的工作机制 首先,训练集用初始权重训练出一个弱学习器1,根据弱学习的学习误差率表现来更新训练样本的权重,使得之前弱学习器1学习误差率高的训练样本点的权重变高,使得这些误差率高的点在后面的弱学习器2中得到更多的重视。然后,基于调整权重后的训练集来训练弱学习器2,如此重复进行,直到训练到指定的弱学习器数量。最后,将这些弱学习器通过集合策略进行整合,得到最终的强
20、学习器。7.4 Boosting7.4.1 AdaBoostBoosting7.4.1 AdaBoostingBoosting7.4.1 AdaBoosting7.4 Boosting7.4.1 AdaBoost,n标准的AdaBoost算法模型是二分类的加法模型,其中损失函数为指数函数,学习方法为前向分步算法。n在AdaBoost中,尽管不同的基学习器使用稍有差异的训练集,但是这种差异不像Bagging那样完全依靠偶然性,而是它前一个基学习器误差的函数。提升对一个特定问题的实际性能显然依赖于训练数据集和基学习器。为此,需要有足够的训练数据,并且学习器应当是弱的但又不是太弱,而且提升对噪声和离
21、群点尤其敏感。n Sklearn提供的AdaBoost分类器实现了SAMME和SAMME.R算法,原型如下:class sklearn.ensemble.AdaBoostClassifier(base_estimator=None,n_estimators=50,learning_rate=1.0,algorithm=SAMME.R,random_state=None)7.4 Boostingn SAMME和SAMME.R算法的主要参数base_estimator:对象,默认值为决策树。该基础分类器必须支持带样本权重的学习。n_estimators:整型,默认值为50。设定基分类器数量的上限值
22、,如果训练集已经完全训练好了,算法会提前终止。learning_rate:浮点型,默认值为1。用于减少每一步的步长,防止步长太大而跨过极值点。通常在learning_rate和n_estimators之间会有一个折中。algorithm:SAMME.R,SAMME,默认值为SAMME.R。n 首先使用sklearn的make_Hastie_10_2生成12000个样本的数据集,并将其分为训练数据集和测试数据集。然后,在基决策树、决策树、AdaBoost(SAMME)和AdaBoost(SAMME.R)上计算分类的错误率。7.4 Boostingn 从实验结果看出,弱分类器(Decision T
23、ree Stump)单独分类的效果很差,错误率将近50%,强分类器(Decision Tree)的效果要明显好于它。但是AdaBoost的效果要明显好于这两者。同时在AdaBoost中,Real AdaBoost的分类效果更好。7.4 Boostingn 梯度提升(Gradient Boosting)是一种用于回归和分类问题的机器学习方法,生成一个由弱预测模型(通常是决策树)组成的集成预测模型(强学习器)。通过迭代选择一个指向负梯度方向上的函数(弱假设),优化函数空间上的成本函数,拟合一棵决策树。在回归问题中,这称为梯度提升回归树GBRT;在分类问题中,这又被称为提升决策树GBDT。7.4.2
24、 Gradient Boosting7.4 Boosting7.4.2 Gradient BoostingBoosting7.4.2 Gradient Boosting 01argmin,MicifL y cxBoosting7.4.2 Gradient Boosting 11Jmmmjmjjffc IRxxx1argmin,imjmjimicRcL yfcxx7.4 Boosting7.4.2 Gradient Boostingn GBDT可用于回归问题,相对Logistic Regression仅能用于线性回归,GBDT能用于线性回归和非线性回归,GBDT的适用面更广。GBDT也可用于二分
25、类问题(设定阈值,大于阈值为正例,反之为负例)。n Sklearn提供的GBDT的实现类原型如下:class sklearn.ensemble.GradientBoostingClassifier(loss=deviance,learning_rate=0.1,n_estimators=100,subsample=1.0,criterion=friedman_mse,min_samples_split=2,min_samples_leaf=1,min_weight_fraction_leaf=0.0,max_depth=3,min_impurity_decrease=0.0,min_impur
26、ity_split=None,init=None,random_state=None,max_features=None,verbose=0,max_leaf_nodes=None,warm_start=False,presort=auto)7.4 Boosting7.4.2 Gradient Boostingn 主要参数如下:7.4 Boostingn 运行效果如下:n针对GradientBoostingClassifier中的learning_rate参数的不同取值,分别构造一颗梯度提升分类学习器,并在手写体数字数据集上进行训练并测试。从图中,可以看到,GBDT的预测准确率对于学习率来说,
27、总体上是平稳的。7.5 综合案例n 集成学习是机器学习中的一种“集大成”的学习方法,下面给出一个示例程序,来比较几种典型的机器学习算法在不同数据集上的性能差异。程序如下:import numpy as npimport matplotlib.pyplot as pltfrom matplotlib.colors import ListedColormapfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.datasets
28、import make_moons,make_circles,make_classificationfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.svm import SVCfrom sklearn.tree import DecisionTreeClassifierfrom sklearn.ensemble import RandomForestClassifier,AdaBoostClassifierfrom sklearn.ensemble import GradientBoostingClassifierf
29、rom sklearn.naive_bayes import GaussianNBfrom sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDAfrom sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis as QDA7.5 综合案例h=.02#网格的步长#分类的名称列表,及其对应的对象列表names=Nearest Neighbors,Linear SVM,RBF SVM,Decision Tree,GBDT,Random
30、Forest,AdaBoost,Naive Bayes,LDA,QDAclassifiers=KNeighborsClassifier(3),SVC(kernel=linear,C=0.025),SVC(gamma=2,C=1),DecisionTreeClassifier(max_depth=5),GradientBoostingClassifier(max_depth=5),RandomForestClassifier(max_depth=5,n_estimators=10,max_features=1),AdaBoostClassifier(),GaussianNB(),LDA(),QD
31、A()7.5 综合案例#生成样本数据集X,y=make_classification(n_features=2,n_redundant=0,n_informative=2,random_state=1,n_clusters_per_class=1)rng=np.random.RandomState(2)X+=2*rng.uniform(size=X.shape)linearly_separable=(X,y)datasets=make_moons(noise=0.3,random_state=0),make_circles(noise=0.2,factor=0.5,random_state=1
32、),linearly_separable figure=plt.figure(figsize=(27,9)i=1#依次处理每一个数据集,在每个数据集上分别用前面列举的10种分类方法for ds in datasets:#将每个数据集划分为训练集和测试集 X,y=ds X=StandardScaler().fit_transform(X)X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=.4)x_min,x_max=X:,0.min()-.5,X:,0.max()+.5 y_min,y_max=X:,1.min()-.5,X
33、:,1.max()+.5 xx,yy=np.meshgrid(np.arange(x_min,x_max,h),np.arange(y_min,y_max,h)#绘制原始数据 cm=plt.cm.RdBu cm_bright=ListedColormap(#FF0000,#0000FF)ax=plt.subplot(len(datasets),len(classifiers)+1,i)#分别绘制训练数据集、测试数据集 ax.scatter(X_train:,0,X_train:,1,c=y_train,cmap=cm_bright)ax.scatter(X_test:,0,X_test:,1,
34、c=y_test,cmap=cm_bright,alpha=0.6)ax.set_xlim(xx.min(),xx.max()ax.set_ylim(yy.min(),yy.max()ax.set_xticks()ax.set_yticks()i+=17.5 综合案例7.5 综合案例#迭代使用上述10种分类方法 for name,clf in zip(names,classifiers):ax=plt.subplot(len(datasets),len(classifiers)+1,i)clf.fit(X_train,y_train)score=clf.score(X_test,y_test)
35、#Plot the decision boundary.For that,we will assign a color to each#point in the mesh x_min,m_maxxy_min,y_max.if hasattr(clf,decision_function):Z=clf.decision_function(np.c_xx.ravel(),yy.ravel()else:Z=clf.predict_proba(np.c_xx.ravel(),yy.ravel():,1#勾勒出分类集的边界 Z=Z.reshape(xx.shape)ax.contourf(xx,yy,Z,
36、cmap=cm,alpha=.8)#分别绘制训练数据集和测试数据集 ax.scatter(X_train:,0,X_train:,1,c=y_train,cmap=cm_bright)ax.scatter(X_test:,0,X_test:,1,c=y_test,cmap=cm_bright,alpha=0.6)ax.set_xlim(xx.min(),xx.max()ax.set_ylim(yy.min(),yy.max()ax.set_xticks()ax.set_yticks()ax.set_title(name)ax.text(xx.max()-.3,yy.min()+.3,(%.2f
37、%score).lstrip(0),size=15,horizontalalignment=right)i+=1 figure.subplots_adjust(left=.02,right=.98)plt.show()7.5 综合案例7.5 综合案例n运行效果如下 7.5 综合案例n结论:首先,构造要比较的机器学习方法对象,并存放在一个列表中。接着,随机生成了三个样本数据集,其分割面分别近似为月形(moons)、圆形(circles)和线形的。最后,在每个样本数据集上,分别用先前定义的学习器去训练模型,并比较学习器在测试数据集上的得分。从运行结果上看,集成学习方法要优于单个的学习器。如随机森林(Random Forest)、梯度提升(GBDT)和自适应提升(AdaBoost)都是以决策树(Decision Tree)为基学习器,但上述三种集成学习的识别率都会好于决策树,尤其是随机森林表现更加优异,在月形数据集上达到了100%,其次是GBDT。