集成学习第一法宝:投票!

参考:DataWhale教程链接

集成学习(上)所有Task:

(一)集成学习上——机器学习三大任务

(二)集成学习上——回归模型

(三)集成学习上——偏差与方差

(四)集成学习上——回归模型评估与超参数调优

(五)集成学习上——分类模型

(六)集成学习上——分类模型评估与超参数调优

(七)集成学习中——投票法

(八)集成学习中——bagging

(九)集成学习中——Boosting简介&AdaBoost

(十)集成学习中——GBDT

(十一)集成学习中——XgBoost、LightGBM

(十二)集成学习(下)——Blending

(十三)集成学习(下)——Stacking

(十四)集成学习(下)——幸福感预测

(十五)集成学习(下)——蒸汽量预测

文章目录

  • 集成学习第一法宝:投票!
    • 投票法的原理分析
    • 投票法的案例分析
      • 问题1 投票效果一定好于单个模型吗?大概率是的
      • 问题2 软投票的效果一定好于硬投票吗?大概率是的
      • 问题3 不同类型的基模型的集成是不是一定好于同一类基模型?大概率是的
      • 实验
      • 反思
      • 还有一些疑惑

投票法的原理分析

投票法是一种遵循少数服从多数原则的集成学习模型,通过多个模型的集成降低方差,从而提高模型的鲁棒性。在理想情况下,投票法的预测效果应当优于任何一个基模型的预测效果。

注意,是理想情况下。真的会存在集成模型不如基模型的情况,看下面的例子就知道了

投票法在回归模型与分类模型上均可使用:

  • 回归投票法:预测结果是所有模型预测结果的平均值。
  • 分类投票法:预测结果是所有模型种出现最多的预测结果。

分类投票法又可以被划分为硬投票与软投票:

  • 硬投票:预测结果是所有投票结果最多出现的类。用基模型的分类结果

  • 软投票:预测结果是所有投票结果中概率加和最大的类。用基模型的分类概率

    注意!!采用软投票的时候,基模型务必是可以输出概率的,比如SVC需要要设置 probability=True 。

下面我们使用一个例子说明硬投票与软投票的区别:

对于某个样本:

模型 1 的预测结果是 类别 A 的概率为 99%,是类别B的概率是1%,基模型预测结果为类别A

模型 2 的预测结果是 类别 A 的概率为 49%,是类别B的概率是51%,基模型预测结果为类别B

模型 3 的预测结果是 类别 A 的概率为 49%,是类别B的概率是51%,基模型预测结果为类别B

硬投票:只考虑基模型的投票结果类别,有2/3的模型预测结果是B,因此硬投票法的预测结果是B

软投票:最终对于类别A的预测概率的平均是 (99 + 49 + 49) / 3 = 65.67%,对类别B的预测概率是平均是(1+51+51)/3=34.33%,因此软投票法的预测结果是A。

从这个例子我们可以看出,软投票法与硬投票法可以得出完全不同的结论。相对于硬投票,软投票法考虑到了预测概率这一额外的信息,因此可以得出比硬投票法更加准确的预测结果。软投票的结果一定比硬投票结果更加准确吗?

在投票法中,我们还需要考虑到不同的基模型可能产生的影响。理论上,基模型可以是任何已被训练好的模型。但在实际应用上,想要投票法产生较好的结果,需要满足两个条件:

  • 基模型之间的效果不能差别过大。当某个基模型相对于其他基模型效果过差时,该模型很可能成为噪声。
  • 基模型之间应该有较小的同质性。例如在基模型预测效果近似的情况下,基于树模型与线性模型的投票,往往优于两个树模型或两个线性模型。

当投票合集中使用的模型能预测出清晰的类别标签时,适合使用硬投票

当投票集合中使用的模型能预测类别的概率时,适合使用软投票。

软投票同样可以用于那些本身并不预测类成员概率的模型,只要他们可以输出类似于概率的预测分数值(例如支持向量机、k-最近邻和决策树)。

投票法的局限性在于,它对所有模型的处理是一样的,这意味着所有模型对预测的贡献是一样的。如果一些模型在某些情况下很好,而在其他情况下很差,这是使用投票法时需要考虑到的一个问题。

投票法的案例分析

Sklearn中提供了 VotingRegressor 与 VotingClassifier 两个投票方法。 这两种模型的操作方式相同,并采用相同的参数。使用模型需要提供一个模型列表,列表中每个模型采用Tuple的结构表示,第一个元素代表名称,第二个元素代表模型,需要保证每个模型必须拥有唯一的名称。

我在代码中设计了几处可以调整设计对比的参数。

dataset:

“generate” 采用sklearn的make_classification 生成的散点数据。

