深度剖析集成学习Adaboost

1 Adaboost

1.1 基本原理和参数概况

  • 通过对每次预测错或者残差较大的数据样本调整数据权值分布间接影响后续的评估器模型结果。
  • 实际上Adaboost除了在算法推到中和GBDT,Xgboost不同之外,还有是使用的基学习器和其他不同,在Adaboost中分类是DecisionTreeClassifier,回归是DecisionTreeRegressor两种弱学习器,其他boosting学习算法使用都是回归学习算法,再通过softmax或signomid函数转化成分类问题。

AdaBoost(Adaptive Boosting,自适应提升法)是当代boosting领域的开山鼻祖,它虽然不是首个实践boosting思想算法,却是首个成功将boosting思想发扬光大的算法。它的主要贡献在于实现了两个变化:

1、首次实现根据之前弱评估器的结果自适应地影响后续建模过程

2、在Boosting算法中,首次实现考虑全部弱评估器结果的输出方式

作为开山算法,AdaBoost的构筑过程非常简单:首先,在全样本上建立一棵决策树,根据该决策树预测的结果和损失函数值,增加被预测错误的样本在数据集中的样本权重,并让加权后的数据集被用于训练下一棵决策树。这个过程相当于有意地加重“难以被分类正确的样本”的权重,同时降低“容易被分类正确的样本”的权重,而将后续要建立的弱评估器的注意力引导到难以被分类正确的样本上。

在该过程中,上一棵决策树的的结果通过影响样本权重、即影响数据分布来影响下一棵决策树的建立,整个过程是自适应的。当全部弱评估器都被建立后,集成算法的输出 H ( x ) H(x) H(x)等于所有弱评估器输出值的加权平均,加权所用的权重也是在建树过程中被自适应地计算出来的。

在sklearn中,AdaBoost既可以实现分类也可以实现回归,我们使用如下两个类来调用它们:

class sklearn.ensemble.AdaBoostClassifier(base_estimator=None, *, n_estimators=50, learning_rate=1.0, algorithm=‘SAMME.R’, random_state=None)

class sklearn.ensemble.AdaBoostRegressor(base_estimator=None, *, n_estimators=50, learning_rate=1.0, loss=‘linear’, random_state=None)

AdaBoostClassifier
AdaBoostRegressor

不难发现,AdaBoost的参数非常非常少,在调用AdaBoost时我们甚至无需理解AdaBoost的具体求解过程。同时,ADB分类器与ADB回归器的参数也高度一致。在课程当中,我们将重点Boosting算法独有的参数,以及ADB分类与ADB回归中表现不一致的参数。

参数参数含义
base_estimator弱评估器
n_estimators集成算法中弱评估器的数量
learning_rate迭代中所使用的学习率
algorithm(分类器专属)用于指定分类ADB中使用的具体实现方法
loss(回归器专属)用于指定回归ADB中使用的损失函数
random_state用于控制每次建树之前随机抽样过程的随机数种子
sklearn.ensemble.AdaBoostClassifier(
    base_estimator=None,  # 自定义弱评估器,默认CART树
    n_estimators=50,  # 默认创建50棵树模型,小了欠拟合,大了过拟合
    learning_rate=1.0,  # 学习率
    algorithm="SAMME.R",
    # 个参数只有AdaBoostClassifier有。主要原因是scikit - learn实现了两种Adaboost分类算法,SAMM.E和SAMME.R。
    # 两者的主要区别是弱学习器权重的度量,SAMME使用了和我们的原理篇里二元分类Adaboost算法的扩展,即用对样本集分类效果作为弱学习器权重
    # 而SAMME.R使用了对样本集分类的预测概率大小来作为弱学习器权重。由于SAMME.R使用了概率度量的连续值,迭代一般比SAMME快
    # 因此AdaBoostClassifier的默认算法algorithm的值也是SAMME.R。我们一般使用默认的SAMME.R就够了,但是要注意的是使用了SAMME.R,
    # 则弱分类学习器参数base_estimator必须限制使用支持概率预测的分类器。SAMME算法则没有这个限制
    random_state=None,  # 随机起始点
)

