机器学习西瓜书笔记(八) 第八章集成学习+代码

第八章

第8章集成学习

8.1 个体与集成

集成学习(ensemble learning)通过构建并结合多个学习器来完成学习任务,有时也被称为多分类器系统、基于委员会的学习等。

下图显示出集成学习的一般结构:先产生一组"个体学习器", 再用某种策略将它们结合起来个体学习器通常由一个现有的学习算法从训练数据产生,例如C4.5决策树算法、BP神经网络算法等,此时集成中只包含同种类型的个体学习器,例如"决策树集成"中全是决策树,"神经网络集成"中全是神经网络,这样的集成是"同质"的。同质集成中的个体学习器亦称"基学习器",相应的学习算法称为"基学习算法"。集成也可包含不同类型的个体学习器,例如同时包含决策树和神经网络,这样的集成是"异质"的。异质集成中的个体学习器由不同的学习算法生成,这时就不再有基学习算法;相应的,个体学习器一般不称为基学习器,常称为"组件学习器"或直接称为个体学习器。

集成学习通过将多个学习器进行结合,常可获得比单一学习器显著优越的泛化性能这对"弱学习器" 尤为明显,因此集成学习的很多理论研究都是针对弱学习器进行的,而基学习器有时也被直接称为弱学习器。但需注意的是,虽然从理论上来说使用弱学习器集成足以获得好的性能,但在实践中出于种种考虑,例如希望使用较少的个体学习器,或是重用关于常见学习器的一些经验等,人们往往会使用比较强的学习器。

在一般经验中,如果把好坏不等的东西掺到一起,那么通常结果会是比最坏的要好一些,比最好的要坏一些。集成学习把多个学习器结合起来,如何能获得比最好的单一学习器更好的性能呢?

考虑一个简单的例子:在二分类任务中,假定三个分类器在三个测试样本上的表现下图所示,其中✓表示分类正确,x表示分类错误,集成学习的结果通过投票法产生,即"少数服从多数"。在(a)中,每个分类器都只有66.6%的精度,但集成学习却达到了100%;在图(b)中,三个分类器没有差别集成之后性能没有提高;在图©中,每个分类器的精度都只有33.3%,集成学习的结果变得更糟。这个简单的例子显示出:要获得好的集成,个体学习器应"好而不同",即个体学习器要有一定的"准确性",即学习器不能太坏,并且要有"多样性"(diversity),即学习器间具有差异。

考虑二分类问题 y ∈ { − 1 , + 1 } y\in \{-1,+1\} y∈{−1,+1}和真实函数 f f f,假定基分类器的错误率为 ϵ \epsilon ϵ,即对每个基分类器 h i h_i hi有, P ( h i ( x ) ≠ f ( x ) ) = ϵ P(h_i(x)\neq f(x))=\epsilon P(hi(x)=f(x))=ϵ。假设集成通过简单投票法结合T个基分类器,若有超过半数的基分类器正确,则集成分类就正确: H ( x ) = s i g n ( ∑ i = 1 T h i ( x ) ) H(x)=sign(\sum_{i=1}^Th_i(x)) H(x)=sign(∑i=1Thi(x))。假设基分类器的错误率相互独立,则由Hoeffding不等式可知,集成的错误率为 P ( H ( x ) ≠ f ( x ) ) = ∑ k = 0 ⌊ T / 2 ⌋ ( T K ) ( 1 − ϵ ) k ϵ T − k ≤ e x p ( − 1 2 T ( 1 − 2 ϵ ) 2 ) P(H(x)\neq f(x))=\sum_{k=0}^{\left \lfloor T/2 \right \rfloor }\binom{T}{K}(1-\epsilon)^k\epsilon^{T-k}\leq exp(-\frac{1}{2}T(1-2\epsilon)^2) P(H(x)=f(x))=∑k=0⌊T/2⌋(KT)(1−ϵ)kϵT−k≤exp(−21T(1−2ϵ)2)。上式显示出,随着集成中个体分类器数目T的增大,集成的错误率将指数级下降,最终趋向于零。

然而必须注意到,上面的分析有一个关键假设:基学习器的误差相互独立在现实任务中,个体学习器是为解决同一个问题训练出来的,它们显然不可能相互独立!事实上,个体学习器的准确性和多样性本身就存在冲突。一般的,准确性很高之后,要增加多样性就需牺牲准确性。事实上,如何产生并结合好而不同的个体学习器,恰是集成学习研究的核心。

根据个体学习器的生成方式,目前的集成学习方法大致可分为两大类,即个体学习器间存在强依赖关系、必须串行生成的序列化方法,以及个体学习器间不存在强依赖关系、可同时生成的并行化方法;前者的代表是Boosting,后者的代表是Bagging和随机森林。

小结

个体学习(Individual Learning)和集成学习(Ensemble Learning)是两种不同的机器学习范式,它们在构建预测模型时采取不同的策略。

个体学习(Individual Learning)

个体学习指的是使用单个学习算法来训练模型。在这种方法中,每个模型独立地从数据中学习,并尝试捕捉数据中的模式。个体学习模型的例子包括:

  • 决策树
  • 支持向量机(SVM)
  • 逻辑回归
  • 神经网络

个体学习的特点包括:

  • 简单性:模型结构和训练过程相对简单,易于理解和实现。
  • 解释性:某些模型(如决策树)具有良好的解释性,可以直观地展示特征与输出之间的关系。
  • 依赖性:模型的性能很大程度上依赖于所选算法的能力和数据的质量。

集成学习(Ensemble Learning)

