一、集成学习
1.概念
集成学习的思想就是综合考虑多个算法的结果,通过投票机制,少数服从多数,将得票最多的结果设为最终的结果。
import numpy as np
import matplotlib.pyplot as pltfrom sklearn import datasets
x,y = datasets.make_moons(n_samples=500,noise=0.3,random_state=42)
plt.scatter(x[y==0,0],x[y==0,1])
plt.scatter(x[y==1,0],x[y==1,1])
plt.show()
下面通过多种算法进行训练。
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(x,y,random_state=42)
from sklearn.linear_model import LogisticRegression
log= LogisticRegression()
log.fit(x_train,y_train)
log.score(x_test,y_test) #0.864
from sklearn.svm import SVC
svm = SVC()
svm.fit(x_train,y_train)
svm.score(x_test,y_test) #0.888
from sklearn.tree import DecisionTreeClassifier
dt = DecisionTreeClassifier()
dt.fit(x_train,y_train)
dt.score(x_test,y_test) #0.872
现在对上面的预测值进行投票,如果将所有的预测值进行相加,那么如果对应的元素大于等于2,就说明有2个以上的算法认为该分类属于1,那么可以投票定分类结果为1。
predictlog = log.predict(x_test)
predictsvm = svm.predict(x_test)
predictdt = dt.predict(x_test)
y_predict = np.array((predictdt+predictlog+predictsvm)>=2,dtype='int')
from sklearn.metrics import accuracy_score
accuracy_score(y_test,y_predict) #0.94大于之前三个算法的预测结果
sklearn封装了集成学习的架构。
from sklearn.ensemble import VotingClassifier
voting_clf = VotingClassifier(estimators=[('log',LogisticRegression()),('svm',SVC()),('dt',DecisionTreeClassifier())
],voting='hard')voting_clf.fit(x_train,y_train)
voting_clf.score(x_test,y_test)
最终的结果和之前一致。
2.soft voting
之前的例子中,使用的是hard voting,这个投票机制中,算法的权重都一样,而实际上,不同算法应该区分不同的权重,某个算法的预测准确,就该分配高权重,而某些算法的预测准确度相对较低就该分配较低的权重。这就是soft voting的思想,soft voting要求算法都能够得到一个概率值,也就是说在soft voting中,模型都必须基于概率 ,例如逻辑回归。knn和决策树也可以支持概率运算,在knn中,最后计算属于哪个类别时,其实也是考虑在k个最近样本哪个类别的比重大,而决策树在叶子节点中,样本可能不唯一,也是通过投票机制,确定比重大的那一类为该类别。SVC也能够计算出概率值,但是实现比较复杂,这里不展开,只需要传入参数probability=True。
from sklearn.ensemble import VotingClassifier
voting_clf = VotingClassifier(estimators=[('log',LogisticRegression()),('svm',SVC(probability=True)),('dt',DecisionTreeClassifier(random_state=666))
],voting='soft')voting_clf.fit(x_train,y_train)
voting_clf.score(x_test,y_test)
二、Bagging和Pasting
1.子模型
对于集成学习,在考虑多个模型预测的结果同时,必须要使投票数足够的多,投票越多结果就越置信。所以单单用几个模型得到的投票结果还是不够的,那么如何在有限个模型的情况下,得到成百上千的投票结果?集成学习的方法是用模型产生多个子模型,每个模型之间有所差异,如果子模型没有差异,那么投票的结果就会相同,这其实考虑的还是同一个投票意见。实现的方法是每个子模型传入不一样的样本数据。例如,现在只有一个逻辑回归模型,样本有3000个,可以将样本分成300份,每份10个样本,这样就训练出300个逻辑回归的子模型,而子模型之间又有所差异。这时候,容易理解,由于样本数据量很少,模型将会欠拟合,预测的结果也不够准确。但是在集成学习中,如果每个子模型只有60%的准确率,如果保证超过一半的预测是正确的,这个结果的准确性将会达到99.9%。这个是理论值,目的是为了让读者对集成学习的威力能够有所认识。
对于每个子模型只看样本数据的一部分,而这种实现方式有2种,分别为bagging和pasting。bagging为返回取样,pasting为不放回取样,相比较而言,bagging使用的比较多。
from sklearn.tree import DecisionTreeClassifier #要形成成百上千的子模型,首选决策树,决策树非参数学习更能产生出不一样的子模型
from sklearn.ensemble import BaggingClassifier
bagging = BaggingClassifier(DecisionTreeClassifier(),n_estimators=5000,max_samples=100,bootstrap=True)
bagging.fit(x_train,y_train)
bagging.score(x_test,y_test)
这里只使用决策树模型,样本数据同上。n_estimators指定子模型个数,max_sample指定每次训练传入的样本个数,最后指定是否用boostrap,即是否采用有放回的方式。
2.OOB
OOB即out of bag,在放回取样中,可能导致一部分样本始终未被取到,通过概率统计,大约会有37%的样本从未被使用到,这些样本就是out of bag,这些样本可以作为测试样本,来验证模型。
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import BaggingClassifier
bagging = BaggingClassifier(DecisionTreeClassifier(),n_estimators=5000,max_samples=100,bootstrap=True,oob_score=True)
bagging.fit(x,y)
bagging.oob_score_
依然用上面的数据,在bagging中传入参数oob_score,接着将所有的样本全部放进去,调用oob_score_就可以得到测试分数。
bagging的方式容易并行处理,可以在baggingclassifier中传入参数,n_jobs=-1,将所有的核用于计算。
3.针对特征取样
目前为止,bagging的随机取样是针对样本,在样本特征足够多,例如图像中,可以针对特征进行随机采样,称为random subspaces,既针对样本,又针对特征进行随机采样的方式称为random patches。
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import BaggingClassifier
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(x,y,random_state=42)
bagging = BaggingClassifier(DecisionTreeClassifier(),n_estimators=5000,max_samples=100,bootstrap=True,oob_score=True,n_jobs=-1,max_features=1,bootstrap_features=True)
bagging.fit(x,y)
bagging.oob_score_
这里既针对样本,又针对特征进行取样(最大样本数小于实际样本数即可),因为样本只有2个特征,所以效果其实不明显,这里只是为了演示,max_features设置取的特征个数,bootstrap_features设置是否为有放回。
三、随机森林
1.概念
上面代码中生成子模型底层依赖的是决策树,这些随机生成的子决策树构成的整体叫做随机森林。sklearn中封装了随机森林,决策树将在节点上划分,在随机的特征子集上寻找最优划分特征。
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_estimators=500,random_state=666,oob_score=True,n_jobs=-1)
rf.fit(x,y)
2.extra-trees
顾名思义,极其随机,决策树在节点划分上,使用随机的特征和随机得到阈值。这种方式提供额外的随机性,训练速度快,抑制了过拟合,但增大了偏差。
from sklearn.ensemble import ExtraTreesClassifier
rf =ExtraTreesClassifier(n_estimators=500,random_state=666,bootstrap=True,oob_score=True,n_jobs=-1)
rf.fit(x,y)
3.回归问题
决策树可以解决回归问题,因此集成森林也可以。
from sklearn.ensemble import BaggingRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import ExtraTreesRegressor
四、boosting
1.Ada boosting
除了上述的集成学习外,还有另外一种集成学习方式boosting,同样也是集成多个模型,但是每个模型都在尝试增强整体的模型效果。例如在Ada boosting 中,对于未被使用的样本点将会增大其权重,在下次训练中将会优先考虑这些点,如此反复下去,知道训练出足够多的子模型。
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(x,y,random_state=42)
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
ada = AdaBoostClassifier(DecisionTreeClassifier(max_depth=2),n_estimators=500)
ada.fit(x_train,y_train)
2.gradient boosting
梯度boosting的思想是训练一个模型m1,该模型产生错误e1,针对e1训练出第二个模型m2,产生错误e2,依次类推,最终预测结果是将所有的模型进行相加。由于每个模型都是上一个模型的修正,因此模型的预测效果将会不断增强。
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(x,y,random_state=42)
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.tree import DecisionTreeClassifier
gra= GradientBoostingClassifier(max_depth=2,n_estimators=30)
gra.fit(x_train,y_train)
五、stacking
1.思想
将子模型训练的预测结果再生成一个模型,通过该模型最终预测出一个结果。
stacking先将数据分成2份,其中第一份用于生成底层的模型,第二份用于生成顶层的模型。方法:在生成底层的模型后,将第二份数据输入到生成的模型中,并产生结果,这些结果和第二份数据作为输入再训练出顶层的模型。
stacking还可以继续构建更复杂的结构,这种方式就类似神经网络。