文章目录
1. 提升树模型
提升方法实际采用加法模型(即基函数的线性组合)与前向分步算法。以决策树为基函数的提升方法称为提升树(boosting tree)。对分类问题决策树是二叉分类树,对回归问题决策树是二叉回归树。提升树模型可以表示为决策树的加法模型:
f
M
(
x
)
=
∑
m
=
1
M
T
(
x
;
θ
m
)
f _ { M } ( x ) = \sum _ { m = 1 } ^ { M } T ( 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. 提升树算法
提升树算法采用前向分步算法。首先确定初始提升树
f
0
(
x
)
=
0
f_0(x)=0
f0(x)=0 ,第m步的模型是:
f
m
(
x
)
=
f
m
−
1
(
x
)
+
T
(
x
;
Θ
m
)
f_m(x)=f_{m-1}(x)+T\left(x ; \Theta_m\right)
fm(x)=fm−1(x)+T(x;Θm)
其中,
f
m
−
1
(
x
)
f_{m-1}(x)
fm−1(x) 为当前模型,通过经验风险极小化确定下一棵决策树的参数
Θ
m
\Theta_m
Θm :
Θ
^
m
=
argmin
(
Θ
n
)
∑
i
=
1
N
L
(
y
i
,
f
m
−
1
(
x
i
)
+
T
(
x
i
;
Θ
m
)
)
\hat{\Theta}_m=\operatorname{argmin}_{\left(\Theta_n\right)} \quad \sum_{i=1}^N L\left(y_i, f_{m-1}\left(x_i\right)+T\left(x_i ; \Theta_m\right)\right)
Θ^m=argmin(Θn)∑i=1NL(yi,fm−1(xi)+T(xi;Θm))
由于树的线性组合可以很好地拟合训练数据,即使数据中的输入与输出之间的关系很复杂也是如此,所以提升树是一个高功能的学习算法。
下面讨论针对不同问题的提升树学习算法,其主要区别在于使用的损失函数不同。包括用平方误差 损失函数的回归问题,用指数损失函数的分类问题,以及用一般损失函数的一般决策问题。
2.1 二叉分类提升树
对于二分类问题,提升树算法只需将AdaBoost算法中的基本分类器限制为二类分类树即可,可以说这时的提升树算法是AdaBoost算法的特殊情况,这里不再细述。下面叙述回归问题的提升树。
2.2 二叉回归提升树
已知一个训练数据集
T
=
{
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
…
,
(
x
N
,
y
N
)
}
,
x
i
∈
X
⊆
R
n
,
x
T=\left\{\left(x_1, y_1\right),\left(x_2, y_2\right), \ldots,\left(x_N, y_N\right)\right\}, x_i \in X \subseteq R^n , \mathrm{x}
T={(x1,y1),(x2,y2),…,(xN,yN)},xi∈X⊆Rn,x 为输入空 间,
y
i
∈
Y
⊆
R
,
y
y_i \in Y \subseteq R , \mathrm{y}
yi∈Y⊆R,y 为输出空间。如果将输入空间
x
x
x划分为
J
J
J个互不相交的区域
R
1
,
R
2
,
…
,
R
J
R_1, R_2, \ldots, 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}^J c_j I\left(x \in R_j\right)
T(x;Θ)=j=1∑JcjI(x∈Rj)
其中,参数
Θ
=
{
(
R
1
,
c
1
)
,
(
R
2
,
c
2
)
,
…
,
(
R
J
,
c
J
)
}
\Theta=\left\{\left(R_1, c_1\right),\left(R_2, c_2\right), \ldots,\left(R_J, c_J\right)\right\}
Θ={(R1,c1),(R2,c2),…,(RJ,cJ)} 表示树的区域划分和各区域上的常数。J 是回归树的复杂度即叶结点个数。
回归问题提升树使用以下前向分步算法:
f
0
(
x
)
=
0
f
m
(
x
)
=
f
m
−
1
(
x
)
+
T
(
x
;
Θ
m
)
,
m
=
1
,
2
,
…
,
M
f
M
(
x
)
=
∑
m
=
1
M
T
(
x
;
Θ
m
)
\begin{aligned} &f_0(x)=0 \\ &f_m(x)=f_{m-1}(x)+T\left(x ; \Theta_m\right), m=1,2, \ldots, M \\ &f_M(x)=\sum_{m=1}^M T\left(x ; \Theta_m\right) \end{aligned}
f0(x)=0fm(x)=fm−1(x)+T(x;Θm),m=1,2,…,MfM(x)=m=1∑MT(x;Θm)
在前向分步算法的第
m
m
m 步,给定当前模型
f
m
−
1
(
x
)
f_{m-1}(x)
fm−1(x) ,需求解:
Θ
^
m
=
argmin
(
Θ
n
)
∑
i
=
1
N
L
(
y
i
,
f
m
−
1
(
x
i
)
+
T
(
x
i
;
Θ
m
)
)
\hat{\Theta}_m=\operatorname{argmin}_{\left(\Theta_n\right)} \sum_{i=1}^N L\left(y_i, f_{m-1}\left(x_i\right)+T\left(x_i ; \Theta_m\right)\right)
Θ^m=argmin(Θn)i=1∑NL(yi,fm−1(xi)+T(xi;Θm))
得到
Θ
^
m
\hat{\Theta}_m
Θ^m ,即第
m
\mathrm{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
L\left(y, f_{m-1}(x)+T\left(x ; \Theta_m\right)\right)=\left[y-f_{m-1}(x)-T\left(x ; \Theta_m\right)\right]^2=\left[r-T\left(x ; \Theta_m\right)\right]^2
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) ,是当前模型拟合数据的残差 (residual) 。所以,对回归问题的提升树算法来说,只需简单地拟合当前模型的残差。这样,算法是相当简单的。
回归提升树算法步骤:
输入:训练数据集
T
=
{
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
…
,
(
x
N
,
y
N
)
}
,
x
i
∈
X
,
y
i
∈
R
T=\left\{\left(x_1, y_1\right),\left(x_2, y_2\right), \ldots,\left(x_N, y_N\right)\right\}, \quad x_i \in X, \quad y_i \in R
T={(x1,y1),(x2,y2),…,(xN,yN)},xi∈X,yi∈R
输出:提升树
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
m=1,2, \ldots, \mathrm{M}(\mathrm{M}
m=1,2,…,M(M 棵树,对每个树进行遍历)
(a)计算残差:
r
m
i
=
y
i
−
f
m
−
1
(
x
i
)
,
i
=
1
,
2
,
…
,
N
r_{m i}=y_i-f_{m-1}\left(x_i\right), \quad i=1,2, \ldots, N
rmi=yi−fm−1(xi),i=1,2,…,N
(b) 拟合残差
r
m
i
r_{m i}
rmi 学习一个回归树,得到
T
(
x
;
Θ
m
)
T\left(x ; \Theta_m\right)
T(x;Θm)
(c)更新
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)
(3) 得到回归问题的提升树
f
M
(
x
)
=
∑
m
=
1
M
T
(
x
;
Θ
m
)
f_M(x)=\sum_{m=1}^M T\left(x ; \Theta_m\right)
fM(x)=m=1∑MT(x;Θm)
3. 回归提升树示例
提升树计算实例,以下实例来自于《统计机器学习》
数据集:
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 |
对于上述训练样本,设定基本模型为只有一个节点回归树模型(树桩)。x的取值范围为区间[0.5, 10.5],y的取值范围为区间[5.0, 10.0]。可能的切分点为1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5。
树桩是由一个根节点直接连接两个叶结点的简单决策树。
首先通过以下优化问题寻找回归树的最佳切分点:
3.1 求 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 _{\left(c_1\right)} \sum_{x_i \in R_1}\left(y_i-c_1\right)^2+\min _{\left(c_2\right)} \sum_{x_i \in R_2}\left(y_i-c_2\right)^2\right]
min(s)[min(c1)∑xi∈R1(yi−c1)2+min(c2)∑xi∈R2(yi−c2)2]
求解训练数据的切分点
s
:
\mathrm{s}:
s:
R
1
=
{
x
∣
x
≤
s
}
,
R
2
=
{
x
∣
x
>
s
}
R_1=\{x \mid x \leq s\}, R_2=\{x \mid x>s\}
R1={x∣x≤s},R2={x∣x>s}
容易求得在
R
1
,
R
2
R_1, R_2
R1,R2 内部使平方损失误差达到最小的
c
1
,
c
2
c_1, c_2
c1,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=N11∑xi∈R1yi,c2=N21∑xi∈R2yi
这里
N
1
,
N
2
N_1, N_2
N1,N2 是
R
1
,
R
2
R_1, R_2
R1,R2 的样本点数。
(1) 求训练数据的切分点
这里的切分点指的是将x值划分界限,数据中x的范围是
[
1
,
10
]
[1,10]
[1,10] ,假设我们考虑如下切分点:
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), m(s)计算公式如下:
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 _{\left(c_1\right)} \sum_{x_i \in R_1}\left(y_i-c_1\right)^2+\min _{\left(c_2\right)} \sum_{x_i \in R_2}\left(y_i-c_2\right)^2
m(s)=min(c1)∑xi∈R1(yi−c1)2+min(c2)∑xi∈R2(yi−c2)2
例如: 当
s
=
1.5
s=1.5
s=1.5 时,
R
1
=
{
1
}
,
R
2
=
{
2
,
3
,
…
,
10
}
R_1=\{1\}, R_2=\{2,3, \ldots, 10\}
R1={1},R2={2,3,…,10} ,那么:
c
1
=
5.56
c
2
=
1
9
(
5.70
+
5.91
+
6.40
+
6.80
+
7.05
+
8.90
+
8.70
+
9.00
+
9.05
)
=
7.50
c_1=5.56\\ c_2=\frac{1}{9}(5.70+5.91+6.40+6.80+7.05+8.90+8.70+9.00+9.05)=7.50
c1=5.56c2=91(5.70+5.91+6.40+6.80+7.05+8.90+8.70+9.00+9.05)=7.50
m
(
1.5
)
=
min
(
c
1
)
∑
x
i
∈
R
1
(
y
i
−
c
1
)
2
+
min
(
c
2
)
∑
x
i
∈
R
2
(
y
i
−
c
2
)
2
=
0
+
15.72
m(1.5)=\min _{\left(c_1\right)} \sum_{x_i \in R_1}\left(y_i-c_1\right)^2+\min _{\left(c_2\right)} \sum_{x_i \in R_2}\left(y_i-c_2\right)^2=0+15.72
m(1.5)=min(c1)∑xi∈R1(yi−c1)2+min(c2)∑xi∈R2(yi−c2)2=0+15.72
=
15.72
=15.72
=15.72
现将s及m(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 |
(2)求回归树
由上表可知,当
s
=
6.5
\mathrm{s}=6.5
s=6.5 时,
m
(
s
)
\mathrm{m}(\mathrm{s})
m(s) 达到最小值,此时
R
1
=
{
1
,
2
,
…
,
6
}
,
R
2
=
{
7
,
8
,
9
,
10
}
R_1=\{1,2, \ldots, 6\}, R_2=\{7,8,9,10\}
R1={1,2,…,6},R2={7,8,9,10} , 且:
c
1
=
1
6
(
5.56
+
5.70
+
5.91
+
6.40
+
6.80
+
7.05
)
=
6.24
c
2
=
1
4
(
8.90
+
8.70
+
9.00
+
9.05
)
=
8.91
\begin{aligned} &c_1=\frac{1}{6}(5.56+5.70+5.91+6.40+6.80+7.05)=6.24 \\ &c_2=\frac{1}{4}(8.90+8.70+9.00+9.05)=8.91 \end{aligned}
c1=61(5.56+5.70+5.91+6.40+6.80+7.05)=6.24c2=41(8.90+8.70+9.00+9.05)=8.91
因此,回归树
T
1
(
x
)
T_1(x)
T1(x) 为:
T
1
(
x
)
=
{
6.24
,
x
<
6.5
8.91
,
x
≥
6.5
T_1(x)= \begin{cases}6.24, & x<6.5 \\ 8.91, & x \geq 6.5\end{cases}
T1(x)={6.24,8.91,x<6.5x≥6.5
(3)求当前加法模型
f
1
(
x
)
f_1(x)
f1(x)
当前的加法模型为:
f
1
(
x
)
=
T
1
(
x
)
f_1(x)=T_1(x)
f1(x)=T1(x)
(4)求当前加法模型的残差
用
f
1
(
x
)
f_1(x)
f1(x) 拟合训练数据的残差如表所示 ,表中
r
2
i
=
y
i
−
f
1
(
x
i
)
,
i
=
1
,
2
,
…
,
10
r_{2 i}=y_i-f_1\left(x_i\right), i=1,2, \ldots, 10
r2i=yi−f1(xi),i=1,2,…,10 。
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\left(y, f_1(x)\right)=\sum_{i=1}^{10}\left(y_i-f_1\left(x_i\right)\right)^2=1.93
L(y,f1(x))=i=1∑10(yi−f1(xi))2=1.93
这里的误差为
1.93
1.93
1.93 ,如果我们定义终止时候的误差比这个误差要小,那么算法继续执行以上步骤, 直到满足误差为止。
3.2 求回归树 T 2 ( x ) T_2(x) T2(x)
方法与求
T
1
(
x
)
T_1(x)
T1(x) 一样,只是拟合的数据是残差表。
(1)求解数据的切分点
仍然对区域
R
=
{
1
,
2
,
…
,
10
}
R=\{1,2, \ldots, 10\}
R={1,2,…,10} 求解数据的切分点。当
s
=
1.5
\mathrm{s}=1.5
s=1.5 时,
R
1
′
=
{
1
}
,
R
2
′
=
{
2
,
3
,
…
,
10
}
R_{1^{\prime}}=\{1\}, R_{2^{\prime}}=\{2,3, \ldots, 10\}
R1′={1},R2′={2,3,…,10} ,那么:
c
1
′
=
−
0.68
c
2
′
=
1
9
(
−
0.54
−
0.33
+
0.16
+
0.56
+
0.81
−
0.01
−
0.21
+
0.09
+
0.14
)
=
0.07
m
(
1.5
)
=
min
(
c
1
)
∑
x
i
∈
R
1
(
r
2
i
−
c
1
)
2
+
min
(
c
2
)
∑
x
i
∈
R
2
(
r
2
i
−
c
2
)
2
=
0
+
1.42
=
1.42
\begin{aligned} &c_{1^{\prime}}=-0.68 \\ &c_{2^{\prime}}=\frac{1}{9}(-0.54-0.33+0.16+0.56+0.81-0.01-0.21+0.09+0.14)=0.07 \\ &m(1.5)=\min _{\left(c_1\right)} \sum_{x_i \in R_1}\left(r_{2 i}-c_1\right)^2+\min _{\left(c_2\right)} \sum_{x_i \in R_2}\left(r_{2 i}-c_2\right)^2=0+1.42 \\ &=1.42 \end{aligned}
c1′=−0.68c2′=91(−0.54−0.33+0.16+0.56+0.81−0.01−0.21+0.09+0.14)=0.07m(1.5)=(c1)minxi∈R1∑(r2i−c1)2+(c2)minxi∈R2∑(r2i−c2)2=0+1.42=1.42
现将
s
s
s 及
m
(
s
)
m(s)
m(s) 的计算结果列表如下 (见表4):
表4
s 、 m(s)
\text{ s 、 m(s)}
s 、 m(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) | 1.42 | 1.01 | 0.80 | 1.14 | 1.67 | 1.93 | 1.93 | 1.90 | 1.91 |
(2)求回归树
由表4可知,当
s
=
3.5
s=3.5
s=3.5 时
m
(
s
)
m(s)
m(s) 达到最小值,此时
R
1
′
=
{
1
,
2
,
3
}
,
R
2
′
=
{
4
,
5
,
…
,
10
}
,
c
1
=
−
0.52
,
c
2
=
0.22
R_{1^{\prime}}=\{1,2,3\}, R_{2^{\prime}}=\{4,5, \ldots, 10\}, c_1=-0.52, c_2=0.22
R1′={1,2,3},R2′={4,5,…,10},c1=−0.52,c2=0.22 ,所以回归树
T
2
(
x
)
T_2(x)
T2(x) 为:
T
2
(
x
)
=
{
−
0.52
,
x
<
3.5
0.22
,
x
≥
3.5
T_2(x)= \begin{cases}-0.52, & x<3.5 \\ 0.22, & x \geq 3.5\end{cases}
T2(x)={−0.52,0.22,x<3.5x≥3.5
(3) 求当前加法模型
f
2
(
x
)
f_2(x)
f2(x)
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)= \begin{cases}5.72, & x<3.5 \\ 6.46, & 3.5 \leqslant x<6.5 \\ 9.13, & x \geqslant 6.5\end{cases}
f2(x)=f1(x)+T2(x)=⎩
⎨
⎧5.72,6.46,9.13,x<3.53.5⩽x<6.5x⩾6.5
(4)求当前加法模型的残差
用
f
2
(
x
)
f_2(x)
f2(x) 拟合训练数据的残差如表5,表中
r
3
i
=
y
i
−
f
2
(
x
i
)
,
i
=
1
,
2
,
…
,
10
r_{3 i}=y_i-f_2\left(x_i\right), i=1,2, \ldots, 10
r3i=yi−f2(xi),i=1,2,…,10 。
x i x_i xi | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
r 3 i r_{3i} r3i | -0.16 | -0.02 | 0.19 | -0.06 | 0.34 | 0.59 | -0.23 | -0.43 | -0.13 | -0.08 |
用
f
2
(
x
)
f_2(x)
f2(x) 拟合训练数据的平方损失误差是:
L
(
y
,
f
2
(
x
)
)
=
∑
i
=
1
10
(
y
i
−
f
2
(
x
i
)
)
2
=
0.79
L\left(y, f_2(x)\right)=\sum_{i=1}^{10}\left(y_i-f_2\left(x_i\right)\right)^2=0.79
L(y,f2(x))=i=1∑10(yi−f2(xi))2=0.79
之后的过程同步骤2一样,我就不在这里故述啦! 最后,给出完整的回归提升树模型。
T
3
(
x
)
=
{
0.15
,
x
<
6.5
−
0.22
,
x
⩾
6.5
L
(
y
,
f
3
(
x
)
)
=
0.47
,
T
4
(
x
)
=
{
−
0.16
,
x
<
4.5
0.11
,
x
⩾
4.5
L
(
y
,
f
4
(
x
)
)
=
0.30
,
T
5
(
x
)
=
{
0.07
,
x
<
6.5
−
0.11
,
x
⩾
6.5
L
(
y
,
f
5
(
x
)
)
=
0.23
,
T
6
(
x
)
=
{
−
0.15
,
x
<
2.5
0.04
,
x
⩾
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} T_3(x) &=\left\{\begin{array}{ll} 0.15, & x<6.5 \\ -0.22, & x \geqslant 6.5 \end{array} \quad L\left(y, f_3(x)\right)=0.47,\right.\\ T_4(x) &=\left\{\begin{array}{ll} -0.16, & x<4.5 \\ 0.11, & x \geqslant 4.5 \end{array} \quad L\left(y, f_4(x)\right)=0.30,\right.\\ T_5(x) &=\left\{\begin{array}{ll} 0.07, & x<6.5 \\ -0.11, & x \geqslant 6.5 \end{array} \quad L\left(y, f_5(x)\right)=0.23,\right.\\ T_6(x) &= \begin{cases}-0.15, & x<2.5 \\ 0.04, & x \geqslant 2.5\end{cases} \\ f_6(x) &=f_5(x)+T_6(x)=T_1(x)+\cdots+T_5(x)+T_6(x) \\ &= \begin{cases}5.63, & x<2.5 \\ 5.82, & 2.5 \leqslant x<3.5 \\ 6.56, & 3.5 \leqslant x<4.5 \\ 6.83, & 4.5 \leqslant x<6.5 \\ 8.95, & x \geqslant 6.5\end{cases} \end{aligned}
T3(x)T4(x)T5(x)T6(x)f6(x)={0.15,−0.22,x<6.5x⩾6.5L(y,f3(x))=0.47,={−0.16,0.11,x<4.5x⩾4.5L(y,f4(x))=0.30,={0.07,−0.11,x<6.5x⩾6.5L(y,f5(x))=0.23,={−0.15,0.04,x<2.5x⩾2.5=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
6
(
x
)
)
=
∑
i
=
1
10
(
y
i
−
f
6
(
x
i
)
)
2
=
0.17
L\left(y, f_6(x)\right)=\sum_{i=1}^{10}\left(y_i-f_6\left(x_i\right)\right)^2=0.17
L(y,f6(x))=i=1∑10(yi−f6(xi))2=0.17
假设此时已满足误差要求, 那么
f
(
x
)
=
f
6
(
x
)
{f}(\mathrm{x})={f}_6(\mathrm{x})
f(x)=f6(x) 即为所求提升树。
4. python代码
import numpy as np
label = np.array([5.56, 5.7, 5.91, 6.4, 6.8, 7.05, 8.9, 8.7, 9, 9.05])
# 已经排好序了。实际情况中单一特征的数据或者多特征的数据,选择切分点的时候也像决策树一样选择
feature = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
class Tree_model:
def __init__(self, stump, mse, left_value, right_value, residual):
'''
:param stump: 为feature最佳切割点
:param mse: 为每棵树的平方误差
:param left_value: 为决策树左值
:param right_value: 为决策树右值
:param residual: 为每棵决策树生成后余下的残差
'''
self.stump = stump
self.mse = mse
self.left_value = left_value
self.right_value = right_value
self.residual = residual
'''根据feature准备好切分点。例如:
feature为[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
切分点为[1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5]
'''
def Get_stump_list(feature):
# 特征值从小到大排序好,错位相加
tmp1 = list(feature.copy())
tmp2 = list(feature.copy())
tmp1.insert(0, 0)
tmp2.append(0)
stump_list = ((np.array(tmp1) + np.array(tmp2)) / float(2))[1:-1]
return stump_list
# 此处的label其实是残差
def Get_decision_tree(stump_list, feature, label):
best_mse = np.inf
best_stump = 0 # min(stump_list)
residual = np.array([])
left_value = 0
right_value = 0
for i in range(np.shape(stump_list)[0]):
left_node = []
right_node = []
for j in range(np.shape(feature)[0]):
if feature[j] < stump_list[i]:
left_node.append(label[j])
else:
right_node.append(label[j])
left_mse = np.sum((np.average(left_node) - np.array(left_node)) ** 2)
right_mse = np.sum((np.average(right_node) - np.array(right_node)) ** 2)
# print("decision stump: %d, left_mse: %f, right_mse: %f, mse: %f" % (i, left_mse, right_mse, (left_mse + right_mse)))
if best_mse > (left_mse + right_mse):
best_mse = left_mse + right_mse
left_value = np.average(left_node)
right_value = np.average(right_node)
best_stump = stump_list[i]
left_residual = np.array(left_node) - left_value
right_residual = np.array(right_node) - right_value
residual = np.append(left_residual, right_residual)
# print("decision stump: %d, residual: %s"% (i, residual))
Tree = Tree_model(best_stump, best_mse, left_value, right_value, residual)
return Tree, residual
# Tree_num就是树的数量
def BDT_model(feature, label, Tree_num=100):
feature = np.array(feature)
label = np.array(label)
stump_list = Get_stump_list(feature)
Trees = []
residual = label.copy()
# 产生每一棵树
for num in range(Tree_num):
# 每次新生成树后,还需要再次更新残差residual
Tree, residual = Get_decision_tree(stump_list, feature, residual)
Trees.append(Tree)
return Trees
def BDT_predict(Trees, feature):
predict_list = [0 for i in range(np.shape(feature)[0])]
# 将每棵树对各个特征预测出来的结果进行相加,相加的最后结果就是最后的预测值
for Tree in Trees:
for i in range(np.shape(feature)[0]):
if feature[i] < Tree.stump:
predict_list[i] = predict_list[i] + Tree.left_value
else:
predict_list[i] = predict_list[i] + Tree.right_value
return predict_list
# 计算误差
def Get_error(predict, label):
predict = np.array(predict)
label = np.array(label)
error = np.sum((label - predict) ** 2)
return error
Trees = BDT_model(feature, label)
predict = BDT_predict(Trees, feature)
print("The error is ", Get_error(predict, label))
print(predict)