集成学习是一种通过结合多个学习算法来提高模型性能的方法。它的核心思想是"集思广益",即通过组合多个模型的预测来获得更准确的结果。集成学习通常包括以下几个步骤:

  1. 训练多个基础模型:使用相同的或不同的算法来训练一组基础模型。
  2. 多样性:确保基础模型具有多样性,即它们在训练数据上犯的错误是不同的。
  3. 组合策略:使用某种策略(如投票、平均或加权)来结合基础模型的预测。

集成学习的例子包括:

  • 随机森林(Random Forest)
  • 梯度提升机(Gradient Boosting Machines, GBM)
  • 堆叠泛化(Stacking)
  • 投票分类器(Voting Classifiers)

集成学习的特点包括:

  • 鲁棒性:通过结合多个模型,集成学习通常能够减少过拟合和提高模型的泛化能力。
  • 性能提升:在许多情况下,集成学习能够显著提高模型的预测准确性。
  • 复杂性:相比于个体学习,集成学习模型的训练和维护可能更加复杂。

比较

  • 模型数量:个体学习使用单个模型,而集成学习使用多个模型。
  • 错误多样性:个体学习可能对数据中的特定模式过于敏感,而集成学习通过多样性减少了这种敏感性。
  • 性能:在许多情况下,集成学习能够提供比个体学习更好的性能,尤其是在基础模型足够多样化时。
  • 计算成本:集成学习通常需要更多的计算资源,因为它涉及到训练和维护多个模型。

总的来说,选择个体学习还是集成学习取决于具体问题的需求、数据的特性以及可用的计算资源。在实践中,集成学习经常被用来提高模型的准确性和鲁棒性。

8.2 Boosting

Boosting是一族可将弱学习器提升为强学习器的算法.这族算法的工作机制类似:先从初始训练集训练出一个基学习器,再根据基学习器的表现对训练样本分布进行调整,使得先前基学习器做错的训练样本在后续受到更多关注,然后基于调整后的样本分布来训练下一个基学习器;如此重复进行,直至基学习器数目达到事先指定的值T,最终将这T个基学习器进行加权结合。

Boosting族算法最著名的代表是AdaBoost,其描述如下图所示,其中 y i ∈ { --- 1 , + 1 } y_i\in \{---1,+1\} yi∈{---1,+1}, f f f是真实函数。这个算法有两个关键需要理解:

  • (1) α t \alpha_t αt代表本次学习器 h t h_t ht占最终投票的权重,根据第六行,其大小与本学习器的准确率正相关。
  • (2) D t ( x ) D_t(x) Dt(x)代表本次学习器学习时对每个样本分配权重,根据第七行,其大小与样本预测的准确率成负相关。代表着若上一学习器对样本学习错误,则本学习器将对该样本着重学习,以降低该样本继续预测错误的概率。

AdaBoost算法有多种推导方式比较容易理解的是基于"加性模型",即基学习器的线性组合 H ( x ) = ∑ t = 1 T α t h t ( x ) H(x)=\sum_{t=1}^T\alpha_th_t(x) H(x)=∑t=1Tαtht(x),来最小化指数损失函数 l e x p ( H ∣ D ) = E x ∼ D [ e − f ( x ) H ( x ) ] l_{exp}(H|D)=E_{x \sim D}[e^{-f(x)H(x)}] lexp(H∣D)=Ex∼D[e−f(x)H(x)]。

这意味着sign(H(x))达到了贝叶斯最优错误率。换言之,若指数损失函数最小化,则分类错误率也将最小化;这说明指数损失函数是分类任务原本0/1损失函数的一致的替代损失函数。由于这个替代函数有更好的数学性质,例如它是连续可微函数,因此用它替代0/1损失函数作为优化目标。

在AdaBoost算法中,第一个基分类器 h 1 h_1 h1是通过直接将基学习算法用于初始数据分布而得;此后迭代地生成 h t h_t ht和 α t \alpha_t αt,当基分类器 h t h_t ht基于分布 D t D_t Dt产生后,该基分类器的权重 α t \alpha_t αt应使得 α t h t \alpha_th_t αtht最小化指数损失函数。

这恰是图中算法第7行的样本分布更新公式。

于是,由上述过程可见,从基于加性模型迭代式优化指数损失函数的角度推导出了图中的AdaBoost算法。Boosting算法要求基学习器能对特定的数据分布进行学习,这可通过重赋权法实施,即在训练过程的每一轮中,根据样本分布为每个训练样本重新赋予一个权重。对无法接受带权样本的基学习算法,则可通过重采样法来处理,即在每一轮学习中,根据样本分布对训练集重新进行采样,再用重采样而得的样本集对基学习器进行训练。一般而言,这两种做法没有显著的优劣差别。需注意的是,Boosting算法在训练的每一轮都要检查当前生成的基学习器是否满足基本条件(例如图中的第5行,检查当前基分类器是否是比随机猜测好),一旦条件不满足,则当前基学习器即被抛弃,且学习过程停止。在此种情形下,初始设置的学习轮数T也许还远未达到,可能导致最终集成中只包含很少的基学习器面性能不佳。若采用重采样法,则可获得重启动机会以避免训练过程过早停止,即在抛弃不满足条件的当前基学习器之后,可根据当前分布重新对训练样本进行采样,再基千新的采样结果重新训练出基学习器,从而使得学习过程可以持续到预设的T轮完成。

从偏差-方差分解的角度看,Boosting主要关注降低偏差,因此Boosting能基于泛化性能相当弱的学习器构建出很强的集成。

小结