sklearn.ensemble.AdaBoostRegressor(
    base_estimator=None,  # 基学习器
    n_estimators=50,  # 弱学习器的数量
    learning_rate=1.0,
    loss="linear",
    # 只有在回归模型中存在有线性‘linear’, 平方‘square’和指数 ‘exponential’三种选择
    # 代表每次对于预测误差较大的数据样本点的关注度,在经典adaboost中使用的是指数更新迭代权重,不过一般使用默认的linear足够
    random_state=None,
)

1.2 n_estimators和learning_rate

在Boosting集成方法中,集成算法的输出 H ( x ) H(x) H(x)往往都是多个弱评估器的输出结果的加权平均结果。但 H ( x ) H(x) H(x)并不是在所有树建好之后才统一加权求解的,而是在算法逐渐建树的过程当中就随着迭代不断计算出来的。例如,对于样本 x i x_i xi,集成算法当中一共有 T T T棵树(也就是参数n_estimators的取值),现在正在建立第 t t t个弱评估器,则第 t t t个弱评估器上 x i x_i xi的结果可以表示为 f t ( x i ) f_t(x_i) ft(xi)。假设整个Boosting算法对样本 x i x_i xi输出的结果为 H ( x i ) H(x_i) H(xi),则该结果一般可以被表示为 t = 1 − − > t = T t=1-->t=T t=1>t=T过程当中,所有弱评估器结果的加权求和:
H ( x i ) = ∑ t = 1 T ϕ t f t ( x i ) H(x_i) = \sum_{t=1}^T\phi_tf_t(x_i) H(xi)=t=1Tϕtft(xi)

其中, ϕ t \phi_t ϕt为第t棵树的权重。对于第 t t t次迭代来说,则有:

H t ( x i ) = H t − 1 ( x i ) + ϕ t f t ( x i ) H_t(x_i) = H_{t-1}(x_i) + \phi_tf_t(x_i) Ht(xi)=Ht1(xi)+ϕtft(xi)

在这个一般过程中,每次将本轮建好的决策树加入之前的建树结果时,可以在权重 ϕ \phi ϕ前面增加参数 η \color{red}\eta η,表示为第t棵树加入整体集成算法时的学习率,对标参数learning_rate

H t ( x i ) = H t − 1 ( x i ) + η ϕ t f t ( x i ) H_t(x_i) = H_{t-1}(x_i) + \boldsymbol{\color{red}\eta} \phi_tf_t(x_i) Ht(xi)=Ht1(xi)+ηϕtft(xi)

该学习率参数控制Boosting集成过程中 H ( x i ) H(x_i) H(xi)的增长速度,是相当关键的参数。当学习率很大时, H ( x i ) H(x_i) H(xi)增长得更快,我们所需的n_estimators更少,当学习率较小时, H ( x i ) H(x_i) H(xi)增长较慢,我们所需的n_estimators就更多,因此boosting算法往往会需要在n_estimators与learning_rate当中做出权衡.

1.3 参数algorithm与loss

1.3.1 algorithm

首先,参数algorithm是针对分类器设置的参数,其中备选项有"SAMME"与"SAMME.R"两个字符串。这两个字符串分别代表了两种不同的、实现AdaBoost分类的手段:AdaBoost-SAMME与AdaBoost-SAMME.R。两者在数学流程上的区别并不大,只不过SAMME是基于算法输出的具体分类结果(例如-1,1,2)进行计算,而SAMME.R则是在SAMME基础上改进过后、基于弱分配器输出的概率值进行计算,两种方法都支持在AdaBoost上完成多分类任务,但SAMME.R往往能够得到更好的结果,因此sklearn中的默认值是SAMME.R,因此sklearn中默认可以输入的base_estimators也需要是能够输出预测概率的弱评估器。实际在预测时,AdaBoost输出的 H ( x ) H(x) H(x)也针对于某一类别的概率

1.3.2 loss

分类loss


SAMME与SAMME.R使用了相同的损失函数:二分类指数损失(Exponential Loss Function)与多分类指数损失(Multi-class Exponential loss function)。