“breastcancer” sklearn中自带的乳腺癌数据,其特征均为连续型

basemodel:

“diff” 基模型为不同的模型

“same” 基模型为同一个模型的不同参数

voting:

“soft”:软投票

“hard”:硬投票

代码原文,在DataWhale教程基础上改的:

# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
from sklearn import datasets
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.ensemble import VotingClassifier
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.neighbors import KNeighborsClassifier
from matplotlib import pyplot
from sklearn.tree import DecisionTreeClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifierclass VoteClassify:# test classification dataset# define datasetdef __init__(self,dataset,basemodel = "diff",voting = "hard"):""":argdataset: 数据集,generate生成数据  breastcancer 乳腺癌数据"""self.basemodel = basemodelself.voting = votingself.dataset = datasetdef get_dataset(self):if self.dataset == "generate":X,y = make_classification(n_samples=1000, n_features=20, n_informative=15,n_redundant=5, random_state=2)return X, yelif self.dataset == "breastcancer":# 乳腺癌数据集breast_cancer = datasets.load_breast_cancer()# print(breast_cancer.feature_names)df = pd.concat([pd.DataFrame(breast_cancer.data,columns=breast_cancer.feature_names),pd.DataFrame(breast_cancer.target,columns=["label"])],axis=1)# print(df.head())X=breast_cancer.datay=breast_cancer.target# print(X.shape)# print(df['label'].value_counts())return X, y# get a voting ensemble of models, the base models are samedef get_voting_samebasemodel(self):# define the base modelsmodel_dict = dict()# model_dict['knn1'] = KNeighborsClassifier(n_neighbors=1)# model_dict['knn3'] = KNeighborsClassifier(n_neighbors=3)# model_dict['knn5'] = KNeighborsClassifier(n_neighbors=5)# model_dict['knn7'] = KNeighborsClassifier(n_neighbors=7)# model_dict['knn9'] = KNeighborsClassifier(n_neighbors=9)model_dict['svm1_with_std'] = make_pipeline(StandardScaler(),SVC(C=0.1,kernel='rbf',gamma=0.05,probability=True))model_dict['svm2_with_std'] = make_pipeline(StandardScaler(),SVC(C=0.1,kernel='rbf',gamma=0.005,probability=True))model_dict['svm3_with_std'] = make_pipeline(StandardScaler(),SVC(C=0.01,kernel='linear',probability=True))model_dict['svm4_with_std'] = make_pipeline(StandardScaler(),SVC(C=1.0,kernel='linear',probability=True))model_dict['svm5_with_std'] = make_pipeline(StandardScaler(),SVC(C=10.0,kernel='linear',probability=True))# define the voting ensembleensemble = VotingClassifier(estimators=self.model_dict2list(model_dict), voting=self.voting)  # voting="soft"为软投票  hard为硬投票return ensemble,model_dict# get a voting ensemble of models, the base models are differentdef get_voting_diffbasemodel(self):# define the base modelsmodel_dict = dict()model_dict['lr'] = LogisticRegression(max_iter=3000) #迭代次数少会报错,原因待查model_dict['lr_with_std'] = make_pipeline(StandardScaler(),LogisticRegression())model_dict['svm'] = SVC(probability=True)model_dict['svm_with_std'] = make_pipeline(StandardScaler(),SVC(probability=True))model_dict['dt3'] = DecisionTreeClassifier(max_depth=3)model_dict['dt3_with_std'] = make_pipeline(StandardScaler(),DecisionTreeClassifier(max_depth=3))model_dict['knn5'] = KNeighborsClassifier(n_neighbors=5)model_dict['knn5_with_std'] = make_pipeline(StandardScaler(),KNeighborsClassifier(n_neighbors=5))model_dict['nb'] = GaussianNB()model_dict['nb_with_std'] = make_pipeline(StandardScaler(), GaussianNB())model_dict['rf'] = RandomForestClassifier(n_estimators=30)model_dict['rf_with_std'] = make_pipeline(StandardScaler(),RandomForestClassifier(n_estimators=30))# define the voting ensembleensemble = VotingClassifier(estimators=self.model_dict2list(model_dict), voting=self.voting)  # voting="soft"为软投票  hard为硬投票return ensemble,model_dictdef model_dict2list(self,model_dict):models = list()for key in model_dict.keys():models.append((key,model_dict[key]))return models# get a list of models to evaluatedef get_models(self):models = dict()if(self.basemodel == "diff"):voting_model,models = self.get_voting_diffbasemodel()else :voting_model,models = self.get_voting_samebasemodel()if(self.voting == "hard"):models['hard_voting'] = voting_modelelse :models['soft_voting'] = voting_modelreturn models# evaluate a give model using cross-validationdef evaluate_model(self,model, X, y):cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=2, random_state=1)scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1, error_score='raise')return scores# 设置投票模型采用的数据集、基模型和投票方式
# vc = VoteClassify(dataset = "generate",basemodel = "diff",voting = "soft")
# vc = VoteClassify(dataset = "generate",basemodel = "same",voting = "soft")
vc = VoteClassify(dataset = "breastcancer",basemodel = "diff",voting = "hard")
# vc = VoteClassify(dataset = "breastcancer",basemodel = "diff",voting = "soft")
# vc = VoteClassify(dataset = "breastcancer",basemodel = "same",voting = "hard")
# vc = VoteClassify(dataset = "breastcancer",basemodel = "same",voting = "soft") # svm比knn效果要好# define dataset
X, y = vc.get_dataset()
# get the models to evaluate
models = vc.get_models()
# evaluate the models and store results
results, names = list(), list()
for name, model in models.items():scores = vc.evaluate_model(model, X, y)results.append(scores)names.append(name)print('>%s %.3f (%.3f)' % (name, np.mean(scores), np.std(scores)))
# plot model performance for comparison
pyplot.boxplot(results, labels=names, showmeans=True)
pyplot.show()

