[深度学习]Part2 集成学习Ch08-2——【DeepBlue学习笔记】

21 篇文章 0 订阅
18 篇文章 0 订阅

本文仅供学习使用


2. XGBoost

XGBoost安装:pip install xgboost

XGBoost是GBDT算法的一种变种,是一种常用的有监督集成学习算法; 是一种伸缩性强、便捷的可并行构建模型的Gradient Boosting算法
在这里插入图片描述

  • 目标函数: O b j ( θ ) = L ( θ ) + Ω ( θ ) Obj(\theta )=L(\theta )+\Omega (\theta ) Obj(θ)=L(θ)+Ω(θ)
    其中: L ( θ ) L(\theta ) L(θ)为误差函数:体现的是模型有多拟合数据; Ω ( θ ) \Omega (\theta ) Ω(θ)为正则化项:惩罚复杂模型的参数,用于解决过拟合——L1与L2。
  • GBDT的目标函数 o b j = ∑ i = 1 n l ( y i , y ^ i ( t ) ) obj=\sum\limits_{i=1}^{n}{l({{y}_{i}},{{{\hat{y}}}_{i}}^{(t)})} obj=i=1nl(yi,y^i(t))
    { y ^ i ( 0 ) = 0 y ^ i ( 1 ) = y ^ i ( 0 ) + f 1 ( x i ) y ^ i ( 2 ) = y ^ i ( 0 ) + f 2 ( x i ) ⋯ y ^ i ( t ) = y ^ i ( t − 1 ) + f t ( x i ) \left\{ \begin{matrix} {{{\hat{y}}}_{i}}^{(0)}=0 \\ {{{\hat{y}}}_{i}}^{(1)}={{{\hat{y}}}_{i}}^{(0)}+{{f}_{1}}({{x}_{i}}) \\ {{{\hat{y}}}_{i}}^{(2)}={{{\hat{y}}}_{i}}^{(0)}+{{f}_{2}}({{x}_{i}}) \\ \cdots \\ {{{\hat{y}}}_{i}}^{(t)}={{{\hat{y}}}_{i}}^{(t-1)}+{{f}_{t}}({{x}_{i}}) \\ \end{matrix} \right. y^i(0)=0y^i(1)=y^i(0)+f1(xi)y^i(2)=y^i(0)+f2(xi)y^i(t)=y^i(t1)+ft(xi)
  • XGBoost的目标函数: o b j = ∑ i = 1 n l ( y i , y ^ i ( t ) ) + ∑ i = 1 t Ω ( f i ) obj=\sum\limits_{i=1}^{n}{l({{y}_{i}},{{{\hat{y}}}_{i}}^{(t)})}+\sum\limits_{i=1}^{t}{\Omega ({{f}_{i}})} obj=i=1nl(yi,y^i(t))+i=1tΩ(fi)——具有惩罚项、防止过拟合
    { y ^ i ( 0 ) = 0 y ^ i ( 1 ) = y ^ i ( 0 ) + f 1 ( x i ) y ^ i ( 2 ) = y ^ i ( 0 ) + f 2 ( x i ) ⋯ y ^ i ( t ) = y ^ i ( t − 1 ) + f t ( x i ) , f t ( x ) = w q ( x ) , Ω ( f ) = γ T + 1 2 λ ∑ j = 1 T w j 2 \left\{ \begin{matrix} {{{\hat{y}}}_{i}}^{(0)}=0 \\ {{{\hat{y}}}_{i}}^{(1)}={{{\hat{y}}}_{i}}^{(0)}+{{f}_{1}}({{x}_{i}}) \\ {{{\hat{y}}}_{i}}^{(2)}={{{\hat{y}}}_{i}}^{(0)}+{{f}_{2}}({{x}_{i}}) \\ \cdots \\ {{{\hat{y}}}_{i}}^{(t)}={{{\hat{y}}}_{i}}^{(t-1)}+{{f}_{t}}({{x}_{i}}) \\ \end{matrix} \right.,{{f}_{t}}(x)={{w}_{q(x)}},\Omega (f)=\gamma T+\frac{1}{2}\lambda \sum\limits_{j=1}^{T}{{{w}_{j}}^{2}} y^i(0)=0y^i(1)=y^i(0)+f1(xi)y^i(2)=y^i(0)+f2(xi)y^i(t)=y^i(t1)+ft(xi),ft(x)=wq(x),Ω(f)=γT+21λj=1Twj2——第j个叶子的值为wj

2.1 公式推导

  • 第t次迭代后,模型的预测等于前 t-1 次的模型加上第 t 棵树的预测: y ^ i ( t ) = y ^ i ( t − 1 ) + f t ( x i ) {{{\hat{y}}}_{i}}^{(t)}={{{\hat{y}}}_{i}}^{(t-1)}+{{f}_{t}}({{x}_{i}}) y^i(t)=y^i(t1)+ft(xi)
  • 目标函数可以写成: l o s s = ∑ i = 1 n l ( y i , y ^ i ( t − 1 ) + f t ( x i ) ) + ∑ i = 1 t − 1 Ω ( f i ) + Ω ( f t ) loss=\sum\limits_{i=1}^{n}{l({{y}_{i}},{{{\hat{y}}}_{i}}^{(t-1)}+{{f}_{t}}({{x}_{i}}))}+\sum\limits_{i=1}^{t-1}{\Omega ({{f}_{i}})}+\Omega ({{f}_{t}}) loss=i=1nl(yi,y^i(t1)+ft(xi))+i=1t1Ω(fi)+Ω(ft)
  • 将误差函数中的 y ^ i ( t − 1 ) + f t ( x i ) {{{\hat{y}}}_{i}}^{(t-1)}+{{f}_{t}}({{x}_{i}}) y^i(t1)+ft(xi),看成一个整体,求解这个整体取值在 y ^ i ( t − 1 ) {{{\hat{y}}}_{i}}^{(t-1)} y^i(t1)处进行二阶泰勒展开: l o s s ≈ ∑ i = 1 n [ l ( y i , y ^ i ( t − 1 ) ) + g i f t ( x i ) + 1 2 h i f t 2 ( x i ) ] + ∑ i = 1 t − 1 Ω ( f i ) + Ω ( f t ) , g i = ∂ y ^ i ( t − 1 ) l ( y i , y ^ i ( t − 1 ) ) , h i = ∂ y ^ i ( t − 1 ) 2 l ( y i , y ^ i ( t − 1 ) ) loss\approx \sum\limits_{i=1}^{n}{[l({{y}_{i}},{{{\hat{y}}}_{i}}^{(t-1)})+{{g}_{i}}{{f}_{t}}({{x}_{i}})+\frac{1}{2}{{h}_{i}}{{f}_{t}}^{2}({{x}_{i}})]}+\sum\limits_{i=1}^{t-1}{\Omega ({{f}_{i}})}+\Omega ({{f}_{t}}),{{g}_{i}}={{\partial }_{{{{\hat{y}}}_{i}}^{(t-1)}}}l({{y}_{i}},{{{\hat{y}}}_{i}}^{(t-1)}),{{h}_{i}}={{\partial }_{{{{\hat{y}}}_{i}}^{(t-1)}}}^{2}l({{y}_{i}},{{{\hat{y}}}_{i}}^{(t-1)}) lossi=1n[l(yi,y^i(t1))+gift(xi)+21hift2(xi)]+i=1t1Ω(fi)+Ω(ft),gi=y^i(t1)l(yi,y^i(t1)),hi=y^i(t1)2l(yi,y^i(t1))
  • 将函数中的所有常数项全部去掉,可以得到以下公式: l o s s ≈ ∑ i = 1 n [ g i f t ( x i ) + 1 2 h i f t 2 ( x i ) ] + Ω ( f t ) loss\approx \sum\limits_{i=1}^{n}{[{{g}_{i}}{{f}_{t}}({{x}_{i}})+\frac{1}{2}{{h}_{i}}{{f}_{t}}^{2}({{x}_{i}})]}+\Omega ({{f}_{t}}) lossi=1n[gift(xi)+21hift2(xi)]+Ω(ft)
  • 将函数f和正则项带入公式中得到以下公式: l o s s ≈ ∑ i = 1 n [ g i w q ( x ) + 1 2 h i w q ( x ) 2 ] + γ T + 1 2 λ ∑ j = 1 T w j 2 loss\approx \sum\limits_{i=1}^{n}{[{{g}_{i}}{{w}_{q(x)}}+\frac{1}{2}{{h}_{i}}{{w}_{q(x)}}^{2}]}+\gamma T+\frac{1}{2}\lambda \sum\limits_{j=1}^{T}{{{w}_{j}}^{2}} lossi=1n[giwq(x)+21hiwq(x)2]+γT+21λj=1Twj2
  • 定义每个叶子节点j上的样本集合为: [ I j = { i ∣ q ( x i ) = = j } [{{I}_{j}}=\{i|q({{x}_{i}})==j\} [Ij={iq(xi)==j}
  • 将样本累加操作转换为叶节点的操作: l o s s ≈ ∑ j = 1 T [ ∑ i ∈ I j g i w j + 1 2 ∑ i ∈ I j h i w j 2 ] + γ T + 1 2 λ ∑ j = 1 T w j 2 = ∑ j = 1 T [ ∑ i ∈ I j g i w j + 1 2 ∑ i ∈ I j ( h i + λ ) w j 2 ] + γ T = ∑ j = 1 T [ G j w j + 1 2 ( H j + λ ) w j 2 ] + γ T loss\approx \sum\limits_{j=1}^{T}{[\sum\limits_{i\in {{I}_{j}}}^{{}}{{{g}_{i}}}{{w}_{j}}+\frac{1}{2}\sum\limits_{i\in {{I}_{j}}}^{{}}{{{h}_{i}}}{{w}_{j}}^{2}]}+\gamma T+\frac{1}{2}\lambda \sum\limits_{j=1}^{T}{{{w}_{j}}^{2}}=\sum\limits_{j=1}^{T}{[\sum\limits_{i\in {{I}_{j}}}^{{}}{{{g}_{i}}}{{w}_{j}}+\frac{1}{2}\sum\limits_{i\in {{I}_{j}}}^{{}}{({{h}_{i}}+\lambda )}{{w}_{j}}^{2}]}+\gamma T=\sum\limits_{j=1}^{T}{[{{G}_{j}}{{w}_{j}}+\frac{1}{2}({{H}_{j}}+\lambda ){{w}_{j}}^{2}]}+\gamma T lossj=1T[iIjgiwj+21iIjhiwj2]+γT+21λj=1Twj2=j=1T[iIjgiwj+21iIj(hi+λ)wj2]+γT=j=1T[Gjwj+21(Hj+λ)wj2]+γT
  • 最终的目标函数: l o s s = ∑ j = 1 T [ G j w j + 1 2 ( H j + λ ) w j 2 ] + γ T loss=\sum\limits_{j=1}^{T}{[{{G}_{j}}{{w}_{j}}+\frac{1}{2}({{H}_{j}}+\lambda ){{w}_{j}}^{2}]}+\gamma T loss=j=1T[Gjwj+21(Hj+λ)wj2]+γT
  • 如果树的结构确定(q函数确定),为了使目标函数最小,可以令导数为0,可以求得最优的w,将w带入目标函数,可以得到最终的损失为: w j ∗ = − G j H j + λ , l o s s ∗ = 1 2 ∑ j = 1 T G j 2 H j + λ + γ T {{w}_{j}}*=-\frac{{{G}_{j}}}{{{H}_{j}}+\lambda },loss*=\frac{1}{2}\sum\limits_{j=1}^{T}{\frac{{{G}_{j}}^{2}}{{{H}_{j}}+\lambda }}+\gamma T wj=Hj+λGj,loss=21j=1THj+λGj2+γT

在这里插入图片描述

2.2 学习策略

当树的结构确定的时候,我们可以得到最优的叶子点分数以及对应的最小损失值,问题在于如何确定树结构?

  • 暴力穷举所有可能的结构,选择损失值最小的;(很难求解)
    • 贪心法,每次尝试选择一个分裂点进行分裂,计算操作前后的增益,选择增益最大的方式进行分裂。

决策树相关算法计算指标:

  • ID3算法:信息增益
  • C4.5算法:信息增益率
  • CART算法:Gini系数

XGBoost目标函数: l o s s ∗ = 1 2 ∑ j = 1 T G j 2 H j + λ + γ T loss*=\frac{1}{2}\sum\limits_{j=1}^{T}{\frac{{{G}_{j}}^{2}}{{{H}_{j}}+\lambda }}+\gamma T loss=21j=1THj+λGj2+γT

  • 从目标函数中,我们希望损失函数越小越好,那就是 G j 2 H j + λ \frac{{{G}_{j}}^{2}}{{{H}_{j}}+\lambda } Hj+λGj2越大越好;从而,对于一个叶子节点的分裂的分裂,分裂前后的信息增益定义为:
    G a i n = 1 2 [ G L 2 H L + λ + G R 2 H R + λ − ( G L + G R ) 2 ( H L + H R ) + λ ] − γ Gain=\frac{1}{2}[\frac{{{G}_{L}}^{2}}{{{H}_{L}}+\lambda }+\frac{{{G}_{R}}^{2}}{{{H}_{R}}+\lambda }-\frac{{{({{G}_{L}}+{{G}_{R}})}^{2}}}{({{H}_{L}}+{{H}_{R}})+\lambda }]-\gamma Gain=21[HL+λGL2+HR+λGR2(HL+HR)+λ(GL+GR)2]γ
    Gain值越大,分裂后减少的损失值越大。所以对于一个叶子节点分割时,计算所有候选的(feature,value)对应的gain,选择gain最大特征进行分割。
    在这里插入图片描述

2.3 树节点分裂方法

  1. 精确算法: 遍历所有特征的所有可能的分割点,计算gain值,选择最大的gain值对应的(feature,value)进行分割
    在这里插入图片描述
  2. 近似算法: 对于每个特征,只考虑分位点,减少计算复杂度

在这里插入图片描述

近似算法案例:三分位数
在这里插入图片描述
G a i n = max ⁡ { 1 2 [ G 1 2 H 1 + λ + G 23 2 H 23 + λ − ( G 123 ) 2 ( H 123 ) + λ ] − γ , G 3 2 H 3 + λ + G 12 2 H 12 + λ − ( G 123 ) 2 ( H 123 ) + λ ] − γ } Gain=\max \{\frac{1}{2}[\frac{{{G}_{1}}^{2}}{{{H}_{1}}+\lambda }+\frac{{{G}_{23}}^{2}}{{{H}_{23}}+\lambda }-\frac{{{({{G}_{123}})}^{2}}}{({{H}_{123}})+\lambda }]-\gamma ,\frac{{{G}_{3}}^{2}}{{{H}_{3}}+\lambda }+\frac{{{G}_{12}}^{2}}{{{H}_{12}}+\lambda }-\frac{{{({{G}_{123}})}^{2}}}{({{H}_{123}})+\lambda }]-\gamma \} Gain=max{21[H1+λG12+H23+λG232(H123)+λ(G123)2]γ,H3+λG32+H12+λG122(H123)+λ(G123)2]γ}

2.4 XGBoost树节点划分方法

XGBoost不是简单的按照样本个数进行分位的,而是按照上一轮的预测误差函数的二阶导数值作为权重来进行划分的:
在这里插入图片描述

2.5 其它特性

列采样(column subsampling):借鉴随机森林的做法,支持列抽样,不仅可以降低过拟合,还可以减少计算量;
• 支持对缺失值的自动处理。对于特征的值有缺失的样本,XGBoost可以自动学习分裂方向;
• XGBoost支持并行。XGBoost的并行是特征粒度上的,在计算特征的Gain的时候,会并行执行,但是在树的构建过程中,还是串行构建的
• XGBoost算法中加入正则项,用于控制模型的复杂度,最终模型更加不容易过拟合;
• XGBoost基学习器支持CART、线性回归、逻辑回归;
• XGBoost支持自定义损失函数(要求损失函数二阶可导)。

2.6 XGBoost相关参数

在这里插入图片描述

参考链接:
https://xgboost.readthedocs.io/en/latest/python/python_api.html
https://xgboost.readthedocs.io/en/latest/parameter.html

3. LightGBM(后续补充)

4. 结合策略

学习器的结合可能会从三个方面带来好处:

  1. 统计的方面来看,由于学习任务的假设空间往往很大,可能有多个假设在训练集上达到同等性能,此时若使用单学习器可能因误选而导致泛化性能不佳,结合多个学习器则会减小这一风险;
  2. 计算的方面来看,学习算法往往会陷入局部极小,有的局部极小点所对应的泛化性能可能很糟糕,而通过多次运行之后进行结合,可降低陷入糟糕局部极小点的风险;
  3. 表示的方面来看,某些学习任务的真实假设可能不在当前学习算法所考虑的假设空间中,此时若使用单学习器则肯定无效,而通过结合多个学习器,由于相应的假设空间所有扩大,有可能学得更好的近似。
    在这里插入图片描述
    假定集成包含 T T T个基学习器    ⁣ ⁣ {  ⁣ ⁣   h 1 , h 2 , . . . h T    ⁣ ⁣ }  ⁣ ⁣   \text{ }\!\!\{\!\!\text{ }{{h}_{1}},{{h}_{2}},...{{h}_{T}}\text{ }\!\!\}\!\!\text{ }  { h1,h2,...hT } ,其中 h i {{h}_{i}} hi在示例x上的输出为 h i ( x ) {{h}_{i}}(x) hi(x)

4.1 平均法

对数值型输出 h i ( x ) ∈ R {{h}_{i}}(x)\in \mathbb{R} hi(x)R,最常见的结合策略是使用平均法(averaging)

  • 简单平均法(simple averaging)
    H ( x ) = 1 T ∑ i = 1 T h i ( x ) H(x)=\frac{1}{T}\sum\limits_{i=1}^{T}{{{h}_{i}}(x)} H(x)=T1i=1Thi(x)
  • 加权平均法(weighted averaging)
    H ( x ) = ∑ i = 1 T w i h i ( x ) H(x)=\sum\limits_{i=1}^{T}{{{w}_{i}}{{h}_{i}}(x)} H(x)=i=1Twihi(x)
    其中 w i {{w}_{i}} wi是个体学习器 h i {{h}_{i}} hi的权重,通常要求 w i ≥ 0 , ∑ i = 1 T w i = 1 {{w}_{i}}\ge 0,\sum\limits_{i=1}^{T}{{{w}_{i}}}=1 wi0,i=1Twi=1

Stacking回归必须使用非负权重才能确保集成性能优于单一最佳个体学习器,因此在集成学习中一般对学习器的权重施以非负约束。

显然,简单平均法是加权平均法令 w i = 1 / T {{w}_{i}}=1/T wi=1/T的特例,集成学习中的各种结合方法都可视为其特例或变体。事实上,加权平均法可认为是集成学习研究的基本出发点,对给定的基学习器,不同的集成学习方法可视为通过不同的方式来确定加权平均法中的基学习器权重。

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

4.2 投票法

对分类任务来说,学习器 h i {{h}_{i}} hi将从类别标记集合    ⁣ ⁣ {  ⁣ ⁣   c 1 , c 2 , . . . , c N    ⁣ ⁣ }  ⁣ ⁣   \text{ }\!\!\{\!\!\text{ }{{c}_{1}},{{c}_{2}},...,{{c}_{N}}\text{ }\!\!\}\!\!\text{ }  { c1,c2,...,cN } 中预测出一个标记,最常见的结合策略是使用投票法(voting)。并将 h i {{h}_{i}} hi在样本 x x 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上的输出。

  • 绝对多数投票法(majority voting)
    H ( x ) = { c j i f ∑ i = 1 T h i j ( x ) > 0.5 ∑ k = 1 T ∑ i = 1 T h i k ( x ) r e j e c t o t h e r w i s e H(x)=\left\{ \begin{matrix} {{c}_{j}} & if\sum\limits_{i=1}^{T}{h_{i}^{j}(x)}>0.5\sum\limits_{k=1}^{T}{\sum\limits_{i=1}^{T}{h_{i}^{k}(x)}} \\ reject & otherwise \\ \end{matrix} \right. H(x)= cjrejectifi=1Thij(x)>0.5k=1Ti=1Thik(x)otherwise
    即若某标记得票过半数,则预测为该标记;否则拒绝预测。
  • 相对多数投票法(plurality voting)
    H ( x ) = c arg ⁡ max ⁡ j   ∑ i = 1 T h i j ( x ) H(x)={{c}_{\underset{j}{\mathop{\arg \max }}\,\sum\limits_{i=1}^{T}{h_{i}^{j}(x)}}} H(x)=cjargmaxi=1Thij(x)
    即预测为得票最多的标记,若同时有多个标记获得最高票,则从中随机选取一个。
  • 加权投票法(weighted voting)
    H ( x ) = c arg ⁡ max ⁡ j   ∑ i = 1 T w i h i j ( x ) H(x)={{c}_{\underset{j}{\mathop{\arg \max }}\,\sum\limits_{i=1}^{T}{{{w}_{i}}h_{i}^{j}(x)}}} H(x)=cjargmaxi=1Twihij(x)
    与加权平均法类似, w i {{w}_{i}} wi h i {{h}_{i}} hi的权重,通常 w i ≥ 0 , ∑ i = 1 T w i = 1 {{w}_{i}}\ge 0,\sum\limits_{i=1}^{T}{{{w}_{i}}}=1 wi0,i=1Twi=1

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

多数投票法的英文文献术语使用不太一致,有的称为“majority voting”,也有直接称为“voting

上述方法没有限制个体学习器输出值的类型,在现实任务中,不同类型个体学习器可能产生不同类型的 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将样本预测为类别 c j {{c}_{j}} cj则取值为1,否则为0,使用类标记的投票亦称硬投票(hard voting)
  • 类概率: 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(cjx)的一个估计。使用类概率的投票亦称软投票(soft voting)

不同类型的 h i j ( x ) h_{i}^{j}(x) hij(x)值不能混用。对一些能在预测出类别标记的同时产生分类置信度的学习器,其分类置信度可转换为类概率使用。虽然分类器估计出的类概率一般都不太准确,但基于类概率进行结合却往往比直接基于类标记进行结合性能更好。若基学习器的类型不同,则其类概率值不能直接进行比较;在这种情况下,通常将类概率输出转化为类标记输出然后再投票。

4.3 学习法 —— Stacking

Stacking安装:
pip install mlxtend
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple mlxtend

当训练数据很多时,一种更为强大的结合策略是使用“学习法”,即通过另一个学习器来进行结合;Stacking是学习法的典型代表——个体学习器称为初级学习器,用于结合的学习器称为次级学习器元学习器(meta-learner)

4.3.1 概述

Stacking(有时候也称之为stacked generalization)是指训练一个模型用于组合 (combine)其他各个模型。即首先我们先训练多个不同的模型,然后再以之前训练的各个模型的输出为输入来训练一个模型,以得到一个最终的输出。

如果可以选用任意一个组合算法,那么理论上,Stacking可以表示前面提到的各种Ensemble方法。然而,实际中,我们通常使用单层logistic回归作为组合模型。

注意:Stacking有两层,一层是不同的基学习器(classifiers/regressors)(特征提取-高阶特征),第二个是用于组合基学习器的元学习器(meta_classifier/meta_regressor)——基学习器的输出当做元学习器的输入

• 直观理解(五折交叉验证)
在这里插入图片描述
图中上半部分是用一个基础模型进行5折交叉验证,如:用XGBoost作为基础模型Model1,5折交叉验证就是先拿出四折作为training learn(蓝色部分),另外一折作为testing predict(橙色部分)。注意:在stacking中此部分数据会用到整个traing data。如:假设我们整个training data包含10000行数据,testing data包含2500行数据,那么每一次交叉验证其实就是对training data进行划分,在每一次的交叉验证中training learn将会是8000行,testing predict是2000行。

每一次的交叉验证包含两个过程:

  1. 基于training learn训练模型;
  2. 基于training learn训练生成的模型对testing predict进行预测。在整个第一次的交叉验证完成之后我们将会得到关于当前testing predict的预测值,这将会是一个一维2000行的数据,记为a1。注意:在这部分操作完成后,我们还要对数据集原来的整个testing data进行预测,这个过程会生成2500个预测值,这部分预测值将会作为下一层模型testing data的一部分,记为b1(绿色部分)。因为我们进行的是5折交叉验证,所以以上提及的过程将会进行五次,最终会生成针对testing data数据预测的5列2000行的数据a1,a2,a3,a4,a5,对testing set的预测会是5列2500行数据b1,b2,b3,b4,b5。

在完成对Model1的整个步骤之后,我们可以发现a1,a2,a3,a4,a5其实就是对原来整个training data的预测值,将他们拼凑起来,会形成一个10000行一列的矩阵,记为A1。而对于b1,b2,b3,b4,b5这部分数据,我们将各部分相加取平均值,得到一个2500行一列的矩阵,记为B1。

以上就是stacking中一个模型的完整流程,stacking中同一层通常包含多个模型,假设还有Model2: LR,Model3:RF,Model4: GBDT,Model5:SVM,对于这四个模型,我们可以重复以上的步骤,在整个流程结束之后,我们可以得到新的A2,A3,A4,A5,B2,B3,B4,B5矩阵。

在此之后,我们把A1,A2,A3,A4,A5并列合并得到一个10000行五列的矩阵作为新的training data,B1,B2,B3,B4,B5并列合并得到一个2500行五列的矩阵作为新的testing data。让下一层的模型(元学习器),基于他们进一步训练。

4.3.2 训练阶段

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 = D / D j {{{\bar{D}}}_{j}}=D/{{D}_{j}} Dˉj=D/Dj分别表示第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 2 ; . . . ; z i T ) {{z}_{i}}\text{=(}{{z}_{i1}};{{z}_{i2}};...;{{z}_{iT}}\text{)} zi=(zi1;zi2;...;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 ′ D' D将用于训练次级学习器。

4.3.3 预测阶段

在这里插入图片描述
次级学习器的输入属性表现和次级学习算法对Stacking集成的泛化性能有很大影响,有研究表明,将初级学习器的输出类概率作为次级学习器的输入属性,用多响应线性回归(Multi-response Linear Regression,简称MLR)作为次级学习算法效果较好,在MLR中使用不同属性集更加。

MLR是基于线性回归的分类器,它对每个类分别进行线性回归,属于该类的训练样例所对应的输出被置为1,其他类置为0;测试示例将被分给输出值最大的类。

4.3.4 stacking API

StackingClassifier(classifiers, meta_classifier, use_probas=False, average_probas=False, verbose=0, use_features_in_secondary=False)
参数:
• classifiers : 基分类器,数组形式,[cl1, cl2, cl3]. 每个基分类器的属性被存储在类属性 self.clfs_.
• meta_classifier : 目标分类器,即将前面分类器合起来的分类器
• use_probas : bool (default: False) ,如果设置为True, 那么目标分类器的输入就是前面分类输出的类别概率值而不是类别标签
• average_probas : bool (default: False),用来设置上一个参数当使用概率值输出的时候是否使用平均值。
• verbose : int, optional (default=0)。用来控制使用过程中的日志输出,当 verbose = 0时,什么也不输出, verbose = 1,输出回归器的序号和名字。verbose = 2,输出详细的参数信息。verbose > 2, 自动将verbose设置为小于等于2的,verbose -2.
• use_features_in_secondary : bool (default: False). 如果设置为True,那么最终的目标分类器就被基分类器产生的数据和最初的数据集同时训练。如果设置为False,最终的分类器只会使用基分类器产生的数据训练。
属性:
• clfs_ : 每个基分类器的属性,list, shape 为 [n_classifiers]。
• meta_clf_ : 最终目标分类器的属性
方法:
• fit(X, y)
• fit_transform(X, y=None, fit_params)
• get_params(deep=True),如果是使用sklearn的GridSearch方法,那么返回分类器的各项参数。
• predict(X)
• predict_proba(X)
• score(X, y, sample_weight=None), 对于给定数据集和给定label,返回评价accuracy
• set_params(params),设置分类器的参数,params的设置方法和sklearn的格式一样
注: 回归的API StackingRegressor(regressors, meta_regressor) 基本类似

4.3.5 Stacking项目案例应用

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl

mpl.rcParams['font.sans-serif'] = [u'simHei']

import time

from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline

from mlxtend.classifier import StackingClassifier

from mlxtend.feature_selection import ColumnSelector

###1、读取数据
datas = pd.read_csv('iris.data', sep=',', header=None, names=['X1', 'X2', 'X3', 'X4', 'Y'])
# print(datas.head())
# print(datas.info())

### 2、数据清洗

### 3、获取特征属性X和目标属性Y
X = datas.iloc[:, :-1]
Y = datas.iloc[:, -1]
# print(X.shape)
# print(Y.shape)
# print(Y.value_counts())  ##看下目标属性的值

# LabelEncoder  0,1, 2
labelencoder = LabelEncoder()
# print(Y.ravel())
Y = labelencoder.fit_transform(Y)
# print(Y)

### 4、分割数据集
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=28)
# print(x_train.shape)
# print(y_train.shape)

### 5、特征工程

### 模型构建
# a、构造基学习器 knn、RF、softmax、GBDT。。。。
knn = KNeighborsClassifier(n_neighbors=7)
softmax = LogisticRegression(C=0.1, solver='lbfgs', multi_class='multinomial', fit_intercept=False)
gbdt = GradientBoostingClassifier(learning_rate=0.1, n_estimators=100, max_depth=3)
rf = RandomForestClassifier(max_depth=5, n_estimators=150)

# b、元学习器
lr = LogisticRegression(C=0.1, solver='lbfgs', multi_class='multinomial')

### stacking学习器
'''
1、最基本的使用方法,用前面基学习器的输出作为元学习器的输入
2、使用基学习器的输出类别的概率值作为元学习器输入,use_probas=True,若average_probas=True,那么这些基分类器对每一个类别产生的概率进行平均,否者直接拼接
 classifier1  = [0.2,0.5,0.3]
 classifier2  = [0.3,0.3,0.4]
  average_probas=True: [0.25,0.4,0.35]
  average_probas=Flase: [0.2,0.5,0.3,0.3,0.3,0.4]
  
3、对训练集中的特征维度进行操作,每次训练不同的基学习器的时候用不同的特征,比如我再训练KNN的时候只用前两个特征,训练RF的时候用其他的几个特征
    通过pipline来实现
'''
'''
classifiers, 基学习器
meta_classifier, 元学习器
use_probas=False, 
drop_last_proba=False,
average_probas=False, 
verbose=0,
use_features_in_secondary=False,
store_train_meta_features=False,
use_clones=True
'''

###方式一
stacking01 = StackingClassifier(classifiers=[knn, softmax, gbdt, rf],
                                meta_classifier=lr)

###方式二
stacking02 = StackingClassifier(classifiers=[knn, softmax, gbdt, rf],
                                meta_classifier=lr,
                                use_probas=True,
                                average_probas=False)

###方式三
# 基学习器
pipe_knn = Pipeline([('x', ColumnSelector([0, 1])),
                     ('knn', knn)])
pipe_softmax = Pipeline([('x', ColumnSelector([2, 3])),
                         ('softmax', softmax)])
pipe_rf = Pipeline([('x', ColumnSelector([0, 3])),
                    ('rf', rf)])
pipe_gbdt = Pipeline([('x', ColumnSelector([1, 2])),
                      ('gbdt', gbdt)])
##stacking
stacking03 = StackingClassifier(classifiers=[pipe_knn, pipe_softmax, pipe_rf, pipe_gbdt],
                                meta_classifier=lr)
                                
###模型训练与比较
scores_train = []
scores_test = []
models = []
times = []

for clf, modelname in zip([knn, softmax, gbdt, rf, stacking01, stacking02, stacking03],
                          ['knn', 'softmax', 'gbdt', 'rf', 'stacking01', 'stacking02', 'stacking03']):
    print('start:%s' % (modelname))
    start = time.time()
    clf.fit(x_train, y_train)
    end = time.time()
    print('耗时:{}'.format(end - start))
    score_train = clf.score(x_train, y_train)
    score_test = clf.score(x_test, y_test)
    scores_train.append(score_train)
    scores_test.append(score_test)
    models.append(modelname)
    times.append(end - start)
print('scores_train:', scores_train)
print('scores_test', scores_test)
print('models:', models)
print('开始画图----------')
plt.figure(num=1)
plt.plot([0, 1, 2, 3, 4, 5, 6], scores_train, 'r', label=u'训练集')
plt.plot([0, 1, 2, 3, 4, 5, 6], scores_test, 'b', label=u'测试集')
plt.title(u'鸢尾花数据不同分类器准确率比较', fontsize=16)
plt.xticks([0, 1, 2, 3, 4, 5, 6], models, rotation=0)
plt.legend(loc='lower left')
plt.figure(num=2)
plt.plot([0, 1, 2, 3, 4, 5, 6], times)
plt.title(u'鸢尾花数据不同分类器训练时间比较', fontsize=16)
plt.xticks([0, 1, 2, 3, 4, 5, 6], models, rotation=0)
plt.legend(loc='lower left')
plt.show()

在这里插入图片描述

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
import time
from sklearn.model_selection import train_test_split


from mlxtend.regressor import StackingRegressor
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Ridge
from sklearn.svm import SVR
from sklearn.neighbors import KNeighborsRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import GridSearchCV

mpl.rcParams['font.sans-serif'] = [u'simHei']

# 1. 加载数据(数据一般存在于磁盘或者数据库)
path = 'household_power_consumption_1000_2.txt'
df = pd.read_csv(path, sep=';')

# 2. 数据清洗
df.replace('?', np.nan, inplace=True)
df = df.dropna(axis=0, how='any')

# 3. 根据需求获取最原始的特征属性矩阵X和目标属性Y
def date_format(dt):
    date_str = time.strptime(' '.join(dt), '%d/%m/%Y %H:%M:%S')
    return [date_str.tm_year, date_str.tm_mon, date_str.tm_mday, date_str.tm_hour, date_str.tm_min, date_str.tm_sec]

X = df.iloc[:, 0:2]
X = X.apply(lambda row: pd.Series(date_format(row)), axis=1)
Y = df.iloc[:, 4].astype(np.float32)

# 4. 数据分割
x_train, x_test, y_train, y_test = train_test_split(X, Y, train_size=0.8, random_state=28)
print("训练数据X的格式:{}, 以及类型:{}".format(x_train.shape, type(x_train)))
print("测试数据X的格式:{}".format(x_test.shape))
print("训练数据Y的类型:{}".format(type(y_train)))

##初始化基模型
linear  = LinearRegression(fit_intercept=True)
ridge = Ridge(alpha=0.1)
knn = KNeighborsRegressor(weights='distance')
rf = RandomForestRegressor(n_estimators=100,max_depth=3)

##组合模型/元模型
svr_rbf = SVR(kernel='rbf',gamma=0.1,C=0.1)
###stacking
stackingreg = StackingRegressor(regressors=[linear,ridge,knn,rf],meta_regressor=svr_rbf)



# params = {'linearregression__fit_intercept': [True,False],
#           'ridge__alpha': [0.01,0.1, 1.0, 10.0],
#           'kneighborsregressor__n_neighbors':[1,3,5,7,9],
#           'randomforestregressor__n_estimators':[50,100,150],
#           'randomforestregressor__max_depth':[1,3,5,7,9],
#           'meta_regressor__C': [0.1, 1.0, 10.0],
#           'meta_regressor__gamma': [0.1, 1.0, 10.0]}
#

# grid = GridSearchCV(estimator=stackingreg,
#                     param_grid=params,
#                     cv=5,
#                     refit=True)
# print(stackingreg.get_params().keys())
# """
#
# """
# # import sys
# # sys.exit(0)
# grid.fit(x_train, y_train)
# print("最优参数:{}".format(grid.best_params_))
""""

"""
# print("最优参数对应的最优模型:{}".format(grid.best_estimator_))
# print("最优模型对应的这个评估值:{}".format(grid.best_score_))

# ## 网格调参后进行训练
stackingreg.fit(x_train,y_train)
print(stackingreg.score(x_train,y_train))
print(stackingreg.score(x_test,y_test))

# ###画图展示
y_hat = stackingreg.predict(x_test)
plt.plot(range(len(x_test)),y_test,'r',label=u'真实值')
plt.plot(range(len(x_test)),y_hat,'b',label=u'测试值')
plt.legend()
plt.title('时间和电压回归预测')
plt.show()

在这里插入图片描述

4.3.6 总结

贝叶斯模型平均(Bayes Model Averaging,简称BMA)基于后验概率来为不同模型赋予权重,可视为加权平均的一种特殊实现。

理论上来说,若数据生成模型恰在当前考虑的模型中,且数据噪声很少,则BMA不差于Stacking;然而,在现实应用中午饭确保数据生成模型一定在当前考虑的模型中,甚至可能难以用当前考虑的模型来进行近似,因此,Stacking通常由于BMA,因为其鲁棒性比BMA更好,而且BMA对模型近似误差非常敏感。

5. 多样性

5.1 误差-分歧分解

预构建泛化能力强的集成,个体学习器应“好而不同”。

  • 假定用个体学习器: h 1 , h 2 , . . . , h T {{h}_{1}},{{h}_{2}},...,{{h}_{T}} h1,h2,...,hT通过加权平均法结合产生的集成来完成回归学习任务 f : R d → R f:{{\mathbb{R}}^{d}}\to \mathbb{R} f:RdR,对示例 x x x,定义学习器 h i {{h}_{i}} hi分歧(ambiguity)为: A ( h i ∣ x ) = ( h i ( x ) − H ( x ) ) 2 A({{h}_{i}}|x)={{({{h}_{i}}(x)-H(x))}^{2}} A(hix)=(hi(x)H(x))2,则集成的分歧为: A ˉ ( h ∣ x ) = ∑ i = 1 T w i A ( h i ∣ x ) = ∑ i = 1 T w i ( h i ( x ) − H ( x ) ) 2 \bar{A}(h|x)=\sum\limits_{i=1}^{T}{{{w}_{i}}A({{h}_{i}}|x)}=\sum\limits_{i=1}^{T}{{{w}_{i}}{{({{h}_{i}}(x)-H(x))}^{2}}} Aˉ(hx)=i=1TwiA(hix)=i=1Twi(hi(x)H(x))2

  • 显然这里的分歧项表征了个体学习器在样本 x x x上的不一致性,即在一定程度上反应了个体学习器的多样性。个体学习器 h i {{h}_{i}} hi和集成 H H H的平方误差分别为: E ( h i ∣ x ) = ( f ( x ) − h i ( x ) ) 2 E({{h}_{i}}|x)={{(f(x)-{{h}_{i}}(x))}^{2}} E(hix)=(f(x)hi(x))2, E ( H ∣ x ) = ( f ( x ) − H ( x ) ) 2 E(H|x)={{(f(x)-H(x))}^{2}} E(Hx)=(f(x)H(x))2

  • E ˉ ( h ∣ x ) = ∑ i = 1 T w i E ( h i ∣ x ) \bar{E}(h|x)=\sum\limits_{i=1}^{T}{{{w}_{i}}E({{h}_{i}}|x)} Eˉ(hx)=i=1TwiE(hix),表示个体学习器误差的加权均值,有 A ˉ ( h ∣ x ) = ∑ i = 1 T w i E ( h i ∣ x ) − E ( H ∣ x ) = E ˉ ( h ∣ x ) − E ( H ∣ x ) \bar{A}(h|x)=\sum\limits_{i=1}^{T}{{{w}_{i}}E({{h}_{i}}|x)}-E(H|x)=\bar{E}(h|x)-E(H|x) Aˉ(hx)=i=1TwiE(hix)E(Hx)=Eˉ(hx)E(Hx),对所有样本 x x x均成立,令 p ( x ) p(x) p(x)表示样本的概率密度,则在全样本上有:
    ∑ i = 1 T w i ∫ A ( h i ∣ x ) p ( x ) d x = ∑ i = 1 T w i ∫ E ( h i ∣ x ) p ( x ) d x − ∫ E ( H ∣ x ) p ( x ) d x \sum\limits_{i=1}^{T}{{{w}_{i}}\int{A({{h}_{i}}|x)p(x)dx}}=\sum\limits_{i=1}^{T}{{{w}_{i}}\int{E({{h}_{i}}|x)p(x)dx}}-\int{E(H|x)p(x)dx} i=1TwiA(hix)p(x)dx=i=1TwiE(hix)p(x)dxE(Hx)p(x)dx

  • 个体学习器 h i {{h}_{i}} hi在全样本上的泛化误差和分歧项分别为: E i = ∫ E ( h i ∣ x ) p ( x ) d x , A i = ∫ A ( h i ∣ x ) p ( x ) d x {{E}_{i}}=\int{E({{h}_{i}}|x)p(x)dx},{{A}_{i}}=\int{A({{h}_{i}}|x)p(x)dx} Ei=E(hix)p(x)dx,Ai=A(hix)p(x)dx E i , A i {{E}_{i}},{{A}_{i}} Ei,Ai简化表示 E ( h i ) , A ( h i ) E({{h}_{i}}),A({{h}_{i}}) E(hi),A(hi)

  • 集成的泛化误差为: E = ∫ E ( H ∣ x ) p ( x ) d x E=\int{E(H|x)p(x)dx} E=E(Hx)p(x)dx E E E简化表示 E ( H ) E(H) E(H)

  • E ˉ = ∑ i = 1 T w i E i \bar{E}=\sum\limits_{i=1}^{T}{{{w}_{i}}{{E}_{i}}} Eˉ=i=1TwiEi表示个体学习器泛化误差的加权均值, A ˉ = ∑ i = 1 T w i A i \bar{A}=\sum\limits_{i=1}^{T}{{{w}_{i}}{{A}_{i}}} Aˉ=i=1TwiAi表示个体学习器的加权分歧值,有: E = E ˉ − A ˉ E=\bar{E}-\bar{A} E=EˉAˉ——个体学习器准确性越高,多样性越大,则集成越好——误差-分歧分解(error-ambiguity decomposition)

在现实任务中很难直接对 E ˉ − A ˉ \bar{E}-\bar{A} EˉAˉ进行优化——定义在整个样本空间上,且由于 A ˉ {\bar{A}} Aˉ不是一个可直接操作的多样性度量,仅在集成构造好后之后才能进行估计。

上述推导过程只适用于回归学习,难以直接推广到分类学习任务中。

5.2 多样性度量

多样性度量(diversity measure),亦称差异性度量,是用于度量集成中个体分类器的多样性,即估算个体学习器的多样化程度。典型做法是考虑个体分类器的两两相似/不相似性

给定数据集 D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x m , y m ) } D=\{({{x}_{1}},{{y}_{1}}),({{x}_{2}},{{y}_{2}}),...,({{x}_{m}},{{y}_{m}})\} D={(x1,y1),(x2,y2),...,(xm,ym)},对二分类任务 y i ∈ { − 1 , + 1 } {{y}_{i}}\in \{-1,+1\} yi{1,+1},分类器 h i {{h}_{i}} hi h j {{h}_{j}} hj预测结果列联表(contingency table)为:——类似混淆矩阵
在这里插入图片描述
其中,a表示 h i {{h}_{i}} hi h j {{h}_{j}} hj均预测为正类的样本数目;b、c、d含义由此类推;a+b+c+d=m。

常见的多样性度量

  • 不合度量(disagreement measure) d i s i j = b + c m di{{s}_{ij}}=\frac{b+c}{m} disij=mb+c d i s i j di{{s}_{ij}} disij的值域为[0,1]。值越大则多样性越大。
  • 相关系数(correlation coefficient) p i j = a d − b c ( a + b ) ( a + c ) ( c + d ) ( b + d ) {{p}_{ij}}=\frac{ad-bc}{\sqrt{(a+b)(a+c)(c+d)(b+d)}} pij=(a+b)(a+c)(c+d)(b+d) adbc p i j {{p}_{ij}} pij的值域为[-1,+1],若 h i {{h}_{i}} hi h j {{h}_{j}} hj无关,则值为0;若 h i {{h}_{i}} hi h j {{h}_{j}} hj正相关则值为正,否则为负;
  • Q-统计量(Q-statistic) Q i j = a d − b c a d + b c {{Q}_{ij}}=\frac{ad-bc}{ad+bc} Qij=ad+bcadbc, Q i j {{Q}_{ij}} Qij与相关系数 p i j {{p}_{ij}} pij的符号相同,且 ∣ Q i j ∣ ≥ ∣ p i j ∣ \left| {{Q}_{ij}} \right|\ge \left| {{p}_{ij}} \right| Qijpij
  • k-统计量(k-statistic) κ = p 1 − p 2 1 − p 2 \kappa \text{=}\frac{{{p}_{1}}-{{p}_{2}}}{1-{{p}_{2}}} κ=1p2p1p2,其中, p 1 {{p}_{1}} p1是两个分类器取得一致的概率; p 2 {{p}_{2}} p2是两个分类器偶然达成一致的概率,它们可由数据集D估算: p 1 = a + d m , p 2 = ( a + b ) ( a + c ) + ( c + d ) ( b + d ) m 2 {{p}_{1}}=\frac{a+d}{m},{{p}_{2}}=\frac{(a+b)(a+c)+(c+d)(b+d)}{{{m}^{2}}} p1=ma+d,p2=m2(a+b)(a+c)+(c+d)(b+d),若分类器 h i {{h}_{i}} hi h j {{h}_{j}} hj在D上完全一致,则k=1;若它们仅是偶然达成一致,则k=0;k通常为非负值,仅在 h i {{h}_{i}} hi h j {{h}_{j}} hj达成一致的概率甚至低于偶然性的情况下取负值。

以上都是成对型(pairwise)多样性度量,它们可以通过二维图绘制出来——数据点云的位置越高,则个体分类器准确性越低;点云的位置越靠右,则个体学习器的多样性越小;
在这里插入图片描述

5.3 多样性增强

在集成学习中需有效地生成多样性大的个体学习器,与简单地直接用初始数据训练出个体学习器相比,如何增强个体多样性?

在学习过程中引入随机性——对数据样本、输入属性、输出表示、算法参数进行扰动。

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

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

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

4. 算法参数扰动
基学习算法一般都有参数需进行设置,例如神经网络的隐层神经元数、初始连接权值等,通过随机设置不同的参数,往往可产生差别较大的个体学习器。——负相关法(Negative Correlation)显式地通过正则化项来强制个体神经网络使用不同的参数;对参数较少的算法,可通过将其学习过程中的某些环节用其他类似方式代替,从而达到扰动的目的。——将决策树使用的属性选择机制替换为其他的属性选择机制——使用单一学习器时通常需使用交叉验证等方法来确定参数值,这事实上已经使用了不同参数训练出多个学习器,只不过最终选择其中一个学习器进行使用,而集成学习则相当于把这些学习器都利用起来——集成学习技术的实际计算开销并不比使用单一学习器大很多;

不同的多样性增强机制可同时使用——随机森林中同时使用了数据样本扰动和输入属性扰动,有些方法甚至同时使用了更多机制。

6. 补充

  • Boosting源于提出的“弱学习是否等价于强学习”这个重要理论问题的构造性证明——不同集成学习方法的工作机理和理论性质往往有显著不同,例如从偏差-方差分解的角度看,Boosting主要关注降低偏差,而Bagging主要关注与降低方差。MultiBoosting等方法尝试将二者的优点加以结合
  • 源于统计视角(statistical view)推导的AdaBoost,此派理论认为AdaBoost实质上是基于加性模型(additive model)以类似牛顿迭代法来优化指数损失函数,受此启发,用过将迭代优化过程替换为其他优化方法,产生了GradientBoosting、LPBoost等变体算法。然而这派理论产生的推论与AdaBoos的实际行为有相当大的差别,尤其是不能解释过拟合这个重要现象——为什么AdaBoost在训练误差达到零之后继续训练仍能提高泛化性能,若一直训练下去,过拟合最终仍会出现。 因此不少人认为,统计视角本身虽很有意义,但其阐释的是一个与AdaBoost相似的学习过程,而非AdaBoost本身。间隔理论(margin theory)能直观地解释这个重要现象,但最近的研究结果使它最终得以确立,并对新型学习方法的设计给出了启示。
  • 常见的几种结合方法还包括:基于D-S证据理论的方法动态分类器选择混合专家(mixture of experts)等。多样性度量都存在显著缺陷,如何理解多样性,被认为是集成学习中的圣杯问题。

专家混合: 输入被提供给网络,并且由每个单独的分类器进行评估。来自分类器的这些输出由相关门加权,其使用当前输入产生权重w,并且在层次结构中进一步传播。
在这里插入图片描述
在这里插入图片描述
训练该网络的最普遍的方法使使用EM算法

  • 在集成产生之后再试图通过去除一些个体学习器来获得较小的集成,称为集成修剪(ensemble pruning)。这有助于减小模型的存储开销和预测时间开销。早期研究主要针对序列化集成进行,减小集成规模后,常导致泛化性能下降;并行化集成进行修剪能在减小规模的同时提升泛化性能,并催化了基于优化的集成修剪技术。
  • 由于集成包含多个学习器,即便个体学习器有较好的可解释性,集成仍是黑箱模型,已有一些工作试图改善集成的可解释性,例如将集成转化为单模型、从集成中抽取符号规则等,这方面的研究衍生了能产生性能超越集成的单学习器的二次学习(twice-learning)技术——NeC4.5算法。可视化技术也对改善可解释性有一定的帮助。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LiongLoure

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值