决策树是一种很简单的算法,它既可以作为分类算法也可以作为回归算法,但它更常见的是用于分类算法中。决策树可以看做是多组if-else规则的组合,所以它简单易懂解释性强容易实现且速度快,但是没有很强的理论保证,且易出现过拟合。决策树一般结构如下图所示:
1. 信息论基础
熵是用来衡量一个系统混论程度的物理量,代表一个系统中蕴含多少信息量,信息量越大表明一个系统不确定性就越大,就存在越多的可能性。
假设一个随机变量X,它的概率分布函数是
p
(
X
=
x
i
)
=
p
i
,
i
=
1
,
2
,
.
.
.
,
n
p(X =x_i)=p_i, i=1,2,...,n
p(X=xi)=pi,i=1,2,...,n,那么X的信息熵是:
H
(
X
)
=
−
∑
i
p
i
l
o
g
2
p
i
H(X)=-\sum_i{p_i}log_2{p_i}
H(X)=−∑ipilog2pi
当X服从均匀分布时,它的信息熵最小。
假设随机变量
(
X
,
Y
)
(X,Y)
(X,Y),它们的概率分布函数是
p
(
x
,
y
)
p(x,y)
p(x,y),那么它们的联合熵是:
H
(
X
,
Y
)
=
−
∑
p
(
x
,
y
)
l
o
g
2
p
(
x
,
y
)
H(X,Y)=-\sum{p(x,y)}log_2{p(x,y)}
H(X,Y)=−∑p(x,y)log2p(x,y)
信息增益表示得知特征x的信息而使得类Y的信息不确定性减少的程度,特征A对于训练数据集D的信息增益
g
(
D
,
A
)
g(D,A)
g(D,A),定义为集合D的经验熵H(D)与特征A给定条件下D的经验熵H(D|A)之差。
g
(
D
,
A
)
=
H
(
D
)
−
H
(
D
∣
A
)
g(D,A) = H(D)-H(D|A)
g(D,A)=H(D)−H(D∣A)
基尼不纯度也就是基尼指数,假设有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=1Kpk1−pk=1−∑k=1Kpk2
2. ID3算法
ID3算法是通过信息增益最大进行特征选择,信息增益表示一直特征X而使得类Y的不确定性减少的程度。
设训练数据集为D,|D|表示其样本容量,即样本个数。设有K个类
C
k
C_k
Ck,
k
=
1
,
2
,
⋯
,
K
k = 1,2,⋯,K
k=1,2,⋯,K,
∣
C
k
∣
|C_k |
∣Ck∣为属于类
C
k
C_k
Ck的样本个数,
∑
k
=
1
K
∣
C
k
∣
=
∣
D
∣
\sum_{k=1}^K|C_k |=|D|
∑k=1K∣Ck∣=∣D∣。设特征A有n个不同的取值
a
1
,
a
2
,
⋯
,
a
n
{a_1,a_2,⋯,a_n}
a1,a2,⋯,an,根据特征A的取值将D划分为n个子集
D
1
,
D
2
,
⋯
,
D
n
D_1, D_2,⋯, D_n
D1,D2,⋯,Dn,
∣
D
i
∣
|D_i|
∣Di∣为
D
i
D_i
Di 的样本个数,
∑
i
=
1
n
∣
D
i
∣
=
∣
D
∣
\sum_{i=1}^n|D_i |=|D|
∑i=1n∣Di∣=∣D∣.记子集
D
i
D_i
Di中属于类
C
k
C_k
Ck的样本的集合为
D
i
k
D_{ik}
Dik,即
D
i
k
=
D
i
∩
C
k
D_{ik} = D_i∩C_k
Dik=Di∩Ck,
∣
D
i
k
∣
|D_{ik} |
∣Dik∣为
D
i
k
D_{ik}
Dik的样本个数。
(1)若D中所有实例属于同一类
C
k
C_k
Ck,则T为单结点数,并将类
C
k
C_k
Ck作为该点的类标记,返回决策树T;
(2)若A = ∅,则T为单结点数,并将D中实例数最大的类
C
k
C_k
Ck作为该结点的类标记,返回决策树T;
(3)否则,计算A中个特征对D的信息增益,选择信息增益最大的特征
A
g
A_g
Ag;
计算特征A对于训练数据集D的信息增益g(D,A),首先计算数据集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=1K∣D∣∣Ck∣)log2∣D∣∣Ck∣
其次,计算特征A对数据集D的经验条件熵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) = -∑_(i=1)^n(|D_i |)/(|D|) ∑_{k=1}^K\frac{|D_{ik}|}{|D_i |}log_2 {\frac{|D_ik |}{|D_i|}}
H(D∣A)=∑i=1n∣D∣∣Di∣H(Di)=−∑(i=1)n(∣Di∣)/(∣D∣)∑k=1K∣Di∣∣Dik∣log2∣Di∣∣Dik∣
最后,计算信息增益
g(D,A) = H(D) – H(D|A)
(4)如果
A
g
A_g
Ag的信息增益小于阈值ε,则置T为单结点树,并将D中实例数最大的类
C
k
C_k
Ck作为该结点的类标记,返回决策树T;
(5)否则,对
A
g
A_g
Ag的每一个可能值
a
i
a_i
ai,依
A
g
=
a
i
A_g = a_i
Ag=ai将D分割为若干非空子集
D
i
D_i
Di,将
D
i
D_i
Di中实例数最大的类作为标记,构建子结点,有结点即其子结点构成数T,返回决策树T;
(6)对第i个子结点,以
D
i
D_i
Di为训练集,以
A
−
A
g
A-{A_g}
A−Ag为特征集,递归地调用步骤(1)~(5),得到子树
T
i
T_i
Ti,返回
T
i
T_i
Ti
ID3算法的缺点:不能处理具有连续值的属性,不能处理缺失值,容易过拟合
3. C4.5算法
决策树C4.5与上面的ID3算法几乎一样,只是在选择特征上有所不同,它是通过判断每个特征的信息增益比最大且超过某个阈值时作为分支的结点。在算法的过程与ID3算法相比,也是除了选择特征的计算方式不同,其余都相同,其中信息增益比的计算方法如下:
(1)首先计算数据集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=1K∣D∣∣Ck∣log2∣D∣∣Ck∣
(2)其次,计算特征A对数据集D的经验条件熵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=1n∣D∣∣Di∣H(Di)=−∑i=1n∣D∣∣Di∣∑k=1K∣Di∣∣Dik∣log2∣Di∣∣Dik∣
(3)计算信息增益
g(D,A) = H(D) – H(D|A)
(4)计算训练数据集关于特征A的熵H_A (D)
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∣
(5)计算信息增益比g_R (D,A)
g
R
(
D
,
A
)
=
(
g
(
D
,
A
)
)
/
(
H
A
(
D
)
)
g_R (D,A) = (g(D,A))/(H_A (D))
gR(D,A)=(g(D,A))/(HA(D))
优点:可以处理连续变量
缺点:偏向取值较多的属性
4. CART分类树
CART树是根据基尼指数来进行特征选择的,同时决定改特征的最优而知切分点。对于给定样本D,其基尼指数为Gini(D)
G
i
n
i
(
D
)
=
1
−
∑
k
=
1
K
(
∣
C
k
∣
∣
D
∣
)
2
Gini(D)=1-\sum_{k=1}^K{(\frac{|C_k|}{|D|})}^2
Gini(D)=1−∑k=1K(∣D∣∣Ck∣)2
其中
C
k
C_k
Ck是D中属于第k类的样本子集,K是类的个数。
如果样本集合D根据特征A是否取某一可能值a被分割为
D
1
D_1
D1和
D
2
D_2
D2两部分,即
D
1
=
(
x
,
y
)
∈
D
∣
A
(
x
)
=
a
D_1 = {{(x,y) ∈D| A(x)=a}}
D1=(x,y)∈D∣A(x)=a,
D
2
=
D
−
D
1
D_2 = D - D_1
D2=D−D1
则在特征A的条件下,集合D的基尼指数Gini(D,A)为
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(D)表示集合D的不确定性,基尼指数Gini(D,A)表示经A=a分割后集合D的不确定性。
根据训练数据集,从根结点开始,递归地每个结点进行以下操作,构建二叉决策树:
(1)设结点的训练数据集为D,计算现有特征对该数据集的基尼指数。此时,对每一个特征A,对其可能取的每个值a,根据样本点对A=a的测试为“是”或“否”将D分割成
D
1
D_1
D1和
D
2
D_2
D2两部分,计算基尼指数Gini(D,A);
(2)在所有可能的特征A以及它们所有可能的切分点a中,选择基尼指数最小的特征及其对应的切分点作为最优特征与最优切分点。依最优特征与最优切分点,从现结点生成两个子结点,将训练数据集依特征分配到两个子结点中去;
(3)对两个子结点递归地调用(1),(2),直至满足停止条件;
5. 连续特征处理
连续的特征可以经过离散化变成离散特征来处理,也可以通过切分成不同的段来实现分支,也可以理解成另一种离散化处理。
6. 减枝和模型评估
剪枝是决策树中一种常见的避免过拟合的方法。决策树算法在学习的过程中为了尽可能的更多得将样本分类正确,需要不断地对结点进行分支,这样会导致分支太多决策树太深,因而出现过拟合。决策树的剪枝策略最基本的有两种:预剪枝(pre-pruning)和后剪枝(post-pruning):
预剪枝(pre-pruning):预剪枝就是在构造决策树的过程中,先对每个结点在划分前进行估计,若果当前结点的划分不能带来决策树模型泛华性能的提升,则不对当前结点进行划分并且将当前结点标记为叶结点。
后剪枝(post-pruning):后剪枝就是先把整颗决策树构造完毕,然后自底向上的对非叶结点进行考察,若将该结点对应的子树换为叶结点能够带来泛华性能的提升,则把该子树替换为叶结点。
7. sklearn参数详解
决策树可以作为分类算法也可以作为回归算法,这里以决策树作为分类算法为例来讲一下常用参数:
class sklearn.tree.DecisionTreeClassifier(criterion=’gini’, splitter=’best’, max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, class_weight=None, presort=False)
criterion:特征选择的标准,主要参数值包括"gini"代表的是Gini impurity(基尼不纯度)与"entropy"代表的是information gain(信息增益)
splitter:参数值可以是"best"或"random"。“best"表示在特征的所有划分点中找出最优的划分点。“random"表示随机的在部分划分点中找局部最优的划分点
max_depth:树的最大深度,如果是"None”,则节点会一直扩展直到所有的叶子都是纯的或者所有的叶子节点都包含少于min_samples_split设置的样本个数
min_samples_split:一个叶子节点再划分所需最小样本数
min_samples_leaf:一个叶子节点下最少样本数,可以是整型数也可以是浮点数
max_features:表示在学习决策树中用的最多的特征数,可以是整型数,即表示多少个特征,可以是浮点数,表示所用的特征数是总特征数乘以浮点数个特征
max_leaf_nodes:最大叶子节点数,可以防止过拟合
min_impurity_decrease:在某个节点往下分支时,只有分支的指标值必须大于这个阀值,否则不分裂
min_impurity_split:设置一个阈值,如果节点的不纯度(基尼系数,信息增益)小于这个阈值,则该结点不再往下分子结点
class_weight:指定样本各类别的的权重,主要是为了防止在样本不均衡问题中,决策树过于偏向样本很多的那个类别。这里可以自己指定各个样本的权重,或者用“balanced”,如果使用“balanced”,则算法会自己计算权重,样本量少的类别所对应的样本权重会高。当然,如果你的样本类别分布没有明显的偏倚,则可以不管这个参数,选择默认的"None”