集成学习—随机森林

集成学习

集成学习目前是机器学习中最先进、最高效也是所具有研究价值的领域之一,它主要是通过训练多个弱评估器、并将他们输出的结果以某种方式结合起来解决一个问题。

在集成学习的发展历程中,集成的思想以及方法启发了众多深度学习和机器学习方面的工作,在学术界和工业界都取得了巨大的成功。今天集成学习的研究领域主要分为三个方面:

1、模型融合

它主要是通过以某种方法对各强分类器进行集成,这个领域的研究方法主要有voting(投票法)、stacking(堆叠法)、blending(混合法),集成的对象必须是强分类器,。当尝试了很多方法没有效果的话,一定要试一试模型融合。

2、弱分类器集成

由此可见,它主要是以弱分类器为集成对象,通过以某种集成方法将它们集成为一种强分类器,这里的弱分类器主要是指一些传统的机器学习算法,比如决策树等,主要的集成方法有bagging(装袋法),boosting(提升法),其中bagging中最具代表的集成学习算法就是随机森林。

3、混合专家模型

混合专家模型常常出现在深度学习(神经网络)的领域。在其他集成领域当中,不同的学习器是针对同一任务、甚至在同一数据上进行训练,但在混合专家模型中,我们将一个复杂的任务拆解成几个相对简单且更小的子任务,然后针对不同的子任务训练个体学习器(专家),然后再结合这些个体学习器的结果得出最终的输出。



bagging方法的思想

在集成学习中bagging方法是最著名、最简单也是最高效的一种操作之一,也被称为装袋法。

在Bagging集成当中,我们并行建立多个弱评估器(通常是决策树,也可以是其他非线性算法),并综合多个弱评估器的结果进行输出,在回归问题中,bagging方法主要是对各弱回归器的预测结果进行平均,从而得到模型最终的预测结果。在分类问题中,bagging主要是根据各弱分类器的结果进行投票,以少数服从多数的原则来确定最终的模型预测结果。

目前bagging中最具代表性的集成算法便是RandomForest(随机森林),随机森林主要是以决策树作为弱分类器进行集成,以bagging的方法来对各决策树的结果进行综合,从而输出模型的最终预测值,随机森林分为随机森林分类器和随机森林回归器,可以运用在分类,回归,甚至是排序问题中。


随机森林

1、随机森林概况

下面就随机森林回归器来进行系统的阐述:

随机森林就是以决策树为弱评估器,以bagging的方法对各决策树的预测结果进行分析,从而让输出模型最终的预测结果,具体的,在随机森林回归器中,它主要以回归决策树为集成对象,对各决策树的预测结果进行平均,从而得到模型最终的预测值。随机森林的随机主要体现在两个方面,其一是样本的有放回的随机抽样,其二是在决策树每次分支时随机抽取部分样本特征来进行分支。在随机森林分类器中,它以分类决策树为集成对象,对各决策树的类别预测结果,以少数服从多数的原则输出最终的模型预测结果。

其算法构筑过程非常简单,从提供的数据集中随机抽取不同的子集,用于建立多颗不同的决策树,并按照bagging的规则对单棵决策树的结果进行集成(回归则平均,分类则少数服从多数)。虽然原理上很简单,但随机森林的学习能力异常强大、算法复杂度高、又具备一定的抗过拟合能力,是从根本上来说比单棵决策树更优越的算法。在机器学习竞赛当中,我们往往会在中小型数据集上优先尝试随机森林模型。

在sklearn中,随机森林可以实现回归也可以实现分类。随机森林回归器由类sklearn.ensemble.RandomForestRegressor实现,随机森林分类器则有类sklearn.ensemble.RandomForestClassifier实现。我们可以像调用逻辑回归、决策树等其他sklearn中的算法一样,使用“实例化、fit、predict/score”三部曲来使用随机森林,同时我们也可以使用sklearn中的交叉验证方法来实现随机森林。其中回归森林的默认评估指标为R2,分类森林的默认评估指标为准确率。有关模型的评估指标我将在后面的部分进行系统的阐述。