Boosting是一种强大的集成学习算法,它通过结合多个弱学习器来构建一个强学习器。这种方法特别关注于减少模型的偏差,以此提高整体模型的性能。以下是对Boosting算法的概述,包括其原理、步骤以及一些流行的Boosting算法实现:

  1. 原理:Boosting算法的核心思想是利用多个弱学习器,每个学习器都在前一个学习器的基础上进行改进,以此来最小化损失函数。每个弱学习器通常是一个简单的模型,比如决策树,其性能略好于随机猜测 。

  2. 步骤

    • 初始时,为训练集中的每个样本分配相同的权重。
    • 训练一个弱学习器,并计算其在训练集上的错误。
    • 根据弱学习器的错误,调整样本的权重,使得被错误分类的样本在下一轮中具有更高的权重。
    • 训练下一个弱学习器,关注于当前模型表现不好的样本。
    • 重复上述步骤,直到达到预定的迭代次数或模型性能不再提升。
    • 将所有弱学习器的预测结果进行加权组合,形成最终的强学习器 。
  3. AdaBoost算法:AdaBoost(Adaptive Boosting)是最著名的Boosting算法之一。它通过逐步增加被前一轮弱学习器错误分类样本的权重来实现模型的迭代训练。最终的强学习器是所有弱学习器的加权和,其中分类误差率低的弱学习器具有更大的权重 。

  4. GBDT算法:GBDT(Gradient Boosting Decision Tree)是另一种流行的Boosting算法,它使用决策树作为基学习器。GBDT通过在前一轮模型的残差上训练新的弱学习器来进行迭代,从而逐步减小损失函数的值 。

  5. XGBoost、LightGBM和CatBoost:这些是Boosting算法的现代实现,它们在处理大规模数据集和高维特征时表现出色。XGBoost添加了正则化项和缺失值处理,提高了模型的稳定性和准确性。LightGBM专注于速度和内存效率,而CatBoost则专注于处理分类特征和减少类别扩展的影响 。

  6. 应用案例:Boosting算法被广泛应用于分类、回归问题,包括医疗诊断、风险评估、推荐系统等。例如,在医学诊断中,Boosting算法可以帮助医生根据症状和检查结果做出更准确的判断 。

Boosting算法通过逐步改进模型,实现了模型性能的显著提升。然而,它也增加了计算的复杂度,并且在某些情况下可能会导致过拟合。因此,在实际应用中,需要仔细调整模型参数以平衡模型的性能和复杂度。

8.3 Bagging与随机森林

由8.1节可知,欲得到泛化性能强的集成,集成中的个体学习器应尽可能相互独立;虽然"独立"在现实任务中无法做到,但可以设法使基学习器尽可能具有较大的差异。给定一个训练数据集,一种可能的做法是对训练样本进行采样,产生出若干个不同的子集,再从每个数据子集中训练出一个基学习器。这样,由于训练数据不同,获得的基学习器可望具有比较大的差异。然而,为获得好的集成,同时还希望个体学习器不能太差.如果采样出的每个子集都完全不同,则每个基学习器只用到了一小部分训练数据,甚至不足以进行有效学习,这显然无法确保产生出比较好的基学习器。为解决这个问题,可考虑使用相互有交叠的采样子集。

8.3.1 Bagging

Bagging是并行式集成学习方法最著名的代表。从名字即可看出,它直接基于2.2.3节介绍过的自助采样法(bootstrap sampling)。给定包含m个样本的数据集,先随机取出一个样本放入采样集中,再把该样本放回初始数据集,使得下次采样时该样本仍有可能被选中,这样,经过m次随机采样操作,得到含m个样本的采样集,初始训练集中有的样本在采样集里多次出现,有的则从未出现。具体而言,初始训练集中约有63.2%的样本出现在采样集中。

照这样,可采样出T个含m个训练样本的采样集,然后基于每个采样集训练出一个基学习器,再将这些基学习器进行结合。这就是Bagging的基本流程。在对预测输出进行结合时,Bagging通常对分类任务使用简单投票法,对回归任务使用简单平均法。若分类预测时出现两个类收到同样票数的情形,则最简单的做法是随机选择一个,也可进一步考察学习器投票的置信度来确定最终胜者。Bagging的算法描述如下图所示。

假定基学习器的计算复杂度为O(m),则Bagging的复杂度大致为T(O(m)+O(s)),考虑到采样与投票平均过程的复杂度O(s)很小,而T通常是 一个不太大的常数,因此,训练一个Bagging集成与直接使用基学习算法训练一个学习器的复杂度同阶,这说明Bagging是一个很高效的集成学习算法。另外,与标准AdaBoost只适用于二分类任务不同Bagging能不经修改地用于多分类、回归等任务。

值得一提的是,自助采样过程还给Bagging带来了另一个优点:由于每个基学习器只使用了初始训练集中约63.2%的样本,剩下约36.8%的样本可用作验证集来对泛化性能进行"包外估计"。为此需记录每个基学习器所使用的训练样本,不妨令 h t h_t ht表示实际使用的训练样本集,令 H o o b ( x ) H^{oob}(x) Hoob(x)表示对样本x的包外预测,即仅考虑那些未使用x训练的基学习器在x上的预测有

事实上,包外样本还有许多其他用途。例如当基学习器是决策树时,可使用包外样本来辅助剪枝,或用于估计决策树中各结点的后验概率以辅助对零训练样本结点的处理;当基学习器是神经网络时,可使用包外样本来辅助早期停止以减小过拟合风险。

从偏差-方差分解的角度看,Bagging主要关注降低方差,因此它在不剪枝决策树、神经网络等易受样本扰动的学习器上效用更为明显。

8.3.2随机森林

随机森林(简称RF)是Bagging的 一个扩展变体。RF在以决策树为基学习器构建Bagging集成的基础上,进一步在决策树的训练过程中引入了随机属性选择。具体来说,传统决策树在选择划分属性时是在当前结点的属性集合(假定有d个属性)中选择一个最优属性;而在RF中,对基决策树的每个结点,先从该结点的属性集合中随机选择一个包含k个属性的子集,然后再从这个子集中选择一个最优属性用于划分这里的参数,k控制了随机性的引入程度。若令k= d,则基决策树的构建与传统决策树相同;若令k= l,则是随机选择一个属性用于划分,一般情况下,推荐值 k = l o g 2 d k=log_2d k=log2d。

