1201 决策树原理与可视化

🎯 教学目标与重难点…

【三维目标】

  • 📚 知识目标:掌握决策树的核心构成(根节点、内部节点、叶节点);理解基尼系数(Gini)与信息增益(Entropy)作为特征选择依据的数学直觉;了解基尼系数和信息增益之间的区别与联系。
  • ⚙️ 能力目标:能够调用 sklearn.tree.DecisionTreeClassifier 训练分类模型;能够使用 plot_tree 函数将训练好的树结构导出为可视化图像;能够通过观察 feature_importances_ 初步分析特征重要性。
  • 💡 素养目标:建立“白盒模型”的可解释性思维,理解模型决策路径在工业界(如风控、医疗辅助)中的价值;培养“调参观察现象”的实验习惯。

【重点与难点】

  • 🟢 教学重点:决策树的训练与可视化流程;基尼系数(Gini)的计算逻辑与直观理解;通过 max_depth 控制过拟合。
  • 🟡 教学难点:理解树模型进行特征分裂时的数学依据(不纯度降低);区分“前置剪枝”与“后置剪枝”的时机与效果。

📌 一、 课程导入(5 分钟)

场景引入:银行审批系统需要判断“是否给一名用户发放信用卡”。系统无法直接给出复杂公式,但可以画出一棵“如果……那么……”的决策树。

展示一颗已经绘制好的、关于“鸢尾花种类识别”的简易决策树截图,让学生直观看到:一层层的 if-else 判断,最终指向一个结论(花的类别)

核心疑问抛出

  1. 计算机是怎么知道先用哪个特征进行判断的(特征选择)?
  2. 树到底要长多深才算合适?
  • 👨‍🏫 教师活动:展示预先绘制好的鸢尾花决策树图片;用日常生活中的“猜动物”游戏类比决策树的分裂过程;提出本节课要解决的两个核心疑问。
  • 🧑‍🎓 学生活动:观察决策树图形结构,口头描述从根节点到叶节点的路径;回忆初中生物中“检索表”的用法,思考与决策树的异同。

从可视化图形入手降低认知负荷,消除对“树模型”的恐惧感。利用“猜动物”或“银行审批”等强场景建立规则系统的直觉,为理解抽象的基尼系数做铺垫。


📖 二、 解决问题过程(一):从数据到树——决策树的核心原理

1. 树的“零件”叫什么?

  • 根节点:第一次做判断的位置(包含全部样本)。
  • 内部节点:中间做判断的位置。
  • 叶节点:最终结论(不再继续分裂)。

2. 计算机怎么选“最佳特征”?——不纯度(Impurity)

  • 目标:每一次分裂,都希望子节点里的样本 越纯越好(最好是同一类)。
  • 基尼系数(Gini)(职高侧重):
    • 公式直觉:随机从集合里抽两个样本,他们类别不一样的概率。
    • 取值范围:0(完全纯) ~ 0.5(二分类完全乱)。
    • 分裂依据:基尼增益 = 父节点基尼 – 子节点加权基尼,选择增益最大的特征。

3. 树长多深?——过拟合 vs 欠拟合

  • 树太深(分支太多):完美记住训练数据,但在新数据上表现差(过拟合)。
  • 树太浅:连训练数据都没学好(欠拟合)。
  • 解决方法(前置剪枝):设定 max_depth=3(限制最大深度)。
  • 👨‍🏫 教师活动:在黑板上手写一个 4 个样本、2 个特征的小数据集,带领学生手动模拟一次“计算基尼系数 – 比较增益 – 选择特征”的分裂过程;强调公式的“朴素直觉”而非复杂数学推导。
  • 🧑‍🎓 学生活动:跟随教师手算步骤,填写导学案上的基尼系数计算空表;尝试口头复述“为什么不纯度越小越好”。

通过手算小例子,破除“黑盒迷信”,让学生亲眼看到机器决策的数学依据。无需学生熟练掌握对数运算,故以基尼系数为核心,降低运算门槛。


💻 三、 解决问题过程(二):从原理到代码——训练与可视化

实验环境:Scikit-learn 内置鸢尾花数据集(Iris)。

步骤 1:训练模型(限制深度)

 1from sklearn.tree import DecisionTreeClassifier
 2from sklearn.datasets import load_iris
 3from sklearn.model_selection import train_test_split
 4
 5X, y = load_iris(return_X_y=True)
 6X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
 7
 8# 关键:限制最大深度为 3
 9clf = DecisionTreeClassifier(max_depth=3, random_state=42)