下面来展示sklearn中随机森林评估器的全部参数:

不难发现,随机森林分类器和随机森林回归器的参数高度一致,因此我们只要学习其中一种就可以,今天我们就来讨论一下随机森林回归器的各项参数。除此之外,各项参数都存在默认值,因此我们在不了解随机森林的情况下也可以顺利调用随机森林模型来解决问题。

2、随机森林回归器参数分析

随机森林回归树相比于传统的机器学习算法,比如决策树,逻辑回归等,随机森林的参数更多,也更加复杂。这里我们将其分成四大类别来进行逐个分析。

2.1、弱评估器结构:

在集成学习算法中,合理的控制单个弱评估器的结构也是一个非常重要的课题,因为弱评估器的结构复杂度/结果会对模型的结果产生非常大的影响,其中单棵树的结构越复杂,集成算法总体的复杂程度就越高,计算也就更加缓慢,模型过拟合也会更加严重,因此集成算法中的弱评估器也需要被剪枝。随机森林回归器的弱评估器是回归树,因此集成评估器中有大量的参数都与弱评估器回归树中的参数重合:

这些参数在随机森林中的用法与默认值与决策树类DecisionTreeRegressor中完全一致,专门用于对决策树进行剪枝、控制单个弱评估器的结构,考虑到大家在决策树中已经充分掌握这些参数,我们不再对这些参数一一进行详细说明了。在这里,我们重点复习一下以下两部分参数:

分枝标准(criterion)与特征重要性(feature_importances_):

与分类树中的信息熵/基尼系数不同,回归树中的criterion可以选择"squared_error"(平方误差),"absolute_error"(绝对误差)以及"poisson"(泊松偏差)。对任意样本𝑖i而言,𝑦𝑖yi为真实标签,𝑦𝑖^yi^为预测标签,则各个criterion的表达式为:

其中平方误差与绝对误差是大家非常熟悉的概念,作为分枝标准,平方误差比绝对误差更敏感(类似于信息熵比基尼系数更敏感),并且在计算上平方误差比绝对误差快很多。泊松偏差则是适用于一个特殊场景的:当需要预测的标签全部为正整数时,标签的分布可以被认为是类似于泊松分布的。正整数预测在实际应用中非常常见,比如预测点击量、预测客户/离职人数、预测销售量等。我们现在正在使用的数据(房价预测),也可能比较适合于泊松偏差。

另外,当我们选择不同的criterion之后,决策树的feature_importances_也会随之变化,因为在sklearn当中,feature_importances_是特征对criterion下降量的总贡献量,因此不同的criterion可能得到不同的特征重要性。

对我们来说,选择criterion的唯一指标就是最终的交叉验证结果——无论理论是如何说明的,我们只取令随机森林的预测结果最好的criterion。

树结构参数:

max_depth:

从树结构的层面来看,max_depth是控制随机森林过拟合影响最大的函数,max_depth的默认值为None,也就是不限深度,因此当模型存在过拟合的情况下,选择一个小的max_depth会更有效。

max_leaf_nodes与min_sample_split:

比max_depth更精细的减枝方式,但限制叶子数量和分枝,既可以实现微调,也可以实现大刀阔斧的剪枝。max_leaf_nodes的默认值为None,即不限叶子数量。min_sample_split的默认值为2,等同于不限制分枝。

min_impurity_decrease:

最精细的减枝方式,可以根据不纯度下降的程度减掉相应的叶子。默认值为0,因此是个相当有空间的参数。

2.2、弱分类器数量(n_estimators):

n_estimators是森林中树木的数量,即弱评估器的数量,在sklearn中默认100,它是唯一一个对随机森林而言必填的参数。n_estimators对随机森林模型的精确程度、复杂度、学习能力、过拟合情况、需要的计算量和计算时间都有很大的影响,因此n_estimators往往是我们在调整随机森林时第一个需要确认的参数。对单一决策树而言,模型复杂度由树结构(树深、树宽、树上的叶子数量等)与数据量(样本量、特征量)决定,而对随机森林而言,模型复杂度由森林中树的数量、树结构与数据量决定,其中树的数量越多,模型越复杂。