随机森林简单、容易实现、计算开销小,令人惊奇的是,它在很多现实任务中展现出强大的性能,被誉为 "代表集成学习技术水平的方法"。可以看出,随机森林对Bagging只做了小改动,但是与Bagging中基学习器的"多样性"仅通过样本扰动(通过对初始训练集采样)不同,随机森林中基学习器的多样性不仅来自样本扰动,还来自属性扰动,这就使得最终集成的泛化性能可通过个体学习器之间差异度的增加而进一步提升。

随机森林的收敛性与Bagging相似如下图所示,随机森林的起始性能往往相对较差,特别是在集成中只包含一个基学习器时。这很容易理解,因为通过引入属性扰动,随机森林中个体学习器的性能往往有所降低。然而,随着个体学习器数目的增加,随机森林通常会收敛到更低的泛化误差。值得一提的是,随机森林的训练效率常优于 Bagging,因为在个体决策树的构建过程中,Bagging使用的是"确定型"决策树,在选择划分属性时要对结点的所有属性进行考察,而随机森林使用的"随机型"决策树则只需考察一个属性子集。

小结

Bagging是一种集成学习技术,全称为Bootstrap Aggregating,即自助法聚合。它通过减少模型的方差来提高预测的稳定性和准确性。Bagging的核心思想是对原始数据集进行多次有放回的抽样,每次抽样得到一个新的数据集,然后在这个新数据集上训练一个基学习器。

Bagging的步骤如下:

  1. 从原始数据集中进行有放回抽样,生成多个新的训练数据集,每个数据集的大小通常与原始数据集相同。
  2. 对于每个新数据集,训练一个基学习器,这些基学习器可以是决策树、神经网络或其他任何模型。
  3. 对于分类问题,通过多数投票的方式来确定最终的预测结果;对于回归问题,则通过计算所有基学习器预测结果的平均值来得到最终预测。

Bagging方法的一个典型应用是随机森林算法,它不仅使用有放回抽样来生成训练数据集,还通过限制每个决策树在分裂时只能使用的特征子集,增加了模型的多样性,从而进一步提高了预测的准确性和鲁棒性。

Bagging的优点包括:

  • 能够减少过拟合,提高模型的泛化能力。
  • 可以并行化训练,提高计算效率。
  • 对于高方差的模型,如决策树,Bagging能够有效地提高其性能。

然而,Bagging也有一些局限性:

  • 它可能需要较多的计算资源,因为它需要训练多个基学习器。
  • 对于已经具有较低方差的模型,Bagging可能不会带来显著的性能提升。

总的来说,Bagging是一种有效的集成学习技术,适用于提高模型的稳定性和准确性,特别是在处理高方差模型时。通过合理选择基学习器和调整Bagging参数,可以在多种应用场景中取得良好的预测效果。

8.4 结合策略

学习器结合可能会从三个方面带来好处:首先,从统计的方面来看,由于学习任务的假设空间往往很大,可能有多个假设在训练集上达到同等性能,此时若使用单学习器可能因误选而导致泛化性能不佳,结合多个学习器则会减小这一风险,第二,从计算的方面来看,学习算法往往会陷入局部极小,有的局部极小点所对应的泛化性能可能很糟糕,而通过多次运行之后进行结合,可降低陷入糟糕局部极小点的风险,第三,从表示的方面来看,某些学习任务的真实假设可能不在当前学习算法所考虑的假设空间中,此时若使用单学习器则肯定无效,而通过结合多个学习器,由于相应的假设空间有所扩大,有可能学得更好的近似,下图给出了直观示意。

8.4.1 平均法

显然,简单平均法是加权平均法令 w i = 1 T w_i=\frac{1}{T} wi=T1的特例。加权平均法可认为是集成学习研究的基本出发点,对给定的基学习器,不同的集成学习方法可视为通过不同的方式来确定加权平均法中的基学习器权重。

加权平均法的权重一般是从训练数据中学习而得,现实任务中的训练样本通常不充分或存在噪声,这将使得学出的权重不完全可靠。尤其是对规模比较大的集成来说,要学习的权重比较多,较容易导致过拟合.因此实验和应用均显示出,加权平均法未必一定优于简单平均法。一般而言,在个体学习器性能相差较大时宜使用加权平均法而在个体学习器性能相近时宜使用简单平均法。

8.4.2 投票法

对分类任务来说,学习器 h i h_i hi,将从类别标记集合 c 1 , c 2 , . . . , c N {c_1,c_2,...,c_N} c1,c2,...,cN中预测出一 个标记,最常见的结合策略是使用投票法。将 h i h_i hi在样本x上的预测输出表示为一个N 维向量 ( h i 1 ( x ) ; h i 2 ( x ) ; . . . ; h i N ( x ) ) (h_i^1(x);h_i^2(x);...;h_i^N(x)) (hi1(x);hi2(x);...;hiN(x)),其中 h i j ( x ) h_i^j(x) hij(x)是 h i h_i hi在类别标记 c j c_j cj上的输出。

标准的绝对多数投票法提供了"拒绝预测"选项,这在可靠性要求较高的学习任务中是一个很好的机制。但若学习任务要求必须提供预测结果,则绝对多数投票法将退化为相对多数投票法。因此,在不允许拒绝预测的任务中,绝对多数、相对多数投票法统称为 "多数投票法"。

