决策树
本节课介绍一种非参数化的有监督学习模型——决策树。
什么是决策树
决策树是一种用于分类和回归的非参数监督学习方法。其目标是通过从数据特征中学习简单的决策规则,来预测目标变量的值。决策树常用于运筹学中的决策分析,以帮助识别最有可能达成目标的策略。它也是机器学习中一种流行的工具。
决策树是一种非常直观的方法:你只需针对目标不断提出一系列问题,并根据答案选择对应的分支。每次对树进行分割时,每个节点都会产生两个子分支。
与其他模型不同,决策树具有很强的可解释性,因为你清楚地知道为何选择了左分支而不是右分支。因此,决策树在金融、保险和医疗等领域被广泛使用,因为这些领域在做决策时需要明确判断依据。
与其他模型的比较
- 易于理解和解释。
- 能够处理类别型数据。
- 能够处理缺失值。
- 推理速度快。
- 容易出现过拟合。
- 性能相比某些模型较差。
- 某些任务无法学习。
在鸢尾花数据集上的建模
我们跳过数据加载与划分过程(完整示例稍后可见)。创建一个决策树非常简单,只需从 tree 模块中创建一个 DecisionTreeClassifier 对象,然后调用 fit 方法训练该树即可。
1from sklearn.tree import DecisionTreeClassifier 2 3tree = DecisionTreeClassifier() 4# train_x, train_y 是训练数据和标签 5tree.fit(train_x, train_y)
你可以使用混淆矩阵评估该模型,如下所示。其中 tree 是模型,test_x 和 test_y 是测试数据。
1import sklearn.metrics as metrics 2 3metrics.ConfusionMatrixDisplay.from_estimator(tree, test_x, test_y)
1import sklearn.datasets as datasets 2from sklearn.tree import DecisionTreeClassifier 3import sklearn.tree as sktree 4from sklearn.model_selection import train_test_split 5import sklearn.metrics as metrics 6 7X, y = datasets.load_iris(return_X_y=True) 8print("iris数据大小为 {}".format(X.shape)) 9print("iris标签大小为 {}".format(y.shape)) 10print("前五个样本数据: {}".format(X[:5])) 11 12train_x, test_x, train_y, test_y = train_test_split(X, 13 y, 14 test_size=0.2, 15 random_state=42) 16 17tree = DecisionTreeClassifier() 18tree.fit(train_x, train_y) 19pred_y = tree.predict(test_x) 20cr = metrics.classification_report(test_y, pred_y) 21print(cr)
- 第7行到第12行:加载鸢尾花数据集并将其划分为训练集和测试集。
- 第17行创建了一个决策树对象
DecisionTreeClassifier(),并在第18行完成训练。 - 本例使用
classification_report来评估模型性能,结果可在第21行输出中查看。
作为一种树形模型,该模型应呈现出类似“真实树木”的结构,包含分支和叶子节点。sklearn 提供了一个非常有用的函数 plot_tree,可用于可视化决策树。下图展示了一棵决策树的结构示意图(请忽略具体数值,仅用于展示树的形态)。
决策树的分裂机制
如上图所示,决策树实际上是一棵二叉树。你从根节点开始,根据非叶节点上的条件选择路径,最终到达某个叶节点。叶节点上的标签即为该样本的分类结果。
那么,如何确定每个非叶节点上的判断条件?我们使用什么指标来进行分裂?在原始决策树算法中,采用的是 基尼不纯度(Gini impurity) 来进行分裂。基尼不纯度衡量的是:如果按照当前节点中各类别样本的比例随机分配标签,那么任意选中的样本被错误标记的概率有多大。
假设目标变量为分类结果,取值为 0, 1, …, K-1。对于表示区域 且包含 个样本的节点 ,定义:
表示节点 中类别为 k 的样本所占比例。
常见的不纯度度量方式——基尼不纯度定义为: