1. 决策树模型与学习
1.1 决策树模型
分类决策树模型是一种描述对实例进行分类的树形结构。决策数由节点和有向边组成。节点有两种类型:内部节点和叶节点。内部节点表示特征,叶节点表示类。
如图所示:
1.2 决策树学习
决策树学习算法:
- 特征选择:如果特征数量很多,也可以在决策树学习开始的时候,对特征进行选择,只留下对训练数据有足够分类能力的特征。
- 决策树的生成:决策树学习的算法通常是 个递归地选择最优特征,并根据该特征对训练数据进行分剖,使得对各个子数据集有一个最好的分类的过程。
- 决策树的剪枝:我们需要对己生成的树自下而上进行剪枝,将树变得更简单,从而使它具有更好的泛化能力。
2. 特征选择
如果一个特征具有较好的分类能力,即按照此特征将数据集分割成子集,各个子集在当前条件下有最好的分类。(最好的分类:基本可以确定其类别,或者是它的不确定性比较小)
2.1 熵
熵:表示随机变量不确定的度量。
假设
X
X
X的概率分布为:
P
(
X
=
x
i
)
=
p
i
P(X=x_i)=p_i
P(X=xi)=pi
则随机变量
X
X
X的熵为
H
(
X
)
=
−
∑
p
i
l
o
g
p
i
H(X)=-\sum p_i logp_i
H(X)=−∑pilogpi
条件熵:表示在已知随机变量 X X X的条件下随机变量 Y Y Y的不确定性。
假设随机变量
(
X
,
Y
)
(X,Y)
(X,Y)的联合分布为:
P
(
X
=
x
i
,
Y
=
y
i
)
=
p
i
j
P(X=x_i,Y=y_i)=p_{ij}
P(X=xi,Y=yi)=pij
则随机变量
X
,
Y
X,Y
X,Y的条件熵为
H
(
Y
∣
X
)
=
∑
p
i
H
(
Y
∣
X
=
x
i
)
H(Y|X)=\sum p_i H(Y|X=x_i)
H(Y∣X)=∑piH(Y∣X=xi)
2.2 信息增益
特征 A A A对训练数据集 D D D的信息增益 g ( D , A ) g(D,A) g(D,A),定义为集合 D D D的熵 H ( D ) H(D) H(D)与特征 A A A给定条件下 D D D的条件熵之差:
g ( D , A ) = H ( D ) − H ( D ∣ A ) g(D,A)=H(D)-H(D|A) g(D,A)=H(D)−H(D∣A)
由于特征 A A A从而使得数据集 D D D的分类的不确定性减少,所以其减少的越多,说明其特征越好,即信息增益大的特征具有更强的分类能力。
信息增益算法:
输入:训练数据集
D
D
D和特征
A
A
A
输出:
g
(
D
,
A
)
g(D,A)
g(D,A)
- 计算
H
(
D
)
H(D)
H(D)
H ( D ) = − ∑ k = 1 K ∣ C k ∣ ∣ D ∣ l o g 2 ∣ C k ∣ ∣ D ∣ H(D)=-\sum_{k=1}^K \frac {|C_k|} {|D|} log_2 \frac {|C_k|} {|D|} H(D)=−k=1∑K∣D∣∣Ck∣log2∣D∣∣Ck∣- ∣ D ∣ |D| ∣D∣:样本个数
- ∣ C k ∣ |C_k| ∣Ck∣:属于类 C k C_k Ck的样本个数
- 计算
H
(
D
∣
A
)
H(D|A)
H(D∣A)
H ( D ∣ A ) = ∑ i = 1 n ∣ D i ∣ ∣ D ∣ H ( D i ) = − ∑ i = 1 n ∣ D i ∣ ∣ D ∣ ∑ k = 1 K ∣ D i k ∣ D i l o g 2 ∣ D i k ∣ ∣ D i ∣ H(D|A)=\sum_{i=1}^n \frac {|D_i|} {|D|} H(D_i)=-\sum_{i=1}^n \frac {|D_i|} {|D|}\sum_{k=1}^K \frac {|D_{ik}|} {D_i} log_2 \frac {|D_{ik}|} {|D_i|} H(D∣A)=i=1∑n∣D∣∣Di∣H(Di)=−i=1∑n∣D∣∣Di∣k=1∑KDi∣Dik∣log2∣Di∣∣Dik∣- ∣ D i ∣ |D_i| ∣Di∣:子集样本个数
- ∣ D i k ∣ |D_{ik}| ∣Dik∣:子集样本 D i D_i Di中属于类 C k C_k Ck的样本个数
- 计算信息增益
g ( D , A ) = H ( D ) − H ( D ∣ A ) g(D,A)=H(D)-H(D|A) g(D,A)=H(D)−H(D∣A)
2.3 信息增益比
以信息增益作为划分训练数据集的特征,存在偏向于选择取值较多的特征的问题。故可采用信息增益比。
特征
A
A
A对训练数据集
D
D
D的信息增益比:
g
R
(
D
,
A
)
=
g
(
D
,
A
)
H
A
(
D
)
g_R(D,A)=\frac {g(D,A)} {H_A(D)}
gR(D,A)=HA(D)g(D,A)
其中: H A ( D ) = − ∑ i = 1 n ∣ D i ∣ ∣ D ∣ l o g 2 ∣ D i ∣ ∣ D ∣ H_A(D)=-\sum_{i=1}^n \frac {|D_i|} {|D|} log_2\frac {|D_i|} {|D|} HA(D)=−∑i=1n∣D∣∣Di∣log2∣D∣∣Di∣
3. 决策树的生成
3.1 ID3算法
ID3算法的核心是在决策树各个结点上利用信息增益准则选择特征,递归地构建决策树。
ID3算法:
输入:训练数据集
D
D
D,特征集
A
A
A
输出:决策树
T
T
T
- 计算各特征对 D D D的信息增益,选择信息增益最大的特征 A g A_g Ag
- 对 A g A_g Ag的每一个可能值 a i a_i ai,按照 A g = a i A_g=a_i Ag=ai将 D D D划分为若干非空子集 D i D_i Di,将 D i D_i Di中实例最大的类作为标记,构建子节点,由结点及其子节点构成树 T T T,返回 T T T
- 对于第 i i i个子节点,以 D i D_i Di为训练集,以 A − { A g } A-\{A_g\} A−{Ag}为特征集。递归调用上面2步
3.2 C4.5算法
C4.5算法与ID3算法类似,在生成过程中,用信息增益比代替了信息增益。
4. 决策树的剪枝
决策树生成算法产生的树通常对训练数据的分类很准确,但对测试数据的分类却没有那么准确,即出现过拟合现象。
解决这个这个问题的方法就是简化树,即剪枝,从而让模型不要过于复杂。
决策树的剪枝通常是极小化决策树整体的损失函数来实现的。损失函数为:
C
α
(
T
)
=
∑
t
=
1
∣
T
∣
N
t
H
t
(
T
)
+
α
∣
T
∣
C_{\alpha}(T)=\sum_{t=1}^{|T|} N_tH_t(T)+\alpha|T|
Cα(T)=t=1∑∣T∣NtHt(T)+α∣T∣
- ∣ T ∣ |T| ∣T∣:树 T T T中叶结点的个数
- H t ( T ) H_t(T) Ht(T):叶节点 t t t的熵
- N t N_t Nt:叶节点 t t t的样本点个数
H t ( T ) = − ∑ k = 1 K N t k N t l o g N t k N t H_t(T) = -\sum_{k=1}^K \frac {N_{tk}} {N_t} log\frac {N_{tk}} {N_t} Ht(T)=−k=1∑KNtNtklogNtNtk
记损失函数第1项为:
C
(
T
)
=
∑
t
=
1
∣
T
∣
N
t
H
t
(
T
)
=
−
∑
t
=
1
∣
T
∣
∑
k
=
1
K
N
t
k
N
t
l
o
g
N
t
k
N
t
C(T)=\sum_{t=1}^{|T|} N_tH_t(T)=-\sum_{t=1}^{|T|}\sum_{k=1}^K \frac {N_{tk}} {N_t} log\frac {N_{tk}} {N_t}
C(T)=t=1∑∣T∣NtHt(T)=−t=1∑∣T∣k=1∑KNtNtklogNtNtk
所以:
C
α
(
T
)
=
C
(
T
)
+
α
∣
T
∣
C_\alpha(T) = C(T) + \alpha|T|
Cα(T)=C(T)+α∣T∣
- C ( T ) C(T) C(T):表示模型对训练数据的预测误差
- ∣ T ∣ |T| ∣T∣:表示模型的复杂度
树的剪枝算法
输入:决策树生成算法生成的整个树
T
T
T,参数
α
\alpha
α
输出:修建后的子树
T
α
T_{\alpha}
Tα
- 计算每个结点的熵
- 递归地从树地叶结点向上回缩
设一组叶结点回缩到其父结点之前与之后地树分别为
T
B
T_B
TB与
T
A
T_A
TA,其对应的损失函数分别为
C
α
(
T
B
)
C_{\alpha}(T_B)
Cα(TB)与
C
α
(
T
A
)
C_{\alpha}(T_A)
Cα(TA),如果
C
α
(
T
A
)
⩽
C
α
(
T
B
)
C_{\alpha}(T_A) \leqslant C_{\alpha}(T_B)
Cα(TA)⩽Cα(TB)
则进行剪枝。
3. 返回第2步,直至不能继续为止,得到损失最小的子树
T
α
T_{\alpha}
Tα
5. CART算法
1. 特征选择
分类树用基尼指数选择最优特征。
基尼指数与熵一样,表示随机变量的不确定性的大小
- Gini = 样本被选中的概率*样本选错的概率
- Gini越大,数据的不确定性越高
- Gini越小,数据的不确定性越低
分类问题中,假设有
K
K
K个类,样本点属于第
k
k
k类的概率为
p
k
p_k
pk,则其基尼指数为:
G
i
n
i
(
p
)
=
∑
k
=
1
K
p
k
(
1
−
p
k
)
Gini(p)=\sum_{k=1}^{K}p_k(1-p_k)
Gini(p)=k=1∑Kpk(1−pk)
如果样本集合
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 |A(x)=a\}, D_2=D-D_1
D1={(x,y)∈D∣A(x)=a},D2=D−D1
则在特征
A
A
A的条件下,集合
D
D
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)
2. 树的生成
输入:训练数据集
D
D
D
输出:CART决策树
- 计算现有特征对数据集的基尼指数
- 选择基尼指数最小的特征及其对应的划分点作为最优特征和最优划分点,并根据此特征将数据集划分为两个子集
- 对两个子集递归调用(1),(2),直至满足条件
- 生成CART决策树
3. 树的剪枝
CART剪枝算法由两步组成
- 由生成算法生成的决策树 T 0 T_0 T0底端开始不断剪枝,直到 T 0 T_0 T0的根节点,形成一个子树序列 { T 0 , T 1 , ⋯ , T n } \{T_0,T_1, \cdots, T_n\} {T0,T1,⋯,Tn}
- 通过交叉验证的方法对子树序列进行验证测试,从中选择最优子树
计算子树的损失函数为:
C
α
(
T
)
=
C
(
T
)
+
α
∣
T
∣
C_\alpha(T)=C(T)+ \alpha|T|
Cα(T)=C(T)+α∣T∣
- C ( T ) C(T) C(T):对训练数据的预测误差
- ∣ T ∣ |T| ∣T∣:为树的叶节点数目
- α \alpha α:权衡训练数据的拟合程度与模型的复杂度
从整体树
T
0
T_0
T0开始剪枝,对于
T
0
T_0
T0的任意内部节点
t
t
t,以
t
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 ) ∣ T t ∣ − 1 \alpha=\frac{C(t)-C(T_t)}{|T_t|-1} α=∣Tt∣−1C(t)−C(Tt), T t T_t Tt与 t t t有相同的损失函数值,但 t t t的节点少,因此 t t t比 T t T_t Tt更可取。
对
T
0
T_0
T0中的每一内部节点
t
t
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)
它表示剪枝后整体损失函数的减少的程度。
在
T
0
T_0
T0中剪去
g
(
t
)
g(t)
g(t)最小的
T
t
T_t
Tt,得到子树作为
T
1
T_1
T1,同时将最小的
g
(
t
)
g(t)
g(t)作为
α
1
\alpha_1
α1,则
T
1
T_1
T1就是
[
α
,
α
1
)
[\alpha,\alpha_1)
[α,α1)的最优树。
CART算法剪枝算法
输入:CART算法生成的决策树
T
0
T_0
T0
输出:最优决策树
T
α
T_\alpha
Tα
- 设 k = 0 , T = T 0 k=0,T=T_0 k=0,T=T0
- 设 α = + ∞ \alpha=+\infty α=+∞
- 自下而上对各内节点
t
t
t计算
C
(
T
t
)
C(T_t)
C(Tt),
∣
T
t
∣
|T_t|
∣Tt∣以及
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)
α = m i n ( α , g ( t ) ) \alpha=min(\alpha,g(t)) α=min(α,g(t))
- 对 g ( t ) = α g(t)=\alpha g(t)=α的内部节点 t t t进行剪枝,并对叶节点 t t t以多数表决法确定其类别,得到树 T T T
- 设 k = k + 1 , α k = α , T k = T k=k+1, \alpha_k=\alpha,T_k=T k=k+1,αk=α,Tk=T
- 如果 T k T_k Tk不是由根节点及两个叶节点组成的树,则返回步骤(2);否则令 T k = T n T_k=T_n Tk=Tn
- 采用交叉验证法从子树序列中选取最优子树 T α T_\alpha Tα
6. 算法实现
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['label'] = iris.target
data = np.array(df)
X, y = data[:,:-1], data[:,-1]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import export_graphviz
import graphviz
clf = DecisionTreeClassifier()
clf.fit(X_train, y_train)
DecisionTreeClassifier()
tree_pic = export_graphviz(clf, out_file='mytree.pdf')
with open('mytree.pdf') as f:
dot_graph = f.read()
graphviz.Source(dot_graph)