上式没有限制个体学习器输出值的类型。在现实任务中,不同类型个体学习器可能产生不同类型的 h i j ( x ) h_i^j(x) hij(x)值,常见的有:

  • 类标记: h i j ( x ) ∈ { 0 , 1 } h_i^j(x) \in \{0,1\} hij(x)∈{0,1},若 h i h_i hi将样本x预测为类别 c j c_j cj则取值为 1,否则为0。使用类标记的投票亦称"硬投票"。
  • 类概率: h i j ( x ) ∈ [ 0 , 1 ] h_i^j(x) \in [0,1] hij(x)∈[0,1],相当于对后验概率 P ( c j ∣ x ) P(c_j|x) P(cj∣x)的一个估计。使用类概率的投票亦称"软投票"。

不同类型的 h i j ( x ) h_i^j(x) hij(x)值不能混用。对一些能在预测出类别标记的同时产生分类置信度的学习器,其分类置信度可转化为类概率使用。若此类值未进行规范化例如支持向量机的分类间隔值则必须使用一些技术如Platt缩放、等分回归等进行"校准"后才能作为类概率使用。有趣的是,虽然分类器估计出的类概率值一般都不太准确,但基于类概率进行结合却往往比直接基于类标记进行结合性能更好。需注意的是,若基学习器的类型不同,则 其类概率值不能直接进行比较;在此种情形下,通常可将类概率输出转化为类标记输出(例如将类概率输出最大的 h i j ( x ) h_i^j(x) hij(x)设为1,其他设为0)然后再投票。

8.4.3 学习法

当训练数据很多时,一种更为强大的结合策略是使用"学习法",即通过另一个学习器来进行结合。Stacking是学习法的典型代表,把个体学习器称为初级学习器,用于结合的学习器称为次级学习器或元学习器。

Stacking先从初始数据集训练出初级学习器,然后"生成"一个新数据集用于训练次级学习器。在这个新数据集中,初级学习器的输出被当作样例输入特征,而初始样本的标记仍被当作样例标记。Stacking的算法描述如下图所示,这里假定初级学习器使用不同学习算法产生,即初级集成是异质的。

在训练阶段次级训练集是利用初级学习器产生的,若直接用初级学习器的训练集来产生次级训练集,则过拟合风险会比较大;因此,一般是通过使用交叉验证或留一法这样的方式,用训练初级学习器未使用的样本来产生次级学习器的训练样本。以K折交叉验证为例,初始训练集D被随机划分为K个大小相似的集合 { D 1 , D 2 , . . . , D k } \{D_1,D_2,...,D_k\} {D1,D2,...,Dk}。令 D j D_j Dj和 D ˉ j \bar{D}j Dˉj分别表示第j折的测试集和训练集。给定T个初级学习算法,初级学习器 h t ( j ) h_t^{(j)} ht(j)通过在 D ˉ j \bar{D}j Dˉj上使用第t个学习算法而得。对 D j D_j Dj中每个样本 x i x_i xi,令 z i t = h t ( j ) ( x i ) z{it}=h_t^{(j)}(x_i) zit=ht(j)(xi),则由 x i x_i xi所产生的次级训练样例的示例部分为 z i = ( z i 1 . . . z i T ) z_i=(z{i1}...z_{iT}) zi=(zi1...ziT),标记部分为 y i y_i yi。于是,在整个交叉验证过程结束后,从这T个初级学习器产生的次级训练集是 D ′ = { ( z i , y i ) } i = 1 m D'=\{(z_i,y_i)\}_{i=1}^m D′={(zi,yi)}i=1m, 然后D'将用于训练次级学习器。

次级学习器的输入属性表示和次级学习算法对Stacking集成的泛化性能有很大影响。有研究表明,将初级学习器的输出类概率作为次级学习器的输入属性,用多响应线性回归(简称MLR)作为次级学习算法效果较好,在MLR中使用不同的属性集更佳。

贝叶斯模型平均(简称 BMA)基于后验概率来为不同模型赋予权重,可视为加权平均法的一种特殊实现。对Stacking和BMA进行了比较理论上来说,若数据生成模型恰在当前考虑的模型中,且数据噪声很少,则BMA不差于Stacking。然而,在现实应用中无法确保数据生成模型一定在当前考虑的模型中,甚至可能难以用当前考虑的模型来进行近似,因此Stacking通常优于BMA, 因为其鲁棒性比BMA更好,而且BMA对模型近似误差非常敏感。

小结

集成学习中的结合策略是提高模型性能的关键因素之一。以下是几种常见的结合策略:

  1. 平均法:在多个模型进行回归预测时,使用所有模型预测结果的简单或加权平均值作为最终预测。这种方法适用于个体学习器性能相近的情况,能够提高泛化性能并降低进入局部最小点的风险 。

  2. 投票法:在分类问题中,根据各个模型的预测结果进行投票,可以是绝对多数投票、相对多数投票或加权投票法。投票法特别适用于集成中的基学习器性能差异较大时 。

  3. Stacking(堆叠):这是一种两层模型的集成技术,首先使用多个不同的基学习器进行训练,然后使用这些基学习器的预测结果作为新的特征,训练一个次级学习器。Stacking可以提高模型的预测性能,因为它结合了不同模型的优势 。

  4. Bagging:即自助聚合,是一种并行集成学习方法,通过从原始数据集中进行有放回的随机采样生成多个子数据集,并在每个子数据集上训练一个基学习器,最终将这些基学习器的预测结果进行平均或投票。Bagging方法可以有效降低模型的方差,提高模型的稳定性 。

  5. Boosting:是一种序列集成方法,通过逐步增加基学习器的权重来最小化预测误差。Boosting方法关注于减少模型的偏差,适用于提高模型的预测准确性 。

  6. 混合(Blending):这种方法结合了多个模型的预测结果,通常使用线性或非线性方法来优化最终的预测。

  7. 随机森林:是一种特殊的Bagging方法,使用多个决策树作为基学习器,并通过特征选择的随机性来增加模型的多样性和稳定性 。

  8. 梯度提升树(GBM):是一种Boosting方法,通过逐步添加弱学习器(通常是决策树)来最小化损失函数,适用于分类和回归问题 。

  9. XGBoost、LightGBM和CatBoost:这些都是基于梯度提升框架的优化算法,具有高效的训练速度和良好的预测性能,适用于处理大规模数据集 。

