(七)统计学习方法 | 提升方法


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 xiXRn,标记 y i ∈ Y = { − 1 , + 1 } y_i\in\mathcal Y=\{-1,+1\} yiY={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 xiXRn y i ∈ Y = { − 1 , + 1 } y_i\in\mathcal Y=\{-1,+1\} yiY={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=1NP(Gm(xi)=yi)=i=1NwmiI(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=21logem1em

(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=1Nexp(α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=1Mα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=1NαmGm(x))(5)

例题 给定下表训练数据集,假设弱分类器由 x < v x<v x<v x > v x>v x>v产生,其阈值 v v v使该分类器在训练数据集上分类误差率最低。

序号12345678910
x0123456789
y111-1-1-1111-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(1e1)/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=1NI(Gi(xi)=yi)N1iexp(yif(xi))=mZm(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} N1iexp(yif(xi))=N1iexp(m=1MαmyiGm(xi))=iw1im=1Mexp(αmyiGm(xi))=Z1iw2im=2Mexp(αmyiGm(xi))=Z1Z2iw3im=2Mexp(αmyiGm(xi))=...=Z1Z2...ZM1iw2im=2Mexp(αmyiGm(xi))=m=1MZm

二分类问题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=1MZm=m=1M[2em(1em) ]=m=1M14γm2 exp(2m=1Mγ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=1Nwmiexp(αmyiGm(xi))=yi=Gm(xi)wmieαmyi=Gm(xi)wmieαm=(1em)eαm+emeαm=2em(1em) =14γ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=1M(14γm2) exp(2m=1Mγm2)

则可先由 e x e^x ex 1 − x \sqrt{1-x} 1x 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) (14γ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=1NI(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=1Mβ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=1NL(yi,m=1Mβ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=1NL(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=1NL(yi,fm1(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)=fm1(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=1Mβ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=1MT(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)=fm1(x)+T(x;Θm)

其中, f m − 1 ( x ) f_{m-1}(x) fm1(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=1NL(yi,fm1(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 xiXRn X \mathcal X X为输入空间, y i ∈ Y ⊂ R n y_i\in\mathcal Y\subset\bold R^n yiYRn 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=1JcjI(xRj)

其中,参数 Θ = { ( 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)=fm1(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=1MT(x;Θm)

在前向分步算法的第 m m m步,给定当前模型 f m − 1 ( x ) f_{m-1}(x) fm1(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=1NL(yi,fm1(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))=(yf(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,fm1(x)+T(x;Θm))=[yfm1(x)T(x;Θm)]2=[rT(x;Θm)]2

这里, r = y − f m − 1 ( x ) r=y-f_{m-1}(x) r=yfm1(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 xiXRn y i ∈ Y ⊂ R n y_i\in\mathcal Y\subset\bold R^n yiYRn

输出 提升树 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=yifm1(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=1MT(x;Θm)

例题 使用以下数据学习这个回归问题的提升树模型,只用树桩作为基函数。

x i x_i xi12345678910
y i y_i yi5.565.705.916.406.807.058.908.709.009.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[c1minxiR1(yic1)2+c2minxiR2(yic2)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={xxs},  R2={xx>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=N11xiR1yi,  c2=N21xiR2yi

这里 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)=c1minxiR1(yic1)2+c2minxiR2(yic2)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 s1.52.53.54.55.56.57.58.59.5
m ( s ) m(s) m(s)15.7212.078.365.783.911.938.0111.7315.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.5x6.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 xi12345678910
r 2 i r_{2i} r2i-0.68-0.54-0.330.160.560.81-0.01-0.210.090.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=110(yif1(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.5x3.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.5x<6.59.13,  x6.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=110(yif1(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.5x6.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.5x4.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.5x6.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.5x2.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.5x<3.53.5x<4.54.5x<6.5x6.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=110(yif1(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)=fm1(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 xiXRn y i ∈ Y ⊂ R n y_i\in\mathcal Y\subset\bold R^n yiYRn

输出 回归树 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=1NL(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)=fm1(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=argcminciRmjL(yi,fm1(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)=fm1(x)+j=1JcmjI(xRmj)

(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=1Mj=1JcmjI(xRmj)


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算法,它是一种加法模型,损失函数是指数函数,算法是前向分步算法。


参考

  1. 统计学习方法/李航著。—2版。—北京:清华大学出版社,2019(2019.6重印).
  2. https://github.com/Dod-o/Statistical-Learning-Method_Code(提升方法代码).


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值