依据上一个弱评估器 f ( x ) t − 1 f(x)_{t-1} f(x)t−1的结果,计算损失函数 L ( x , y ) L(x,y) L(x,y),
并使用 L ( x , y ) L(x,y) L(x,y)自适应地影响下一个弱评估器 f ( x ) t f(x)_t f(x)t的构建。
集成模型输出的结果,受到整体所有弱评估器 f ( x ) 0 f(x)_0 f(x)0 ~ f ( x ) T f(x)_T f(x)T的影响。
在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过程当中,所有弱评估器结果的加权求和:
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=1∑Tϕ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)=Ht−1(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)=Ht−1(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当中做出权衡(以XGBoost算法为例)。
首先,参数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)也针对于某一类别的概率。
2.2 AdaBoost的损失函数
需要注意的是,在分类器中,我们虽然被允许选择算法,却不被允许选择算法所使用的损失函数,这是因为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)=e−yH∗(x)
其中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)={1−1if H(x)>0.5if H(x)<0.5
在sklearn当中,由于 H ( x ) H(x) H(x)是概率值,因此需要转换为 H ∗ ( x ) H^*(x) H∗(x),如果在其他实现AdaBoost的算法库中, H ( x ) H(x) H(x)输出直接为预测类别,则可以不执行转换流程。
根据指数损失的特殊性质,二分类状况下的类别取值只能为-1或1 ,因此 y y y的取值只能为-1或1。当算法预测正确时, y H ∗ ( x ) yH^*(x) yH∗(x)的符号为正,则在函数 e − x e^{-x} e−x上损失很小。当算法预测错误时, y H ∗ ( x ) yH^*(x) yH∗(x)的符号为负,则在函数 e − x e^{-x} e−x上损失较大。二分类指数损失是AdaBoost最经典的损失函数,它在数学推导上的有效性以及在实践过程中很强的指导性让其沿用至今。
多分类指数损失------
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(−K1y∗⋅H∗(x))=exp(−K1(y∗1H∗1(x)+y∗2H∗2(x) + ...+y∗kH∗k(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} y∗1与 H ∗ 1 ( x ) H^{*1}(x) H∗1(x)的上标1都表示当前类别。
在二分类算法中,算法会直接针对二分类中的其中一个类别 输出概率,因为在二分类中 P ( Y = 1 ) = 1 − P ( Y = − 1 ) P(Y=1) = 1 - P(Y=-1) P(Y=1)=1−P(Y=−1),所以只计算出一类的概率即可判断预测的标签。但在多分类算法中,算法必须针对所有可能的取值类型都输出概率,才能够从中找出最大概率所对应的预测标签。
对一棵决策树我们会输出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)=Ht−10(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)=Ht−11(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)=Ht−12(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)=Ht−1k(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)={1−K−11if 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∗的构成如下所示:
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
用公式表示则有:
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∗={1−K−11if 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} −K−11相加。
多分类指数损失:
假设K=2,
L = e x p ( − 1 K ( y ∗ 1 H ∗ 1 ( x ) + y ∗ 2 H ∗ 2 ( x ) ) ) \begin{aligned} L = exp \left( -\frac{1}{K} \left( y^{*1}H^{*1}(x)+y^{*2}H^{*2}(x) \right) \right) \end{aligned} L=exp(−K1(y∗1H∗1(x)+y∗2H∗2(x)))
首先:
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=sup∣H(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=D∣H(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=D2∣H(xi)−yi∣2
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=1−exp(D−∣H(xi)−yi∣)
不难发现,其实线性损失就是我们常说的MAE的变体,平方损失就是MSE的变体,而指数损失也与分类中的指数损失高度相似。在R2算法当中,这些损失函数特殊的地方在于分母D。由于D是所有样本中真实值与预测值差异最大的那一组差异 ,因此任意样本的 L i L_i Li在上述线性与平方损失定义下,取值范围都只有[0,1](当真实值=预测值时,取值为0,当真实值-预测值=D时,取值为1)。
特别的,对于指数损失来说,自变量的部分是在[0,1]中取值,因此 e − x e^{-x} e−x的在该定义域上的值域也为[0,1],因此 1 − e − x 1-e^{-x} 1−e−x的值域为[0,1]。事实上,在R2算法的论文当中,就有明确对损失函数的唯一要求:即值域为[0,1]。该规则使得整个AdaBoost算法的求解流程变得顺畅,具体可以在《2 原理进阶:AdaBoost的求解流程》中看到。
损失函数 L ( x , y ) L(x,y) L(x,y)的表达式是什么?损失函数如何影响模型构建?
弱评估器 f ( x ) f(x) f(x) 是什么,当下boosting算法使用的具体建树过程是什么?
综合集成结果 H ( x ) H(x) H(x)是什么?集成算法具体如何输出集成结果?
同时,还可能存在其他需要明确的问题,例如:
是加权求和吗?如果是,加权求和中的权重如何求解?
训练过程中,拟合的数据 X X X与 y y y分别是什么?
模型训练到什么时候停下来最好?
同时,别忘记boosting算法的基本规则:
依据上一个弱评估器 f ( x ) t − 1 f(x)_{t-1} f(x)t−1的结果,计算损失函数 L ( x , y ) L(x,y) L(x,y),
并使用 L ( x , y ) L(x,y) L(x,y)自适应地影响下一个弱评估器 f ( x ) t f(x)_t f(x)t的构建。
集成模型输出的结果,受到整体所有弱评估器 f ( x ) 0 f(x)_0 f(x)0 ~ f ( x ) T f(x)_T f(x)T的影响。
AdaBoost.R2算法是当前AdaBoost实现流程中使用最多的回归类实践方式,它囊括了对数据进行有放回抽样、按损失函数结果调整样本权重、自动计算弱分类器权重、并输出预测结果等AdaBoost算法经典的全流程。假设现有数据集N,含有样本 M M M个,任意样本编号为 i i i,同时,弱评估器为决策树 f f f,总共学习 T T T轮,则AdaBoost.R2的基本流程如下所示:
初始化原始数据集的权重 w i w_i wi,其中任意 w i = 1 M w_i = \frac{1}{M} wi=M1
开始循环,for t in 1,2,...T:
在现有数据集 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,当后续权重变化时,拥有更大权重的样本被抽中的概率会更大。
在训练集 N t N^t Nt上按照CART树 规则建立一棵回归树 f t f^t ft,训练时所拟合的标签为样本的真实标签 y i t y^t_i yit。
将 N t N^t Nt上所有的样本输入 f t f^t ft进行预测,得出预测结果 f t ( x i ) f^t(x_i) ft(xi),其中i = 1,2,...M。
计算单一样本 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=sup∣ft(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=D∣ft(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=D2∣ft(xi)−yi∣2
指数损失: 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=1−exp(D−∣ft(xi)−yi∣)
根据AdaBoost的要求,所有损失的值域都在[0,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的。
依据加权平均损失 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=1−Ltˉ+λ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的。
依据置信度评估 β t \beta_t βt更新样本权重
w i = w i β ( 1 − L i ) w_i = w_i\beta^{(1-L_i)} wi=wiβ(1−Li)
我们可以根据 L i L_i Li的范围[0,1],以及 β \beta β的计算公式,绘制出横坐标为 L i L_i Li,纵坐标为 β ( 1 − L i ) \beta^{(1-L_i)} β(1−Li)的图像。不难发现,单一样本的损失越大、 β ( 1 − L i ) \beta^{(1-L_i)} β(1−Li)也会越大,因此该样本的权重会被更新得越大 。
求解迭代过程中弱分类器 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)的值越大。所以,损失更小的树对应的权重更大,损失更大的树对应的权重更小。
求解出当前迭代 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)=Ht−1(xi)+ηϕtft(xi)
在步骤2~10中循环,直到迭代次数被使用完毕。理想上来说,Adaboost至少应该迭代到 T T T次以满足下列条件:
( ∑ t : H t ( x ) ≤ y l o g 1 β t ) ≥ ( 1 2 ∑ t = 1 T l o g 1 β t ) \left(\sum_{t:H^t(x) \leq y} log\frac{1}{\beta^t} \right)\ \ \geq \ \ \left(\frac{1}{2}\sum_{t=1}^T log\frac{1}{\beta^t} \right) t:Ht(x)≤y∑logβt1 ≥ (21t=1∑Tlogβt1)
等同于:
( ∑ t : H t ( x ) ≤ y ϕ t ) ≥ ( 1 2 ∑ t = 1 T ϕ t ) \left(\sum_{t:H^t(x) \leq y} \phi^t \right)\ \ \geq \ \ \left(\frac{1}{2}\sum_{t=1}^T \phi^t \right) t:Ht(x)≤y∑ϕt ≥ (21t=1∑Tϕt)
并且,最终算法的输出值是上述等式满足"等于"条件时所对应的 H t ( x ) H^t(x) Ht(x)。对于一个正常迭代的AdaBoost来说,每一轮迭代后获得的 H ( x i ) H(x_i) H(xi)都是累加结果,因此 H ( x i ) H(x_i) H(xi)之间应该满足以下关系:
H 0 ( x i ) < H 1 ( x i ) < , . . . , < H T ( x i ) H^0(x_i) < H^1(x_i) <, ... , < H^T(x_i) H0(xi)<H1(xi)<,...,<HT(xi)
在 H 0 ( x i ) H^0(x_i) H0(xi)到 H T ( x i ) H^T(x_i) HT(xi)过程中,必然只有部分 H ( x i ) H(x_i) H(xi)是小于真实标签 y i y_i yi的,假设有 t t t次迭代中 H ( x i ) H(x_i) H(xi)都小于 y i y_i yi,则理想状况下,前 t t t次迭代中权重的累加,应该大于0.5 * 所有 T T T次迭代中权重的累加。当两者相等时,t就是最佳迭代次数,而 t t t对应的 H t ( x ) H^t(x) Ht(x)也就是最佳预测值。