通过合理选择和应用这些结合策略,可以显著提升集成学习模型的性能,解决实际问题中的复杂挑战。

8.5多样性

8.5.1 误差-分歧分解

8.1节提到欲构建泛化能力强的集成个体学习器应"而不同",现在来做一个简单的理论分析。

遗憾的是,在现实任务中很难直接将 E ˉ − A ˉ \bar{E}-\bar{A} Eˉ−Aˉ作为优化目标,进行优化求解,不仅由于它们是定义在整个样本空间上,还由于 A ˉ \bar{A} Aˉ不是一个可直接操作的多样性度量,它仅在集成构造好之后才能进行估计.此外需注意的是上面的推导过程只适用千回归学习,难以直接推广到分类学习任务上去.

8.5.2 多样性度量

顾名思义,多样性度量是用于度量集成中个体分类器的多样性,即估算个体学习器的多样化程度。典型做法是考虑个体分类器的两两相似/不相似性。

以上介绍的都是"成对型"多样性度量,它们可以容易地通过2维图绘制出来。例如著名的"K-误差图",就是将每一对分类器作为图上的一个点,横坐标是这对分类器的K值,纵坐标是它们的平均误差,下图给出了一个例子。显然,数据点云的位置越高,则个体分类器准确性越低;点云的位置越靠右,则个体学习器的多样性越小。

8.5.3多样性增强

在集成学习中需有效地生成多样性大的个体学习器,为增强多样性,一般思路是在学习过程中引入随机性,常见做法主要是对数据样本、输入属性、输出表示、算法参数进行扰动。

  • 数据样本扰动

给定初始数据集,可从中产生出不同的数据子集,再利用不同的数据子集训练出不同的个体学习器。数据样本扰动通常是基于采样法,例如在Bagging中使用自助采样,在AdaBoost中使用序列采样。此类做法简单高效,使用最广。对很多常见的基学习器,例如决策树、神经网络等,训练样本稍加变化就会导致学习器有显著变动,数据样本扰动法对这样的"不稳定基学习器"很有效;然而,有一些基学习器对数据样本的扰动小敏感,例如线性学习器、支持向最机、朴素贝叶斯、K近邻学习器等,这样的基学习器称为稳定基学习器,对此类基学习器进行集成往往需使用输入属性扰动等其他机制。

  • 输入属性扰动

训练样本通常由一组属性描述,不同的"子空间"(即属性子集)提供了观察数据的不同视角。显然,从不同子空间训练出的个体学习器,必然有所不同。著名的随机子空间算法就依赖于输入属性扰动,该算法从初始属性集中抽取出若干个属性子集,再基于每个属性子集训练一个基学习器。算法描述如下图所示,对包含大量冗余属性的数据,在子空间中训练个体学习器不仅能产生多样性大的个体,还会因属性数的减少而大幅节省时间开销。同时,由于冗余属性多,减少一些属性后训练出的个体学习器也不至于太差。若数据只包含少量属性,或者冗余属性很少,则不宜使用输入属性扰动法。

  • 输出表示扰动

此类做法的基本思路是对输出表示进行操纵以增强多样性。可对训练样本的类标记稍作变动,如"翻转法",随机改变一些训练样本的标记;也可对输出表示进行转化,如"输出调制法",将分类输出转化为回归输出后构建个体学习器;还可将原任务拆解为多个可同时求解的子任务,如ECOC法,利用纠错输出码将多分类任务拆解为一系列二分类任务来训练基学习器

  • 算法参数扰动

基学习算法一般都有参数需进行设置,例如神经网络的隐层神经元数、初始连接权值等,通过随机设置不同的参数,往往可产生差别较大的个体学习器。

例如"负相关法",显式地通过正则化项来强制个体神经网络使用不同的参数。对参数较少的算法,可通过将其学习过程中某些环节用其他类似方式代替,从而达到扰动的目的,例如可将决策树使用的属性选择机制替换成其他的属性选择机制值得指出的是,使用单一学习器时通常需使用交叉验证等方法来确定参数值,这事实上已使用了不同参数训练出多个学习器,只不过最终仅选择其中一个学习器进行使用,而集成学习则相当于把这些学习器都利用起来;由此也可看出,集成学习技术的实际计算开销并不比使用单一学习器大很多。

不同的多样性增强机制可同时使用,例如8.3.2节介绍的随机森林中同时使用了数据样本扰动和输入属性扰动。

小结

集成学习的多样性是指在构建集成模型时,基学习器之间的差异性。多样性是集成学习成功的关键因素之一,因为它可以提高模型的泛化能力和减少过拟合的风险。以下是一些提高多样性的策略:

  1. 数据样本扰动:通过对原始数据集进行有放回的抽样(Bootstrap抽样),为每个基学习器生成不同的训练数据集。这种方法适用于不稳定的学习器,如决策树和神经网络。

  2. 输入属性扰动:通过选择原始数据集中的不同属性子集来训练每个基学习器,这种方法适用于稳定学习器,如线性模型和k-近邻算法。

  3. 输出表示扰动:通过对训练样本的类标记进行轻微的变动,例如翻转法或ECOC编码法,来增加基学习器的多样性。

  4. 算法参数扰动:通过改变基学习器的参数设置,例如决策树的树深或神经网络的层数,来训练不同的模型。

  5. 模型选择多样性:使用不同类型的学习算法作为基学习器,例如决策树、支持向量机、神经网络等,每种算法可能捕捉数据的不同特征。

  6. 特征随机性:在构建模型时,随机选择一部分特征进行训练,如随机森林中的随机特征选择。

  7. 训练数据的随机性:在每次迭代中使用不同的训练数据子集,增加模型的随机性。

  8. 学习率调整:在Boosting方法中,通过调整学习率来控制每一步的贡献,从而影响模型的多样性。

  9. 损失函数的选择:在不同的基学习器中使用不同的损失函数,可以鼓励模型学习不同的数据表示。

  10. 集成策略的多样性:使用不同的集成策略,如Bagging、Boosting、Stacking等,每种策略都有其独特的方式增加多样性。