二分类指数损失——
L ( H ( x ) , y ) = e − y H ∗ ( x ) L(H(x),y) = e^{-yH^*(x)} L(H(x),y)=eyH(x)


其中 y y y为真实分类, H ∗ ( x ) H^*(x) H(x)则是从集成算法输出的概率结果 H ( x ) H(x) H(x)转换来的向量。

转换规则如下:

H ∗ ( x ) = { 1 i f   H ( x ) > 0.5 − 1 i f   H ( x ) < 0.5 H^*(x)= \begin{cases} 1& if \ H(x)>0.5 \\ -1& if\ H(x) < 0.5 \end{cases} H(x)={11if H(x)>0.5if H(x)<0.5
预测正确的损失就是 e − ( 1 × 1 ) e^{-(1\times1)} e(1×1),错误的就是 e − ( 1 × − 1 ) e^{-(1\times-1)} e(1×−1)
在sklearn当中,由于 H ( x ) H(x) H(x)是概率值,因此需要转换为 H ∗ ( x ) H^*(x) H(x),如果在其他实现AdaBoost的算法库中, H ( x ) H(x) H(x)输出直接为预测类别,则可以不执行转换流程。

多分类指数损失——

L ( H ( x ) , y ) = e x p ( − 1 K y ∗ ⋅ H ∗ ( x ) ) = e x p ( − 1 K ( y ∗ 1 H ∗ 1 ( x ) + y ∗ 2 H ∗ 2 ( x )   +   . . . + y ∗ k H ∗ k ( x ) ) ) \begin{aligned} L(H(x),y) &=exp \left( -\frac{1}{K}\boldsymbol{y^* · H^*(x)} \right) \\ & = exp \left( -\frac{1}{K}(y^{*1}H^{*1}(x)+y^{*2}H^{*2}(x) \ + \ ... + y^{*k}H^{*k}(x)) \right) \end{aligned} L(H(x),y)=exp(K1yH(x))=exp(K1(y1H1(x)+y2H2(x) + ...+ykHk(x)))
其中, K K K为总类别数,如四分类[0,1,2,3]的情况时, K = 4 K=4 K=4 y ∗ \boldsymbol{y^*} y H ∗ ( x ) \boldsymbol{H^*(x)} H(x)都是根据多分类具体情况、以及集成算法实际输出 H ( x ) H(x) H(x)转化出的向量,其中 y ∗ 1 y^{*1} y1 H ∗ 1 ( x ) H^{*1}(x) H1(x)的上标1都表示当前类别。
对一棵决策树我们会输出一个概率,K类就有K个树模型,对于boosting集成中的每一棵树,在任意样本上都会得到 f c = 0 ( x ) f^{c=0}(x) fc=0(x) f c = 1 ( x ) f^{c=1}(x) fc=1(x) f c = 2 ( x ) f^{c=2}(x) fc=2(x)……数个不同的结果。在集成算法当中,每个样本在第t次建树过程中,都会生成针对于不同类别的结果:

H t 0 ( x i ) = H t − 1 0 ( x i ) + ϕ t f t 0 ( x i ) H_{t}^0(x_i) = H_{t-1}^0(x_i) + \phi_tf_t^0(x_i) Ht0(xi)=Ht10(xi)+ϕtft0(xi)
H t 1 ( x i ) = H t − 1 1 ( x i ) + ϕ t f t 1 ( x i ) H_{t}^1(x_i) = H_{t-1}^1(x_i) + \phi_tf_t^1(x_i) Ht1(xi)=Ht11(xi)+ϕtft1(xi)
H t 2 ( x i ) = H t − 1 2 ( x i ) + ϕ t f t 2 ( x i ) H_{t}^2(x_i) = H_{t-1}^2(x_i) + \phi_tf_t^2(x_i) Ht2(xi)=Ht12(xi)+ϕtft2(xi)
… … …… ……
H t k ( x i ) = H t − 1 k ( x i ) + ϕ t f t k ( x i ) H_{t}^k(x_i) = H_{t-1}^k(x_i) + \phi_tf_t^k(x_i) Htk(xi)=Ht1k(xi)+ϕtftk(xi)

因此,我们可以得到向量 [ H 0 ( x ) , H 1 ( x ) , H 2 ( x ) , . . . , H k ( x ) ] [H^0(x),H^1(x),H^2(x),...,H^k(x)] [H0(x),H1(x),H2(x),...,Hk(x)],表示当前集成算法计算出的、针对多个类别的概率(也是对全部弱分类器输出的、针对多个类别的概率进行的加权求和)。针对该向量,一定可以得到向量中的一个最大值,该最大值所对应的标签类别就是多分类算法中的预测标签类别。根据该向量,以及指数损失的特性,我们规定:

H ∗ ( x ) = { 1 i f   k = a r g m a x H ( x ) − 1 K − 1 i f   k ≠ a r g m a x H ( x ) H^*(x)= \begin{cases} 1& if \ k = argmaxH(x) \\ -\frac{1}{K-1}& if\ k \neq argmaxH(x) \end{cases} H(x)={1K11if k=argmaxH(x)if k=argmaxH(x)

其中, a r g m a x H ( x ) argmaxH(x) argmaxH(x)对应的是预测标签, k k k为所有预选标签类别。因此,假设在4分类情况下,集成算法针对样本 i i i的各个分类输出的概率如下所示,则向量 H ∗ ( x ) \boldsymbol{H^*(x)} H(x)的取值如下所示:

类别 0 0 0 1 1 1 2 2 2 3 3 3
H t k ( x i ) H_t^k(x_i) Htk(xi) 0.1 0.1 0.1 0.2 0.2 0.2 0.2 0.2 0.2 0.5 0.5 0.5
H ∗ ( x ) H^*(x) H(x) − 1 3 -\frac{1}{3} 31 − 1 3 -\frac{1}{3} 31 − 1 3 -\frac{1}{3} 31 1 1 1

其中3就是当前集成算法针对样本 i i i预测的标签。

另外一方面, y ∗ \boldsymbol{y^*} y一般来说都是真实标签经过上述处理后的结果。同样是4分类器情况下,假设样本 i i i的真实标签为2,则向量 y ∗ \boldsymbol{y^*} y的构成如下所示:

用公式表示则有:
y ∗ = { 1 i f   k = y i − 1 K − 1 i f   k ≠ y i y^*= \begin{cases} 1& if \ k=y_i \\ -\frac{1}{K-1}& if\ k\neq y_i \end{cases} y={1K11if k=yiif k=yi

其中 y i y_i yi为样本的真实标签, k k k为所有预选标签类别。不难发现,在此规则下,此时向量 y ∗ \boldsymbol{y^*} y以及向量 H ∗ ( x ) \boldsymbol{H^*(x)} H(x)的和永远是0,因为向量内部总是1与(K-1)个 − 1 K − 1 -\frac{1}{K-1} K11相加。

0 0 0 1 1 1 2 2 2 3 3 3
y ∗ \boldsymbol{y^*} y − 1 3 -\frac{1}{3} 31 − 1 3 -\frac{1}{3} 31 1 1 1 − 1 3 -\frac{1}{3} 31

对于上述的这个例子多分类的loss就是:
L ( H ( x ) , y ) = exp ⁡ ( − 1 4 ( ( − 1 3 × − 1 3 ) + ( − 1 3 × − 1 3 ) + ( − 1 3 × 1 ) + ( − 1 3 × 1 ) ) ) L(H(x), y)=\exp \left(-\frac{1}{4}\left((-\frac{1}{3} \times-\frac{1}{3})+(-\frac{1}{3} \times-\frac{1}{3})+(-\frac{1}{3} \times 1)+(-\frac{1}{3} \times 1)\right)\right) L(H(x),y)=exp(41((31×31)+(31×31)+(31×1)+(31×1)))

回归loss


与分类的情况完全相反,在AdaBoost回归当中,我们能够使用的算法是唯一的,即AdaBoost.R2,但是在R2算法下,我们却可以选择三种损失函数,分别是"linear"(线性),“square”(平方),“exponential”(指数)。

在算法AdaBoost.R2当中,三种损失函数如下定义:

首先:
D = s u p ∣ H ( x i ) − y i ∣ , i = 1 , 2 , . . . , N D = sup|H(x_i) - y_i|, i = 1,2,...,N D=supH(xi)yi,i=1,2,...,N

其中 y i y_i yi为真实标签, H ( x i ) H(x_i) H(xi)为预测标签,sup表示“取最大值”,但它与直接写作max的函数的区别在于,max中的元素已是固定的数值,而sup中的元素可以是一个表达式、并让该表达式在i的备选值中循环。上述式子表示,取出1~N号样本中真实值与预测值差距最大的那一组差异来作为D的值。

R2算法线性损失——

L i = ∣ H ( x i ) − y i ∣ D L_i = \frac{|H(x_i) - y_i|}{D} Li=DH(xi)yi

R2算法平方损失——

L i = ∣ H ( x i ) − y i ∣ 2 D 2 L_i = \frac{|H(x_i) - y_i|^2}{D^2} Li=D2H(xi)yi2

R2算法指数损失——

L i = 1 − e x p ( − ∣ H ( x i ) − y i ∣ D ) L_i = 1 - exp \left( \frac{-|H(x_i) - y_i|}{D} \right) Li=1exp(DH(xi)yi)

不难发现,其实线性损失就是我们常说的MAE的变体,平方损失就是MSE的变体,而指数损失也与分类中的指数损失高度相似。在R2算法当中,这些损失函数特殊的地方在于分母D。由于D是所有样本中真实值与预测值差异最大的那一组差异,因此任意样本的 L i L_i Li在上述线性与平方损失定义下,取值范围都只有[0,1](当真实值=预测值时,取值为0,当真实值-预测值=D时,取值为1)。

1.4 Adaboost算法流程

AdaBoost.R2算法是当前AdaBoost实现流程中使用最多的回归类实践方式,它囊括了对数据进行有放回抽样、按损失函数结果调整样本权重、自动计算弱分类器权重、并输出预测结果等AdaBoost算法经典的全流程。假设现有数据集N,含有样本 M M M个,任意样本编号为 i i i,同时,弱评估器为决策树 f f f,总共学习 T T T轮,则AdaBoost.R2的基本流程如下所示:

  1. 初始化原始数据集的权重 w i w_i wi,其中任意 w i = 1 M w_i = \frac{1}{M} wi=M1
    开始循环,for t in 1,2,…T:
  2. 在现有数据集 N N N中,有放回抽样 M M M个样本,构成训练集 N t N^t Nt。在每次抽取一个样本时,任意样本被抽中的概率为 P i t = w i ∑ w i P_i^t = \frac{w_i}{\sum w_i} Pit=wiwi,很显然,该概率就是当前样本在训练集 N t N^t Nt中的权重。当从初始权重中抽样时,概率 P i 1 = 1 M P_i^1 = \frac{1}{M} Pi1=M1,当后续权重变化时,拥有更大权重的样本被抽中的概率会更大。

  3. 在训练集 N t N^t Nt上按照CART树规则建立一棵回归树 f t f^t ft,训练时所拟合的标签为样本的真实标签 y i t y^t_i yit

  4. N t N^t Nt上所有的样本输入 f t f^t ft进行预测,得出预测结果 f t ( x i ) f^t(x_i) ft(xi),其中i = 1,2,…M。

  5. 计算单一样本 i i i上的损失函数 L i t = L ( f t ( x i ) , y i ) L^t_i = L(f^t(x_i),y_i) Lit=L(ft(xi),yi),计算过程如下所示:

求解 D = s u p ∣ f t ( x i ) − y i ∣ , i = 1 , 2 , . . . , N D = sup|f^t(x_i) - y_i|, i = 1,2,...,N D=supft(xi)yi,i=1,2,...,N

选择线性/平方或指数损失函数中的一种计算 L i t L^t_i Lit

线性损失: L i = ∣ f t ( x i ) − y i ∣ D L_i = \frac{|f^t(x_i) - y_i|}{D} Li=Dft(xi)yi

平方损失: L i = ∣ f t ( x i ) − y i ∣ 2 D 2 L_i = \frac{|f^t(x_i) - y_i|^2}{D^2} Li=D2ft(xi)yi2

指数损失: L i = 1 − e x p ( − ∣ f t ( x i ) − y i ∣ D ) L_i = 1 - exp \left( \frac{-|f^t(x_i) - y_i|}{D} \right) Li=1exp(Dft(xi)yi)

根据AdaBoost的要求,所有损失的值域都在[0,1]之间。

  1. 计算全样本上的加权平均损失 L t ˉ = ∑ i = 1 M L i t P i t \bar{L^t} = \sum_{i=1}^ML_i^tP_i^t Ltˉ=i=1MLitPit

注意此时 P i t P_i^t Pit就等于样本的权重。由于 P i t = w i ∑ w i P_i^t = \frac{w_i}{\sum w_i} Pit=wiwi,所以 P i t P_i^t Pit一定位于[0,1]范围内,并且 ∑ P i t , i = 1 , 2 , . . . M \sum{P_i^t}, i=1,2,...M Pit,i=1,2,...M一定为1。

当权重之和为1时,加权平均值一定会小于等于单一数值的最大值(同时大于等于单一数值的最小值),因此加权平均的值域不会超出单一平均数的值域。由于所有损失的值域都是[0,1],因此加权平均值 L t ˉ \bar{L^t} Ltˉ的值域也是[0,1]。同时,由于损失的最大值为1,而权重 P i t P_i^t Pit的最大值一定是远远小于1的,因此加权平均值 L t ˉ \bar{L^t} Ltˉ的最大值一般也是远远小于1的。

  1. 依据加权平均损失 L t ˉ \bar{L^t} Ltˉ计算衡量当前集成算法的置信度 β t \beta^t βt

β t = L t ˉ 1 − L t ˉ + λ \beta^t = \frac{\bar{L^t}}{1-\bar{L^t} + \lambda} βt=1Ltˉ+λLtˉ,其中 λ \lambda λ是为了防止分母为0的常数

不难发现,当加权平平均损失很高时, β t \beta^t βt很大,因此置信度小,当加权平均损失很低时, β t \beta^t βt很小,因此置信度大。置信度越大,集成算法当前的预测结果越好。

已知 L t ˉ \bar{L^t} Ltˉ的理论值域是[0,1],因此 β t \beta^t βt的理论值域是[0, + ∞ +\infty +],因此 β t \beta_t βt的值越接近0越好。

同时,我们还知道 L t ˉ \bar{L^t} Ltˉ的实际范围大约都在0.2~0.3之间,因此一般来说 β t \beta^t βt的实际范围基本都是小于1的。

  1. 依据置信度评估 β t \beta_t βt更新样本权重

w i = w i β ( 1 − L i ) w_i = w_i\beta^{(1-L_i)} wi=wiβ(1Li)

我们可以根据 L i L_i Li的范围[0,1],以及 β \beta β的计算公式,绘制出横坐标为 L i L_i Li,纵坐标为 β ( 1 − L i ) \beta^{(1-L_i)} β(1Li)的图像。不难发现,单一样本的损失越大、 β ( 1 − L i ) \beta^{(1-L_i)} β(1Li)也会越大,因此该样本的权重会被更新得越大

  1. 求解迭代过程中弱分类器 f t f^t ft所需的权重

ϕ t = l o g ( 1 β t ) \phi^t = log(\frac{1}{\beta^t}) ϕt=log(βt1)
其中log的底数为e或者为2皆可。当 β \beta β值越接近于0,说明损失越小、置信度越高,则 l o g ( 1 β t ) log(\frac{1}{\beta^t}) log(βt1)的值越大。所以,损失更小的树对应的权重更大,损失更大的树对应的权重更小。

  1. 求解出当前迭代 t t t下集成算法的输出值:

H t ( x i ) = H t − 1 ( x i ) + η ϕ t f t ( x i ) H^t(x_i) = H^{t-1}(x_i) + \eta \phi^t f^t(x_i) Ht(xi)=Ht1(xi)+ηϕtft(xi)

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

「 25' h 」

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

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

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

打赏作者

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

抵扣说明:

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

余额充值