当模型复杂度上升时,模型的泛化能力会先增加再下降(相对的泛化误差会先下降再上升),我们需要找到模型泛化能力最佳的复杂度。在实际进行训练时,最佳复杂度往往是一个比较明显的转折点,当复杂度高于最佳复杂度时,模型的泛化误差要么开始上升,要么不再下降。

对随机森林而言,该图像的横坐标可以被无缝切换为参数n_estimators上的值。当n_estimators越大时:

模型的复杂程度上升,泛化能先增强再减弱(或不变)

模型的学习能力越来越强,在训练集上的分数可能越来越高,过拟合风险越来越高

模型需要的算力和内存越来越多

模型训练的时间会越来越长

2.3、弱分类器训练的数据:

还记得决策树是如何分枝的吗?对每个特征决策树都会找到不纯度下降程度最大的节点进行分枝,因此原则上来说,只要给出数据一致、并且不对决策树进行减枝的话,决策树的结构一定是完全相同的。对集成算法来说,平均多棵相同的决策树的结果并没有意义,因此集成算法中每棵树必然是不同的树,Bagging算法是依赖于随机抽样数据来实现这一点的。

随机森林会从提供的数据中随机抽样出不同的子集,用于建立多棵不同的决策树,最终再按照Bagging的规则对众多决策树的结果进行集成。因此在随机森林回归器的参数当中,有数个关于数据随机抽样的参数。

样本的随机抽样:

bootstrap:

bootstrap参数的输入为布尔值,默认True,控制是否在每次建立决策树之前对数据进行随机抽样。如果设置为False,则表示每次都使用全部样本进行建树,如果为True,则随机抽样建树。从语言的意义上来看,bootstrap可以指代任意类型的随机抽样,但在随机森林中它特指有放回随机抽样技术

max_samples:

max_samples表示自助集的大小,可以输入整数、浮点数或None,默认为None。

输入整数m,则代表每次从全数据集中有放回抽样m个样本

输入浮点数f,则表示每次从全数据集中有放回抽样f*全数据量个样本

输入None,则表示每次抽样都抽取与全数据集一致的样本量(X.shape[0])

通常来说,max_samples是等于m的(行业惯例),也就是抽样数据集的大小与原始数据集一致,但是如果原始数据集太大、或者太小,我们也可以自由调整max_samples的大小。由于是随机采样,这样每次的自助集和原始数据集不同,和其他的采样集也是不同的。这样我们就可以自由创造取之不尽用之不竭,并且互不相同的自助集,用这些自助集来训练我们的弱分类器,我们的弱分类器自然也就各不相同了。

然而有放回抽样也会有自己的问题。由于是有放回,一些样本可能在同一个自助集中出现多次,而其他一些却可能被忽略。当抽样次数足够多、且原始数据集足够大时,自助集大约平均会包含全数据的63%,这个数字是有数学依据的。因为在max_samples次抽样中,一个样本被抽到某个自助集中的概率为:

这个式子是怎么来的呢?对于任意一个样本而言:

一次抽样时抽到该样本的概率为1𝑚1m

一次抽样时抽不到该样本的概率为1−1𝑚1−1m

总共抽样max_samples次,一次也没有抽到该样本的概率就是(1−1𝑚)𝑚𝑎𝑥_𝑠𝑎𝑚𝑝𝑙𝑒𝑠(1−1m)max_samples

因此1减去该概率,就是一个样本在抽样中一定会被抽到某个自助集的概率。 当m刚好等于max_samples时,公式可以被修改为:

