分类回归树(classification and regression tree,CART)也是由特征选择、树的生成、剪枝组成的。既可以用于回归,也可以用于分类。CART算法主要由以下两个步骤组成:
(1)基于训练集生成决策树
(2)用验证数据集对已生成的树进行剪枝并选择最优子树,用损失函数最小作为剪枝的标准。
CART生成
回归树的生成
构建回归树有两个问题:
(1) 如何得到预测结果?
(2) 如何对输入空间进行划分?
一颗回归树是输入空间的一个划分,以及在划分单元的输出值。假设输入空间已经划分为M个:
R
1
,
R
2
,
.
.
.
,
R
M
R_1, R_2, ..., R_M
R1,R2,...,RM,并且在每个单元
R
m
R_m
Rm有一个固定的输出值
c
m
c_m
cm,于是回归树模型可表示为:
f
(
x
)
=
∑
m
=
1
M
c
m
I
(
x
∈
R
m
)
f(x) = \sum_{m=1}^{M} c_m I(x \in R_m)
f(x)=m=1∑McmI(x∈Rm)
可以用平方误差
∑
x
i
∈
R
m
(
y
i
−
f
(
x
i
)
)
2
\sum_{x_i \in R_m} (y_i - f(x_i))^2
∑xi∈Rm(yi−f(xi))2来表示回归树的预测误差,用平方误差最小的准则求解每个单元的最优输出值。
对于第一个问题,单元
R
m
R_m
Rm上的
c
m
c_m
cm的最优值
c
^
m
\hat c_m
c^m是
R
m
R_m
Rm上所有输入实例
x
i
x_i
xi对应的输出
y
i
y_i
yi的均值,即:
c
^
m
=
a
v
e
(
y
i
∣
x
i
∈
R
m
)
\hat{c}_m = ave(y_i \ | \ x_i \in R_m)
c^m=ave(yi ∣ xi∈Rm)
那么如何对输入空间进行划分?可以采用启发式的方法,选择样本x的第j个特征
x
(
j
)
x^{(j)}
x(j)和它的均值s作为切分变量和切分点。定义两个区域:
R
1
(
j
,
s
)
=
{
x
∣
x
(
j
)
⩽
s
}
R
2
(
j
,
s
)
=
{
x
∣
x
(
j
)
>
s
}
R_1(j, s) = \{x \ | \ x^{(j)} \leqslant s\}\\ \ R_2(j, s) = \{x \ | \ x^{(j)} > s\}
R1(j,s)={x ∣ x(j)⩽s} R2(j,s)={x ∣ x(j)>s}
然后寻找最优切分变量 j 和最优切分点 s,具体地就是遍历所有特征的所有切分点,求解:
min
j
,
s
[
min
c
1
∑
x
i
∈
R
1
(
j
,
s
)
(
y
i
−
c
1
)
2
+
min
c
2
∑
x
i
∈
R
2
(
j
,
s
)
(
y
i
−
c
2
)
2
]
\min_{j, s} \ [ \min_{c_1} \sum_{x_i \in R_1(j,s)} (y_i - c_1)^2 + \min_{c_2} \sum_{x_i \in R_2(j,s)} (y_i - c_2)^2]
j,smin [c1minxi∈R1(j,s)∑(yi−c1)2+c2minxi∈R2(j,s)∑(yi−c2)2]
其中,
c
1
c_1
c1为R1数据集的样本输出均值,
c
2
c_2
c2为R2数据集的样本输出均值:
c
^
1
=
a
v
e
(
y
i
∣
x
i
∈
R
1
(
j
,
s
)
)
,
c
^
2
=
a
v
e
(
y
i
∣
x
i
∈
R
2
(
j
,
s
)
)
\hat{c}_1 = ave( y_i \ | \ x_i \in R_1(j, s)), \ \hat{c}_2 = ave( y_i \ | \ x_i \in R_2(j, s))
c^1=ave(yi ∣ xi∈R1(j,s)), c^2=ave(yi ∣ xi∈R2(j,s))
遍历所有输入变量,找到最优的切分变量 j,构成一个对(j,s)。依次将输入空间划分为两个区域。对每个区域重复上述划分过程,直到满足停止条件位置,这样的回归树通常称为最小二乘回归树,算法叙述如下:
输入:训练数据集 D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , … ( x n , y n ) } D=\{(x_1,y_1),(x_2,y_2),\ldots(x_n,y_n)\} D={(x1,y1),(x2,y2),…(xn,yn)}
输出:回归树 f ( x ) f(x) f(x)
步骤:
-
遍历特征变量 j j j,对固定的切分变量 j j j扫描切分点 s s s,得到满足下面关系的 ( j , s ) (j,s) (j,s)
min j , s [ min c 1 ∑ x i ∈ R 1 ( j , s ) ( y i − c 1 ) 2 + min c 2 ∑ x i ∈ R 2 ( j , s ) ( y i − c 2 ) 2 ] \min\limits_{j,s}\left[\min\limits_{c_1}\sum\limits_{x_i\in R_1(j,s)}(y_i-c_1)^2+\min\limits_{c_2}\sum\limits_{x_i\in R_2(j,s)}(y_i-c_2)^2\right] j,smin⎣⎡c1minxi∈R1(j,s)∑(yi−c1)2+c2minxi∈R2(j,s)∑(yi−c2)2⎦⎤ -
用选定的 ( j , s ) (j,s) (j,s), 划分区域并决定相应的输出值
R 1 ( j , s ) = { x ∣ x ( j ) ≤ s } , R 2 ( j , s ) = { x ∣ x ( j ) > s } c ^ m = 1 N ∑ x i ∈ R m ( j , s ) y j , x ∈ R m , m = 1 , 2 R_1(j,s)=\{x|x^{(j)}\leq s\}, R_2(j,s)=\{x|x^{(j)}> s\} \\ \hat{c}_m= \frac{1}{N}\sum\limits_{x_i\in R_m(j,s)} y_j, x\in R_m, m=1,2 R1(j,s)={x∣x(j)≤s},R2(j,s)={x∣x(j)>s}c^m=N1xi∈Rm(j,s)∑yj,x∈Rm,m=1,2 -
对两个子区域调用(1)(2)步骤, 直至满足停止条件
-
将输入空间划分为 M M M个区域 R 1 , R 2 , … , R M R_1, R_2,\dots,R_M R1,R2,…,RM,生成决策树:
f ( x ) = ∑ m = 1 M c ^ m I ( x ∈ R m ) f(x)=\sum_{m=1}^M\hat{c}_mI(x\in R_m) f(x)=m=1∑Mc^mI(x∈Rm)
在输入空间划分时,用平方误差 ∑ ( y i − f ( x i ) ) 2 \sum(y_i - f(x_i))^2 ∑(yi−f(xi))2 来表示回归树的预测误差,用平方误差最小的准则求解每个单元上的最优输出值。这样的回归树称为最小二乘回归树。
分类树的生成
CART分类树有以下两个特点:
分类树用基于基尼指数选择最优特征,同时决定该特征的最优二值切分点。CART分类树算法每次仅仅对某个特征的值进行二分,这样CART分类树算法建立起来的是二叉树,而不是多叉树,提高了效率。假设某个特征A(有三种取值 a 1 , a 2 , a 3 a_1,a_2,a_3 a1,a2,a3)被选取建立决策树节点,ID3和C4.5 会在决策树上建立一个三叉的结点,但CART 树采用二分法,将A分为 { a 1 } 和 { a 2 , a 3 } \{a_1\} 和 \{a_2,a_3\} {a1}和{a2,a3}, { a 2 } 和 { a 1 , a 3 } \{a_2\} 和 \{a_1,a_3\} {a2}和{a1,a3}, { a 3 } 和 { a 2 , a 1 } \{a_3\} 和 \{a_2,a_1\} {a3}和{a2,a1} 三种情况,找到基尼指数最小的组合,如: { a 3 } 和 { a 2 , a 1 } \{a_3\} 和 \{a_2,a_1\} {a3}和{a2,a1} ,建立二叉树,后面继续对 { a 2 , a 1 } \{a_2,a_1\} {a2,a1} 进行划分。在CART中,离散特征也会多次参与树结点的建立。
对于CART分类树连续值的处理方式也是是将连续的特征离散化。唯一的区别在于在选择划分点时的度量方式不同,C4.5使用的是信息增益比,则CART分类树使用的是基尼系数。
基尼指数定义:在分类问题中,假设由K个类,样本点属于第
k
k
k类的概率为
p
k
p_k
pk,则概率分布的基尼指数为:
G
i
n
i
(
p
)
=
∑
k
=
1
K
p
k
(
1
−
p
k
)
=
1
−
∑
k
=
1
K
p
k
2
Gini(p) = \sum_{k=1}^Kp_k(1-p_k)=1-\sum_{k=1}^Kp_k^2
Gini(p)=k=1∑Kpk(1−pk)=1−k=1∑Kpk2
对于二分类问题,若样本点属于第一类的概率是p,则其概率分布的基尼指数:
G
i
n
i
(
p
)
=
2
p
(
1
−
p
)
Gini(p) = 2p(1-p)
Gini(p)=2p(1−p)
对于给定的样本集合D,其基尼指数为:
G
i
n
i
(
D
)
=
1
−
∑
k
=
1
K
(
∣
C
k
∣
∣
D
∣
)
2
Gini(D) = 1-\sum_{k=1}^K\left(\frac{|C_k|}{|D|}\right)^2
Gini(D)=1−k=1∑K(∣D∣∣Ck∣)2
如果D按照特征A是否取某个值a,分割为子集
D
1
,
D
2
D_1, D_2
D1,D2两个部分,即
D
1
=
{
(
x
,
y
)
∈
D
∣
A
(
x
)
=
a
}
,
D
2
=
D
−
D
1
D_1 = \{(x, y) \in D \ | \ A(x) = a\}, D_2 = D - D_1
D1={(x,y)∈D ∣ A(x)=a},D2=D−D1,则在特征A的条件下,集合D的基尼指数为:
G
i
n
i
(
D
,
A
)
=
∣
D
1
∣
∣
D
∣
G
i
n
i
(
D
1
)
+
∣
D
2
∣
∣
D
∣
G
i
n
i
(
D
2
)
Gini(D, A) = \frac{|D_1|}{|D|} Gini(D_1) + \frac{|D_2|}{|D|} Gini(D_2)
Gini(D,A)=∣D∣∣D1∣Gini(D1)+∣D∣∣D2∣Gini(D2)
Gini值越大,样本集合的不确定性也越大(与熵类似),因此每次选择Gini小的特征来划分。
使用基尼指数作为特征选择的准则,相比信息增益或信息增益比,避免了大量的对数运算。基尼指数代表了模型的不纯度,基尼指数越小,不纯度越低,特征越好。
生成算法
输入:训练数据集D,基尼系数的阈值,样本个数阈值。
输出:决策树T。
根据训练数据集,从根结点开始,递归地对每个结点进行以下操作,构建二叉决策树:
(1) 设结点的训练数据集为D,计算现有特征对该数据集的基尼指数。此时,对每一个特征A,对其可能取的每个值a,根据样本点对A=a的测试为“是"或“否”,将D分割成 D 1 D_1 D1和 D 2 D_2 D2两部分,计算 A = a A=a A=a时的基尼指数。
(2) 在所有可能的特征A以及它们所有可能的切分点a中,选择基尼指数最小的特征及其对应的切分点作为最优特征与最优切分点。依最优特征与最优切分点,从现结点生成两个子结点,将训练数据集依特征分配到两个子结点中去。
(3) 对两个子结点递归地调用(1),,(2),直至满足停止条件。
(4) 生成CART决策树。
算法停止计算的条件是结点中的样本个数小于预定阈值,或样本集的基尼指数小于预定阈值(样本基本属于同-类),或者没有更多特征。
举例说明:
分别用
A
1
,
A
2
,
A
3
,
A
4
A_1,A_2,A_3,A_4
A1,A2,A3,A4表示年龄、有工作、有房子、贷款情况4个特征,则有:
G
i
n
i
(
D
,
A
1
=
1
)
=
5
15
(
2
×
2
5
×
(
1
−
2
5
)
)
+
10
15
(
2
×
7
10
×
(
1
−
7
10
)
)
=
0.44
G
i
n
i
(
D
,
A
1
=
2
)
=
0.48
G
i
n
i
(
D
,
A
1
=
3
)
=
0.44
\begin{aligned} & Gini(D,A_1=1)=\frac{5}{15}(2 \times \frac{2}{5} \times (1-\frac{2}{5})) + \frac{10}{15}(2 \times \frac{7}{10} \times (1-\frac{7}{10})) = 0.44 \\ & Gini(D,A_1=2)=0.48\\ & Gini(D,A_1=3)=0.44 \end{aligned}
Gini(D,A1=1)=155(2×52×(1−52))+1510(2×107×(1−107))=0.44Gini(D,A1=2)=0.48Gini(D,A1=3)=0.44
由于
G
i
n
i
(
D
,
A
1
=
1
)
Gini(D,A_1=1)
Gini(D,A1=1)和
G
i
n
i
(
D
,
A
1
=
3
)
Gini(D,A_1=3)
Gini(D,A1=3)最小且相等,所以
A
1
,
A
3
A_1, A_3
A1,A3都可以作为最优切分点。同理可以得到
A
2
,
A
3
A_2,A_3
A2,A3的基尼指数:
G
i
n
i
(
D
,
A
2
=
1
)
=
0.32
G
i
n
i
(
D
,
A
3
=
1
)
=
0.27
Gini(D,A_2=1) = 0.32 \\ Gini(D,A_3=1) = 0.27
Gini(D,A2=1)=0.32Gini(D,A3=1)=0.27
由于
A
2
,
A
3
A_2,A_3
A2,A3只有一个切分点,所以基尼指数最小的即为对应特征的最优切分点。
A
4
A_4
A4的基尼指数:
G
i
n
i
(
D
,
A
4
=
1
)
=
0.36
G
i
n
i
(
D
,
A
4
=
2
)
=
0.47
G
i
n
i
(
D
,
A
4
=
3
)
=
0.32
Gini(D,A_4=1) = 0.36 \\ Gini(D,A_4=2) = 0.47\\ Gini(D,A_4=3) = 0.32
Gini(D,A4=1)=0.36Gini(D,A4=2)=0.47Gini(D,A4=3)=0.32
G
i
n
i
(
D
,
A
4
=
3
)
Gini(D,A_4=3)
Gini(D,A4=3)最小,所以
A
4
=
3
A_4=3
A4=3为
A
4
A_4
A4的最优切分点。
A 1 , A 2 , A 3 , A 4 A_1,A_2,A_3,A_4 A1,A2,A3,A4的特征中, G i n i ( D , A 3 = 1 ) = 0.27 Gini(D,A_3=1)=0.27 Gini(D,A3=1)=0.27最小,所以选择 A 3 A_3 A3为最优特征, A 3 = 1 A_3=1 A3=1为最优切分点,于是生成了两个子节点。左子节点是叶节点,右子节点则需要继续在 A 1 , A 2 , A 4 A_1,A_2,A_4 A1,A2,A4中选择最优切分点,如此往复,直到所以节点都是叶节点。
CART剪枝
CART剪枝包含以下两个步骤:
(1)从生成算法产生的决策树 T 0 T_0 T0 底端开始剪枝,直到根结点,形成一个子树序列 { T 0 , T 1 , … T n } \{T_0,T_1,\ldots T_n\} {T0,T1,…Tn} 。
(2)通过交叉验证在独立的验证集上对子树进行册数,选择最优的子树。
1、剪枝,形成子树序列
在剪枝过程中,计算子树的损失函数:
C
α
(
T
)
=
C
(
T
)
+
α
∣
T
∣
C_{\alpha}(T) = C(T) + \alpha|T|
Cα(T)=C(T)+α∣T∣
其中,T为任意子树,
C
(
T
)
C(T)
C(T) 为训练数据的预测误差(如基尼指数)。
∣
T
∣
|T|
∣T∣ 为子树的叶结点个数,
α
≥
0
\alpha \geq 0
α≥0 为参数,权衡训练数据的拟合程度与模型的复杂度。
当 α = 0 \alpha =0 α=0时,损失函数等于预测误差,相当于不进行剪枝,对应的最优子树即决策树本身(计为 T 0 T_0 T0); α \alpha α 越大,则惩罚越大,会得到更加简单的树,即剪枝幅度更大。
固定 α \alpha α,一定存在使损失函数 C α ( T ) C_\alpha(T) Cα(T) 最小的唯一子树,将其表示为 T α T_\alpha Tα。$\alpha $ 不同,最优子树不同。
Breiman等人证明:可以用递归的方法对树进行剪枝。将 α \alpha α 从小增大, 0 = α 0 < α 1 < . . . < α n < + ∞ 0 = \alpha_0 < \alpha_1 < ... < \alpha_n < + \infty 0=α0<α1<...<αn<+∞,产生一系列的区间 [ α i , α i + 1 ) , i = 0 , 1 , . . . , n [\alpha_i, \alpha_{i+1}), i = 0, 1, ..., n [αi,αi+1),i=0,1,...,n,剪枝得到的子树序列对应着区间 α ∈ [ α i , α i + 1 ) \alpha \in [\alpha_i, \alpha_{i+1}) α∈[αi,αi+1) 的最优子树序列 { T 0 , T 1 , . . . , T n } \{T_0, T_1, ..., T_n\} {T0,T1,...,Tn}。
剪枝的原则是:剪枝后的损失函数要小于等于剪枝前的损失函数。因此,t处进行剪枝(即将t的所有子节点剔除,将t设置为叶子节点),只需要将问题聚焦于节点t以及t对应的子树 T t T_t Tt上( T t T_t Tt为在t处剪枝剪掉的部分)。
具体剪枝思路如下:
从整体树
T
0
T_0
T0 开始剪枝。对
T
0
T_0
T0的任意内部结点t,以t为单结点树的损失函数是:
C
α
(
t
)
=
C
(
t
)
+
α
C_\alpha(t) = C(t) + \alpha
Cα(t)=C(t)+α
若不进行剪枝,以
t
t
t为根结点的子树
T
t
T_t
Tt的损失函数是:
C
α
(
T
t
)
=
C
(
T
t
)
+
α
∣
T
t
∣
C_\alpha(T_t) = C(T_t) + \alpha | T_t |
Cα(Tt)=C(Tt)+α∣Tt∣
已知剪枝后的损失函数小于等于剪枝前的损失函数
C
α
(
t
)
≤
C
α
(
T
t
)
C_\alpha(t) \leq C_\alpha(T_t)
Cα(t)≤Cα(Tt)
即:
C
(
t
)
+
α
≤
C
(
T
t
)
+
α
∣
T
t
∣
C(t) + \alpha \leq C(T_t) + \alpha | T_t |
C(t)+α≤C(Tt)+α∣Tt∣
可得:
α
≥
C
(
t
)
−
C
(
T
t
)
∣
T
t
∣
−
1
\alpha \geq \frac{C(t) - C(T_t)}{|T_t| - 1}
α≥∣Tt∣−1C(t)−C(Tt)
即当
α
∈
[
0
,
C
(
t
)
−
C
(
T
t
)
∣
T
t
∣
−
1
)
\alpha \in [0, \frac{C(t) - C(T_t)}{|T_t| - 1})
α∈[0,∣Tt∣−1C(t)−C(Tt))时,不满足剪枝条件,所以,满足剪枝条件的最小
α
\alpha
α为:
α
=
C
(
t
)
−
C
(
T
t
)
∣
T
t
∣
−
1
\alpha = \frac{C(t) - C(T_t)}{|T_t| - 1}
α=∣Tt∣−1C(t)−C(Tt)
自下而上地对内部每个内部节点t计算可以剪枝的最小
α
\alpha
α ,记为
g
(
t
)
g(t)
g(t):
g
(
t
)
=
C
(
t
)
−
C
(
T
t
)
∣
T
t
∣
−
1
g(t)= \frac{C(t) - C(T_t)}{|T_t| - 1}
g(t)=∣Tt∣−1C(t)−C(Tt)
取其中最小的作
α
\alpha
α 为
α
1
\alpha_1
α1(
α
\alpha
α 序列逐渐增大,树序列T逐渐更简单,最小的
α
\alpha
α保证没有遗漏可以剪枝的子树),对应的子树为
T
1
T_1
T1,剪切点为
t
1
t_1
t1。这样我们便得到了序列
α
\alpha
α 中的
α
1
\alpha_1
α1 以及对应的子树
T
1
T_1
T1。
接着对子树 T 1 T_1 T1执行以上过程便可以得到( α 2 和 T 2 α_2和T_2 α2和T2),不停地重复以上过程便可以得到最优子树序列 { T 0 , T 1 , . . . , T n } \{T_0,T_1,...,T_n\} {T0,T1,...,Tn},且每一颗树都是上一颗树的子集(在上一颗的基础上进行剪枝)。
2、在剪枝得到的子树序列中 T 0 , T 1 , … , T n T_0,T_1,\ldots,T_n T0,T1,…,Tn 中通过交叉验证选取最优的子树 T 0 T_0 T0。
在获得了可以剪枝的最优子树序列{ T 0 , T 1 , . . . , T n T_0,T_1,...,T_n T0,T1,...,Tn}之后,再将每棵树进行交叉验证,交叉验证结果最好的那颗子树便是最终的剪枝结果(平方误差最小或者基尼指数最小)。当最优子树 T k T_k Tk 确定,对应的 α k \alpha_k αk 也确定。
CART剪枝算法
输入: CART算法生成的决策树 T 0 T_0 T0
输出: 最优决策树 T α T_α Tα
(1) 设 k = 0 , T = T 0 k=0, T=T_0 k=0,T=T0
(2) 设 α = + ∞ α= +∞ α=+∞。.
(3) 自下而上地对各内部结点 t 计算
C
(
T
t
)
,
∣
T
t
∣
C(T_t), |T_t|
C(Tt),∣Tt∣以及
g
(
t
)
=
C
(
t
)
−
C
(
T
t
)
∣
T
t
∣
−
1
α
=
m
i
n
(
α
,
g
(
t
)
)
g(t) = \frac{C(t) - C(T_t)}{|T_t| - 1} \\ α = min(α, g(t))
g(t)=∣Tt∣−1C(t)−C(Tt)α=min(α,g(t))
这里, T t T_t Tt表示以t为根结点的子树, C ( T t ) C(T_t) C(Tt)是对训练数据的预测误差, ∣ T t ∣ |T_t| ∣Tt∣ 是 T t T_t Tt的叶结点个数。
(4) 对 g ( t ) = α g(t)=\alpha g(t)=α的内部结点t进行剪枝,并对叶结点t以多数表决法决定其类,得到树T。
(5) 设 k = k + 1 , α k = α , T k = T k=k+1, \alpha_k=\alpha, T_k= T k=k+1,αk=α,Tk=T
(6) 如果 T k T_k Tk不是由根结点及两个叶结点构成的树,则回到步骤(2); 否则令 T k = T n T_k= T_n Tk=Tn。
(7) 采用交叉验证法在子树序列{ T 0 , T 1 , . . . , T n T_0,T_1,...,T_n T0,T1,...,Tn}中选取最优子树 T α T_{\alpha} Tα