文章目录
1. 提升算法AdaBoost算法
1.1 简介与定义
提升方法基于这样一个思想:对于一个复杂任务来说,将多个专家的判断进行适当的综合所得出的判断,要比其中任何一个专家单独的判断好。对于分类问题而言,给定一个训练数据集,求比较粗糙的分类规则(弱分类器)要比求景区的分类规则(强分类器)容易得多。提升方法就是从若学习算法出发,反复学习,得到一系列弱分类器,然后组合这些弱分类器,构成一个强分类器。这样,对提升方法而言,存在两个需要回答的问题:每一轮如何改变训练数据的权值或概率分布;如何将弱分类器组成一个强分类器。
1.2 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)}
其中,每个样本点由实例与标记组成。实例 x i ∈ X ⊂ R n x_i\in\mathcal X\subset\bold R^n xi∈X⊂Rn,标记 y i ∈ Y = { − 1 , + 1 } y_i\in\mathcal Y=\{-1,+1\} yi∈Y={−1,+1}, X \mathcal X X是实例空间, Y \mathcal Y Y是标记集合。 A d a B o o s t {\rm AdaBoost} 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)},其中 x i ∈ X ⊂ R n x_i\in\mathcal X\subset\bold R^n xi∈X⊂Rn, y i ∈ Y = { − 1 , + 1 } y_i\in\mathcal Y=\{-1,+1\} yi∈Y={−1,+1};弱学习算法;
输出 最终分类器 G ( x ) G(x) G(x)。
(1)初始化训练数据的权值分布: D 1 = ( w 11 , . . . , w 1 i , . . . , w 1 N ) , w 1 i = 1 N , i = 1 , 2 , . . . , N D_1=(w_{11},...,w_{1i},...,w_{1N}),\ \ w_{1i}=\frac{1}{N},\ \ i=1,2,...,N D1=(w11,...,w1i,...,w1N), w1i=N1, i=1,2,...,N
(2)对 m = 1 , 2 , . . . , M m=1,2,...,M m=1,2,...,M
(2-1)使用具有权值分布 D m D_m Dm的训练数据集学习,得到基本分类器: G m ( x ) : X → { − 1 , + 1 } G_m(x):\mathcal X\rightarrow\{-1,+1\} Gm(x):X→{−1,+1}
(2-2)计算 G m ( x ) G_m(x) Gm(x)在训练数据集上的分类误差率: e m = ∑ i = 1 N P ( G m ( x i ) ≠ y i ) = ∑ i = 1 N w m i I ( G m ( x i ) ≠ y i ) (1) e_m=\sum_{i=1}^NP(G_m(x_i)\not=y_i)=\sum_{i=1}^Nw_{mi}I(G_m(x_i)\not=y_i)\tag{1} em=i=1∑NP(Gm(xi)=yi)=i=1∑NwmiI(Gm(xi)=yi)(1)
(2-3)计算 G m ( x ) G_m(x) Gm(x)的系数: α m = 1 2 log 1 − e m e m \alpha_m=\frac{1}{2}\log\frac{1-e_m}{e_m} αm=21logem1−em
(2-4)更新训练数据集的权值分布: 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 exp ( − α m y i G m ( x i ) ) , i = 1 , 2 , . . . , N (2) w_{m+1,i}=\frac{w_{mi}}{Z_m}\exp(-\alpha_my_iG_m(x_i)),\ \ i=1,2,...,N\tag{2} wm+1,i=Zmwmiexp(−αmyiGm(xi)), i=1,2,...,N(2)
这里, Z m Z_m Zm是规范化因子: Z m = ∑ i = 1 N exp ( − α m y i G m ( x i ) ) (3) Z_m=\sum_{i=1}^N\exp(-\alpha_my_iG_m(x_i))\tag{3} Zm=i=1∑Nexp(−αmyiGm(xi))(3)
它使 D m + 1 D_{m+1} Dm+1称为一个概率分布。
(3)构建基本分类器的线性组合: f ( x ) = ∑ m = 1 M α m G m ( x ) (4) f(x)=\sum_{m=1}^M\alpha_mG_m(x)\tag{4} f(x)=m=1∑MαmGm(x)(4)
得到最终分类器:
G
(
x
)
=
s
i
g
n
(
f
(
x
)
)
=
s
i
g
n
(
∑
m
=
1
N
α
m
G
m
(
x
)
)
(5)
\begin{aligned} G(x)&={\rm sign}(f(x))\\&={\rm sign}\left(\sum_{m=1}^N\alpha_mG_m(x)\right) \end{aligned}\tag{5}
G(x)=sign(f(x))=sign(m=1∑NαmGm(x))(5)
例题 给定下表训练数据集,假设弱分类器由 x < v x<v x<v或 x > v x>v x>v产生,其阈值 v v v使该分类器在训练数据集上分类误差率最低。
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
x | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
y | 1 | 1 | 1 | -1 | -1 | -1 | 1 | 1 | 1 | -1 |
解 初始化权重分布: D 1 = ( w 11 , w 12 , . . . , w 110 ) D_1=(w_{11},w_{12},...,w_{110}) D1=(w11,w12,...,w110)
w 1 i = 0.1 , i = 1 , 2 , . . . , 10 w_{1i}=0.1,\ \ i=1,2,...,10 w1i=0.1, i=1,2,...,10
对 m = 1 m=1 m=1,在权值分布 D 1 D_1 D1的训练数据上,阈值 v v v取 2.5 2.5 2.5时分类误差率最低,故基本分类器为 G 1 ( x ) = { 1 , x < 2.5 − 1 , x > 2.5 G_1(x)=\left\{ \begin{aligned} 1, & & x<2.5 \\ -1, & & x>2.5 \end{aligned} \right. G1(x)={1,−1,x<2.5x>2.5
G 1 ( x ) G_1(x) G1(x)在训练数据集上的误差率 e 1 = P ( G 1 ( x i ) ≠ y i ) = 0.3 e_1=P(G_1(x_i)\not=y_i)=0.3 e1=P(G1(xi)=yi)=0.3。计算 G 1 ( x ) G_1(x) G1(x)的系数: α 1 = 1 / 2 log ( 1 − e 1 ) / e 1 = 0.4236 \alpha_1=1/2\log(1-e_1)/e_1=0.4236 α1=1/2log(1−e1)/e1=0.4236。更新训练数据的权值分布: D 2 = ( w 21 , . . . , w 2 i , . . . , w 210 ) D_2=(w_{21},...,w_{2i},...,w_{210}) D2=(w21,...,w2i,...,w210)
w 2 i = w 1 i Z 1 exp ( − α 1 y i G 1 ( x i ) ) , i = 1 , 2 , . . . , N w_{2i}=\frac{w_{1i}}{Z_1}\exp(-\alpha_1y_iG_1(x_i)),\ \ i=1,2,...,N w2i=Z1w1iexp(−α1yiG1(xi)), i=1,2,...,N
D 2 = ( 0.07143 , 0.07143 , 0.07143 , 0.07143 , 0.07143 , 0.07143 , 0.16667 , 0.16667 , 0.16667 , 0.07143 ) D_2=(0.07143,0.07143,0.07143,0.07143,0.07143,0.07143,0.16667,0.16667,0.16667,0.07143) D2=(0.07143,0.07143,0.07143,0.07143,0.07143,0.07143,0.16667,0.16667,0.16667,0.07143)
f 1 ( x ) = 0.4236 G 1 ( x ) f_1(x)=0.4236G_1(x) f1(x)=0.4236G1(x)
分类器 s i g n [ f 1 ( x ) ] {\rm sign}[f_1(x)] sign[f1(x)]在训练数据集上有 3 3 3个误分类点。
对 m = 2 m=2 m=2,在权值分布 D 2 D_2 D2的训练数据上,阈值 v v v是 8.5 8.5 8.5时分类误差率最低,基本分类器为 G 2 ( x ) = { 1 , x < 8.5 − 1 , x > 8.5 G_2(x)=\left\{ \begin{aligned} 1, & & x<8.5 \\ -1, & & x>8.5 \end{aligned} \right. G2(x)={1,−1,x<8.5x>8.5
G
2
(
x
)
G_2(x)
G2(x)在训练数据集上的误差率为
e
2
=
0.2143
e_2=0.2143
e2=0.2143。计算
α
2
=
0.6496
\alpha_2=0.6496
α2=0.6496。更新训练数据权值分布:
D
3
=
(
0.0455
,
0.0455
,
0.0455
,
0.1667
,
0.1667
,
0.1667
,
0.1060
,
0.1060
,
0.1060
,
0.0455
)
D_3=(0.0455,0.0455,0.0455,0.1667,0.1667,0.1667,0.1060,0.1060,0.1060,0.0455)
D3=(0.0455,0.0455,0.0455,0.1667,0.1667,0.1667,0.1060,0.1060,0.1060,0.0455)
f 2 ( x ) = 0.4236 G 1 ( x ) + 0.6496 G 2 ( x ) f_2(x)=0.4236G_1(x)+0.6496G_2(x) f2(x)=0.4236G1(x)+0.6496G2(x)
分类器 s i g n [ f 2 ( x ) ] {\rm sign}[f_2(x)] sign[f2(x)]在训练数据集上有 3 3 3个误分类点。
对 m = 3 m=3 m=3,在权值分布 D 3 D_3 D3的训练数据上,阈值 v v v是 5.5 5.5 5.5时分类误差率最低,基本分类器为 G 3 ( x ) = { 1 , x < 5.5 − 1 , x > 5.5 G_3(x)=\left\{ \begin{aligned} 1, & & x<5.5 \\ -1, & & x>5.5 \end{aligned} \right. G3(x)={1,−1,x<5.5x>5.5
G
3
(
x
)
G_3(x)
G3(x)在训练数据集上的误差率为
e
3
=
0.1820
e_3=0.1820
e3=0.1820。计算
α
3
=
0.7514
\alpha_3=0.7514
α3=0.7514。更新训练数据权值分布:
D
3
=
(
0.125
,
0.125
,
0.125
,
0.102
,
0.102
,
0.102
,
0.065
,
0.065
,
0.065
,
0.065
,
0.125
)
D_3=(0.125,0.125,0.125,0.102,0.102,0.102,0.065,0.065,0.065,0.065,0.125)
D3=(0.125,0.125,0.125,0.102,0.102,0.102,0.065,0.065,0.065,0.065,0.125)
分类器 s i g n [ f 3 ( x ) ] {\rm sign}[f_3(x)] sign[f3(x)]在训练数据集上的误分类点个数为 0 0 0。于是,最终的分类器为:
G ( x ) = s i g n [ f 3 ( x ) ] = s i g n [ 0.4236 G 1 ( x ) + 0.6496 G 2 ( x ) + 0.7514 G 3 ( x ) ] G(x)={\rm sign}[f_3(x)]={\rm sign}[0.4236G_1(x)+0.6496G_2(x)+0.7514G_3(x)] G(x)=sign[f3(x)]=sign[0.4236G1(x)+0.6496G2(x)+0.7514G3(x)]
1.3 AdaBoost算法的训练误差分析
A d a B o o s t {\rm AdaBoost} AdaBoost最基本的性质是它能在学习过程中不断减少训练误差,即在训练数据集上的数据的分类误差率。
AdaBoost的训练误差界 A d a B o o s t {\rm AdaBoost} AdaBoost算法最终分类器的训练误差界为: 1 N ∑ i = 1 N I ( G i ( x i ) ≠ y i ) ≤ 1 N ∑ i exp ( − y i f ( x i ) ) = ∏ m Z m (6) \frac{1}{N}\sum_{i=1}^NI(G_i(x_i)\not=y_i)\leq\frac{1}{N}\sum_i\exp(-y_if(x_i))=\prod_mZ_m\tag{6} N1i=1∑NI(Gi(xi)=yi)≤N1i∑exp(−yif(xi))=m∏Zm(6)
证明 当 G ( x i ) ≠ y i G(x_i)\not=y_i G(xi)=yi时, y i f ( x i ) < 0 y_if(x_i)<0 yif(xi)<0,因而 exp ( − y i f ( x i ) ) ≥ 1 \exp(-y_if(x_i))\geq1 exp(−yif(xi))≥1,由此前半部分的不等式得证。由 Z m Z_m Zm的定义,有: w m i exp ( − α m y i G m ( x i ) ) = Z m w m + 1 , i w_{mi}\exp(-\alpha_my_iG_m(x_i))=Z_mw_{m+1,i} wmiexp(−αmyiGm(xi))=Zmwm+1,i
1 N ∑ i exp ( − y i f ( x i ) ) = 1 N ∑ i exp ( − ∑ m = 1 M α m y i G m ( x i ) ) = ∑ i w 1 i ∏ m = 1 M exp ( − α m y i G m ( x i ) ) = Z 1 ∑ i w 2 i ∏ m = 2 M exp ( − α m y i G m ( x i ) ) = Z 1 Z 2 ∑ i w 3 i ∏ m = 2 M exp ( − α m y i G m ( x i ) ) = . . . = Z 1 Z 2 . . . Z M − 1 ∑ i w 2 i ∏ m = 2 M exp ( − α m y i G m ( x i ) ) = ∏ m = 1 M Z m \begin{aligned} \frac{1}{N}\sum_i\exp(-y_if(x_i))&=\frac{1}{N}\sum_i\exp\left(-\sum_{m=1}^M\alpha_my_iG_m(x_i)\right)\\&=\sum_iw_{1i}\prod_{m=1}^M\exp(-\alpha_my_iG_m(x_i))\\&=Z_1\sum_iw_{2i}\prod_{m=2}^M\exp(-\alpha_my_iG_m(x_i))\\&=Z_1Z_2\sum_iw_{3i}\prod_{m=2}^M\exp(-\alpha_my_iG_m(x_i))\\&=...\\&=Z_1Z_2...Z_{M-1}\sum_iw_{2i}\prod_{m=2}^M\exp(-\alpha_my_iG_m(x_i))\\&=\prod_{m=1}^MZ_m \end{aligned} N1i∑exp(−yif(xi))=N1i∑exp(−m=1∑MαmyiGm(xi))=i∑w1im=1∏Mexp(−αmyiGm(xi))=Z1i∑w2im=2∏Mexp(−αmyiGm(xi))=Z1Z2i∑w3im=2∏Mexp(−αmyiGm(xi))=...=Z1Z2...ZM−1i∑w2im=2∏Mexp(−αmyiGm(xi))=m=1∏MZm
二分类问题AdaBoost的训练误差界 ∏ m = 1 M Z m = ∏ m = 1 M [ 2 e m ( 1 − e m ) ] = ∏ m = 1 M 1 − 4 γ m 2 ≤ exp ( − 2 ∑ m = 1 M γ m 2 ) (7) \begin{aligned} \prod_{m=1}^MZ_m&=\prod_{m=1}^M[2\sqrt{e_m(1-e_m)}]\\&=\prod_{m=1}^M\sqrt {1-4\gamma_m^2}\\&\leq\exp\left(-2\sum_{m=1}^M\gamma_m^2\right) \end{aligned}\tag{7} m=1∏MZm=m=1∏M[2em(1−em)]=m=1∏M1−4γm2≤exp(−2m=1∑Mγm2)(7)
证明 由 Z m Z_m Zm的定义及式(1): Z m = ∑ i = 1 N w m i exp ( − α m y i G m ( x i ) ) = ∑ y i = G m ( x i ) w m i e − α m ∑ y i ≠ G m ( x i ) w m i e α m = ( 1 − e m ) e − α m + e m e α m = 2 e m ( 1 − e m ) = 1 − 4 γ m 2 \begin{aligned} Z_m&=\sum_{i=1}^Nw_{mi}\exp(-\alpha_my_iG_m(x_i))\\&=\sum_{y_i=G_m(x_i)}w_{mi}e^{-\alpha_m}\sum_{y_i\not=G_m(x_i)}w_{mi}e^{\alpha_m}\\&=(1-e_m)e^{-\alpha_m}+e_me^{\alpha_m}\\&=2\sqrt{e_m(1-e_m)}\\&=\sqrt{1-4\gamma_m^2} \end{aligned} Zm=i=1∑Nwmiexp(−αmyiGm(xi))=yi=Gm(xi)∑wmie−αmyi=Gm(xi)∑wmieαm=(1−em)e−αm+emeαm=2em(1−em)=1−4γm2
对于不等式: ∏ m = 1 M ( 1 − 4 γ m 2 ) ≤ exp ( − 2 ∑ m = 1 M γ m 2 ) \prod_{m=1}^M\sqrt{(1-4\gamma_m^2)}\leq\exp\left(-2\sum_{m=1}^M\gamma_m^2\right) m=1∏M(1−4γm2)≤exp(−2m=1∑Mγm2)
则可先由 e x e^x ex和 1 − x \sqrt{1-x} 1−x在 x = 0 x=0 x=0的泰勒展开推出不等式 ( 1 − 4 γ m 2 ) ≤ exp ( − 2 γ m 2 ) \sqrt{(1-4\gamma_m^2)}\leq\exp(-2\gamma_m^2) (1−4γm2)≤exp(−2γm2),进而得到。
推论 如果存在 γ > 0 \gamma>0 γ>0,对所有 m m m有 γ m ≥ γ \gamma_m\geq\gamma γm≥γ,则: 1 N ∑ i = 1 N I ( G ( x i ) ≠ y i ) ≤ exp ( − 2 M γ 2 ) \frac{1}{N}\sum_{i=1}^NI(G(x_i)\not=y_i)\leq\exp(-2M\gamma^2) N1i=1∑NI(G(xi)=yi)≤exp(−2Mγ2)
1.4 AdaBoost算法的解释
A d a B o o s t {\rm AdaBoost} AdaBoost算法还有另外一个解释:即模型为加法模型、损失函数为指数函数、学习算法为前向分步算法时的二分类学习方法。
1.4.1 前向分步算法
考虑加法模型: f ( x ) = ∑ m = 1 M β m b ( x ; γ m ) f(x)=\sum_{m=1}^M\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))的条件下,学习加法模型成为经验风险极小化: min β m , γ m ∑ i = 1 N L ( y i , ∑ m = 1 M β m b ( x i ; γ m ) ) (8) \min_{\beta_m,\gamma_m}\sum_{i=1}^NL\left(y_i,\sum_{m=1}^M\beta_mb(x_i;\gamma_m)\right)\tag{8} βm,γmmini=1∑NL(yi,m=1∑Mβmb(xi;γm))(8)
这时一个复杂的优化问题,前向分步算法的思路是:因为学习的时加法模型,如果能够从前往后,每一步只学习一个基函数及其系数,逐步逼近优化目标函数式,那么就可以简化优化的复杂度。具体地,每一步只需优化以下函数: min β , γ ∑ i = 1 N L ( y i , β b ( x i ; γ ) ) (9) \min_{\beta,\gamma}\sum_{i=1}^NL(y_i,\beta b(x_i;\gamma))\tag{9} β,γmini=1∑NL(yi,βb(xi;γ))(9)
前向分步算法
输入 训练数据集 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 ) f(x) f(x)。
(1)初始化 f ( x 0 ) = 0 f(x_0)=0 f(x0)=0;
(2)对 m = 1 , 2 , . . . , M m=1,2,...,M m=1,2,...,M
(2-1)极小化损失函数: ( β m , γ m ) = arg min β , γ ∑ i = 1 N L ( y i , f m − 1 ( x i ) + β b ( x i ; γ ) ) (\beta_m,\gamma_m)=\arg \min_{\beta,\gamma}\sum_{i=1}^NL(y_i,f_{m-1}(x_i)+\beta b(x_i;\gamma)) (βm,γm)=argβ,γmini=1∑NL(yi,fm−1(xi)+βb(xi;γ))
得到参数 β m \beta_m βm, γ \gamma γ;
(2-2)更新: 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)
(3)得到加法模型: f ( x ) = f M ( x ) = ∑ m = 1 M β m b ( x ; γ m ) f(x)=f_M(x)=\sum_{m=1}^M\beta_mb(x;\gamma_m) f(x)=fM(x)=m=1∑Mβmb(x;γm)
1.4.2 前向分步算法与AdaBoost
定理 A d a B o o s t {\rm AdaBoost} AdaBoost算法是前向分步加法算法的特例。这时,模型是由基本分类器组成的加法模型,损失函数是指数函数。
2. 提升树
2.1 提升树模型
提升方法实际采用加法模型与前向分步算法。以决策树为基函数的提升方法称为提升树。基本分类器如 x < v x<v x<v或 x > v x>v x>v,可以看作是由一个根结点直接连接两个叶结点的简单决策树,即所谓的决策树桩。提升树模型可以表示为决策树的加法模型: f M ( x ) = ∑ m = 1 M T ( x ; Θ m ) f_M(x)=\sum_{m=1}^MT(x;\Theta_m) fM(x)=m=1∑MT(x;Θm)
其中, T ( x ; Θ m ) T(x;\Theta_m) T(x;Θm)表示决策树, Θ m \Theta_m Θm为决策树参数, M M M为树的个数。
2.2 提升树算法
提升树算法采用前向分步算法。首先确定初始提升树 f 0 ( x ) = 0 f_0(x)=0 f0(x)=0,第 m m m步的模型是: f m ( x ) = f m − 1 ( x ) + T ( x ; Θ m ) f_m(x)=f_{m-1}(x)+T(x;\Theta_m) fm(x)=fm−1(x)+T(x;Θm)
其中, f m − 1 ( x ) f_{m-1}(x) fm−1(x)表示当前模型,通过经验风险最小化确定下一棵决策树的参数 Θ m \Theta_m Θm: Θ ^ m = arg min Θ m ∑ i = 1 N L ( y i , f m − 1 ( x i ) + T ( x i ; Θ m ) ) \hat\Theta_m=\arg\min_{\Theta_m}\sum_{i=1}^NL(y_i,f_{m-1}(x_i)+T(x_i;\Theta_m)) Θ^m=argΘmmini=1∑NL(yi,fm−1(xi)+T(xi;Θm))
由于树的线性组合可以很好地拟合训练数据,即使数据的输入与输出之间的关系很复杂也是如此,所以提升树是一个高功能的学习算法。而对于二分类问题,提升树算法只需将基本分类器限制为二分类树即可。这里介绍回归问题的提升树。已知一个训练集 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)}, x i ∈ X ⊂ R n x_i\in\mathcal X\subset\bold R^n xi∈X⊂Rn, X \mathcal X X为输入空间, y i ∈ Y ⊂ R n y_i\in\mathcal Y\subset\bold R^n yi∈Y⊂Rn, Y \mathcal Y Y为输出空间。现在,如果将输入空间 X \mathcal X X划分为 J J J个互不相交的区域 R 1 , R 2 , . . . , R J R_1,R_2,...,R_J R1,R2,...,RJ,并且在每个区域上确定输出的常量 c j c_j cj,那么树可以表示为: T ( x ; Θ ) = ∑ j = 1 J c j I ( x ∈ R j ) T(x;\Theta)=\sum_{j=1}^Jc_jI(x\in R_j) T(x;Θ)=j=1∑JcjI(x∈Rj)
其中,参数 Θ = { ( R 1 , c 1 ) , ( R 2 , c 2 ) , . . . , ( R J , c J ) } \Theta=\{(R_1,c_1),(R_2,c_2),...,(R_J,c_J)\} Θ={(R1,c1),(R2,c2),...,(RJ,cJ)}表示树的区域和各区域上的常数。 J J J是回归树的复杂度也即叶结点个数。回归问题的提升树使用以下前向分步算法: f 0 ( x ) = 0 f_0(x)=0 f0(x)=0
f m ( x ) = f m − 1 ( x ) = T ( x ; Θ m ) , m = 1 , 2 , . . . , M f_m(x)=f_{m-1}(x)=T(x;\Theta_m),\ m=1,2,...,M fm(x)=fm−1(x)=T(x;Θm), m=1,2,...,M
f M ( x ) = ∑ i = 1 M T ( x ; Θ m ) f_M(x)=\sum_{i=1}^MT(x;\Theta_m) fM(x)=i=1∑MT(x;Θm)
在前向分步算法的第 m m m步,给定当前模型 f m − 1 ( x ) f_{m-1}(x) fm−1(x),需求解: Θ ^ m = arg min Θ m ∑ i = 1 N L ( y i , f m − 1 ( x i ) + T ( x i ; Θ m ) ) \hat\Theta_m=\arg\min_{\Theta_m}\sum_{i=1}^NL(y_i,f_{m-1}(x_i)+T(x_i;\Theta_m)) Θ^m=argΘmmini=1∑NL(yi,fm−1(xi)+T(xi;Θm))
得到 Θ ^ m \hat\Theta_m Θ^m,即第 m m m棵树的参数。当采用平方误差损失函数时: L ( y , f ( x ) ) = ( y − f ( x ) ) 2 L(y,f(x))=(y-f(x))^2 L(y,f(x))=(y−f(x))2
其损失变为: L ( y , f m − 1 ( x ) + T ( x ; Θ m ) ) = [ y − f m − 1 ( x ) − T ( x ; Θ m ) ] 2 = [ r − T ( x ; Θ m ) ] 2 \begin{aligned} L(y,f_{m-1}(x)+T(x;\Theta_m))&=[y-f_{m-1}(x)-T(x;\Theta_m)]^2\\&=[r-T(x;\Theta_m)]^2 \end{aligned} L(y,fm−1(x)+T(x;Θm))=[y−fm−1(x)−T(x;Θm)]2=[r−T(x;Θm)]2
这里, r = y − f m − 1 ( x ) r=y-f_{m-1}(x) r=y−fm−1(x)是当前模型拟合数据的残差。所以,对于回归问题的提升树算法来说,只需简单地拟合当前模型的残差。
回归问题的提升树算法
输入 训练数据集 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)}, x i ∈ X ⊂ R n x_i\in\mathcal X\subset\bold R^n xi∈X⊂Rn, y i ∈ Y ⊂ R n y_i\in\mathcal Y\subset\bold R^n yi∈Y⊂Rn;
输出 提升树 f M ( x ) f_M(x) fM(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
(2-1)计算残差 r m i = y i − f m − 1 ( x i ) , i = 1 , 2 , . . . , N r_{mi}=y_i-f_{m-1}(x_i),\ i=1,2,...,N rmi=yi−fm−1(xi), i=1,2,...,N;
(2-2)拟合残差 r m i r_{mi} rmi学习一个回归树,得到 T ( x ; Θ m ) T(x;\Theta_m) T(x;Θm);
(3)得到回归问题提升树: f M ( x ) = ∑ i = 1 M T ( x ; Θ m ) f_M(x)=\sum_{i=1}^MT(x;\Theta_m) fM(x)=i=1∑MT(x;Θm)
例题 使用以下数据学习这个回归问题的提升树模型,只用树桩作为基函数。
x i x_i xi | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
y i y_i yi | 5.56 | 5.70 | 5.91 | 6.40 | 6.80 | 7.05 | 8.90 | 8.70 | 9.00 | 9.05 |
解 首先求 f 1 ( x ) f_1(x) f1(x),即回归树 T 1 ( x ) T_1(x) T1(x)。根据以下最优化问题: min s [ min c 1 ∑ x i ∈ R 1 ( y i − c 1 ) 2 + min c 2 ∑ x i ∈ R 2 ( y i − c 2 ) 2 ] \min_s\left[\min_{c_1}\sum_{x_i\in R_1}(y_i-c_1)^2+\min_{c_2}\sum_{x_i\in R_2}(y_i-c_2)^2\right] smin[c1minxi∈R1∑(yi−c1)2+c2minxi∈R2∑(yi−c2)2]
求解训练数据的切分点 s s s: R 1 = { x ∣ x ≤ s } , R 2 = { x ∣ x > s } R_1=\{x|x\leq s\},\ \ R_2=\{x|x>s\} R1={x∣x≤s}, R2={x∣x>s}
容易求得在 R 1 , R 2 R_1,R_2 R1,R2内部使平方损失误差达到最小值的 c 1 c_1 c1, c 2 c_2 c2为: c 1 = 1 N 1 ∑ x i ∈ R 1 y i , c 2 = 1 N 2 ∑ x i ∈ R 2 y i c_1=\frac{1}{N_1}\sum_{x_i\in R_1}y_i,\ \ c_2=\frac{1}{N_2}\sum_{x_i\in R_2}y_i c1=N11xi∈R1∑yi, c2=N21xi∈R2∑yi
这里 N 1 , N 2 N_1,N_2 N1,N2分别表示 R 1 , R 2 R_1,R_2 R1,R2的样本点数。对于训练数据,考虑如下切分点: 1.5 , 2.5 , 3.5 , 4.5 , 5.5 , 6.5 , 7.5 , 8.5 , 9.5 1.5,\ 2.5,\ 3.5,\ 4.5,\ 5.5,\ 6.5,\ 7.5,\ 8.5,\ 9.5 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5
对各切分点,依次求出 R 1 , R 2 , c 1 , c 2 R_1,R_2,c_1,c_2 R1,R2,c1,c2以及: m ( s ) = min c 1 ∑ x i ∈ R 1 ( y i − c 1 ) 2 + min c 2 ∑ x i ∈ R 2 ( y i − c 2 ) 2 m(s)=\min_{c_1}\sum_{x_i\in R_1}(y_i-c_1)^2+\min_{c_2}\sum_{x_i\in R_2}(y_i-c_2)^2 m(s)=c1minxi∈R1∑(yi−c1)2+c2minxi∈R2∑(yi−c2)2
如,当取切分点为 1.5 1.5 1.5时, R 1 = { 1 } , R 2 = { 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 } , c 1 = 5.56 , c 2 = 7.50 R_1=\{1\},\ R_2=\{2,3,4,5,6,7,8,9,10\}, \ c_1=5.56,\ c_2=7.50 R1={1}, R2={2,3,4,5,6,7,8,9,10}, c1=5.56, c2=7.50。先将各切分点的计算结果列表如下:
s s s | 1.5 | 2.5 | 3.5 | 4.5 | 5.5 | 6.5 | 7.5 | 8.5 | 9.5 |
---|---|---|---|---|---|---|---|---|---|
m ( s ) m(s) m(s) | 15.72 | 12.07 | 8.36 | 5.78 | 3.91 | 1.93 | 8.01 | 11.73 | 15.74 |
有表结果可知, s = 6.5 s=6.5 s=6.5时 m ( s ) m(s) m(s)达到最小值,此时 R 1 = { 1 , 2 , 3 , 4 , 5 , 6 } , R 2 = { 7 , 8 , 9 , 10 } , c 1 = 6.24 , c 2 = 8.91 R_1=\{1,2,3,4,5,6\},\ R_2=\{7,8,9,10\}, \ c_1=6.24,\ c_2=8.91 R1={1,2,3,4,5,6}, R2={7,8,9,10}, c1=6.24, c2=8.91,此时的回归树为: T 1 ( x ) = { 6.24 , x < 6.5 8.91 , x ≥ 6.5 T_1(x)=\left\{ \begin{aligned} & 6.24,\ &x<6.5 \\ & 8.91,\ &x\geq6.5 \end{aligned} \right. T1(x)={6.24, 8.91, x<6.5x≥6.5
f 1 ( x ) = T 1 ( x ) f_1(x)=T_1(x) f1(x)=T1(x)
用 f 1 ( x ) f_1(x) f1(x)拟合训练数据的残差如下:
x i x_i xi | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
r 2 i r_{2i} r2i | -0.68 | -0.54 | -0.33 | 0.16 | 0.56 | 0.81 | -0.01 | -0.21 | 0.09 | 0.14 |
用 f 1 ( x ) f_1(x) f1(x)拟合训练数据的平方损失误差: L ( y , f 1 ( x ) ) = ∑ i = 1 10 ( y i − f 1 ( x i ) ) 2 = 1.93 L(y,f_1(x))=\sum_{i=1}^{10}(y_i-f_1(x_i))^2=1.93 L(y,f1(x))=i=1∑10(yi−f1(xi))2=1.93
第二步求 T 2 ( x ) T_2(x) T2(x)。方法同 T 1 ( x ) T_1(x) T1(x),只是拟合的数据是上表中的残差: T 2 ( x ) = { − 0.52 , x < 3.5 0.22 , x ≥ 3.5 T_2(x)=\left\{ \begin{aligned} -0.52,\ \ &x<3.5 \\ 0.22,\ \ &x\geq3.5 \end{aligned} \right. T2(x)={−0.52, 0.22, x<3.5x≥3.5
f 2 ( x ) = f 1 ( x ) + T 2 ( x ) = { 5.72 , x < 3.5 6.46 , 3.5 ≤ x < 6.5 9.13 , x ≥ 6.5 f_2(x)=f_1(x)+T_2(x)=\left\{ \begin{aligned} & 5.72,\ \ x<3.5& \\ & 6.46,\ \ 3.5\leq x<6.5& \\ & 9.13,\ \ x\geq 6.5& \end{aligned} \right. f2(x)=f1(x)+T2(x)=⎩⎪⎨⎪⎧5.72, x<3.56.46, 3.5≤x<6.59.13, x≥6.5
用 f 2 ( x ) f_2(x) f2(x)拟合训练数据的平方损失误差: L ( y , f 1 ( x ) ) = ∑ i = 1 10 ( y i − f 1 ( x i ) ) 2 = 0.79 L(y,f_1(x))=\sum_{i=1}^{10}(y_i-f_1(x_i))^2=0.79 L(y,f1(x))=i=1∑10(yi−f1(xi))2=0.79
继续求得:
T
3
(
x
)
=
{
0.15
,
x
<
6.5
−
0.22
,
x
≥
6.5
L
(
y
,
f
3
(
x
)
)
=
0.47
T_3(x)=\left\{ \begin{aligned} 0.15,\ \ &x<6.5 \\ -0.22,\ \ &x\geq6.5 \end{aligned}\ \ \ \ \ \ \ L(y,f_3(x))=0.47 \right.
T3(x)={0.15, −0.22, x<6.5x≥6.5 L(y,f3(x))=0.47
T 4 ( x ) = { − 0.16 , x < 4.5 0.11 , x ≥ 4.5 L ( y , f 3 ( x ) ) = 0.30 T_4(x)=\left\{ \begin{aligned} -0.16,\ \ &x<4.5 \\ 0.11,\ \ &x\geq4.5 \end{aligned}\ \ \ \ \ \ \ L(y,f_3(x))=0.30 \right. T4(x)={−0.16, 0.11, x<4.5x≥4.5 L(y,f3(x))=0.30
T 5 ( x ) = { 0.07 , x < 6.5 − 0.11 , x ≥ 6.5 L ( y , f 3 ( x ) ) = 0.23 T_5(x)=\left\{ \begin{aligned} 0.07,\ \ &x<6.5 \\ -0.11,\ \ &x\geq6.5 \end{aligned}\ \ \ \ \ \ \ L(y,f_3(x))=0.23 \right. T5(x)={0.07, −0.11, x<6.5x≥6.5 L(y,f3(x))=0.23
T 6 ( x ) = { − 0.15 , x < 2.5 0.04 , x ≥ 2.5 T_6(x)=\left\{ \begin{aligned} -0.15,\ &x<2.5 \\ 0.04,\ &x\geq2.5 \end{aligned} \right. T6(x)={−0.15, 0.04, x<2.5x≥2.5
f 6 ( x ) = f 5 ( x ) + T 6 ( x ) = T 1 ( x ) + . . . + T 5 ( x ) + T 6 ( x ) = { 5.63 , x < 2.5 5.82 , 2.5 ≤ x < 3.5 6.56 , 3.5 ≤ x < 4.5 6.83 , 4.5 ≤ x < 6.5 8.95 , x ≥ 6.5 \begin{aligned} f_6(x)&=f_5(x)+T_6(x)=T_1(x)+...+T_5(x)+T_6(x)\\&=\left\{ \begin{aligned} & 5.63,\ & &x<2.5 \\ & 5.82,\ &&2.5\leq x<3.5 \\ & 6.56,\ &&3.5\leq x<4.5 \\ & 6.83,\ &&4.5\leq x<6.5 \\ & 8.95,\ &&x\geq 6.5 \end{aligned} \right. \end{aligned} f6(x)=f5(x)+T6(x)=T1(x)+...+T5(x)+T6(x)=⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧5.63, 5.82, 6.56, 6.83, 8.95, x<2.52.5≤x<3.53.5≤x<4.54.5≤x<6.5x≥6.5
用 f 6 ( x ) f_6(x) f6(x)拟合训练数据的平方损失误差: L ( y , f 1 ( x ) ) = ∑ i = 1 10 ( y i − f 1 ( x i ) ) 2 = 0.17 L(y,f_1(x))=\sum_{i=1}^{10}(y_i-f_1(x_i))^2=0.17 L(y,f1(x))=i=1∑10(yi−f1(xi))2=0.17
假设此时已经满足误差要求,那么 f ( x ) = f 6 ( x ) f(x)=f_6(x) f(x)=f6(x)即为所求提升树。
2.3 梯度提升
提升树利用加法模型与前向分步算法实现学习的优化过程。当损失函数是平方损失和指数函数时,每一步优化是很简单的。但对于一般的损失函数而言,往往采用梯度上升算法。这是利用最速下降法的近似方法,其关键是利用损失函数的负梯度在当前模型的值: − [ ∂ L ( y , f ( x i ) ) ∂ f ( x i ) ] f ( x ) = f m − 1 ( x ) -\left[\frac{\partial L(y,f(x_i))}{\partial f(x_i)}\right]_{f(x)=f_{m-1}(x)} −[∂f(xi)∂L(y,f(xi))]f(x)=fm−1(x)
作为回归问题提升树算法中的残差的近似值,拟合一个回归树。
梯度提升算法
输入 训练数据集 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)}, x i ∈ X ⊂ R n x_i\in\mathcal X\subset\bold R^n xi∈X⊂Rn, y i ∈ Y ⊂ R n y_i\in\mathcal Y\subset\bold R^n yi∈Y⊂Rn;
输出 回归树 f ^ ( x ) \hat f(x) f^(x)。
(1)初始化: f 0 ( x ) = arg min c ∑ i = 1 N L ( y i , c ) f_0(x)=\arg \min_c\sum_{i=1}^NL(y_i,c) f0(x)=argcmini=1∑NL(yi,c)
(2)对 m = 1 , 2 , . . . , M m=1,2,...,M m=1,2,...,M
(2-1)对 i = 1 , 2 , . . . , N i=1,2,...,N i=1,2,...,N,计算: r m i = − [ ∂ L ( y i , f ( x i ) ) ∂ f ( x i ) ] f ( x ) = f m − 1 ( x ) r_{mi}=-\left[\frac{\partial L(y_i,f(x_i))}{\partial f(x_i)}\right]_{f(x)=f_{m-1}(x)} rmi=−[∂f(xi)∂L(yi,f(xi))]f(x)=fm−1(x)
(2-2)对 r m i r_{mi} rmi拟合一个回归树,得到第 m m m棵树的叶结点区域 R m j , j = 1 , 2 , . . . , J R_{mj},j=1,2,...,J Rmj,j=1,2,...,J;
(2-3)对 j = 1 , 2 , . . . , J j=1,2,...,J j=1,2,...,J,计算: c m j = arg min c ∑ c i ∈ R m j L ( y i , f m − 1 ( x i ) + c ) c_{mj}=\arg\min_c\sum_{c_i\in R_{mj}}L(y_i,f_{m-1}(x_i)+c) cmj=argcminci∈Rmj∑L(yi,fm−1(xi)+c)
(2-4)更新: f m ( x ) = f m − 1 ( x ) + ∑ j = 1 J c m j I ( x ∈ R m j ) f_m(x)=f_{m-1}(x)+\sum_{j=1}^Jc_{mj}I(x\in R_{mj}) fm(x)=fm−1(x)+j=1∑JcmjI(x∈Rmj)
(3)得到回归树: f ^ ( x ) = f M ( x ) = ∑ m = 1 M ∑ j = 1 J c m j I ( x ∈ R m j ) \hat f(x)=f_M(x)=\sum_{m=1}^M\sum_{j=1}^Jc_{mj}I(x\in R_{mj}) f^(x)=fM(x)=m=1∑Mj=1∑JcmjI(x∈Rmj)
3. Python实现提升方法
首先加载数据集:
def load_data(file):
# 定义空列表
dataArr = []
labelArr = []
# 打开并处理文件
with open(file, "r") as f:
lines = f.readlines()
for line in lines:
# 针对csv文件格式,使用','分割数据
curLine = line.strip().split(',')
# csv文件第一列存放着具体类别
if int(curLine[0]) < 5:
labelArr.append(-1)
else:
labelArr.append(1)
# 处理具体数据,为了简化计算量,将像素取值限制在01两个部分
# 如果不简化,处理的数据量是10×784×256,现在是10×784×2
dataArr.append([int(int(num) > 128) for num in curLine[1:]])
# 返回
return dataArr, labelArr
计算错误率:
def cal_e_gx(train_data, train_label, n, div, relu, d):
# 计算分类错误率,首先初始化为零
e = 0
# 抽取第n列特征
x = train_data[:, n]
y = train_label
predict = []
if relu == "LisOne":
L = 1
H = -1
else:
L = -1
H = 1
# 遍历样本
for i in range(train_data.shape[0]):
if x[i] < div:
# 如果小于切分点,则预测为L
predict.append(L)
# 累计错误
if y[i] != L:
e += d[i]
else:
# 如果大于切分点,则预测为H
predict.append(H)
if y[i] != H:
e += d[i]
# 返回
return np.array(predict), e
创建单层决策树:
def cal_single_boosting_tree(train_data, train_label, d):
# 创建单层提升树
m, n = np.shape(train_data)
# 定义单层树的字典,用于存放该提升树的参数并初始化分类错误率
single_boost_tree = {'e': 1}
# 遍历寻找最佳切分点
for i in range(n):
# 由于特征经过了二值化后为0和1,切分点为-0.5,0.5和1.5
for div in [-0.5, 0.5, 1.5]:
for relu in ["LisOne", "HisOne"]:
# 第i个特征,以div值进行切分,得到预测结果和分类错误率
gx, e = cal_e_gx(train_data, train_label, i, div, relu, d)
# 是否为最小分类错误率,如果是则更新切分点等信息
if e < single_boost_tree['e']:
single_boost_tree['e'] = e
# 同时存储切分点、切分规则、预测结果、特征索引
single_boost_tree['div'] = div
single_boost_tree['relu'] = relu
single_boost_tree['gx'] = gx
single_boost_tree['feature'] = i
# 返回单层提升树
return single_boost_tree
创建整棵树:
# https://github.com/Dod-o/Statistical-Learning-Method_Code/blob/master/AdaBoost/AdaBoost.py#L166
def create_boosting_tree(train_data, train_label, tree_num=50):
# 创建提升树
train_data = np.array(train_data)
train_label = np.array(train_label)
m, n = np.shape(train_data)
# 根据AdaBoost算法,首先初始化权值分布为1/N
d = [1 / m] * m
# 初始化提升树列表,每个位置为一层
tree = []
# 循环创建提升树
for i in range(tree_num):
# 当前层的提升树
curr_tree = cal_single_boosting_tree(train_data, train_label, d)
# 计算G(x)的系数为alpha
alpha = 1 / 2 * np.log((1 - curr_tree['e']) / curr_tree['e'])
# 当前层的预测结果结果用于更新权值分布
gx = curr_tree["gx"]
d = np.multiply(d, np.exp(-1 * alpha * np.multiply(train_label, gx))) / sum(d)
# 增加alpha参数
curr_tree["alpha"] = alpha
# 将当前层添加到树中
tree.append(curr_tree)
# 返回整个提升树
return tree
根据给定输入产生预测结果:
def predict(x, div, relu, feature):
# 输出单层的预测结果,relu表示不同分类规则
if relu == "LisOne":
L = 1
H = -1
else:
L = -1
H = 1
# 判断预测结果
if x[feature] < div:
return L
else:
return H
测试集上的表现:
def model_test(test_data, test_label, tree):
errCnt = 0
# 遍历
for i in range(len(test_data)):
# 预测结果值,初始化为0
result = 0
# 遍历每层树
for curr_tree in tree:
# 该层树的信息参数
div = curr_tree["div"]
relu = curr_tree["relu"]
feature = curr_tree["feature"]
alpha = curr_tree["alpha"]
# 将当前层结果加入预测中
result += alpha * predict(test_data[i], div, relu, feature)
# 预测错误
if np.sign(result) != test_label[i]:
errCnt += 1
return 1 - errCnt / len(test_data)
4. 提升方法总结
提升方法是将弱学习算法提升为强学习算法的统计学习方法。在分类学习中,提升方法通过反复修改训练数据的权值分布,构建一系列基本分类器,并将这些基本分类线性组合以构成一个强分类器。其中较经典的提升方法是 A d a B o o s t {\rm AdaBoost} AdaBoost算法,它是一种加法模型,损失函数是指数函数,算法是前向分步算法。
参考
- 统计学习方法/李航著。—2版。—北京:清华大学出版社,2019(2019.6重印).
- https://github.com/Dod-o/Statistical-Learning-Method_Code(提升方法代码).