查看原文
其他

取长补短、互通有无 ——集成学习介绍之Bagging &随机森林

爬虫俱乐部 Stata and Python数据分析 2022-03-15

本文作者:王   歌

文字编辑:孙晓玲

技术总编:张   邯



Stata暑期线上课程火热招生中~

爬虫俱乐部将于2020年7月11日至14日线上举行为期四天的Stata编程技术定制培训。课程通过案例教学模式,旨在帮助大家在短期内掌握Stata的基本命令、编程、数据处理以及结果输出等技术,并针对最新版Stata中的实用新功能做出详细介绍,包括框架功能(frame:读入多个数据集)等等。同时,此次云端课程提供录播,提供线上答疑。详细培训大纲及报名方式请查看《Stata云端课程来啦》,或点击文末阅读原文直接提交报名信息呦~

我们前面所介绍的都属于个体学习器,也就是由训练数据出发得到的单个学习器,这样做往往泛化性能有限,因此在此基础上,进一步发展了集成学习,也就是将多个个体学习器用某种方法结合在一起,集成之后得到的学习器的泛化能力与单个学习器相比能得到极大提升。当然,个体学习器的选择也是有一定要求的,一是每个个体学习器都要有一定的准确度,其泛化性能不能太弱;二是个体学习器之间要有一定的差异,这样才能取长补短提升泛化性能。若所集成的个体学习器是同类型的,比如均为SVM算法的学习器,那么这样的集成称为“同质”的,这样的个体学习器称为“基学习器”;反之如果是不同类型的,这样的集成称为“异质”的,其个体学习器称为“组件学习器”或直接称个体学习器。目前来说同质学习器的应用是更广泛的,我们一般所指的也基本上是同质学习器的集成。而按照个体学习器是否存在依赖关系可以分为Bagging算法Boosting算法两类,前者个体学习器间不存在强依赖关系,可以并行生成个体学习器,后者个体学习器之间存在强依赖关系,需要串行生成个体学习器。我们今天先介绍Bagging算法以及由它扩展出来的随机森林(Random Forest)

1算法介绍

Bagging是基于bootstrap方法的集成学习算法,由于我们要让训练出来的基学习器有一定的差异性,因此我们就要尽可能使训练学习器的训练集之间存在差异。通过使用bootstrap的采样方法,每次都进行有放回的随机采样,然后对每一个样本训练一个个体学习器,然后再将这些学习器结合在一起,这就是Bagging得到学习器的基本流程。在使用bootstrap生成训练集的过程中,假设每个训练集都含有n个样本,那么在每次抽样中没有被抽中的概率为1-1/n, n次抽样都没有被采集中的概率是(1-1/n)^n,当n→∞时,(1-1/n)^n→1/e≈0.368,因此约有36.8%的数据没有被抽中,称之为袋外数据(Out Of Bag),它们没有出现在训练集中,可以用来检测模型的泛化能力。

对于分类问题,Bagging在进行结合时使用的是简单投票法,票数最多的类别为最终输出,如果有多个类别票数一样多,通常随机选择一个;对于回归问题则采用简单算术平均的方式,将这些弱学习器得到的回归结果进行算术平均即为最终的输出。

随机森林则是在Bagging基础上的一个扩展。顾名思义,它的每个基学习器都是一棵CART决策树,决策树之间没有关联。假设总属性个数为n,我们之前讲的决策树在选择划分属性时是在当前结点的属性集中选择一个最优属性,而在随机森林中,对每个决策树的结点,先从该结点的属性集中随机选择一个包含k(k<n)个属性的子集,然后再从这个子集中选择一个最优属性用于划分,其他内容则与Bagging算法是一致的。相比于Bagging算法,随机森林增强了基学习器之间的差异性,使得最终集成的学习模型的泛化能力增强。

2类参数介绍

2.1 BaggingClassifier

首先我们说一下Bagging使用的类。在sklearn中, BaggingClassifierBaggingRegressor分别是用于分类和回归的Bagging算法。我们这里主要介绍 BaggingClassifier,其主要参数如下:

(1) base_estimator:选择基学习器,默认为决策树;

(2) n_estimators:确定基学习器的个数,默认为10;

(3) max_samples:抽样时的样本量,默认为1.0,接受整型或浮点型;

