机器学习实战——决策树
1 决策树模型介绍
常用的决策树算法有 ID3、C4.5与CART,其依据的分类准则分别为信息增益、信息增益比和基尼系数。
1.1 ID3 算法的分类准则
“信息熵” (information entropy)是度量样本集合纯度最常用的一种指标。假定当前样本集合 D 中第 k 类样本所占的比例为 p k ( k = 1 , 2 , ⋯   , ∣ y ∣ ) p_k(k = 1,2,\cdots,\mid{y}\mid) pk(k=1,2,⋯,∣y∣),则 D 的信息熵定义为
p
k
=
∣
D
k
∣
∣
D
∣
{p_k=\frac{\mid{D_k}\mid}{\mid{D}\mid}}
pk=∣D∣∣Dk∣
E
n
d
(
D
)
End(D)
End(D)的值越小,则
D
D
D的纯度越高。
信息增益表示某一特征
a
a
a 具有可能的属性
{
a
1
,
a
2
,
…
,
a
V
}
\{a^1,a^2,\dots,a^V\}
{a1,a2,…,aV},若用
a
a
a 来划分样本集
D
D
D,则在属性
a
V
a^V
aV上的信息熵为
E
n
d
(
D
V
)
End(D^V)
End(DV),再考虑到不同的分支结点所包含的样本数不同,给分支结点赋予权重
∣
D
V
∣
∣
D
∣
\frac{\mid{D^V}\mid}{\mid{D}\mid}
∣D∣∣DV∣。其公式如下:
在决策树的分类过程中,选择信息增益最大的特征进行分类处理。信息增益准则对可取值数目较多的属性有所偏好,为减少这种偏好可能带来的不利影响,可以使用信息增益的比率进行分类。
1.2 C4.5 算法的分类准则
信息增益比为
在决策树的分类过程中,选择信息增益比最大的特征进行分类处理。
1.3 CART 算法的分类准则
基尼系数
上式说明
G
i
n
i
(
D
)
Gini(D)
Gini(D) 反映了从数据集
D
D
D 中随机抽取两个样本,其类别标记不一致的概率。因此,
G
i
n
i
(
D
)
Gini(D)
Gini(D) 越小,则数据集
D
D
D 的纯度越高。
对于二分类问题,其基尼系数可以表示为:
若某一特征
a
a
a 具有不同的几种属性,则特征
a
a
a 取某一属性之后,可以把样本集划分为
D
1
D_1
D1、
D
2
D_2
D2 两个集合,其基尼系数可以表示为:
然后比较特征中各属性的基尼系数,选择最小的基尼系数作为根节点(特征)与叶节点(特征的属性)的划分标准。
2 决策树的剪枝处理
决策树剪枝的基本策略有预剪枝和后剪枝。 预剪枝是指在决策树生成过程中,对每个结点在划分前先进行估计,若当前结点的划分不能带来决策树泛化性能提升,则停止划分并将当前结点标记为叶结点;后剪枝则是先从训练集生成一棵完整的决策树,然后自底向上地对非叶结点进行考察,若将该结点对应的子树替换为叶结点能带来决策树泛化性能提升,则将该子树替换为叶结点。
3 决策树在sklearn包中的实现
3.1 DecisionTreeClassifier 的调用
sklearn 中构建DecisionTreeClassifier 类来实现决策树的算法,目前只支持ID3、CART算法,详细的参考文档:http://sklearn.apachecn.org/cn/0.19.0/modules/tree.html
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"或者"entropy",默认使用基尼系数"gini"。
splitter:特征划分点选择标准,可以使用"best"或者"random"。默认使用"best",表示在特征的所有划分点中找出最优的划分点,适合样本量不大的情况。“random"表示随机的在部分划分点中找局部最优的划分点。
max_features:划分时考虑的最大特征数,默认是"None”,意味着划分时考虑所有的特征数;“log2"意味着划分时最多考虑log2N个特征;“sqrt"或者"auto"意味着划分时最多考虑 N \sqrt{N} N个特征。一般样本特征数小于50,默认使用"None”。如果特征数非常多,可以灵活使用其他取值来控制划分时考虑的最大特征数,以控制决策树的生成时间。
max_depth:决策树的最大深度,默认可以不输入,如果不输入的话,决策树在建立子树的时候不会限制子树的深度。一般来说,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。常用的可以取值10-100之间。
min_samples_split:内部节点再划分所需最小样本数,这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进行划分。 默认是2。如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。
min_samples_leaf:叶子节点最少样本数,这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝。 默认是1,可以输入最少的样本数的整数,或者最少样本数占样本总数的百分比。如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。
min_weight_fraction_leaf:叶子节点最小的样本权重和, 这个值限制了叶子节点所有样本权重和的最小值,如果小于这个值,则会和兄弟节点一起被剪枝。 默认是0,就是不考虑权重问题。一般来说,如果我们有较多样本有缺失值,或者分类树样本的分布类别偏差很大,就会引入样本权重,这时我们就要注意这个值了。
max_leaf_nodes:最大叶子节点数,通过限制最大叶子节点数,可以防止过拟合,默认是"None”,即不限制最大的叶子节点数。如果加了限制,算法会建立在最大叶子节点数内最优的决策树。如果特征不多,可以不考虑这个值,但是如果特征分成多的话,可以加以限制,具体的值可以通过交叉验证得到。
class_weight:类别权重,指定样本各类别的的权重,主要是为了防止训练集某些类别的样本过多,导致训练的决策树过于偏向这些类别。这里可以自己指定各个样本的权重,或者用“balanced”,如果使用“balanced”,则算法会自己计算权重,样本量少的类别所对应的样本权重会高。当然,如果你的样本类别分布没有明显的偏倚,则可以不管这个参数,选择默认的"None” ,不适用于回归树。
min_impurity_split:节点划分最小不纯度,这个值限制了决策树的增长,如果某节点的不纯度(基尼系数,信息增益,均方差,绝对差)小于这个阈值,则该节点不再生成子节点。即为叶子节点 。
presort:数据是否预排序,这个值是布尔值,默认是False不排序。一般来说,如果样本量少或者限制了一个深度很小的决策树,设置为true可以让划分点选择更加快,决策树建立的更加快。如果样本量太大的话,反而没有什么好处。问题是样本量少的时候,我速度本来就不慢。所以这个值一般懒得理它就可以了。
本文以 iris 数据集为例说明 DecisionTreeClassifier 如何调用:
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
iris = load_iris()
iris_data = iris.data # 数据集
iris_labels = iris.target # 对应的分类标签
# 使用train_test_split对数据集按比例进行随机抽取,本文按37开进行抽取
X_train, X_test, Y_train, Y_test = train_test_split(iris_data, iris_labels, test_size=0.3, random_state=0)
# 定义决策树分类器对象
Tree = DecisionTreeClassifier(criterion='entropy') # ID3算法
# Tree = DecisionTreeClassifier(criterion='gini') # CART算法
# 调用所定义的分类器的训练方法,主要接收两个参数:训练数据集及训练标签
Tree.fit(X_train,Y_train)
#调用该对象的测试方法,主要接收一个参数:测试数据集
Y_predict = Tree.predict(X_test)
#计算各测试样本属于不同类的概率预测值
probility=Tree.predict_proba(X_test)
# 调用打分方法,计算模型在测试集上的准确率
score = Tree.score(X_test,Y_test)
3.2 决策树模型的可视化
3.2.1 环境安装与配置
一般实现决策树的可视化需要用到 graphviz 和 pydotplus,可以参考这篇博文,其详细的安装步骤如下:
- 安装可视化软件graphviz。在官网下载对应的版本并进行安装,本文下载的版本如下
- 配置graphviz的环境变量,根据刚才安装的 graphviz 的 bin目录路径,本文我的是D:/Graphviz2.38/bin,具体的配置可以参考这篇文章,也可以在 Python 中直接添加路径,os.environ[“PATH”] += os.pathsep + ‘D:/Graphviz2.38/bin’(该路径是自己电脑上的安装路径)
- 在python中安装graphviz,pip install graphviz;
- 在python中安装pydotplus,pip install pydotplus。
3.2.2 可视化的实现
决策树的可视化实现需要使用方法 export_graphviz 生成 graphviz 所需的 dot 文件。以上文生成的决策树为例
from sklearn import tree
from sklearn.datasets import load_iris
import pydotplus
import os
# 配置graphviz的环境
os.environ["PATH"] += os.pathsep + 'D:/Graphviz2.38/bin'
# 可视化图形无颜色
#dot_data = tree.export_graphviz(Tree, out_file=None)
# 可视化图形有颜色
dot_data = tree.export_graphviz(Tree, out_file=None,
feature_names=iris.feature_names,
class_names=iris.target_names,
filled=True, rounded=True,
special_characters=True)
graph = pydotplus.graph_from_dot_data(dot_data)
# 生成可视化图形,可自己设置图片的类型及路径
graph.write_png("tree.png") #生成png文件
#graph.write_png("tree.jpg") # 生成jpg文件
#graph.write_png("tree.pdf") # 生成pdf文件