

本章会介绍机器学习领域中非常重要的集成学习方法。在机器学习中,集成学习方法使用多种学习算法来获得比使用任何单独的学习算法更好的预测性能。
集成学习类似新世纪福音战士(EVA)中名为 "三贤者" 的超级电脑。三贤者的创作者是赤木博士,三贤者可以看成拥有独立思维的三个不同身份,分别是赤木博士作为科学家的身份、作为母亲的身份以及作为女性的身份。对于同意或反对的决策问题,三贤者会根据三个不同的身份(三种不同的思维)分别给出对应的决策,最终根据 "少数服从多数" 的原则作出最终是同意还是反对的决策。三贤者就应用了集成学习的思路。
前面已经学习了很多机器学习算法,不同的机器学习算法考虑问题的方式有所不同,因此对于同一个问题不同的机器学习算法可能给出不同的结果。在这种情况下,我们完全可以应用集成学习的思路,让多个机器学习算法在同一个问题上分别进行学习并预测,最终根据 "少数服从多数" 的原则作出最终预测。
现实生活中,我们很多时候也在使用这种集成学习的思路。比如:
我们熟知很多机器学习算法,比如 kNN、逻辑回归、SVM、决策树,神经网络和贝叶斯等,这些算法都能够解决回归问题和分类问题(除了逻辑回归算法只能解决分类问题),因此面对同一个问题,可以让不同的机器学习算法去解决,最终根据 "少数服从多数" 的原则给出针对问题的最终结果。
通过上面的介绍,大致了解了集成学习,其实自己手动编写集成学习的代码并不难。具体来说,针对某一个二分类问题,将二分类训练集分别在逻辑回归、SVM 和决策树三种机器学习算法上进行训练,最终综合三种训练好的机器学习算法在测试集上的预测结果,根据 "少数服从多数" 的原则给出最终的预测结果。
接下来就通过手动的编写代码的方式来实现集成学习。
In[1]: import numpy as np
import matplotlib.pyplot as plt
本小节使用分布呈现交错半圆形的二分类虚拟数据集,使用 sklearn.datasets 包下的 make_moons 函数即可生成这样的虚拟数据集。
In[2]: from sklearn import datasets
X, y = datasets.make_moons(n_samples = 500,
noise = 0.3,
random_state = 42)
在使用 make_moons 函数时指定三个参数:
使用散点图将生成的虚拟数据集绘制出来。
In[3]: plt.scatter(X[y == 0, 0], X[y == 0, 1])
plt.scatter(X[y == 1, 0], X[y == 1, 1])
plt.show()

使用 train_test_split 方法将数据集划分为训练集和测试集。
In[4]: from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 42)
In[5]: from sklearn.linear_model import LogisticRegression
log_clf = LogisticRegression()
log_clf.fit(X_train, y_train)
log_clf.score(X_test, y_test)
Out[5]: 0.86
In[6]: from sklearn.svm import SVC
svm_clf = SVC()
svm_clf.fit(X_train, y_train)
svm_clf.score(X_test, y_test)
Out[6]: 0.88
In[7]: from sklearn.tree import DecisionTreeClassifier
dt_clf = DecisionTreeClassifier()
dt_clf.fit(X_train, y_train)
dt_clf.score(X_test, y_test)
Out[7]: 0.86399
接下来使用三种在同一个训练集上训练好的分类器对相同的数据集进行预测(这里使用X_test)。y_predict1、y_predict2 和 y_predict3 分别是三种训练好的分类器对 X_test 的预测结果。
In[8]: y_predict1 = log_clf.predict(X_test)
y_predict2 = svm_clf.predict(X_test)
y_predict3 = dt_clf.predict(X_test)
接下来使用集成学习方法,将三种训练好的分类器对 X_test 的预测结果根据 "少数服从多数" 的原则得到最终的预测结果 y_predict。实现也非常简单,只需要将 y_predict1、y_predict2 和 y_predict3 加在一起,判断累加的结果是否大于等于 2,如果对应预测结果大于等于 2 则表示至少有两个模型,至多有三个模型认为这个预测结果等于 1(二分类预测结果要不是 1 要不是 0),将最终布尔值转换为 int 类型(转不转都可以,Python 会将 True 看作 1,False 看作0)。
In[9]: y_predict = np.array((y_predict1 + y_predict2 + y_predict3) >= 2, dtype = 'int')
y_predict 是使用集成学习的方法得到对 X_test 的最终预测结果。
In[10]: y_predict[:10]
Out[10]: array([1, 0, 0, 1, 1, 1, 0, 0, 0, 0])
使用 sklearn.metrics 包下的 accuracy_score 函数计算使用集成学习得到最终预测结果的准确率。
In[11]: from sklearn.metrics import accuracy_score
accuracy_score(y_test, y_predict)
Out[11]: 0.896
通过集成学习得到的准确度为 0.896,显然要高于单独使用三种机器学习算法得到的准确度要高。换句话说,通过这种集成学习的方法提高了预测的准确度。
sklearn 已经封装好了类来实现集成学习,只需要从 sklearn.ensemble 包下导入 VotingClassifier 类(ensemble 是集成的意思,集成学习为 ensemble learning)。sklearn 框架的设计和使用规范统一,因此使用 VotingClassifier 和使用其它机器学习算法的方法大致相同,首先实例化 VotingClassifier 类。
In[12]: from sklearn.ensemble import VotingClassifier
voting_clf = VotingClassifier(estimators = [
('log_clf', LogisticRegression()),
('svm_clf', SVC()),
('dt_clf', DecisionTreeClassifier())
], voting = 'hard')
实例化 VotingClassifier 类的同时指定两个参数:
接下来调用 fit 方法进行拟合训练。
In[13]: voting_clf.fit(X_train, y_train)
Out[13]: VotingClassifier(estimators=[('log_clf', LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
penalty='l2', random_state=None, solver='liblinear', tol=0.0001,
verbose=0, warm_start=False)), ('svm_clf... min_weight_fraction_leaf=0.0, presort=False, random_state=None,
splitter='best'))],
flatten_transform=None, n_jobs=1, voting='hard', weights=None)
最后调用 score 方法计算在测试集上的准确度。
In[14]: voting_clf.score(X_test, y_test)
Out[14]: 0.896
通过 sklearn 封装的 VotingClassifier 类实现的集成学习和前面手动实现的集成学习最终得到准确率的结果都是 0.896。这里需要注意,本小节实例化的三个机器学习算法使用的都是默认的参数,在具体的使用中,可以先找出每个机器学习算法在训练集上的最优参数,在使用 sklearn 实例化 VotingClassifier 类实现集成学习时,指定 estimators 参数,传入的机器学习算法实例对象时传入对应的最优参数。
References:
本文分享自 AI机器学习与深度学习算法 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!