决策树算法及其Python实现

目录

1.什么是决策树?

2.如何构建决策树?

2.1分类问题中的决策树

2.2决策树的剪枝

3.用Python实现决策树算法

3.1 导入sklean中的tree模块

​编辑

3.2 使用sklean的基本流程

3.3 剪枝操作

3.4 绘制决策树


1.什么是决策树?

决策树(Decision Tree)是一种基本的分类与回归方法,本文主要讨论分类决策树。决策树模型呈树形结构,在分类问题中,表示基于特征对数据进行分类的过程。它可以认为是if-then规则的集合。每个内部节点表示在属性上的一个测试,每个分支代表一个测试输出,每个叶节点代表一种类别。
 

2.如何构建决策树?

决策树构建的基本步骤如下:
1. 开始,所有记录看作一个节点
2. 遍历每个特征的每一种分裂方式,找到最好的分裂特征(分裂点)
3. 分裂成两个或多个节点
4. 对分裂后的节点分别继续执行2-3步,直到每个节点足够“纯”为止

如何评估分裂点的好坏?
具体实践中,到底选择哪个特征作为当前分裂特征,常用的有下面三种算法:
ID3:使用信息增益g(D,A)进行特征选择
C4.5:信息增益率 =g(D,A)/H(A)
CART:基尼系数
一个特征的信息增益(或信息增益率,或基尼系数)越大,表明特征对样本的熵的减少能力更强,这个特征使得数据由不确定性到确定性的能力越强。

2.1分类问题中的决策树

决策树算法在树形结构的基础上直接模仿现实生活中人类做决策的过程如:医学诊断、商业决策等

构成决策树的元素是节点和边。节点会根据样本的特征作出判断,最初的分支点称为根节点,其余的被称为子节点,不再有分支的节点则被称为叶子节点,这些节点代表了样本的分类结果。边则指示着方向

在分类问题中,表示基于特征对实例进行分类的过程,可以认为是if-then的集合,也可以认为是定义在特征空间与类空间上的条件概率分布。

决策树通常有三个步骤:特征选择、决策树的生成、决策树的修剪。

用决策树分类:从根节点开始,对实例的某一特征进行测试,根据测试结果将实例分配到其子节点,此时每个子节点对应着该特征的一个取值,如此递归的对实例进行测试并分配,直到到达叶子节点,最后将实例分到叶节点的类中。

决策树学习的目标:根据给定的训练数据集构建一个决策树模型,使它能够对实例进行正确的分类并在损失函数的意义下,选择最优决策树的问题。

决策树学习的本质:从训练集中归纳出一组分类规则,或者说是由训练数据集估计条件概率模型。

决策树学习的损失函数:正则化的极大似然函数。

决策树学习的测试:最小化损失函数。

决策树原理和问答猜测结果游戏相似,根据一系列数据,然后给出游戏的答案。如下图便是一个简单决策树。

上图为一个决策树流程图,正方形代表判断模块,椭圆代表终止模块,表示已经得出结论,可以终止运行,左右箭头叫做分支。

决策树的优点:
1)可以自学习。在学习过程中不需要使用者了解过多的背景知识,只需要对训练数据进行较好的标注,就能进行学习。
2)决策树模型可读性好,具有描述性,有助于人工分析;
3)效率高,决策树只需要一次构建,就可以反复使用,每一次预测的最大计算次数不超过决策树的深度。

2.2决策树的剪枝

剪枝算法
CART的后剪枝采用最小代价复杂度剪枝法(Minimal Cost Complexity Pruning,MCCP),剪枝的目的是解决模型的过拟合,以得到测试误差最小的树,或者说,达到复杂度和测试误差的平衡。

可以使用叶节点个数来测度决策树的复杂度,将误差看成树的“测试代价”,那么树 T 的代价复杂度定义为:

其中,为树T的叶节点个数,α为复杂度参数(Complexity Parameter,CP参数),R(T)为测试误差:对于分类树使用判错率计算;对于回归树使用均方误差或者离差平方和计算,即此时:

一般希望测试误差R(T)和模型复杂度均较低,但两者其实是此高彼低的关系,因此只要两者之和即代价复杂度较小即可。