多样性度量方法包括:

  • 不合度量:衡量分类器对同一样本预测不一致的程度。
  • 相关系数:评估两个分类器预测结果的相关性。
  • Q-统计量:衡量两个分类器预测一致性的概率。
  • κ-统计量:评估两个分类器一致性的概率与随机一致性的概率之间的差异。

增强多样性的目的是为了提高集成模型的性能,通过减少基学习器之间的相互关系,使得每个学习器都能独立地捕捉数据的不同方面,最终通过集成策略提高整体模型的泛化能力和鲁棒性。

代码

决策树与Bagging对比

复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import BaggingRegressor
from sklearn.tree import DecisionTreeRegressor

# Settings
n_repeat = 50       # Number of iterations for computing expectations
n_train = 50        # Size of the training set
n_test = 1000       # Size of the test set
noise = 0.1         # Standard deviation of the noise
np.random.seed(0)
estimators = [("Tree", DecisionTreeRegressor()), ("Bagging(Tree)", BaggingRegressor(DecisionTreeRegressor()))]
n_estimators = len(estimators)


# Generate data
def f(x):
    x = x.ravel()
    return np.exp(-x ** 2) + 1.5 * np.exp(-(x - 2) ** 2)


def generate(n_samples, noise, n_repeat=1):
    X = np.random.rand(n_samples) * 10 - 5
    X = np.sort(X)
    if n_repeat == 1:
        y = f(X) + np.random.normal(0.0, noise, n_samples)
    else:
        y = np.zeros((n_samples, n_repeat))
        for i in range(n_repeat):
            y[:, i] = f(X) + np.random.normal(0.0, noise, n_samples)
    X = X.reshape((n_samples, 1))
    return X, y


X_train = []
y_train = []
for i in range(n_repeat):
    X, y = generate(n_samples=n_train, noise=noise)
    X_train.append(X)
    y_train.append(y)

X_test, y_test = generate(n_samples=n_test, noise=noise, n_repeat=n_repeat)

plt.figure(figsize=(10, 8))

# Loop over estimators to compare
for n, (name, estimator) in enumerate(estimators):
    # Compute predictions
    y_predict = np.zeros((n_test, n_repeat))
    for i in range(n_repeat):
        estimator.fit(X_train[i], y_train[i])
        y_predict[:, i] = estimator.predict(X_test)
    # Bias^2 + Variance + Noise decomposition of the mean squared error
    y_error = np.zeros(n_test)
    for i in range(n_repeat):
        for j in range(n_repeat):
            y_error += (y_test[:, j] - y_predict[:, i]) ** 2
    y_error /= (n_repeat * n_repeat)
    y_noise = np.var(y_test, axis=1)
    y_bias = (f(X_test) - np.mean(y_predict, axis=1)) ** 2
    y_var = np.var(y_predict, axis=1)
    print("{0}: {1:.4f} (error) = {2:.4f} (bias^2) " " + {3:.4f} (var) + {4:.4f} (noise)".format(name, np.mean(y_error),np.mean(y_bias),np.mean(y_var),np.mean(y_noise)))

    # Plot figures
    plt.subplot(2, n_estimators, n + 1)
    plt.plot(X_test, f(X_test), "b", label="$f(x)$")
    plt.plot(X_train[0], y_train[0], ".b", label="LS ~ $y = f(x)+noise$")

    for i in range(n_repeat):
        if i == 0:
            plt.plot(X_test, y_predict[:, i], "r", label=r"$\^y(x)$")
        else:
            plt.plot(X_test, y_predict[:, i], "r", alpha=0.05)

    plt.plot(X_test, np.mean(y_predict, axis=1), "c", label=r"$\mathbb{E}_{LS} \^y(x)$")

    plt.xlim([-5, 5])
    plt.title(name)

    if n == n_estimators - 1:
        plt.legend(loc=(1.1, .5))

    plt.subplot(2, n_estimators, n_estimators + n + 1)
    plt.plot(X_test, y_error, "r", label="$error(x)$")
    plt.plot(X_test, y_bias, "b", label="$bias^2(x)$"),
    plt.plot(X_test, y_var, "g", label="$variance(x)$"),
    plt.plot(X_test, y_noise, "c", label="$noise(x)$")

    plt.xlim([-5, 5])
    plt.ylim([0, 0.1])

    if n == n_estimators - 1:
        plt.legend(loc=(1.1, .5))

plt.subplots_adjust(right=.75)
plt.show()

左上角的图说明了一维回归问题, 在玩具的随机数据集LS(蓝点)上训练的单个决策树的预测(以暗红色表示)。它还说明了在其他随机绘制实例LS上训练的其他单个决策树的预测(以淡红色表示)。显而易见地,这里的方差项对应于单个估计器的预测光束的宽度(以亮红色表示)。方差越大,x对训练集中微小变化的预测就越敏感。偏差项对应于估计器(青色)的平均预测值与最佳模型(深蓝色)之间的差异。在这个问题上,我们可以观察到偏差很小(蓝曲线和青色曲线都很接近),而方差很大(红色光束比较宽)。

