前言
本想在暑期阶段通过博客的形式整理沉淀所学的一些统计方法,但受各门课程复习进程的压迫,使我不得不收一收自己的"野心"。但若不完成心中所想,定会心有不甘,于是采用分段发表的形式,好为自己带来一些动力。
参考课本依旧是李航老师的小蓝书。
Boosting方法,我会将AdaBoost与GBDT放在一起书写,XGBoost与LightGBM分为另一组。
引入
我们平时学习到的单个模型,例如决策树,神经网络等,往往不会达到我们预期的效果,通常的方法是从两个角度入手,一种是继续通过一些方法去提取特征以提高准确率,而另一种方式就是集成(ensemble)。
集成学习的主要思想便是化复杂问题为简单问题,通常我们想要得到一个精妙的学习器,较之得到一个较为粗糙的学习器,是较为困难的(这里的粗糙和精妙往往在不同问题中有不同的衡量标准),古语常道"积小流而成江海"。于是集成学习应运而生,其主要解决问题便是我们可以通过怎样的方式将众多较为粗糙的学习器组合起来,得到较为精妙的学习器以为我们服务。(给我的直观感觉是神经网络是以质取胜(参数多难训练),而集成是以量取胜。)
Boosting是现在大多网络上所流传的三种集成手段的其中一种,另外两尊大神分别是Stacking与Bagging。(当然,这只是其中的一种分类方式,另一种常见的分类标准是根据各种个体学习器的种类是否相同而分为homogeneous与heterogeneous)。Boosting的主要特点是:
- 更加“重视”上一个弱学习器学习错误的样本
而本篇博客的主角AdaBoost便是最常见的一种Boosting算法,他算法中自然解决了ensemble与Boosting的两个主要矛盾。
-
如何体现对上一个弱学习器学习错误样本的“重视”。
-
通过“怎样的方式”,将众多弱学习器转化为强学习器。
下面我将通过AdaBoost的算法流程,加入我自己的理解去解析AdaBoost是通过怎么样的策略解决上述两个主要矛盾的。
AdaBoost algorithm
首先明确普通的AdaBoost算法是一个二分类算法。于是实例的标签我们可以记成 Y = { − 1 , + 1 } \mathcal{Y} = \{-1,+1\} Y={−1,+1},并且在此处我们假定弱分类器是同质的,即是通过一种学习算法得出的(比如设置这里的弱分类器算法是Decision Tree(C4.5),那么决策树的分支准则就是信息增益率,按照Hunt算法生成一个决策树,作为一个弱分类器)。
设训练数据集 T = { ( x 1 , y 1 ) , … , ( x N , y N ) } T =\{(x_1,y_1),\ldots,(x_N,y_N)\} T={(x1,y1),…,(xN,yN)}。其中 x i ∈ X ⊆ R n , y i ∈ Y , x_i \in \mathcal{X}\subseteq \mathbb{R}^n,y_i \in \mathcal{Y}, xi∈X⊆Rn,yi∈Y, X \mathcal{X} X是实例空间(说人话就是特征是 n n n维向量, y i y_i yi是 ± 1 ±1 ±1)
在我们拿到训练数据集并且确定下来一种弱分类算法后(如SVM,Logistic regression,Decision Tree等),我们来看看AdaBoost如何是如何解决上面的两个矛盾的。
首先,AdaBoost是通过每一个样本的权值来反映每一轮对于每一个样本的重视程度不同的,(用面向对象的思想去看,若每一个样本看成一个对象,那么每一个样本在每一轮训练中都有一个属性,即是他们的权值)。而一开始没有经过任何分类器的衡量,我们可以认为这些样本是同等主要的。于是我们给每一个样本附加相等的权值
D
1
=
(
ω
11
,
ω
12
,
…
,
ω
1
N
)
,
ω
1
i
=
1
N
,
i
=
1
,
2
,
…
,
N
D_1 = (\omega_{11},\omega_{12},\ldots,\omega_{1N}),\quad \omega_{1i} = \frac{1}{N}, \quad i = 1,2,\ldots,N
D1=(ω11,ω12,…,ω1N),ω1i=N1,i=1,2,…,N
ω i j \omega_{ij} ωij的第一个角标 i i i代表是训练第 i i i个弱分类器的权值分布,第 j j j个角标代表训练第 i i i个弱分类器的样本权值分布的第 j j j个分量。
这里出现了我认为第一个较难理解的点
- 为什么要将样本的权值做成一个概率分布的形式,每一个设置为1或其他数值不行吗?这么做的好处在哪?
这个问题我们暂且记下,后面会给出回答。
我们假定现在已经拿到了第
m
m
m轮的样本权值分布,
m
=
1
,
2
,
…
,
M
,
M
m = 1,2,\ldots,M,\quad M
m=1,2,…,M,M为自行设置的集成轮数。
D
m
=
(
ω
m
1
,
ω
m
2
,
…
,
ω
m
N
)
D_m = (\omega_{m1},\omega_{m2},\ldots,\omega_{mN})
Dm=(ωm1,ωm2,…,ωmN)
于是我们通过一开始设定的基分类器的学习方法,可以训练出第 m m m个基分类器,记为 G m ( x ) : X → { − 1 , + 1 } G_m(x):\mathcal{X}\rightarrow \{-1,+1\} Gm(x):X→{−1,+1}。
关于这里,有两处需要注意:
- 这里事实上暗含了一个迭代过程,有了一开始设定的样本权值初始分布,就可以通过解下面的方式给出第二轮的样本权值分布 D 2 D_2 D2,从而给出 D 3 , … , D M D_3,\ldots,D_M D3,…,DM。若是看不顺眼,可以直接将上面的 m m m改为 2 2 2,帮助理解。
- 在训练每一个基分类器的时候,我们在计算误差时,要将每一个样本带来的误差乘以其对应的权重,而不是原本的损失函数。以ID3算法为例,则分支分裂的损失函数变为如下的带权信息增益 G a i n w e i g h t ( T , a ) = E n t ( T ) − ∑ v = 1 V ω v E n t ( T v ) Gain_{weight}(T,a) = Ent(T) - \sum_{v = 1}^V{\omega^v}Ent(T^v) Gainweight(T,a)=Ent(T)−v=1∑VωvEnt(Tv)其中 E n t ( T ) Ent(T) Ent(T)代表数据集 T T T的信息熵, V V V离散属性 a a a的取值总数, ω v \omega^v ωv代表属性 a a a取值为 v v v的那些样本权值和, T v T^v Tv代表样本集 T T T中属性 a a a取值为 v v v的那些样本的信息增益。建议与周志华——《机器学习》P75的信息增益公式 G a i n ( D , a ) Gain(D,a) Gain(D,a)进行对比。这里主要想说明的一点是,并非所有算法都是如李航老师的《统计学习方法》一书中实例所述,用带权误差率去训练基分类器,根据基分类器的学习算法的选择不同,其内部的损失函数公式也在不断改变。这点需要特别注意。
训练完成后,我们可以拿到第
m
m
m个基分类器
G
m
(
x
)
G_m(x)
Gm(x),于是可以计算
G
m
(
x
)
G_m(x)
Gm(x)在训练数据集上的分类误差率
e
m
=
∑
i
=
1
N
P
(
G
m
≠
y
i
)
=
∑
i
=
1
N
ω
m
i
I
(
G
m
(
x
i
)
≠
y
i
)
e_m = \sum_{i=1}^NP(G_m \neq y_i) = \sum_{i=1}^N\omega_{mi}I(G_m(x_i)\neq y_i)
em=i=1∑NP(Gm=yi)=i=1∑NωmiI(Gm(xi)=yi)
下面我们回答上面的第二个主要问题:AdaBoost是通过对每一轮的基分类器进行线性组合后,形成最终的强分类器。
即
f
(
x
)
=
∑
i
=
1
M
α
m
G
m
(
x
)
G
(
x
)
=
s
i
g
n
(
f
(
x
)
)
=
s
i
g
n
(
∑
m
=
1
M
α
m
G
m
)
\begin{aligned} &f(x) = \sum_{i=1}^M\alpha_mG_m(x) \\ &G(x) = sign(f(x)) = sign(\sum_{m=1}^M\alpha_mG_m) \end{aligned}
f(x)=i=1∑MαmGm(x)G(x)=sign(f(x))=sign(m=1∑MαmGm)
而随之而来的问题即是——每一个弱分类器的权重
α
m
\alpha_m
αm如何确定?回想一下我们生活中的现象,在一个团体中,如果一个人的本领过硬,那么这个人的话语权通常就会较大,此处也应是如此,所谓的本领,不妨就体现在
G
m
G_m
Gm在训练集上的带权准确率
e
m
e_m
em,李航老师给出的弱分类器的权重计算公式如下
α
m
=
1
2
l
o
g
1
−
e
m
e
m
\alpha_m = \frac{1}{2}log{\frac{1-e_m}{e_m}}
αm=21logem1−em
我特地画了一张图来初步说明这个公式设置的合理性以帮助理解,后面的系列也将会看到如此设置会为AdaBoost带来一些良好的统计性质(训练误差上界会随着弱分类器的错误率
e
m
e_m
em的上界的减小以指数速率下降,从而解释了AdaBoost为什么可以work)。
首先证明
α
m
\alpha_m
αm是一个非负值。
由于是一个二分类问题,所以我们可以假定每一个弱分类器在训练集的带权分类正确率的下限是
0.5
0.5
0.5,若不然,则将原本预测为正类的预测为负类,负类则预测为正类,便可以使带权分类误差率
e
m
⩽
0.5
e_m \leqslant0.5
em⩽0.5。于是有
即
α
m
=
1
2
l
o
g
(
1
e
m
−
1
)
⩾
1
2
l
o
g
1
=
0
\begin{aligned} \alpha_m &= \frac{1}{2}log(\frac{1}{e_m}-{1}) \\ &\geqslant \frac{1}{2}log1 = 0 \end{aligned}
αm=21log(em1−1)⩾21log1=0
其次,不难证明该函数值 α m \alpha_m αm随着 e m e_m em的增加而减少,这一点也正好应合了我们的直觉,即带权分类正确率越高的弱分类器,话语权越大。
解决了弱分类器间的组合策略问题后,我们来解决前面两个重要问题中的第一条,每一轮训练弱分类器时要更加重视上一轮弱分类器分类错误的样本,相信你已经猜到,这里的更加重视即是通过某个公式去增加上一轮被分类错误样本的权值且减少上一轮被分类正确样本的权值从而达成该目的。
我们在已知第 m m m轮样本权值分布 D m D_m Dm的前提下,来看看AdaBoost如何更新权重的
D
m
→
D
m
+
1
D_m \rightarrow D_{m+1}
Dm→Dm+1
D
m
+
1
=
(
ω
m
+
1
,
1
,
ω
m
+
1
,
2
,
…
,
ω
m
+
1
,
N
)
D_{m+1} = (\omega_{m+1,1},\omega_{m+1,2},\ldots,\omega_{m+1,N})
Dm+1=(ωm+1,1,ωm+1,2,…,ωm+1,N)
ω
m
+
1
,
i
=
ω
m
i
Z
m
e
x
p
(
−
α
m
y
i
G
m
(
x
i
)
)
,
i
=
1
,
2
…
,
N
\omega_{m+1,i} = \frac{\omega_{mi}}{Z_m}exp(-\alpha_my_iG_m(x_i)),\quad i = 1,2\ldots,N
ωm+1,i=Zmωmiexp(−αmyiGm(xi)),i=1,2…,N
其中,
Z
m
Z_m
Zm是归一化因子,保证更新后的样本分布是一个概率分布,即
Z
m
=
∑
i
=
1
N
ω
m
i
e
x
p
(
−
α
m
y
i
G
m
(
x
i
)
)
Z_m = \sum_{i=1}^{N}\omega_{mi}exp(-\alpha_my_iG_m(x_i))
Zm=i=1∑Nωmiexp(−αmyiGm(xi))
我们对于上面这个样本权值更新公式稍加变形,来看看其是否具有我们想要的性质。
首先, G m G_m Gm是一个二分类学习算法学习得到的分类器,则其值只能取±1。故 ω m + 1 , i \omega_{m+1,i} ωm+1,i的值可分为下面两种情况:
ω
m
+
1
,
i
=
{
ω
m
i
Z
m
e
x
p
(
−
α
m
)
G
m
(
x
i
)
=
y
i
ω
m
i
Z
m
e
x
p
(
α
m
)
G
m
(
x
i
)
≠
y
i
\omega_{m+1,i} = \begin{cases} \frac{\omega_{mi}}{Z_m}exp(-\alpha_m) & G_m(x_i) = y_i\\ \frac{\omega_{mi}}{Z_m}exp(\alpha_m) & G_m(x_i) \neq y_i \end{cases}
ωm+1,i={Zmωmiexp(−αm)Zmωmiexp(αm)Gm(xi)=yiGm(xi)=yi
而通过上面的推导我们已经知道了
α
m
⩾
0
\alpha_m \geqslant 0
αm⩾0。于是被分类错误样本在新的样本权值分布中的份量增大,分类正确的样本在新的样本权值分布中的份量减小。(
e
x
p
(
−
α
m
)
⩽
1
exp(-\alpha_m)\leqslant 1
exp(−αm)⩽1,比较相对增减时归一化因子
Z
m
Z_m
Zm可以直接忽略)
另一方面,从上式也可以看出关于样本权值更新幅度与本轮弱分类器权值的关系,本轮分类器话语权越大,即 α m \alpha_m αm越大,增长与减小的幅度就越大,这也可以间接反应比较精妙的弱分类器在最终的强分类器的地位较高。
到此刻,前面提出的问题——为什么要保证样本权值是一个类似概率分布的形式就很好解答了,若没有这一设置, e m ⩽ 0.5 e_m \leqslant0.5 em⩽0.5这一条件便会消失,从而会带来一系列问题使其与下面的一系列公式无法融洽相处(各位可自行探讨)。
我们在上面分别说明了AdaBoost是如何解决开始提出的两大问题后,得到AdaBoost的初始形式的算法(这里我懒,直接摆图吧)
需要特别指出的是,我与上算法图中阐述认知不同的一点在 e m > 0.5 e_m>0.5 em>0.5时做预测标签的反转操作而不应直接break(但直观感觉上貌似没多大影响,待我实验过后会补到后续的博客中。)