机器学习之决策树
目录
一、决策树概念
1.1 什么是决策树算法
- 决策树算法是最流行的机器学习算法之一。它使用树形结构和它们的可能组合来解决特定的问题。它属于监督学习算法的一类,它可以用于分类和回归目的。
- 决策树是一个包含根节点、分支节点和叶节点的结构。每个内部节点表示对一个属性的测试,每个分支表示测试的结果,每个叶子节点保存一个类标签。树中最顶层的节点是根节点。
1.2 分类与回归树(CART)
- 如今,决策树算法被称为CART,即分类与回归树。分类与回归树(Classification and Regression Trees, CART)是Leo Breiman提出的一个术语,指的是可用于分类和回归建模问题的决策树算法。
- CART算法为袋装决策树、随机森林和增强决策树等重要算法提供了基础
1.3 决策树算法术语
- 在Decision Tree算法中,有一个类似树的结构,其中每个内部节点表示对一个属性的测试,每个分支表示测试的结果,每个叶子节点表示一个类标签。从根节点到叶节点的路径表示分类规则。我们可以看到决策树算法中涉及到一些术语。决策树算法中涉及的术语有:
根节点 - 它代表整个总体或样本。这进一步被分成两个或多个齐次集合。
分裂 - 它是将一个节点划分为两个或多个子节点的过程。
决策节点 - 当一个子节点分裂成更多的子节点时,它被称为决策节点。
叶/终端节点 - 不分裂的节点称为叶节点或终端节点。
剪枝 - 当我们移除决策节点的子节点时,这个过程被称为剪枝。这是分裂的相反过程。
分支/子树 - 整棵树的一个子部分称为分支或子树。
父节点和子节点 - 被划分为子节点的节点称为子节点的父节点,其中子节点是父节点的子节点。
1.4 决策树算法的基本思路
- 决策树算法是最常用和最广泛使用的监督机器学习算法之一,可用于分类和回归任务
决策树算法的基本思路如下:
1.对于数据集中的每个属性,Decision-Tree算法形成一个节点。最重要的属性放在根节点上。
2.为了评估手头的任务,我们从根节点开始,沿着满足条件或决策的相应节点向下工作。
3.这个过程一直持续到到达一个叶节点。它包含决策树的预测或结果。
1.5 属性选择方法
- 决策树实现中的主要挑战是识别我们认为是根节点和每个级别的属性,这个过程被称为属性选择。在每一层有不同的属性选择度量来识别可以被认为是根节点的属性。
有两种流行的属性选择方法。分别是:
信息增益
基尼系数
当使用信息增益作为标准时,我们假设属性是分类的,并且假设基尼指数属性是连续的。这些属性选择度量描述如下。
1.5.1 信息增益(Information gain)
- 通过使用信息增益作为标准,我们尝试估计每个属性所包含的信息。为了理解信息增益的概念,我们需要知道另一个叫做熵的概念。
- 熵(Entropy)
熵度量给定数据集中的杂质。在物理和数学中,熵指的是随机变量x的随机性或不确定性。在信息论中,熵指的是一组例子中的不杂质。信息增益是熵的减少。信息增益根据给定的属性值计算数据集分裂前的熵和分裂后的平均熵之差。
熵由下式表示:
E n t r o p y = ∑ i = 1 c − p i ∗ l o g 2 ( p i ) Entropy = \sum_{i=1}^c -p_i*log_2(p_i) Entropy=i=1∑c−pi∗log2(pi)
这里,c是类的数量,pi是与第i类相关的概率。
ID3(迭代二分法)决策树算法使用熵来计算信息增益。因此,通过计算每个属性的熵值减少量,就可以计算出它们的信息增益。选择信息增益最高的属性作为节点上的拆分属性。
1.5.2 基尼指数(Gini index)
- CART(分类和回归树)使用的另一个属性选择度量是基尼指数。它使用基尼方法来创建分裂点。
基尼指数可以用下图表示:
G i n i ( p ) = ∑ i = 1 c p i ∗ ( 1 − p i ) = 1 − ∑ i = 1 c p i 2 Gini(p) = \sum_{i=1}^c p_i *(1 - p_i) = 1 - \sum_{i=1}^c p_i^2 Gini(p)=i=1∑cpi∗(1−pi)=1−i=1∑cpi2
这里,c是类的数量,pi是与第i类相关的概率。 - 基尼指数表示,如果我们从总体中随机选择两个项目,它们必须属于同一类别,如果总体是纯的,那么这个概率是1。
它与“成功”或“失败”的分类目标变量一起工作。它只执行二进制分裂。基尼系数越高,同质性越强。CART(分类和回归树)使用基尼系数方法来创建二元分裂。
计算分裂基尼系数的步骤:
1.计算子节点的基尼系数,使用公式成功和失败概率的平方和 p 2 + q 2 p^2 + q^2 p2+q2
2.使用该分裂的每个节点的加权基尼分数计算分裂的基尼系数
如果是离散值属性,则选择为所选属性提供最小gini索引的子集作为分裂属性。在连续值属性的情况下,策略是选择每一对相邻值作为可能的分裂点,并选择基尼指数较小的点作为分裂点。选择Gini指数最小的属性作为分裂属性。
1.6 决策树算法中的过拟合
- 过度拟合是构建决策树模型的一个实际问题。当算法不断深入以减少训练集误差,但结果是测试集误差增加时,会考虑过拟合问题。因此,我们模型的预测精度下降了。它通常发生在我们由于数据中的异常值和不规则而构建许多分支时。
避免过拟合的两种方法如下: - 先剪枝(Pre-Pruning)
- 后剪枝(Post-Pruning)
1.6.1 先剪枝(Pre-Pruning)
- 在先剪枝中,我们提前停止树的建设。如果一个节点的优度度量值低于阈值,我们宁愿不拆分它。但很难选择一个合适的停止点。
1.6.2 后剪枝(Post-Pruning)
- 在后剪枝中,我们会在树中不断深入,构建一个完整的树。如果树显示出过拟合问题,那么就会进行剪枝作为后剪枝的步骤。我们使用交叉验证数据来检查剪枝的效果。使用交叉验证数据,我们测试扩展一个节点是否会导致改进。如果显示出改进,则可以继续扩展该节点。但如果显示出准确性下降,则不应扩展该节点。因此,该节点应转换为叶节点。
二、决策树实例及代码
数据集
链接:https://pan.baidu.com/s/16Yk7RnjeIj389M4zrhfdVQ
提取码:2da4
2.1 导入库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
2.2 导入数据集
data = pd.read_csv('...\PlayTennis.csv')
print(data) #显示数据集
2.3 编码分类变量
数值决策树是一种易于实现的决策树。所以我们可以利用category_encoders的方法将所有非数值转换为数值
#导入类别编码器
import category_encoders as ce
#创建了一个序号编码器(OrdinalEncoder),该编码器将指定的列('outlook'、'temp'、'humidity'、'windy')中的分类变量转换为序号。这将每个分类变量映射到整数值
encoder = ce.OrdinalEncoder(cols=['outlook', 'temp', 'humidity', 'windy'])
#使用创建的编码器对数据进行转换,并将转换后的数据存储回 data 变量中
data = encoder.fit_transform(data);
#打印转换后的数据
print(data)
2.4 基于gini指数的决策树分类器
#定义目标变量和特征变量
#从数据中选择目标变量(在这里是'play'列),并将其存储在变量 y 中
y = data['play']
#从数据中删除目标变量列('play'列),并将剩余的特征列存储在变量 X 中
X = data.drop(['play'],axis=1)
#从 scikit-learn 库中导入决策树分类器模型
from sklearn.tree import DecisionTreeClassifier
#创建一个基于基尼系数的决策树分类器对象。criterion='gini' 表示使用基尼系数作为分裂标准,max_depth=3 表示树的最大深度为3,random_state=0 用于控制随机性,以确保结果可复现
clf_gini = DecisionTreeClassifier(criterion='gini', max_depth=3, random_state=0)
#使用 X 和 y 来拟合(训练)决策树模型
clf_gini.fit(X, y)
#导入 tree 模块,该模块提供了用于可视化决策树的函数
from sklearn import tree
#创建一个图形对象,指定图形的大小为12x8英寸
plt.figure(figsize=(12, 8))
#利用 tree 模块中的 plot_tree 函数可视化已经训练好的决策树模型 clf_gini
tree.plot_tree(clf_gini)
#将可视化的决策树保存为名为 'decision_tree.png' 的图像文件
plt.savefig('decision_tree.png')
观察到显示的图像不能较好的呈现决策树的过程,于是我们可以通过调用graphviz库的方法对决策树进行可视化
2.5 用graphviz可视化决策树
#导入 graphviz 库
import graphviz
#使用 export_graphviz 函数将训练好的决策树模型 clf_gini 转换为 Graphviz 格式的数据
#参数说明:
#clf_gini:训练好的决策树模型。
#out_file=None:不将结果写入文件,而是将其存储在变量 dot_data 中。
#feature_names=X.columns:指定特征的名称,这里使用 X 的列名作为特征名称。
#class_names=np.unique(y):指定类别的名称,这里使用 y 中的唯一值作为类别名称。
#filled=True:填充节点的颜色,表示节点的多数类别。
#rounded=True:使节点的框形状为圆角。
#special_characters=True:处理特殊字符,如换行符和引号
dot_data = tree.export_graphviz(clf_gini, out_file=None,
feature_names=X.columns,
class_names=np.unique(y),
filled=True, rounded=True,
special_characters=True)
#使用 graphviz.Source 类将 Graphviz 格式的数据 dot_data 转换为图形对象 graph
graph = graphviz.Source(dot_data)
#将图形对象 graph 渲染为图像文件,并保存为名为 'decision_tree_graphviz.png' 的 PNG 文件
graph.render("decision_tree_graphviz", format='png')
图片解释:
- humidity<=1.5 是个用来判断ture false条件
- humidity = 1 则为true
- humidity = 2 则为false
- gini = 0.459 表示基尼指数为0.459
- sample = 14 表示样本容量为14
- value = [5,9] 表示样本的类别有两种,其中play = no 有5个,play = yes 有9个
- class = yes 表示决策树预测类别为 play = yes
- 其余同理