问题1 投票效果一定好于单个模型吗?大概率是的

问题2 软投票的效果一定好于硬投票吗?大概率是的

问题3 不同类型的基模型的集成是不是一定好于同一类基模型?大概率是的

实验

实验1设置:vc = VoteClassify(dataset = “breastcancer”,basemodel = “same”,voting = “hard”)

实验1结果:投票效果比5个基模型中的4个基模型效果好

>svm1_with_std 0.947 (0.023)
>svm2_with_std 0.938 (0.021)
>svm3_with_std 0.967 (0.020)
>svm4_with_std 0.970 (0.018)
>svm5_with_std 0.966 (0.023)
>hard_voting 0.969 (0.023)

实验2设置:vc = VoteClassify(dataset = “breastcancer”,basemodel = “same”,voting = “soft”)

实验2结果:投票效果比5个基模型中的所有基模型效果都要好

>svm1_with_std 0.947 (0.023)
>svm2_with_std 0.938 (0.021)
>svm3_with_std 0.967 (0.020)
>svm4_with_std 0.970 (0.018)
>svm5_with_std 0.966 (0.023)
>soft_voting 0.971 (0.017)

同时,在实验1和实验2 中,软投票比硬投票效果好。

实验3设置:vc = VoteClassify(dataset = “breastcancer”,basemodel = “diff”,voting = “hard”)

实验3结果:投票效果比12个基模型中的9个基模型效果好

>lr_with_std 0.978 (0.017)
>svm 0.914 (0.039)
>svm_with_std 0.975 (0.019)
>dt3 0.919 (0.038)
>dt3_with_std 0.920 (0.041)
>knn5 0.935 (0.030)
>knn5_with_std 0.968 (0.022)
>nb 0.939 (0.030)
>nb_with_std 0.932 (0.030)
>rf 0.963 (0.035)
>rf_with_std 0.961 (0.021)
>hard_voting 0.963 (0.022)

实验4设置:vc = VoteClassify(dataset = “breastcancer”,basemodel = “diff”,voting = “soft”)

实验4结果:投票效果比11个基模型中的8个基模型效果都要好

>lr 0.953 (0.024)
>lr_with_std 0.978 (0.017)
>svm 0.914 (0.039)
>svm_with_std 0.975 (0.019)
>dt3 0.925 (0.035)
>dt3_with_std 0.919 (0.040)
>knn5 0.935 (0.030)
>knn5_with_std 0.968 (0.022)
>nb 0.939 (0.030)
>nb_with_std 0.932 (0.030)
>rf 0.958 (0.027)
>rf_with_std 0.962 (0.030)
>soft_voting 0.963 (0.023)

在实验3和实验4 中,软投票没有比硬投票效果好。

反思

  1. 我认为我上面的实验结果,不能严谨得得出结论。主要原因在于,我的基模型,并不是已经训练好的,确认过的最佳模型,所以基模型的好坏对最终结果的影响很大。

  2. 在实际工业生产环境中,还是需要多次尝试。

  3. 在实验中有一个意外小收获,第一次真切感受到标准化的力量。

    收获:对于部分模型(比如lr、svm、knn)来说,数据进行标准化会使得模型效果大幅提升(精确率提升且方差变小),当然,也有下降的(比如NB)。

还有一些疑惑

  1. 基模型是已被训练好的模型,是否还有必要在投票模型中整体调参呢?

  2. 硬投票,如果1:1平怎么办?

