集成学习(中) Task7 投票法的思路
投票法的思想来源来自于我们日常常见的“少数服从多数”,对于参与这次“研讨会”的每一个机器学习模型,对同一个“分类”问题都有有一个看法,我们统计所有模型的投票结果,被多次认同的结果,作为这个融合模型的最终结果。这就是集成学习中的投票法想法来源。
对于回归模型来说,投票法最终的预测结果是多个其他回归模型预测结果的平均值。
对于分类模型,硬投票法的预测结果是多个模型预测结果中出现次数最多的类别,软投票对各类预测结果的概率进行求和,最终选取概率之和最大的类标签。
常见的投票策略
-
绝对多数投票法
这种策略的想法很简单,就是单纯的超过半数的结果,就视为是最终的结果。
即:
-
相对多数投票法
H ( x ) = c a r g M A X j ∑ i = 1 T h i j ( x ) H(x) = c_{argMAX j} \sum_{i=1}^{T}h_{i}^{j}(x) H(x)=cargMAXji=1∑Thij(x)
这就是我们传统的最高票者,若同时多个标记获得最高票数,则从中随机选择 -
加权投票
与加权和有点相似,一般用在有专家与普通投票者的场景,也就是某些模型的可信度较高,他的票数比较有说服力
H ( x ) = c a r g M A X j ∑ i = 1 T w i h i j ( x ) H(x) = c_{argMAX j} \sum_{i=1}^{T}w_i h_{i}^{j}(x) H(x)=cargMAXji=1∑Twihij(x)
怎么样让模型集成得有质量
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RP6OLXlp-1618331317123)(C:\Users\melon\AppData\Roaming\Typora\typora-user-images\image-20210413203837498.png)\
由以上可知,理论上一个由投票产生的集成模型要具有更好的效果,应该满足两个条件:
- 个体学习器应该要有一定的准确性
- 个体学习器要有多样性,模型之间的结合才有意义
换句话说,也就是 “和而不同”
- 基模型之间的效果不能差别过大。当某个基模型相对于其他基模型效果过差时,该模型很可能成为噪声。
- 基模型之间应该有较小的同质性。例如在基模型预测效果近似的情况下,基于树模型与线性模型的投票,往往优于两个树模型或两个线性模型。
当然投票法也存在局限性:它对所有模型的处理是一样的,这意味着所有模型对预测的贡献是一样的。如果一些模型在某些情况下很好,而在其他情况下很差,这是使用投票法时需要考虑到的一个问题。
sklearn
投票法实战
针对回归问题,也就是针对软投票问题,sklearn提供了VotingRegressor
接口,而对于分类问题,即硬投票问题VotingClassifier
接口。
这两种模型的操作方式相同,并采用相同的参数。使用模型需要提供一个模型列表,列表中每个模型采用Tuple的结构表示,第一个元素代表名称,第二个元素代表模型,需要保证每个模型必须拥有唯一的名称。
利用糖尿病数据集的集成学习实战
使用糖尿病数据集,其中包括从一组糖尿病患者中收集的10个特征。目标是基线后一年的疾病进展的定量测量。
使用三种不同的回归模型预测数据: GradientBoostingRegressor
, RandomForestRegressor
和 LinearRegression
。然后将上述3个回归模型用于 VotingRegressor。
最后,绘制所有模型所做的预测以进行比较。
引入必要库
import matplotlib.pyplot as plt
from sklearn.datasets import load_diabetes
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import VotingRegressor
训练分类器
加载糖尿病数据集并启动梯度增强回归,随机森林回归和线性回归。
接下来,我们将使用3个回归变量来构建投票回归变量:
X, y = load_diabetes(return_X_y=True)
# Train classifiers
reg1 = GradientBoostingRegressor(random_state=1)
reg2 = RandomForestRegressor(random_state=1)
reg3 = LinearRegression()
reg1.fit(X, y)
reg2.fit(X, y)
reg3.fit(X, y)
ereg = VotingRegressor([('gb', reg1), ('rf', reg2), ('lr', reg3)])
ereg.fit(X, y)
VotingRegressor(estimators=[('gb', GradientBoostingRegressor(random_state=1)),
('rf', RandomForestRegressor(random_state=1)),
('lr', LinearRegression())])
预测
xt = X[:20]
pred1 = reg1.predict(xt)
pred2 = reg2.predict(xt)
pred3 = reg3.predict(xt)
pred4 = ereg.predict(xt)
可视化
中文显示
from pylab import *
from matplotlib.font_manager import FontProperties
import matplotlib.pyplot as plt
#支持中文
mpl.rcParams['font.sans-serif'] = ['SimHei']
plt.figure()
plt.plot(pred1, 'gd', label='梯度提升')
plt.plot(pred2, 'b^', label='随机森林')
plt.plot(pred3, 'ys', label='线性回归')
plt.plot(pred4, 'r*', ms=10, label='投票回归')
plt.tick_params(axis='x', which='both', bottom=False, top=False,
labelbottom=False)
plt.ylabel('predicted')
plt.xlabel('training samples')
plt.legend(loc="best")
plt.title('Regressor predictions and their average')
plt.show()
我们可以清晰地看见投票的预测结果最为均衡