10clf.fit(X_train, y_train)
11
12print("训练集准确率:", clf.score(X_train, y_train))
13print("测试集准确率:", clf.score(X_test, y_test))

步骤 2:可视化树结构(需要安装 graphviz)

1from sklearn.tree import plot_tree
2import matplotlib.pyplot as plt
3
4plt.figure(figsize=(12, 8))
5plot_tree(clf, filled=True, feature_names=['花萼长', '花萼宽', '花瓣长', '花瓣宽'], 
6          class_names=['山鸢尾', '变色鸢尾', '维吉尼亚鸢尾'])
7plt.show()

步骤 3:查看特征重要性

1print(clf.feature_importances_)

现象解释:观察哪个特征被用作根节点(花瓣长度),这与鸢尾花数据集的常识相符。

  • 👨‍🏫 教师活动:在 Jupyter Notebook 中逐行运行代码,并实时展示生成的树形图;点击图像中的节点,放大解释每个节点包含的“样本数(samples)”和“类别分布(value)”。
  • 🧑‍🎓 学生活动:在教师机上同步观看演示;在本地电脑上复现代码,修改 max_depth 为 2、5、10,观察树结构变化;截图记录不同深度下的树形状。

“代码 + 可视化”强反馈机制,让学生快速建立“参数改动 → 树形变化 → 性能变化”的因果链条,为后续调参积累感性经验。


✍️ 四、 解决问题过程(三):课堂练习——用决策树分析“西瓜好坏”

📝 任务一:训练西瓜数据集(手动构造)…

背景与题目: 现有一个简化版西瓜数据集(6 个样本),特征包括:色泽(0=浅绿,1=深绿)根蒂(0=蜷缩,1=稍蜷),标签为 好瓜(1)坏瓜(0)

样本 色泽 根蒂 好瓜
1 0 0 0
2 0 1 1
3 1 0 1
4 1 1 1
5 0 0 0
6 1 0 1

任务要求

  1. 使用 sklearn.tree.DecisionTreeClassifier 训练模型(不限制深度)。
  2. 使用 plot_tree 可视化生成的树,并手动计算根节点的基尼系数,验证代码结果。
  3. 观察模型是否出现了过拟合(训练集 100%,测试集?因为没有测试集,观察树是否把每个样本都记住了)。
🔍 查看参考代码与解析…
 1import numpy as np
 2from sklearn.tree import DecisionTreeClassifier, plot_tree
 3import matplotlib.pyplot as plt
 4
 5# 构造数据
 6X = np.array([[0,0], [0,1], [1,0], [1,1], [0,0], [1,0]])
 7y = np.array([0, 1, 1, 1, 0, 1])
 8
 9clf = DecisionTreeClassifier(random_state=42)
10clf.fit(X, y)
11
12plt.figure(figsize=(8, 6))
13plot_tree(clf, filled=True, feature_names=['色泽', '根蒂'], 
14          class_names=['坏瓜', '好瓜'], rounded=True)
15plt.show()
16
17# 基尼系数验证:根节点共6个样本,好瓜4个,坏瓜2个。
18# Gini = 1 - (4/6)^2 - (2/6)^2 = 1 - 0.444 - 0.111 = 0.445

解析:模型将所有样本都正确分类,树完全生长(每个叶子节点纯度为 1),这是典型的过拟合表现。


📝 五、 课堂小结(5 分钟)

flowchart LR
    root["🌳 决策树(第一次课)"]

    subgraph C1["📖 核心概念"]
        direction TB
        A1["树结构:根/内部/叶节点"]
        A2["特征选择:基尼系数"]
    end

    subgraph C2["💻 代码实践"]
        direction TB
        B1["sklearn 训练与可视化"]
        B2["feature_importances_ 提取"]
    end

    subgraph C3["⚖️ 过拟合控制"]
        direction TB
        C1_node["前置剪枝:max_depth"]
        C2_node["观察训练集与测试集差异"]
    end

    root --> C1
    root --> C2
    root --> C3

    style root fill:#4b6cb7,stroke:#253b6e,color:#fff,stroke-width:2px,rx:8px,ry:8px
    style C1 fill:#e3f2fd,stroke:#2196f3,stroke-width:1px
    style C2 fill:#fff3e0,stroke:#ff9800,stroke-width:1px
    style C3 fill:#e8f5e9,stroke:#4caf50,stroke-width:1px

✏️ 随堂检测与互动练习

点击展开:随堂测试题(带解析)

一、 单选题

  1. 关于决策树的特征选择标准(基尼系数),下列说法正确的是?
  • A. 基尼系数越大,代表节点越纯
  • B. 基尼系数为 0 时,表示该节点内样本类别完全随机
  • C. 基尼系数为 0 时,表示该节点内样本全部属于同一类别
  • D. 基尼系数只用于回归问题