这明显是一个经典的极限问题,由洛必达法则(L'Hôpital's rule)我们可知:当m足够大时(接近极限时),这个概率收敛于1-(1/e),其中e是自然常数,整体概率约等于0.632。因此,会有约37%的训练数据被浪费掉,没有参与建模,这些数据被称为袋外数据(out of bag data,简写为oob)。在实际使用随机森林时,袋外数据常常被我们当做验证集使用,所以我们或许可以不做交叉验证、不分割数据集,而只依赖于袋外数据来测试我们的模型即可。当然,这也不是绝对的,当树的数量n_estimators不足,或者max_samples太小时,很可能就没有数据掉落在袋外,自然也有无法使用oob数据来作为验证集了。

obb_score:

oob_score控制是否使用袋外数据进行验证,输入为布尔值,默认为False,如果希望使用袋外数据进行验证,修改为True即可。

在使用袋外数据时,我们可以用随机森林的另一个重要属性:oob_score_来查看我们的在袋外数据上测试的结果,遗憾的是我们无法调整oob_score_输出的评估指标,它默认是R2。

这里单独解释一下随机森林回归数的评估指标R2:

R^2_ score,即判定定系数,反映因变量的全部变化中能通过回归关系被自变量解释的比例。计算公式:

特征的随机抽样(max_features):

输入整数,表示每次分枝时随机抽取max_features个特征

输入浮点数,表示每次分枝时抽取round(max_features * n_features)个特征

输入"auto"或者None,表示每次分枝时使用全部特征n_features

输入"sqrt",表示每次分枝时使用sqrt(n_features)

输入"log2",表示每次分枝时使用log2(n_features)

不难发现,sqrt(n_features)和log2(n_features)都会返回一个比原始特征量小很多的数,但一般情况下log2返回的值比sqrt返回的值更小,因此如果我们想要树之间的差异更大,我们可以设置模式为log2。在实际使用时,我们往往会先使用上述的文字输入,观察模型的结果,然后再在有效的范围附近进行网格搜索。

需要注意的是,无论对数据进行怎样的抽样,我们能够控制的都只是建立单棵树时的数据而已。在总数据量有限的情况下,单棵树使用的数据量越大,每一棵树使用的数据就会越相似,每棵树的结构也就会越相似,bagging的效果难以发挥、模型也很容易变得过拟合,这是因为随机森林主要是通过决策树之间的独立性来降低模型方差,从而来提高模型的泛化能力。因此,当数据量足够时,我们往往会消减单棵树使用的数据量。

随机数种子(random_state):

在决策树当中,我们已经学习过控制随机模式的参数random_state,这个参数是“随机数种子”,它控制决策树当中多个具有随机性的流程。在sklearn实现的随机森林当中,决策树上也存在众多有随机性的流程:

「强制」随机抽取每棵树建立时分枝用的特征,抽取的数量可由参数max_features决定

「强制」随机排序每棵树分枝时所用的特征

「可选」随机抽取每棵树建立时训练用的样本,抽取的比例可由参数max_samples决定

因此每次使用随机森林类时,我们建立的集成算法都是不同的,在同一个数据集上多次建树自然也会产生不同的模型结果。因此在工程部署和教学当中,我们在建树的第一步总是会先设置随机数种子为一个固定值,让算法固定下来。在设置的时候,需要注意两个问题:

1、不同库中的随机数种子遵循不同的规则,对不同库中的随机数种子给与相同的数字,也不会得到相同的结果

2、如何选择最佳随机数种子?

当数据样本量足够大的时候(数万),变换随机数种子几乎不会对模型的泛化能力有影响,因此在数据量巨大的情况下,我们可以随意设置任意的数值。

当数据量较小的时候,我们可以把随机数种子当做参数进行调整,但前提是必须依赖于交叉验证的结果。选择交叉验证结果中均值最高、方差最低的随机数种子,以找到泛化能力最强大的随机模式。

2.4、其他参数:

我们已经了解过前三个参数。需要稍微说明一下verbose参数。随机森林的verbose参数打印的是建树过程,但只有在树的数量众多、建模耗时很长时,verbose才会打印建树的具体过程,否则它只会打印出一行两简单的报告。这些参数中需要重点说明的是warm_start。warm_start是控制增量学习的参数,默认为False,该参数可以帮助随机森林处理巨量数据,解决围绕随机森林的众多关键问题。我们将在之后的章节中重点讲解warm_start的应用。