此外,树T代价复杂度是α的函数,α=0时表示不考虑复杂度的影响,基于代价复杂度最小是最优树的原则,此时的最优树为叶节点最多的树。显然最优树与CP参数α有关,因此可以通过调整α的取值得到一系列当前最优树,而真正的最优树就在其中。

剪枝过程
在从叶节点逐渐向根节点方向剪枝的过程中,需要判断先剪哪一只,是否需要剪枝的问题。即在判断是否应剪掉中间节点{t}下的子树时,应计算两者的代价复杂度,其中中间节点的代价复杂度通常被视为剪掉其所有子树后的代价复杂度(此时仅有一个叶节点):

中间节点的子树的代价复杂度为:

其中为左右两个子节点测试误差的加权均值,权重为各自样本量占比。

CART后剪枝主要分为两个阶段

from sklean import tree

3.用Python实现决策树算法

3.1 导入sklean中的tree模块
from sklean import tree
3.2 使用sklean的基本流程

1.实例化模型对象

clf = tree.DecisionTreeClassifier()

2.通过模型接口训练模型1

clf = clf.fit(X_train,y_train)

3.通过测试集对模型评分

Test_score = clf,score(X_test,y_test)
3.3 剪枝操作

1.max_depth预剪枝:

限制树的最大深度,超过设定深度的树枝全部剪掉

2.min_samples_leaf:

一个节点在分支后的每个子节点都必须包含至少min_samples_leaf个训练样本,否则分支就不会发生,或者,分支会朝着满足每个子节点都包含min_samples_leaf个样本的方向去发生。

3.min_samples_split

一个节点必须要包含至少min_samples_split个训练样本,这个节点才允许被分支,否则分支就不会发生。一般搭配max_depth使用,这个参数的数量设置的大小会引起过拟合,设置的太大会阻止模型学习数据。对于类别不多的分类问题,=1通常就是最佳选择。一般来说,建立从=5开始使用。如果叶节点中含有的样本量变化很大,建立输入浮点数作为样本量的百分比来使用。同时,这个参数可以保证每个叶子的最小尺寸,可以在回归问题中避免低方差,过拟合的叶子节点出现。

4.max_features

限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃,和max_depth相似

5.min_impurity_decreases

限制信息增益的大小,信息增益小于设定数值的分枝不会发生。

6.确认最优的剪枝参数

我们已经训练好的决策树模型c l f clfclf,确定超参数的曲线来进行判断,超参数的学习曲线,是一条以超参数的取值为横坐标,模型的度量指标作为纵坐标的曲线,它是用来衡量不同超参数取值下模型的表现的线,我们的模型度量指标就是score。

3.4 绘制决策树
导入模块
from sklearn.datasets import load_iris
from sklearn import model_selection
import graphviz
from sklearn import tree
# 加载鸢尾花数据集,X为数据集,y为标签
dataSet = load_iris()
X = dataSet.data
y = dataSet.target
# 特征名称
feature_names = dataSet.feature_names
# 类名
target_names = dataSet.target_names
# 划分数据集
X_trainer, X_test, Y_trainer, Y_test = model_selection.train_test_split(X, y, test_size=0.3)
# 创建决策树对象
clf = tree.DecisionTreeClassifier(criterion = 'entropy')

# 训练样本
clf_tree = clf.fit(X_trainer, Y_trainer)
score = clf_tree.score(X_test,Y_test)
print("模型在测试集上进行评分:\n",score)
predict_y = clf.predict(X_test)
print("对测试集样本的预测结果:\n", predict_y)
predict_y1 = clf.predict_proba(X_test)
print("预测样本为某个标签的概率:\n", predict_y1)
clf_dot = tree.export_graphviz(clf_tree,
                                   out_file= None,
                                   feature_names= feature_names,
                                   class_names= target_names,
                                   filled= True,
                                   rounded= True)
graph = graphviz.Source(clf_dot,
                        filename="iris_decisionTree",
                        format="png")
graph.view()
print("\n特征重要程度为:")
info = [*zip(feature_names, clf.feature_importances_)]
for cell in info:
    print(cell)

Iris数据集决策树分类结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值