参考资料:
《机器学习》周志华
《统计学习方法》李航
【知乎】adaboost为什么不容易过拟合呢?
集成学习AdaBoost原理小结——刘建平
————————————————————————————————————
简介
关于集成学习中的boosting和bagging我就不多说了,都是将弱学习器通过不同的集成方法变成强学习器的过程。而AdaBoost是Boosting算法中最著名的代表。
AdaBoost的原理非常简单:先从初始训练集训练出一个基学习器,再根据基学习器的表现对训练样本分布进行调整,具体来说是提高预测结果中错误样本的权重,降低预测结果中正确样本的权重,使得先前基学习器做错的训练样本在后续得到更多的关注,然后基于调整后的权重来训练下一个基学习器;如此重复进行,直至基学习器数量达到了事先指定的数量。
从上面的原理简介中可以抛出两个问题:
- 权重调整具体是怎么操作的?
- 如何将多个基学习器组合起来?
算法流程
基于上一节提出的两个问题,我们先来走一遍AdaBoost算法的数学流程,看一下它的内部运作原理。
以二分类问题为例,给定一个数据集
T
=
{
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
.
.
.
,
(
x
n
,
y
n
)
}
T=\{(x_1,y_1),(x_2,y_2)...,(x_n,y_n)\}
T={(x1,y1),(x2,y2)...,(xn,yn)},其中
y
y
y取1和-1分类别代表两类。
1、第一步首先要对权值初始化,因为后面要调整权值,自然就有权值的初始化。第一轮对每个训练样本肯定是一视同仁的,所以每个样本的权值都相等。
D
1
=
(
w
11
,
.
.
.
,
w
1
N
)
,
w
1
i
=
1
N
,
i
=
1
,
2
,
.
.
.
,
N
D_1=(w_{11},...,w_{1N}),w_{1i}=\frac{1}{N},i=1,2,...,N
D1=(w11,...,w1N),w1i=N1,i=1,2,...,N其中
D
1
D_1
D1为第一轮的权重集合,
w
1
i
w_{1i}
w1i代表第一轮第
i
i
i个样本的权值。
2、第二步就要对于这个带有初始化权值的训练样本,训练出第一个基分类器。也就是说,此时对于带有权值
D
1
D_1
D1的训练样本,得到基分类器:
G
m
(
x
)
:
x
—
—
>
{
−
1
,
+
1
}
G_m(x):x——>\{-1,+1\}
Gm(x):x——>{−1,+1}其中m代表这是第m轮迭代产生的基分类器。
3、计算基分类器
G
m
(
x
)
G_m(x)
Gm(x)在训练数据上的分类误差率
e
m
=
P
(
G
m
(
x
i
)
≠
y
i
)
=
∑
i
=
1
N
w
m
i
I
(
G
m
(
x
i
)
≠
y
i
)
e_m=P(G_m(x_i)\neq y_i)=\sum^{N}_{i=1}w_{mi}I(G_m(x_i)\neq y_i)
em=P(Gm(xi)̸=yi)=i=1∑NwmiI(Gm(xi)̸=yi)注意这里计算的是分类误差率,其中
I
I
I为一个输出只有0和1的函数,当括号里的条件成立时,输出1,反之输出0。
我们可以看出,误差率的就是错误分类的样本的权值之和,其实这也很好理解,所有样本的权值都相同且权值之和为1,那么自然权值之和就能代表误差率。从这一点出发我们就能想到,在之后调整权值之后,也就是分类错误的样本权值增大后,下一轮迭代为了降低误差率(错误样本权值之和),自然会尽量把拥有较大权值的上一轮分类错误样本判断正确。(只要在这一步理解了将权值之和设为误差率的原因,整个AdaBoost的优化机制就通透很多了)
4、接下来这一步计算
G
m
(
x
)
G_m(x)
Gm(x)的系数,也就是我们上面抛出的两个问题的第二个问题,基学习器是怎么结合的,答案是通过特定的系数线性加和,系数计算如下:
a
m
=
1
2
l
o
g
1
−
e
m
e
m
a_m=\frac{1}{2}log\frac{1-e_m}{e_m}
am=21logem1−em这里的对数是自然对数。
从这个式子可以知道,这个系数实际是在衡量基分类器在最终分类器重的作用大小。当 e m ≤ 1 2 e_m\leq\frac{1}{2} em≤21时, a m ≥ 0 a_m\geq0 am≥0,并且 a m a_m am随着 e m e_m em的减小而增大,也就是说分类误差率越小的基分类器在最终分类器中的作用越大。
然而此时还能抛出一个问题,使得 a m a_m am随着 e m e_m em的减小而增大的表达形式有很多,为啥偏偏长这个样子呢?其实这个系数长成这种形式的出发点并不是专门为了实现 a m a_m am随着 e m e_m em的减小而增大设计出来的,而是从AdaBoost原理出发就能推导出来。具体推导后面再说,先走通算法流程。
5、计算完基学习器的系数,基学习器就可以带权加到总学习器中,那么接下来就该整下一个基学习器了,当然,学习下一个基学习器之前要根据之前的预测结果来调整权值。
D
m
+
1
=
(
w
m
+
1
,
1
,
.
.
.
,
w
m
+
1
,
i
,
.
.
.
,
w
m
+
1
,
N
)
D_{m+1}=(w_{m+1,1},...,w_{m+1,i},...,w_{m+1,N})
Dm+1=(wm+1,1,...,wm+1,i,...,wm+1,N)
w
m
+
1
,
i
=
w
m
i
Z
m
e
x
p
(
−
α
m
y
i
G
M
(
x
i
)
)
,
i
=
1
,
2
,
.
.
.
,
N
w_{m+1,i}=\frac{w_{mi}}{Z_m}exp(-\alpha_my_iG_M(x_i)),i=1,2,...,N
wm+1,i=Zmwmiexp(−αmyiGM(xi)),i=1,2,...,N其中,
Z
m
是
规
范
化
因
子
Z_m是规范化因子
Zm是规范化因子
Z
m
=
∑
i
=
1
N
w
m
i
e
x
p
(
−
α
m
y
i
G
M
(
x
i
)
)
Z_m=\sum^{N}_{i=1}w_{mi}exp(-\alpha_my_iG_M(x_i))
Zm=i=1∑Nwmiexp(−αmyiGM(xi))它使
D
m
+
1
D_{m+1}
Dm+1成为一个概率分布。其实说白了这个规范化因子就是个总和,作为分母使得权值即使调整但仍然压缩在0到1之间,因为误差率就是错误样本的权值之和,而压缩在0到1之间对成为概率是非常必要的。
那么问题来了,权值为什么要这么调整?压缩到0到1之间好理解,也就是说分母好理解,分子怎么理解呢?一会儿再说,先把算法流程跑通。
6、调整完权值之后,我们像第2步一样学出一个基学习器就好了,剩下的就是无限循环直至基学习器的数量到达实现的设定。那么最后一步就是将所有的基分类器线性组合起来,非常简单:
f
(
x
)
=
∑
m
=
1
M
α
m
G
m
(
x
)
f(x)=\sum^{M}_{m=1}\alpha_mG_m(x)
f(x)=m=1∑MαmGm(x)得到最终分类器
G
(
x
)
=
s
i
g
n
(
f
(
x
)
)
=
s
i
g
n
(
∑
m
=
1
M
α
m
G
m
(
x
)
)
G(x)=sign(f(x))=sign(\sum^{M}_{m=1}\alpha_mG_m(x))
G(x)=sign(f(x))=sign(m=1∑MαmGm(x))其中
s
i
g
n
(
)
sign()
sign()函数是符号函数,自变量大于等于0输出1,否则输出-1。
tips:
1、上述推导中,如果相对正确分类的样本来说(把其看作基准),误分类样本相当于被放大了
e
2
α
m
=
e
m
1
−
e
m
e^{2\alpha_m}=\frac{e_m}{1-e_m}
e2αm=1−emem倍
2、线性组合实现了基分类器的加权表决,系数表示了基分类器的重要性,系数的和并不为1
3、最终分类器
f
(
x
)
f(x)
f(x)的符号决定样本的分类,而
f
(
x
)
f(x)
f(x)的绝对值表示 分类的确信程度。
算法内部原理
这一部分将解决算法流程中的那两个遗留问题。
AdaBoost的本质是损失函数为指数函数的加法模型,学习过程本质是前向分布算法。听起来是不是很拗口,加法模型可以理解为一种形式、框架,损失函数就是算法要优化的目标,学习过程就是说算法的寻友过程,就像BP神经网络的学习过程是误差逆传播算法一样。下面来一个一个解释。
加法模型
形如:
f
(
x
)
=
∑
m
=
1
M
β
m
b
(
x
;
γ
m
)
f(x)=\sum^{M}_{m=1}\beta_mb(x;\gamma_m)
f(x)=m=1∑Mβmb(x;γm)其中,
b
(
x
;
γ
m
)
b(x;\gamma_m)
b(x;γm)为基函数,
γ
m
\gamma_m
γm为基函数的参数,
β
m
\beta_m
βm为基函数的系数。
这样的模型就是加法模型
前向分布算法
设
L
(
y
,
f
(
x
)
)
L(y,f(x))
L(y,f(x))为损失函数,那么加法模型的损失函数就是
m
i
n
β
m
,
γ
∑
i
=
1
N
L
(
y
i
,
∑
m
=
1
M
β
m
b
(
x
i
;
γ
m
)
)
\underset{\beta_m,\gamma}{min}\sum^{N}_{i=1}L(y_i,\sum^{M}_{m=1}\beta_mb(x_i;\gamma_m))
βm,γmini=1∑NL(yi,m=1∑Mβmb(xi;γm))想要优化这个损失函数就非常困难,因为需要协调每个基函数的参数以及系数来达到最优。而前向分布算法的思路是:基于加法模型的每一步,从前向后,每一步只学习一个基函数及其系数,逐步逼近优化目标,这样就可以大大简化复杂度。这说白了就是每一步都尽量做到当前的最好,但这种做法最后加和起来是否能达到全局最优呢?显然是不一定的,因为总体最优并不一定是由每一步最优加起来得到的。
那么具体的,每步只需要优化以下损失函数:
m
i
n
β
,
γ
∑
i
=
1
N
L
(
y
i
,
β
b
(
x
i
;
γ
)
)
\underset{\beta,\gamma}{min}\sum^{N}_{i=1}L(y_i,\beta b(x_i;\gamma))
β,γmini=1∑NL(yi,βb(xi;γ))
总结一下前向分布算法的算法流程就是:
输入:训练数据集 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x N , y N ) } T=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\} T={(x1,y1),(x2,y2),...,(xN,yN)};损失函数 L ( y , f ( x ) ) L(y,f(x)) L(y,f(x));基函数集 { b ( x ; γ ) } \{b(x;\gamma)\} {b(x;γ)}
输出:加法模型f(x)
1、初始化
f
0
(
x
)
=
0
f_0(x)=0
f0(x)=0
2、对
m
=
1
,
2
,
.
.
.
,
M
m=1,2,...,M
m=1,2,...,M(代表第m个基函数),极小化损失函数
(
β
m
,
γ
m
)
=
a
r
g
m
i
n
β
,
γ
∑
i
=
1
N
L
(
y
i
,
f
m
−
1
(
x
i
)
+
β
b
(
x
i
;
γ
)
)
(\beta_m,\gamma_m)=\underset{\beta,\gamma}{argmin}\sum^{N}_{i=1}L(y_i,f_{m-1}(x_i)+\beta b(x_i;\gamma))
(βm,γm)=β,γargmini=1∑NL(yi,fm−1(xi)+βb(xi;γ))得到参数
β
m
,
γ
m
\beta_m,\gamma_m
βm,γm
3、更新总模型
f
m
(
x
)
=
f
m
−
1
(
x
)
+
β
m
b
(
x
;
γ
m
)
f_m(x)=f_{m-1}(x)+\beta_mb(x;\gamma_m)
fm(x)=fm−1(x)+βmb(x;γm)
4、循环以上步骤,直到基分类器的个数到达指定数量。
这节的开篇我们说,AdaBoost就是学习过程为前向分布算法、损失函数为指数函数的加法模型,加法模型和前向分布算法都介绍了,现在只需要指定损失函数就可以得到AdaBoost从损失函数出发的推导过程了。(指数损失函数不介绍了)
AdaBoost从损失函数理解
上面说了,我们只差个损失函数了,指数损失函数为:
L
(
y
,
f
(
x
)
)
=
e
x
p
[
−
y
f
(
x
)
]
L(y,f(x))=exp[-yf(x)]
L(y,f(x))=exp[−yf(x)]将指数损失函数代入上面的损失函数内,得到没更新一个基分类器需要在训练数据T上极小化以下:
(
α
m
,
G
m
(
x
)
)
=
a
r
g
m
i
n
α
,
G
∑
i
=
1
N
e
x
p
[
−
y
i
(
f
m
−
1
(
x
i
)
+
α
G
(
x
i
)
)
]
(\alpha_m,G_m(x))=\underset{\alpha,G}{argmin}\sum^{N}_{i=1}exp[-y_i(f_{m-1}(x_i)+\alpha G(x_i))]
(αm,Gm(x))=α,Gargmini=1∑Nexp[−yi(fm−1(xi)+αG(xi))]推导一下,可以得到
(
α
m
,
G
m
(
x
)
)
=
a
r
g
m
i
n
α
,
G
∑
i
=
1
N
w
ˉ
m
i
e
x
p
[
−
y
i
α
G
(
x
i
)
]
(\alpha_m,G_m(x))=\underset{\alpha,G}{argmin}\sum^{N}_{i=1}\bar{w}_{mi}exp[-y_i\alpha G(x_i)]
(αm,Gm(x))=α,Gargmini=1∑Nwˉmiexp[−yiαG(xi)]其中,
w
ˉ
m
i
=
e
x
p
[
−
y
i
f
m
−
1
(
x
i
)
]
\bar{w}_{mi}=exp[-y_if_{m-1}(x_i)]
wˉmi=exp[−yifm−1(xi)]。
w
ˉ
m
i
\bar{w}_{mi}
wˉmi既不依赖
α
\alpha
α也不依赖
G
G
G,与最小化无关,但依赖于
f
m
−
1
(
x
)
f_{m-1}(x)
fm−1(x),随着每一轮迭代而发生改变。像不像AdaBoost前面推导中的权值?非常像,但并不完全等价,这个随后解释。
我们先来讨论一下使上述目标函数最小的
G
m
∗
(
x
)
G_m^*(x)
Gm∗(x),当
G
m
∗
(
x
)
G_m^*(x)
Gm∗(x)预测正确的时候,它与
y
i
y_i
yi的积必然为1(此处还是二分类情况,1和-1两类),此时
e
x
p
(
−
α
)
exp(-\alpha)
exp(−α)对于任意
α
>
0
\alpha>0
α>0结果都是一个较小的数字。但当
G
m
∗
(
x
)
G_m^*(x)
Gm∗(x)预测错误的时候,符号就改变了,此时
e
x
p
(
α
)
exp(\alpha)
exp(α)对于任意
α
>
0
\alpha>0
α>0结果相对于预测正确的时候都是一个较大的数字。
e
x
p
(
)
exp()
exp()这一步只会产生两种结果,要么
e
x
p
(
−
α
)
exp(-\alpha)
exp(−α)要么
e
x
p
(
α
)
exp(\alpha)
exp(α),不同的是它所要相乘的为
w
ˉ
m
i
\bar{w}_{mi}
wˉmi,所以要想使得上述目标函数最小,在
α
\alpha
α不变的情况下,使其最小的
G
(
x
)
G(x)
G(x)必然由下式得到:
G
m
∗
(
x
)
=
a
r
g
m
i
n
G
∑
i
=
1
N
w
ˉ
m
i
I
(
y
i
≠
G
(
x
i
)
)
G^*_m(x)=\underset{G}{argmin}\sum^{N}_{i=1}\bar{w}_{mi}I(y_i\neq G(x_i))
Gm∗(x)=Gargmini=1∑NwˉmiI(yi̸=G(xi))这是一个显而易见的结果。那么此时这个
G
m
∗
(
x
)
G_m^*(x)
Gm∗(x)是否等价于之前AdaBoost算法流程中推导的那个每一轮迭代的基函数?其实是等价的,但是一眼看不出来,因为要证明等价就需要证明它是使得每一轮误差率最小的基函数,要证明它是使得每一轮误差率最小的基函数就需要证明
w
ˉ
m
i
\bar{w}_{mi}
wˉmi代表着权值,因为错误样本的权值之和才等于误差率。然而此时这个所谓的权值还不好证明,那么我们就先放一边,先看
α
\alpha
α。
接着上面的损失函数进行推导:
∑
i
=
1
N
w
ˉ
m
i
e
x
p
[
−
y
i
α
G
(
x
i
)
]
=
∑
y
i
=
G
m
(
x
i
)
w
ˉ
m
i
e
−
α
+
∑
y
i
≠
G
m
(
x
i
)
w
ˉ
m
i
e
α
=
(
e
α
−
e
−
α
)
∑
i
=
1
N
w
ˉ
m
i
I
(
y
i
≠
G
(
x
i
)
)
+
e
−
α
∑
i
=
1
N
w
ˉ
m
i
\sum^{N}_{i=1}\bar{w}_{mi}exp[-y_i\alpha G(x_i)]\\=\sum_{y_i=G_m(x_i)}\bar{w}_{mi}e^{-\alpha}+\sum_{y_i\neq G_m(x_i)}\bar{w}_{mi}e^{\alpha}\\=(e^{\alpha}-e^{-\alpha})\sum^{N}_{i=1}\bar{w}_{mi}I(y_i\neq G(x_i))+e^{-\alpha}\sum^{N}_{i=1}\bar{w}_{mi}
i=1∑Nwˉmiexp[−yiαG(xi)]=yi=Gm(xi)∑wˉmie−α+yi̸=Gm(xi)∑wˉmieα=(eα−e−α)i=1∑NwˉmiI(yi̸=G(xi))+e−αi=1∑Nwˉmi最后一步是把上面推导出来的
G
m
∗
(
x
)
G_m^*(x)
Gm∗(x)代入其中了。损失函数推到现在,也就是说我们需要最小化的就是上面这一堆东西。我们之前说了,先来求
α
\alpha
α,那么我们就对其求导并使导数为0,就可以轻松得到结果。
求解过程是非常容易的,但需要一个小的变换:
e
m
=
∑
i
=
1
N
w
ˉ
m
i
I
(
y
i
≠
G
m
(
x
i
)
)
∑
i
=
1
N
w
ˉ
m
i
e_m=\frac{\sum^{N}_{i=1}\bar{w}_{mi}I(y_i\neq G_m(x_i))}{\sum^{N}_{i=1}\bar{w}_{mi}}
em=∑i=1Nwˉmi∑i=1NwˉmiI(yi̸=Gm(xi))其实从这里我们依稀可以看出
w
ˉ
m
i
\bar{w}_{mi}
wˉmi是个什么东西了,它虽然不完全等价于算法流程中推导的权值,但是它等价于权值的分子啊,也就是说只相差规范化因子而已。我们这里可以这么说,只要他等价于算法流程中权值的分子,那么上面推导的这个误差率的公式就是正确的。那么,我们目前的遗留问题又变了——证明
w
ˉ
m
i
\bar{w}_{mi}
wˉmi是权值的分子,一会儿再说。
当这个误差率公式成立之后,我们可以轻松根据导数为0求出:
α
m
∗
=
1
2
l
o
g
1
−
e
m
e
m
\alpha_m^*=\frac12log\frac{1-e_m}{e_m}
αm∗=21logem1−em这里推导出来的
α
\alpha
α的表达形式就与之前算法流程中相同了。接下来我们再来解决权值的问题。
根据:
w
ˉ
m
i
=
e
x
p
[
−
y
i
f
m
−
1
(
x
i
)
]
f
m
=
f
m
−
1
(
x
)
+
α
m
G
m
(
x
)
\bar{w}_{mi}=exp[-y_if_{m-1}(x_i)] \\ f_m=f_{m-1}(x)+\alpha_mG_m(x)
wˉmi=exp[−yifm−1(xi)]fm=fm−1(x)+αmGm(x) 可以求得:
w
ˉ
m
+
1
,
i
=
w
ˉ
m
i
(
x
)
e
x
p
[
−
y
i
α
m
G
m
(
x
)
]
\bar{w}_{m+1,i}=\bar{w}_{mi}(x)exp[-y_i\alpha_mG_m(x)]
wˉm+1,i=wˉmi(x)exp[−yiαmGm(x)]这个更新公式是不是非常面熟,与之前推导的权值就差一个规范化因子了!所以啊,它与之前权值的分子等价,上面的一切也就说得通了。
其实我们将两个损失函数拿出来看看就会发现是完全等价的:
e
m
=
P
(
G
m
(
x
i
)
≠
y
i
)
=
∑
i
=
1
N
w
m
i
I
(
G
m
(
x
i
)
≠
y
i
)
e_m=P(G_m(x_i)\neq y_i)=\sum^{N}_{i=1}w_{mi}I(G_m(x_i)\neq y_i)
em=P(Gm(xi)̸=yi)=i=1∑NwmiI(Gm(xi)̸=yi)这是之前算法流程中误差率的表达形式,每一轮需要极小化的也是它。
∑
i
=
1
N
w
ˉ
m
i
e
x
p
[
−
y
i
α
G
(
x
i
)
]
\sum^{N}_{i=1}\bar{w}_{mi}exp[-y_i\alpha G(x_i)]
i=1∑Nwˉmiexp[−yiαG(xi)]这是从加法模型角度推导的损失函数形式,我们需要最小化的是它,而最小化它又等价于最小化:
∑
i
=
1
N
w
ˉ
m
i
I
(
y
i
≠
G
(
x
i
)
)
\sum^{N}_{i=1}\bar{w}_{mi}I(y_i\neq G(x_i))
i=1∑NwˉmiI(yi̸=G(xi))这和算法流程中需要最小化的东西就是等价的,一个最小化分数的和,一个最小化分子的和,然而分母相同,那么就是等价的。
两个性质的一点说明
以上AdaBoost的基本数学原理已经说完了,但我在学习的时候看到两个性质需要格外说明一下。第一个是AdaBoost的训练误差是以指数速率下降的,虽然我不知道这个性质能怎么应用,但还是要拿出来说一下。(我怎么想都只是一个优点。。而已)第二个是AdBoost不容易过拟合,经常有人说AdaBoost不会过拟合,其实是不容易,完全不会是不可能的。这个优点其实现在都没有一个完全令人信服的答案和严谨的推导过程,但前人为证明这个问题做出的贡献我们也不能忽略。
1、误差以指数速率下降
这个问题李航的《统计学习方法》中的证明过程已经非常清晰易懂了,我也就不再详细解读了,直接把过程截图过来。
这一部分简单说就是先证明了权值的累加小于等于
Z
m
Z_m
Zm的累乘,之后又证明
Z
m
Z_m
Zm的累乘小于等于指数形式的累乘。所以,权值的累加(也就是最终误差)小于等于指数的累乘,也就是说误差是沿着指数速率下降的。
AdaBoost不容易过拟合
这个问题直到现在都没有一个完美的答案,我就在这里引用一个知乎的回答吧,这个回答里简要介绍了前人的研究成果,希望能有所启发。
[知乎] adaboost为什么不容易过拟合——愈扬的回答
优缺点
Adaboost的主要优点有:
1、AdaBoost作为分类器时,分类精度很高
2、AdaBoost本身是一种框架,可以使用各种回归分类模型建立弱学习器
3、作为简单的二元分类器时,构造简单,结果可理解。
4、误差以指数速率下降
5、不容易发生过拟合
AdaBoost的主要缺点有:
对异常样本敏感,异常样本在迭代中可能会获得较高的权重,影响最终的强学习器的预测准确性。
关于AdaBoost在sklearn中的应用,贴上刘建平大佬的博客,他写的非常好。
scikit-learn Adaboost类库使用小结——刘建平