【答案】

【解析】C。基尼系数越小,节点纯度越高。系数为 0 代表完全纯净(全部同一类)。

  1. 当决策树的 max_depth 参数从 3 调整为 10 时,最可能出现的现象是?
  • A. 训练集准确率下降,测试集准确率上升
  • B. 训练集准确率上升,测试集准确率可能下降
  • C. 训练集准确率下降,测试集准确率下降
  • D. 没有任何变化
【答案】

【解析】B。树越深,对训练数据拟合能力越强(训练集准确率上升),但可能导致过拟合,使测试集准确率下降。

二、 代码填空题

题目:现有模型 clf 已在鸢尾花数据集上训练完成,请补充代码以可视化决策树,并将图像保存为 tree.png

1from sklearn.tree import plot_tree
2import matplotlib.pyplot as plt
3
4plt.figure(figsize=(12, 8))
5# 1. 绘制树结构
6plot_tree(_________________________________)
7# 2. 保存图像
8plt.savefig('tree.png')
【答案】
  1. clf, filled=True, feature_names=['花萼长', '花萼宽', '花瓣长', '花瓣宽'], class_names=['山鸢尾', '变色鸢尾', '维吉尼亚鸢尾']

三、 简答题

题目:观察代码实践环节中不同 max_depth 生成的树结构,说明限制树深度对防止过拟合的作用机制。

【答案】

限制树深度(前置剪枝)相当于在树生长过程中提前停止分裂,防止模型学习到训练数据中的噪声或特例。这使得树的规则更加通用,从而提高在未知数据上的泛化能力。

📮 六、 课后作业与拓展

📮 课后作业…
  1. 基础作业:在 Jupyter Notebook 中复现鸢尾花决策树代码,并分别设置 max_depth=2, 4, 6, None,截图记录每次的树形结构,并记录训练集与测试集准确率。
  2. 进阶作业:使用 sklearn.datasets.load_wine(葡萄酒数据集)训练一个决策树模型,用 plot_tree 展示树结构,并输出最重要的前两个特征名称。
  3. 挑战作业:在西瓜数据集上,手动计算使用“色泽”作为根节点分裂前后的基尼增益,验证代码选择的根节点是否合理。
  4. 阅读作业:预习教材中关于“随机森林”的基本概念,思考“多棵树”比“一棵树”强在哪里。
  5. 思考题:在医疗诊断中,如果决策树深度很深,医生可能很难理解,这对“可解释性”有什么影响?

📋 七、 板书设计

🛠️ 板书设计…
 1🌳 决策树 – 第一次课
 2
 3一、 树的零件
 4    根节点(首次分裂) → 内部节点(中间判断) → 叶节点(结论)
 5
 6二、 怎么选特征?(分裂依据)
 7    目标:让子节点更纯
 8    工具:基尼系数 Gini = 1 - Σ(Pi)^2
 9    策略:选择 基尼增益 最大的特征
10
11三、 控制树的生长
12    问题:太深 → 过拟合(记住训练数据,但预测新数据差)
13    解决:前置剪枝 → 限制 max_depth
14
15四、 代码三连
16    ① 训练:model = DecisionTreeClassifier(max_depth=3)
17    ② 画图:plot_tree(model, ...)
18    ③ 看重要性:model.feature_importances_

本课用到的单词

英文术语 发音(美式) 中文释义 专业语境解释
Decision Tree /dɪˈsɪʒ.ən triː/ 决策树 一种基于树形结构的分类与回归模型,通过一系列规则对样本进行决策。
Root Node /ruːt noʊd/ 根节点 决策树的顶端节点,包含全部训练样本,是第一次分裂发生的位置。
Leaf Node /liːf noʊd/ 叶节点 决策树的末端节点,该节点不再继续分裂,输出最终的预测结果。
Gini Impurity /ˈdʒiː.ni ɪmˈpjʊr.ə.ti/ 基尼不纯度 衡量节点内样本类别混杂程度的指标,值越小代表节点越“纯”。
Overfitting /ˌoʊ.vərˈfɪt.ɪŋ/ 过拟合 模型在训练集上表现过好,但泛化能力差,无法适应新数据。
Max Depth /mæks depθ/ 最大深度 控制决策树生长的关键超参数,用于限制树的层数,防止过拟合。
Feature Importance /ˈfiː.tʃər ɪmˈpɔːr.təns/ 特征重要性 衡量每个特征在决策树构建中对分类贡献程度的数值。