(七)集成学习中-投票法Voting相关推荐

  1. 集成学习中boosting、bagging、随机森林算法的介绍

    集成学习的概念 定义:集成学习通过构建并结合多个学习器来完成学习任务. 分类:只包含同种类型的个体学习器,这样的集成是"同质"的,例如都是神经网络或者决策树:包含不同类型的个体学习 ...

  2. 图解集成学习中的梯度提升思想

    摘要: 本文讲述集成学习中的梯度提升方法的思想,以简单算术及图片的形式展示整个过程,一看就懂! 简介 机器学习(ML)中的一个关键步骤是选择适合数据的最佳算法,根据数据中的一些统计数据和可视化信息,机 ...

  3. 集成学习中的随机森林

    摘要:随机森林是集成算法最前沿的代表之一.随机森林是Bagging的升级,它和Bagging的主要区别在于引入了随机特征选择. 本文分享自华为云社区<集成学习中的随机森林>,原文作者:ch ...

  4. 集成学习中的软投票和硬投票机制详解和代码实现

    快速回顾集成方法中的软投票和硬投票 集成方法是将两个或多个单独的机器学习算法的结果结合在一起,并试图产生比任何单个算法都准确的结果. 在软投票中,每个类别的概率被平均以产生结果. 例如,如果算法 1 ...

  5. 集成学习中的Boosting和Bagging

    集成学习是一大类模型融合策略和方法的统称,其中包含多种集成学习的思想. Boosting Boosting方法训练基分类器时采用串行的方式,各个基分类器之间有依赖. 它的基本思路是将基分类器层层叠加, ...

  6. 运用神经网络方法找寻集成学习中的最优权重

    众所周知,如今在众多数据科学竞赛中的获奖方案中,使用集成学习算法已然成为了家常便饭.集成学习独有的依据一系列假设对大量机器学习算法进行训练的能力,不仅增加了模型的稳定性,同时也使得模型的精确程度得到了 ...

  7. (三)集成学习上——偏差与方差

    参考:DataWhale教程链接 集成学习(上)所有Task: (一)集成学习上--机器学习三大任务 (二)集成学习上--回归模型 (三)集成学习上--偏差与方差 (四)集成学习上--回归模型评估与超 ...

  8. (十五)集成学习(下)——蒸汽量预测

    参考:DataWhale教程链接 集成学习(上)所有Task: (一)集成学习上--机器学习三大任务 (二)集成学习上--回归模型 (三)集成学习上--偏差与方差 (四)集成学习上--回归模型评估与超 ...

  9. 集成学习结合策略——投票法

    初识投票法的一点联想   其实第一次遇见集成学习中的投票法时候,会不由自主联系到leetcode 169. 多数元素和leetcode 229. 求众数 II中利用摩尔投票法求解问题.摩尔投票的基本思 ...

最新文章

  1. 深入浅出 ZooKeeper
  2. C# 小数位数保留的方法集锦
  3. SaaS服务在未来云计算中该如何发展
  4. 【风控流程】大数据风控代码逻辑
  5. 03-Arm SiP Services
  6. 1.1.2 标准化工作及相关组织
  7. Docker 实战总结(非常全面)
  8. python之闭包,装饰器
  9. CF827F-Dirty Arkady‘s Kitchen【堆】
  10. 从fork-join /线程池调用的Singelton bean中的访问spring请求范围缓存
  11. docker开放的端口_docker-5-解决宿主机没有开放81端口却可以直接访问docker启动的81端口nginx容器的问题...
  12. C/C++编程笔记:浅析 C 语言中宏定义的使用,知识点全解
  13. Linux学习总结(28)——Linux主机加固
  14. 花书+吴恩达深度学习(一)前馈神经网络(多层感知机 MLP)
  15. Java并发包下的CAS相关的原子操作
  16. 国外图片分享网站有哪些?20个国外免费、高清图片素材网站、图库全合集
  17. CMMI3认证升级CMMI5认证需满足的基本条件
  18. 微PE工具箱(CGI)安装Win10系统教程
  19. 计算机网络 --- IP地址的详细分类
  20. docker attach 和 exec 的区别

热门文章

  1. 最新!中国内地大学ESI排名出炉:362所高校上榜!
  2. 转行学java好学吗?完全没有经验怎么办?
  3. Tailwind Spacing
  4. 怎么把Word转换PPT?这几个方法超好用
  5. 单机版Docker Swarm安装及试用
  6. 浅析微信支付:支付结果通知
  7. 探究音节bo、po、 mo、 fo韵母的实际发音
  8. STM32F767--->时钟
  9. unity urp内置lit材质源码解析(上)
  10. 微信小程序电影购票+后台管理系统