(4) max_features:训练学习器所需属性的个数,默认为1.0;

(5) bootstrap:是否使用bootstrap,默认为True;

(6) oob_score:是否由袋外样本估计泛化误差,默认为False;

(7) warm_start:是否使用上次训练结果作为初始化参数,默认为False;

(8) n_jobs:表示用CPU的几个内核运行程序,默认为1,当为-1的时候表示用所有CPU的内核运行程序;

(9) random_state:设定随机数种子,默认为None。

2.2 RandomForestClassifier

与Bagging的类相同,随机森林也分为用于分类的 RandomForestClassifier和用于回归的 RandomForestRegressor类,我们这里主要介绍 RandomForestClassifier的参数,该类中有部分参数的用法与 BaggingClassifier是一致的,包括 n_estimatorsmax_featuresbootstrapoob_scoren_jobsrandom_statewarm_start,还有一部分参数与我们前面介绍的决策树是相同的(“抽丝剥茧”,层层下分——机器学习基本算法之决策树),包括 criterionmax_depthmin_samples_splitmin_samples_leafmin_weight_fraction_leafmax_leaf_nodesclass_weight。还有两个没有介绍过的参数,一是 verbose,用来控制决策树的冗余度,默认为0;二是 min_impurity_split,设定分裂的最小不纯度,默认为1e-07。

3算法实例

我们使用的数据依然是我们数据的鸢尾花数据,为了与随机森林的结果形成对比,这里我们在Bagging算法中设定使用k近邻算法作为基学习算法,两个分类器的基学习器数目一致,同时为便于与之前讲决策树时的结果进行对比,因此树的深度等参数都与前面一致,程序如下:

from sklearn.datasets import load_irisfrom sklearn.model_selection import train_test_splitfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.ensemble import BaggingClassifierfrom sklearn.ensemble import RandomForestClassifier
iris_sample = load_iris()x_train, x_test, y_train, y_test = train_test_split( iris_sample.data, iris_sample.target, test_size=0.25, random_state=123)knclf = KNeighborsClassifier(n_neighbors=5) # k值设为5bagclf = BaggingClassifier( base_estimator=knclf, n_estimators=10, max_samples=0.5)rfclf = RandomForestClassifier(n_estimators=10)bagclf.fit(x_train, y_train)rfclf.fit(x_train, y_train)y_bag_pre = bagclf.predict(x_test)y_rf_pre = rfclf.predict(x_test)print('真实值:', y_test)print('bagging预测值:', y_bag_pre)print('随机森林预测值:', y_rf_pre)print('bagging预测准确度:', bagclf.score(x_test, y_test))print('随机森林预测准确度:', rfclf.score(x_test, y_test))

预测结果如下:

这里我们可以看到针对这个数据以及参数设置,Bagging算法的准确度稍高一些,与之前决策树中92.11%的准确度相比,无论是Bagging还是随机森林都是要优于单一的决策树的,当然我们还可以通过调参来优化这一结果。同时对于随机森林,我们还可以利用estimators_属性来查看生成的所有树,这里由于我们设置生成了100棵树,篇幅所限就不再展示了。总体而言,Bagging算法由于使用了bootstrap,因此泛化能力很强,可以降低模型的方差,而随机森林由于可以随机选择结点划分属性,因此在高维时仍可以有效训练,但在噪音较大的数据集上就容易产生过拟合。

以上就是我们今天全部的内容。







对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!
往期推文推荐
PDF表格信息提取
神经网络——brain
marktouse标记使用变量
换种视角看问题——支持向量机(SVM)
提取PDF文本信息:入门
毕业季|b站《入海》评论爬取
Stata云端课程来啦
利用广义线性模型实现的分类——Logistic回归
Requests get爬虫之设置headers
数据分析薪资待遇如何?——跟我来,带你看
Vardistinct一键去重计数
从statsmodels到线性回归
Pandas的GroupBy机制
首行数据如何快速转变量名?
文件太多乱乱的?合并一下吧!
线性回归的正则化 ——岭回归与LASSO回归
Pandas中节约空间的小tip—categorical类型

关于我们



微信公众号“Stata and Python数据分析”分享实用的stata、python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。

此外,欢迎大家踊跃投稿,介绍一些关于stata和python的数据处理和分析技巧。
投稿邮箱:statatraining@163.com
投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存