机器学习预测乳腺肿瘤性质(7)
作者:汪君,专职数据分析,Python和R爱好者
个人微信公众号:学英文和玩数据
前文传送门:
在前面一系列的文章中,我们运用logistic回归,SVM支持向量机、随机森林、朴素贝叶斯以及神经网络多层感知机等不同机器学习算法在Wisconsin 乳腺组织数据集上训练模型来预测肿瘤的性质。本篇重点关注如何把这些分类算法集成起来,构建出一个效果更好的综合分类器。
机器学习称这种把机器学习模型集成起来的方法为ensemble learning(集成学习)。集成学习的原理很容易理解,非常intuitiv,就是把不同的机器学习模型组合起来,发挥各自的优势,扬长避短。集成学习有下面几个优势:
预测效果好,集成学习多数情况下优于单一模型的预测效果。在诸如kaggle这样的机器学习模型竞赛中,名列前茅的选手们往往无一例外使用ensemble learning的方法来提升模型的最终预测效果。
部分集成学习可以并列实现,在不同的cpu上跑不同的模型,然后将这些模型再集成起来
组合方法简单灵活,可以组合不同类型的机器学习模型,也可以组合同一类型的随机机器学习模型(典型案例就是决策树模型组合为随机森林),可以自己设定集成的规则。
集成各个学习器的结果主要是通过voting(投票)的方式。例如面对一个二分类问题(0和1)的时候,logistic回归给出一个分类结果1,svm预测的结果是0,朴素贝叶斯预测出来的是1,人工神经网络给出的是1,那么按照少数服从多数的原则,集成分类的预测结果就是1. 这在机器学习中称为hard voting 硬投票方式,还有soft voting 软投票方式,就是依据分类器给出的概率平均值结果来投票,比如A分类器预测的概率是{0:0.53,1:0.47},B分类器预测出的概率是{0:0.36,1:0.64},那分类为0的概率均值为(0.53+0.36)/2=0.445, 分类为1的概率为(0.47+0.64)/2=0.555,所以最终预测结果为分类1,当然soft voting仅限于那些能够给出分类概率的学习器。另外还可以给每个学习器设置不同权重,给效果较好的学习器赋予较大的权重,使其预测结果在最终决策中发挥作用更大。
下面介绍集成学习的两种主要形式:bagging and boosting,
bagging就是反复有放回(或无放回)在样本数据集中随机抽出子样本作为训练集,不断从这些子样本训练出模型,然后把所有模型结果集成。bagging不仅 可以抽取数据样例(instance),也可以随机抽取特征(feature)。 总之可以理解为在样本空间里不断提取亚空间出来做训练集不断训练模型,最后把众多个模型集成起来。前面文章里用到的Random Forest随机森林就是bagging的典型代表。
boosting也是把弱学习器集成为强学习器,和bagging的不同之处在于,大部分boosting方法强调有先后顺序的进行模型训练,从前一个学习器所犯的错误中学习,吃一堑长一智,不断迭代循环改进下一个学习器。然后再把所有的学习器按照一定的规则再集成其预测结果。boosting的两大主力分别为adaboosting和Gradient boosting。
我们这里多花一点笔墨,简单描述一下两者的实现细节。有兴趣的童鞋可以去搜索这两个算法的详细资料,挖个深坑。
AdaBoosting的算法思想是给学习器和训练集的个案都赋予权重,表现越好的学习器权重越高,越难被预测准确的训练数据个案权重越高,越受重视。AdaBoosting的实现细节是:先给每个训练样本个案赋予权重(初始权重一般都是平等的),第一个学习器训练出来以后,会预测错一部分样本个案,根据预测错的比例以及个案权重来给该学习器本身计算一个权重,同时更新被分错训练集个案的权重(强调所犯错误),然后进行第二次训练,依照第二个学习器错误预测的情况和新个案权重再计算第二个学习器的权重,并再次更新个案的权重,如此依次迭代下去,直至学习器的数量达到预先指定的数量,或是迭代到一个非常完美的学习器。最后在做预测时,通过每个分类器的预测结果及分类器的权重对预测结果进行集成,得到最终的预测结果。
Gradient boosting同样也是关注上一个学习器所犯的错误,但是其方式不同于AdaBoosting。Gradient boosting是先训练一个学习器,然后计算这个学习器预测结果和实际值之间的残差e1,然后训练第二个学习器,第二个学习器的训练方法变了,不是去拟合原始数据y,而是去拟合e1,第二个学习器构建好以后,再次计算它的残差e2, 得到e2以后,就可以构建第三个学习器去拟合e2,将这个过程持续迭代,最后在预测时,把这些学习器的预测结果相加,就得到了最终预测结果。
下面我们在数据集上将这些算法用代码实现:
##把前面几篇文章里使用的分类器都集成起来,包括logistic regression,支持
##向量机,朴素贝叶斯,多层感知器,随机森林,
from sklearn.model_selection import cross_val_predict
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import StratifiedShuffleSplit
##分割训练集和测试集数据,在测试集上计算每个分类学习算法的混淆矩阵
cut=StratifiedShuffleSplit(n_splits=1,random_state=42,test_size=0.2)
for a,b in cut.split(X=predi_features,y=diagnosis):
train_x,train_y=predi_features.iloc[a,:],diagnosis[a]
test_x,test_y=predi_features.iloc[b,:],diagnosis[b]
##logistic 回归
test_prediction_log=logClf.fit(train_x,train_y).predict(test_x)
print('confusion matrix for logistical classifier is:')
print(confusion_matrix(test_y,test_prediction_log))
##支持向量机
from sklearn.svm import SVC
svmClf=SVC(kernel="linear",C=1)
test_prediction_svm=svmClf.fit(train_x,train_y).predict(test_x)
print('confusion matrix for SVM classifier is:')
print(confusion_matrix(test_y,test_prediction_svm))
##随机森林
from sklearn.ensemble import RandomForestClassifier
rfClf=RandomForestClassifier()
test_prediction_rf=rfClf.fit(train_x,train_y).predict(test_x)
print('confusion matrix for randomForest classifier is:')
print(confusion_matrix(test_y,test_prediction_rf))
##多层感知器
from sklearn.neural_network import MLPClassifier
MLPclf=MLPClassifier(activation="relu",batch_size=80,
hidden_layer_sizes=(30,30,30,15,55,15,15,30),
max_iter=2000,random_state=42,learning_rate_init=0.001)
test_prediction_MLP=MLPclf.fit(train_x,train_y).predict(test_x)
print('confusion matrix for MLP classifier is:')
print(confusion_matrix(test_y,test_prediction_MLP))
##朴素贝叶斯
from sklearn.naive_bayes import GaussianNB
nbClf=GaussianNB()
test_prediction_NB=GaussianNB().fit(X=train_x,y=train_y).predict(test_x)
print("confusion matrix for Naive Bayesian is:")
print(confusion_matrix(test_y,test_prediction_NB))
##集成学习,把上面的分类器结果综合起来,进行hard voting
from sklearn.ensemble import VotingClassifier
vot=VotingClassifier(estimators=[('logistic',logClf),("svm",svmClf),("rf",rfClf),('nb',nbClf),('nn',MLPclf)],voting="hard")
votClf=vot.fit(train_x,train_y)
vot_prediction=votClf.predict(test_x)
from sklearn.metrics import confusion_matrix
print("confusion matrix for ensemble learning is:")
print(confusion_matrix(test_y,vot_prediction))
from sklearn.metrics import f1_score
print(f1_score(test_y=="M",vot_prediction=="M"))
最终结果:
可以看到ensemble以后效果还是有的,在接下来的文章中,我们会继续学习Adaboosting 和Gradient Boosting。
如果本篇文章对您有帮助,请帮我点个赞吧 👍
Python爱好者社区历史文章大合集:
Python爱好者社区历史文章列表(每周append更新一次)
关注后在公众号内回复“课程”即可获取:
小编的Python入门视频课程!!!
崔老师爬虫实战案例免费学习视频。
丘老师数据科学入门指导免费学习视频。
陈老师数据分析报告制作免费学习视频。
玩转大数据分析!Spark2.X+Python 精华实战课程免费学习视频。
丘老师Python网络爬虫实战免费学习视频。