左下角图描绘了单个决策树的期望均方误差的点态分解。它证实了偏差项(蓝色)是低的,而方差是大的(绿色)。它还说明了误差的噪声部分,如预期的,似乎是恒定的,在0.01左右。

右边的图对应是一样的,但使用的bagging集成的一组决策树。在这两个图中,我们可以观察到偏差项比以前的情况要大。在右上角图中,平均预测值(青色)与最佳模型之间的差异较大(例如,注意x=2附近的偏移量)。在右下角图中,偏置曲线也略高于左下角图。然而,就方差而言,预测束较窄,表明方差较小。事实上,正如右下角的数字所证实的,方差项(绿色)比单个决策树的方差项要低。总的来说,偏差-方差分解不再是相同的。这种折衷更适合于bagging:在数据集的副本上平均几个决策树的结果会略微增加偏差项,但允许更大程度地减少方差,从而导致整体均方误差较低(比较下图中的红色曲线)。脚本输出也证实了这种直觉。bagging的总误差小于单棵决策树的总误差,这种差异确实主要是由于方差的减小所致。

AdaBoost决策树回归

使用AdaBoost提升决策树。在一维正弦数据集上的R2算法,具有少量高斯噪声。299个增强(300个决策树)与一个决策树回归器进行比较。随着提升次数的增加,回归器可以适应更多的细节。

复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import AdaBoostRegressor

# Create the dataset
rng = np.random.RandomState(1)
X = np.linspace(0, 6, 100)[:, np.newaxis]
y = np.sin(X).ravel() + np.sin(6 * X).ravel() + rng.normal(0, 0.1, X.shape[0])

# Fit regression model
regr_1 = DecisionTreeRegressor(max_depth=4)

regr_2 = AdaBoostRegressor(DecisionTreeRegressor(max_depth=4), n_estimators=300, random_state=rng)

regr_1.fit(X, y)
regr_2.fit(X, y)

# Predict
y_1 = regr_1.predict(X)
y_2 = regr_2.predict(X)

# Plot the results
plt.figure()
plt.scatter(X, y, c="k", label="training samples")
plt.plot(X, y_1, c="g", label="n_estimators=1", linewidth=2)
plt.plot(X, y_2, c="r", label="n_estimators=300", linewidth=2)
plt.xlabel("data")
plt.ylabel("target")
plt.title("Boosted Decision Tree Regression")
plt.legend()
plt.show()

总结

第七章详细介绍了集成学习,包括了集成学习的概念、原理、常见方法(如Boosting、Bagging、随机森林)、结合策略(如平均法、投票法、学习法)以及多样性的度量和增强。此外,在本章学习时,我还提供了一些Python代码示例,用于展示决策树与Bagging方法的对比,以及使用AdaBoost进行决策树回归的实例。

集成学习是一种通过组合多个学习器来解决单一学习器难以解决的复杂问题的方法。它的核心思想是"集思广益",即通过结合多个学习器的预测结果来提高整体的泛化性能。文中提到的Boosting、Bagging和随机森林是集成学习中最常用的几种方法:

  1. Boosting:是一种逐步提高学习器性能的方法,通过不断调整训练样本的权重,使学习器在前一轮中预测错误的样本在下一轮中获得更多的关注。

  2. Bagging:即自助采样法,通过从原始训练数据中随机抽取样本来构建多个不同的训练集,然后训练多个基学习器,最后通过投票或平均的方式来进行预测。

  3. 随机森林:是Bagging的一种扩展,除了使用自助采样外,还在决策树的每个分裂节点上引入了属性选择的随机性,从而增加了基学习器的多样性。

文中还讨论了集成学习中的结合策略,包括简单平均法、加权平均法、投票法等。这些策略决定了如何将多个学习器的预测结果结合起来,以得到最终的预测。

此外,文中还提到了多样性的重要性。在集成学习中,个体学习器的多样性对于提高整体性能至关重要。为了增强多样性,可以引入数据样本扰动、输入属性扰动、输出表示扰动和算法参数扰动等方法。

最后,文中提供的代码示例展示了如何使用Python的sklearn库来实现决策树、Bagging和AdaBoost方法,并对比了它们在一维回归问题上的表现。这些代码示例可以帮助读者更好地理解集成学习的原理和实现方式。

相关推荐
摇滚侠14 分钟前
Spring Boot 3零基础教程,WEB 开发 通过配置类代码方式修改静态资源配置 笔记32
java·spring boot·笔记
JJJJ_iii2 小时前
【机器学习05】神经网络、模型表示、前向传播、TensorFlow实现
人工智能·pytorch·python·深度学习·神经网络·机器学习·tensorflow
聪明的笨猪猪2 小时前
Java JVM “内存(1)”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
_dindong2 小时前
Linux网络编程:Socket编程TCP
linux·服务器·网络·笔记·学习·tcp/ip
第六五2 小时前
DPC和DPC-KNN算法
人工智能·算法·机器学习
龙俊杰的读书笔记3 小时前
《小白学随机过程》第一章:随机过程——定义和形式 (附录1 探究随机变量)
人工智能·机器学习·概率论·随机过程和rl
摇滚侠3 小时前
Spring Boot 3零基础教程,WEB 开发 Thymeleaf 属性优先级 行内写法 变量选择 笔记42
java·spring boot·笔记
摇滚侠3 小时前
Spring Boot 3零基础教程,WEB 开发 Thymeleaf 总结 热部署 常用配置 笔记44
java·spring boot·笔记
rechol4 小时前
汇编与底层编程笔记
汇编·arm开发·笔记
Blossom.1184 小时前
把 AI“缝”进布里:生成式编织神经网络让布料自带摄像头
人工智能·python·单片机·深度学习·神经网络·目标检测·机器学习