- 点赞、关注再看,养成良好习惯
- Life is short, U need Python
0. 前言
经过近一个月的时间系统地学习了机器学习几乎所有模型以及深度学习相关模型,后期计划会陆续登陆CSDN,敬请期待!鉴于这两天反复修改CART决策树,立志做到 “零入门的学生” 能看明白,所以才敢登录CSDN,如有不妥之处,请博友留言批评指正,博主将将尽快核实并做出相应修改!!
1. 概述
CART(Classification and Regression Tree,CART)即分类与回归树,该模型由 Breiman 等人于1984年提出,是应用广泛的决策树学习方法之一。
CART 学习过程由特征选择、树的生成、树的剪枝三部分组成,既可以用于分类又可以用于回归。为叙述方便,以下把二者统一称为决策树。
CART 是在给定输入随机变量 X X X 条件下输出随机变量 Y Y Y 的条件概率分布的学习方法。CART 假设决策树为二叉树,内部结点特征取值为“是”和“否”,分别记为左、右分支。具体地,将输入空间(特征空间)划分为有限个单元,然后在这些单元上确定预测的概率分布。
2. 回归树的生成
准则:回归树用平方误差最小准则,进行特征选择,生成二叉树。
假设
X
X
X 与
Y
Y
Y 分别为输入和输出变量,并且
Y
Y
Y 是连续变量,给定训练数据集
D
=
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
…
,
(
x
N
,
y
N
)
D = {(x_1,y_1),(x_2,y_2),\dots,(x_N,y_N)}
D=(x1,y1),(x2,y2),…,(xN,yN)
问题:如何生成回归树?
假设已将输入空间划分为
M
M
M 个区域
R
1
R_1
R1,
R
2
R_2
R2,
…
\dots
…,
R
M
R_M
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\left(x \in R_{m}\right)
f(x)=m=1∑McmI(x∈Rm)
当输入空间的划分确定后,可以利用平方误差
∑
x
i
∈
R
m
(
y
i
−
f
(
x
i
)
)
2
\sum_{x_{i} \in R_{m}}\left(y_{i}-f(x_i)\right)^{2}
xi∈Rm∑(yi−f(xi))2
来表示回归树对于训练数据的预测误差,用 平方误差最小准则
求解每个单元上的最优输出值
c
c
c。
易知,单元 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 的平均值。
问题:如何划分输入空间?
启发式的方法
(1) 选择第 j j j 个变量 x j x^{j} xj 和对应的取值 s s s,分别作为切分变量(spliting variable)和切分点(splitting point),并定义两个区域:
R 1 ( j , s ) = { x ∣ x ( j ) ≤ s } 和 R 2 ( j , s ) = { x ∣ x ( j ) > s } R_{1}(j, s) = \{x\left|x^{(j)} \leq s\} \ \ \text{和} \ \ R_{2}(j, s) = \{x\right| x^{(j)}>s\} R1(j,s)={x x(j)≤s} 和 R2(j,s)={x x(j)>s}
(2) 寻找最优切分变量 j j j 和最优切分点 s s 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}\left[\min _{c_{1}} \sum_{x_{i} \in R_{1}(j, s)}\left(y_{i}-c_{1}\right)^{2}+\min _{c_{2}} \sum_{x_{i} \in R_{2}(j, s)}\left(y_{i}-c_{2}\right)^{2}\right] j,smin c1minxi∈R1(j,s)∑(yi−c1)2+c2minxi∈R2(j,s)∑(yi−c2)2
遍历所有输入变量,找到最优的切分变量 j j j,进而构成一对 ( j , s ) (j,s) (j,s)。以此将输入空间划分为两个区域。
(3) 对每个区域重复上述划分过程,直到满足停止条件为止。于是生成一棵回归树(通常成为最小二乘回归树)。算法 1(回归树)
输入:训练数据集 D D D
输出:回归树 f ( x ) f(x) f(x)
(1) 选择最优切分变量 j j j 和最优切分点 s s 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}\left[\min _{c_{1}} \sum_{x_{i} \in R_{1}(j, s)}\left(y_{i}-c_{1}\right)^{2}+\min _{c_{2}} \sum_{x_{i} \in R_{2}(j, s)}\left(y_{i}-c_{2}\right)^{2}\right] j,smin c1minxi∈R1(j,s)∑(yi−c1)2+c2minxi∈R2(j,s)∑(yi−c2)2
达到最小值的最优组合 ( j , s ) (j,s) (j,s)。
(2) 对选定的 ( j , s ) (j,s) (j,s) 划分区域并决定相应的输出值:
R 1 ( j , s ) = { x ∣ x ( j ) ≤ s } 和 R 2 ( j , s ) = { x ∣ x ( j ) > s } R_{1}(j, s) = \{x\left|x^{(j)} \leq s\} \ \ \text{和} \ \ R_{2}(j, s) = \{x\right| x^{(j)}>s\} R1(j,s)={x x(j)≤s} 和 R2(j,s)={x x(j)>s}
c ^ m = 1 N m ∑ x i ∈ R m ( j , s ) y i , x ∈ R m , m = 1 , 2 \hat{c}_m = \frac{1}{N_m}\sum_{x_{i} \in R_{m}(j, s)}y_{i},\ \ x\in R_m, \ m=1,2 c^m=Nm1xi∈Rm(j,s)∑yi, x∈Rm, m=1,2
(3) 继续对两个子区域重复上述步骤(1)、(2),直到满足停止条件。
(4) 将输入空间划分为 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}_{m} I\left(x \in R_{m}\right) f(x)=m=1∑Mc^mI(x∈Rm)
3. 分类树的生成
准则:分类树用基尼指数准则,选择最优特征,进而决定该特征的最优二值切分点。
定义(基尼指数) 分类问题中,假设有
K
K
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}^{K}p_k(1-p_k) = 1-\sum_{k=1}^{K}p_{k}^2
Gini(p)=k=1∑Kpk(1−pk)=1−k=1∑Kpk2
特别地,对于二分类问题(
K
=
2
K=2
K=2),若样本点属于第1类的概率为
p
p
p,则概率分布的基尼指数为:
G
i
n
i
(
p
)
=
2
p
(
1
−
p
)
Gini(p) = 2p(1-p)
Gini(p)=2p(1−p)
对于给定的样本集合
D
D
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
其中,
C
k
C_k
Ck 是
D
D
D 中属于第
k
k
k 类的样本子集,
K
K
K 是类的个数。
如果样本集合
D
D
D 根据特征
A
A
A 是否取某一可能值
a
a
a 被分割成
D
1
D_{1}
D1 和
D
2
D_{2}
D2 两部分, 即
D
1
=
{
(
x
,
y
)
∈
D
∣
A
(
x
)
=
a
}
,
D
2
=
D
−
D
1
D_{1}=\{(x, y) \in D \mid A(x)=a\}, \quad D_{2}=D-D_{1}
D1={(x,y)∈D∣A(x)=a},D2=D−D1
则在特征
A
A
A 的条件下, 集合
D
D
D 的基尼指数定义为
Gini
(
D
,
A
)
=
∣
D
1
∣
∣
D
∣
Gini
(
D
1
)
+
∣
D
2
∣
∣
D
∣
Gini
(
D
2
)
\operatorname{Gini}(D, A)=\frac{\left|D_{1}\right|}{|D|} \operatorname{Gini}\left(D_{1}\right)+\frac{\left|D_{2}\right|}{|D|} \operatorname{Gini}\left(D_{2}\right)
Gini(D,A)=∣D∣∣D1∣Gini(D1)+∣D∣∣D2∣Gini(D2)
基尼指数
Gini
(
D
)
\operatorname{Gini}(D)
Gini(D) 表示集合
D
D
D 的不确定性, 基尼指数
Gini
(
D
,
A
)
\operatorname{Gini}(D, A)
Gini(D,A) 表示经
A
=
a
A=a
A=a 分割后集合
D
D
D 的不确定性。基尼指数值越大, 样本集合的不确定性也就越大, 这一点 与樀相似。
下图显示二类分类问题中基尼指数
Gini
(
p
)
\operatorname{Gini}(p)
Gini(p) 、熵 (单位比特) 之半
1
2
H
(
p
)
\frac{1}{2} H(p)
21H(p) 和 分类误差率的关系。 横坐标表示概率
p
p
p , 纵坐标表示损失。 可以看出基尼指数和嫡之半的曲线很接近, 都可以近似地代表分类误差率。
)
算法 2(分类树)
输入:训练数据集 和 停止计算条件 D D D
输出:CART 决策树
(1) 设结点的训练数据集为 D D D,计算现有特征对该数据集的基尼指数。对每一个特征 A A A,对其可能的每个取值 a a a,根据样本点对 A = a A=a A=a 的测试为“是”或者“否”将 D D D 分割为 D 1 D_1 D1 和 D 2 D_2 D2,利用公式计算 A = a A=a A=a 时的基尼指数。
(2) 所有可能的特征 A A A 以及对应可能的切分点 a a a,选择基尼指数最小
的特征及其对应的切分点作为最优特征与最优切分点,从该结点生成两个子节点,将训练数据集依特征分配到两个子结点中去。
(3) 对两个子结点递归地重复(1)和(2),直到满足停止条件。
(4) 生成 CART 树。
4. 示例计算
4.1 分类问题
- 设 A 1 , A 2 , A 3 , A 4 A_1,A_2,A_3,A_4 A1,A2,A3,A4 分别表示年龄、工作、房子、贷款情况4个特征。
目标:求各特征的基尼指数,选择最优特征及其最优切分点。
- 特征 A 1 A_1 A1 的基尼指数:
Gini ( D , A 1 = 1 ) = 5 15 ( 2 × 2 5 × ( 1 − 2 5 ) ) + 10 15 ( 2 × 7 10 × ( 1 − 7 10 ) ) = 0.44 Gini ( D , A 1 = 2 ) = 0.48 Gini ( D , A 1 = 3 ) = 0.44 \begin{array}{l} \operatorname{Gini}\left(D, A_{1}=1\right)=\frac{5}{15}\left(2 \times \frac{2}{5} \times\left(1-\frac{2}{5}\right)\right)+\frac{10}{15}\left(2 \times \frac{7}{10} \times\left(1-\frac{7}{10}\right)\right)=0.44 \\ \operatorname{Gini}\left(D, A_{1}=2\right)=0.48 \\ \operatorname{Gini}\left(D, A_{1}=3\right)=0.44 \end{array} 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
由于 Gini ( D , A 1 = 1 ) \operatorname{Gini}\left(D, A_{1}=1\right) Gini(D,A1=1) 和 Gini ( D , A 1 = 3 ) \operatorname{Gini}\left(D, A_{1}=3\right) Gini(D,A1=3) 相等,且最小,所以 A 1 = 1 A_{1}=1 A1=1 和 A 1 = 3 A_{1}=3 A1=3 都可 以选作 A 1 A_{1} A1 的最优切分点。
-
特征 A 2 A_{2} A2 和 A 3 A_{3} A3 的基尼指数:
Gini ( D , A 2 = 1 ) = 0.32 Gini ( D , A 3 = 1 ) = 0.27 \begin{array}{l} \operatorname{Gini}\left(D, A_{2}=1\right)=0.32 \\ \operatorname{Gini}\left(D, A_{3}=1\right)=0.27 \end{array} Gini(D,A2=1)=0.32Gini(D,A3=1)=0.27
由于 A 2 A_{2} A2 和 $ A_{3}$ 只有一个切分点,所以它们就是最优切分点。 -
特征 A 4 A_{4} A4 的基尼指数:
Gini ( D , A 4 = 1 ) = 0.36 Gini ( D , A 4 = 2 ) = 0.47 Gini ( D , A 4 = 3 ) = 0.32 \begin{array}{l} \operatorname{Gini}\left(D, A_{4}=1\right)=0.36 \\ \operatorname{Gini}\left(D, A_{4}=2\right)=0.47 \\ \operatorname{Gini}\left(D, A_{4}=3\right)=0.32 \end{array} Gini(D,A4=1)=0.36Gini(D,A4=2)=0.47Gini(D,A4=3)=0.32
由于 Gini ( D , A 4 = 3 ) \operatorname{Gini}\left(D, A_{4}=3\right) 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 几个特征中, Gini ( D , A 3 = 1 ) = 0.27 \operatorname{Gini}\left(D, A_{3}=1\right)=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 中选择最优特征及其最优切分点,结果是 A 2 = 1 A_{2}=1 A2=1。 依此计算得知,所得结点都是叶结点。
4.2 回归问题
当
(
j
,
s
)
=
(
1
,
4.50
)
(j,s)=(1,4.50)
(j,s)=(1,4.50) 时,
R
1
(
1
,
4.50
)
=
{
1
}
R_1(1,4.50)=\{1\}
R1(1,4.50)={1},
R
2
(
1
,
4.50
)
=
{
2
,
3
,
4
,
5
,
6
}
R_2(1,4.50)=\{2,3,4,5,6\}
R2(1,4.50)={2,3,4,5,6}。
由
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}\left[\min _{c_{1}} \sum_{x_{i} \in R_{1}(j, s)}\left(y_{i}-c_{1}\right)^{2}+\min _{c_{2}} \sum_{x_{i} \in R_{2}(j, s)}\left(y_{i}-c_{2}\right)^{2}\right]
j,smin
c1minxi∈R1(j,s)∑(yi−c1)2+c2minxi∈R2(j,s)∑(yi−c2)2
可知: c ^ 11 = 4.500 , c ^ 12 = 4.75 + 4.91 + 5.34 + 5.80 + 7.05 5 = 5.570 \hat{c}_{11}=4.500,\hat{c}_{12}=\frac{4.75+4.91+5.34+5.80+7.05}{5}=5.570 c^11=4.500,c^12=54.75+4.91+5.34+5.80+7.05=5.570,且此时最小值为: 3.404 3.404 3.404。
类似地,当 ( j , s ) = ( 2 , 4.75 ) (j,s)=(2,4.75) (j,s)=(2,4.75) 时, c ^ 21 = 4.625 , c ^ 22 = 5.775 \hat{c}_{21}=4.625,\hat{c}_{22}=5.775 c^21=4.625,c^22=5.775,且此时最小值为: 2.595 2.595 2.595。
类似地,当 ( j , s ) = ( 3 , 4.91 ) (j,s)=(3,4.91) (j,s)=(3,4.91) 时, c ^ 31 = 4.720 , c ^ 32 = 6.063 \hat{c}_{31}=4.720,\hat{c}_{32}=6.063 c^31=4.720,c^32=6.063,且此时最小值为: 1.651 1.651 1.651。
类似地,当 ( j , s ) = ( 4 , 5.34 ) (j,s)=(4,5.34) (j,s)=(4,5.34) 时, c ^ 41 = 4.875 , c ^ 42 = 6.425 \hat{c}_{41}=4.875,\hat{c}_{42}=6.425 c^41=4.875,c^42=6.425,且此时最小值为: 1.155 1.155 1.155。
类似地,当 ( j , s ) = ( 5 , 5.80 ) (j,s)=(5,5.80) (j,s)=(5,5.80) 时, c ^ 51 = 5.060 , c ^ 52 = 7.050 \hat{c}_{51}=5.060,\hat{c}_{52}=7.050 c^51=5.060,c^52=7.050,且此时最小值为: 1.058 1.058 1.058。
类似地,当 ( j , s ) = ( 6 , 7.05 ) (j,s)=(6,7.05) (j,s)=(6,7.05) 时, c ^ 61 = 5.392 , c ^ 62 = 0.000 \hat{c}_{61}=5.392,\hat{c}_{62}=0.000 c^61=5.392,c^62=0.000,且此时最小值为: 4.358 4.358 4.358。
综上可知:最优切分组为 ( j , s ) = ( 5 , 5.80 ) (j,s)=(5,5.80) (j,s)=(5,5.80),此时 R 1 ( 1 , 4.50 ) = { 1 , 2 , 3 , 4 , 5 } R_1(1,4.50)=\{1,2,3,4,5\} R1(1,4.50)={1,2,3,4,5}, R 2 ( 1 , 4.50 ) = { 6 } R_2(1,4.50)=\{6\} R2(1,4.50)={6}。
继续
对子区间
R
1
(
1
,
4.50
)
=
{
1
,
2
,
3
,
4
,
5
}
R_1(1,4.50)=\{1,2,3,4,5\}
R1(1,4.50)={1,2,3,4,5} 重复上述计算可得最优切分组为
(
j
,
s
)
=
(
3
,
4.91
)
(j,s)=(3,4.91)
(j,s)=(3,4.91),此时最优切分组对应的划分区间为
R
11
(
4
,
4.91
)
=
{
1
,
2
,
3
}
R_{11}(4,4.91)=\{1,2,3\}
R11(4,4.91)={1,2,3},
R
12
(
4
,
4.91
)
=
{
4
,
5
}
R_{12}(4,4.91)=\{4,5\}
R12(4,4.91)={4,5},对应的最小值为:
0.191
0.191
0.191。
假设最小误差
0.191
0.191
0.191 已满足停止条件,则将输入空间划分为三个区域,即
R
1
=
{
1
,
2
,
3
}
,
R
2
=
{
4
,
5
}
,
R
3
=
{
6
}
R_1=\{1,2,3\},R_2=\{4,5\},R_3=\{6\}
R1={1,2,3},R2={4,5},R3={6}
从而生成回归决策树为:
f
(
x
)
=
∑
m
=
1
3
c
^
m
I
(
x
∈
R
m
)
f(x) = \sum_{m=1}^{3}\hat{c}_m I(x \in R_m)
f(x)=m=1∑3c^mI(x∈Rm)
其中,
c
^
1
=
4.720
,
c
^
2
=
6.063
,
c
^
3
=
7.050
\hat{c}_{1}=4.720,\hat{c}_{2}=6.063,\hat{c}_{3}=7.050
c^1=4.720,c^2=6.063,c^3=7.050。
5. Python 实现
5.1 分类问题
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeClassifier
loan = pd.read_csv('loan.csv')
X = loan.iloc[:,:-1]
y = loan.iloc[:,-1]
model = DecisionTreeClassifier(max_depth=1,max_leaf_nodes=3)
model.fit(X,y)
y_pred = model.predict(X)
plt.scatter(range(len(X)),y, color='blue',s=100)
plt.scatter(range(len(X)),y_pred, color='red',marker='p')
plt.show()
5.2 回归问题
from sklearn.tree import DecisionTreeRegressor
import numpy as np
import matplotlib.pyplot as plt
X = np.array(list(range(1,7))).reshape(-1,1)
y = np.array([4.50, 4.75, 4.91, 5.34, 5.80, 7.05]).ravel()
model = DecisionTreeRegressor(max_depth=1,max_leaf_nodes=3)
# model = DecisionTreeRegressor(max_depth=2,max_leaf_nodes=3)
model.fit(X,y)
plt.scatter(X,y)
plt.plot(X,model.predict(X),color='green')
plt.show()
注:此图和上面的示例(回归树)计算第一次划分区间对应!如果对上述代码调参,读者自己发掘一下还是一致的!
参考文献
- 李航. 统计学习方法[M]. 清华大学出版社,2018.
- 写作不易,切勿白剽
- 博友们的点赞和关注就是对博主坚持写作的最大鼓励
- 持续更新,未完待续…