3、集成算法的参数空间和网格优化:

如随机森林中所展示的,集成算法的超参数种类繁多、取值丰富,且参数之间会相互影响、共同作用于算法的最终结果,因此集成算法的调参是一个难度很高的过程。在超参数优化还未盛行的时候,随机森林的调参是基于方差-偏差理论(variance-bias trade-off)和学习曲线完成的,而现在我们可以依赖于网格搜索来完成自动优化。在对任意算法进行网格搜索时,我们需要明确两个基本事实:

1、参数对算法结果的影响力大小

2、用于进行搜索的参数空间

3.1、参数对算法结果的影响力大小:

对随机森林来说,我们可以大致如下排列各个参数对算法的影响:

随机森林在剪枝方面的空间总是很大的,因为默认参数下树的结构基本没有被影响(也就是几乎没有剪枝),因此当随机森林过拟合的时候,我们可以尝试粗、精、随机等各种方式来影响随机森林。通常在网格搜索当中,我们会考虑所有有巨大影响力的参数、以及1、2个影响力不明显的参数。

3.2、用于进行搜索的参数空间的确定方法:

虽然随机森林调参的空间较大,大部分人在调参过程中依然难以突破,因为树的集成模型的参数空间非常难以确定。当没有数据支撑时,人们很难通过感觉或经验来找到正确的参数范围。举例来说,我们也很难直接判断究竟多少棵树对于当前的模型最有效,同时,我们也很难判断不剪枝时一棵决策树究竟有多深、有多少叶子、或者一片叶子上究竟有多少个样本,更不要谈凭经验判断树模型整体的不纯度情况了。可以说,当森林建好之后,我们简直是对森林一无所知。对于网格搜索来说,新增一个潜在的参数可选值,计算量就会指数级增长,因此找到有效的参数空间非常重要。此时我们就要引入两个工具来帮助我们:

1、学习曲线

2、决策树对象Tree的属性

学习曲线

学习曲线是以参数的不同取值为横坐标,模型的结果为纵坐标的曲线。当模型的参数较少、且参数之间的相互作用较小时,我们可以直接使用学习曲线进行调参。但对于集成算法来说,学习曲线更多是我们探索参数与模型关系的关键手段。许多参数对模型的影响是确定且单调的,例如n_estimators,树越多模型的学习能力越强,再比如ccp_alpha,该参数值越大模型抗过拟合能力越强,因此我们可能通过学习曲线找到这些参数对模型影响的极限。我们会围绕这些极限点来构筑我们的参数空间。

先来看看n_estimators的学习曲线(以下为示例):


当绘制学习曲线时,我们可以很容易找到泛化误差开始上升、或转变为平稳趋势的转折点。因此我们可以选择转折点或转折点附近的n_estimators取值,例如20。然而,n_estimators会受到其他参数的影响,例如:

单棵决策树的结构更简单时(依赖剪枝时),可能需要更多的树

单棵决策树训练的数据更简单时(依赖随机性时),可能需要更多的树

因此n_estimators的参数空间可以被确定为range(20,100,5),如果你比较保守,甚至可以确认为是range(15,25,5)。

决策树对象Tree

在sklearn中,树模型是单独的一类对象,每个树模型背后都有一套完整的属性供我们调用,包括树的结构、树的规模等众多细节。在之前的课程中,我们曾经使用过树模型的绘图功能plot_tree,除此之外树还有许多有用的属性。随机森林是树组成的算法,因此也可以调用这些属性。我们来表格展示:

根据经验,当决策树不减枝且在训练集上的预测结果不错时,一棵树上的叶子量常常与样本量相当或比样本量更多,算法结果越糟糕,叶子量越少,如果RMSE很高或者R2很低,则可以考虑使用样本量的一半或3/4作为不减枝时的叶子量的参考。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

相关阅读更多精彩内容

友情链接更多精彩内容