1、决策树介绍
决策树简单的理解为if-then的集合,其优点主要有分类速度快、可读性等。决策树的生成主要可分为三个步骤:特征的选择、决策树的生成、决策树的剪枝。
1.1特征选择
对于结点的选择,总得需要一个计算方法来实现,这个方法的目标是优先选择分类能力强的特征,这样才提高决策树的效率,如果随机选择特征的话将会产生复杂度或者是结点更多的决策树,显然不是我们想要的。
怎么计算特征的分类能力呢,通常选择的准则是信息增益或信息增益比。
要计算信息增益,首先要知道熵的概念:表示随机变量不确定程度,
设X是一个取有限个值的离散随机变量,其概率分布为:
P(X=xi)=Pi,i=1,2,,,n
P
(
X
=
x
i
)
=
P
i
,
i
=
1
,
2
,
,
,
n
则随机变量的熵定义为:
H(X)=−∑i=1npilog2pi
H
(
X
)
=
−
∑
i
=
1
n
p
i
l
o
g
2
p
i
其中对数不一定必须以2为底,也可自然对数e。
如,随机变量只取两个值0,1,则分布为:
P(X=1)=p,P(X=0)=1−p,0<=p<=1
P
(
X
=
1
)
=
p
,
P
(
X
=
0
)
=
1
−
p
,
0
<=
p
<=
1
则,熵为:
H(p)=−plog2p−(1−p)log2(1−p)
H
(
p
)
=
−
p
l
o
g
2
p
−
(
1
−
p
)
l
o
g
2
(
1
−
p
)
其次还需要条件熵H(Y|X),其定义为X给定的条件下Y的条件概率分布的熵对X的数学期望:
H(X|Y)=∑i=1npiH(Y|X=xi)
H
(
X
|
Y
)
=
∑
i
=
1
n
p
i
H
(
Y
|
X
=
x
i
)
看起来比较难以理解, H(Y|X=xi) H ( Y | X = x i ) 可以简单的理解为:在某个特征等于 xi x i 的条件下取类 Yj Y j 的熵。对应如果为二分类,j=1,2.
当熵和条件熵中的概率由数据估计得到时,对应的熵分别成为条件熵和经验条件熵。
信息增益表示得知特征X的信息而使类Y的不确定性减少的程度。定义为:
g(D,A)=H(D)−H(D|A)
g
(
D
,
A
)
=
H
(
D
)
−
H
(
D
|
A
)
信息增益比:信息增益g(D,A)与训练数据集D关于A的值的熵之比,即
gR(D,A)=g(D,A)HA(D)
g
R
(
D
,
A
)
=
g
(
D
,
A
)
H
A
(
D
)
1.2生成决策树
对生成树,ID3算法的方法是从根结点开始,对结点计算所有可能的信息增益,选择信息增益最大的特征作为结点的特征,由该特征的不同取值建立子结点,再递归的计算信息增益建立结点,直到信息增益均很小或者没有特征可以选择为止。
C4.5算法,与ID3算法唯一不同是使用信息增益比来选择特征。
1.3剪枝
当使用训练数据进行生成决策树,而不进行处理时,会出现训练集精度为100%,但测试集上表现不是很好,这是由于对训练集进行生成决策树时过于细分,不进行剪枝,很有可能产生过拟合。剪枝分为两种,1、预剪枝,在构造树的同时停止信息量较少,也就是信息增益或信息增益比较小的枝生长。2、后剪枝,先生成树,再进行剪枝。
2、sklearn
当不进行剪枝时:
#!/user/bin/env python
#-*- coding:utf-8 -*-
from sklearn.tree import export_graphviz
from sklearn.tree import DecisionTreeClassifier
#3:1拆分数据集
from sklearn.model_selection import train_test_split
#乳腺癌数据集
from sklearn.datasets import load_breast_cancer
import pydot
cancer = load_breast_cancer()
#参数random_state是指随机生成器,0表示函数输出是固定不变的
X_train,X_test,y_train,y_test = train_test_split(cancer['data'],cancer['target'],random_state=42)
tree = DecisionTreeClassifier(random_state=0)
tree.fit(X_train,y_train)
print('Train score:{:.3f}'.format(tree.score(X_train,y_train)))
print('Test score:{:.3f}'.format(tree.score(X_test,y_test)))
#生成可视化图
export_graphviz(tree,out_file="tree.dot",class_names=['严重','轻微'],feature_names=cancer.feature_names,impurity=False,filled=True)
#展示可视化图
(graph,) = pydot.graph_from_dot_file('tree.dot')
graph.write_png('tree.png')
执行结果:
Train score:1.000
Test score:0.930
进行预剪枝时:
#!/user/bin/env python
#-*- coding:utf-8 -*-
from sklearn.tree import export_graphviz
from sklearn.tree import DecisionTreeClassifier
#3:1拆分数据集
from sklearn.model_selection import train_test_split
#乳腺癌数据集
from sklearn.datasets import load_breast_cancer
import pydot
cancer = load_breast_cancer()
#参数random_state是指随机生成器,0表示函数输出是固定不变的
X_train,X_test,y_train,y_test = train_test_split(cancer['data'],cancer['target'],random_state=42)
#设置深度为4,即产生4个问题就停止生长
tree = DecisionTreeClassifier(max_depth=4,random_state=0)
tree.fit(X_train,y_train)
print('Train score:{:.3f}'.format(tree.score(X_train,y_train)))
print('Test score:{:.3f}'.format(tree.score(X_test,y_test)))
#生成可视化图
export_graphviz(tree,out_file="tree.dot",class_names=['严重','轻微'],feature_names=cancer.feature_names,impurity=False,filled=True)
#展示可视化图
(graph,) = pydot.graph_from_dot_file('tree.dot')
graph.write_png('tree.png')
结果
Train score:0.995
Test score:0.951