查看全课大纲(第 27 / 82 节)
  1. 1.函数与数据泛化
  2. 2.向量:从几何直觉到高维空间
  3. 3.矩阵与张量
  4. 4.特征值与特征向量:矩阵变换的不动方向
  5. 5.凸函数:从向量求导的矩阵记号到好优化的函数形状
  6. 6.概率与统计:机器学习的数学基础
  7. 7.独立性与随机变量:贝叶斯公式与二项分布
  8. 8.期望、方差与协方差:随机变量的数字画像
  9. 9.联合概率:当一条轴不够用的时候
  10. 10.概率分布(一):从伯努利到伽马函数
  11. 11.概率分布(二):贝塔、泊松、正态与两个贝叶斯故事
  12. 12.机器学习的模型:找输入与输出的关系
  13. 13.机器学习的应用
  14. 14.过拟合
  15. 15.机器学习的分类
  16. 16.有监督学习:从房价预测说起
  17. 17.损失函数
  18. 18.梯度下降(上):更新规则与学习速率
  19. 19.梯度下降(2)
  20. 20.牛顿方法
  21. 21.KNN简介
  22. 22.距离测算
  23. 23.朴素贝叶斯
  24. 24.朴素贝叶斯的实际应用
  25. 25.信息熵:决策树构建的度量基础
  26. 26.信息增益与决策树的构建
  27. 27.ID3算法
  28. 28.决策树节点的划分
  29. 29.CART树
  30. 30.Bagging
  31. 31.Boosting:自适应提升算法
  32. 32.Gradient Boosting
  33. 33.线性模型:回归与分类的同一副骨架
  34. 34.最小二乘:把最优参数直接解出来
  35. 35.最小二乘法的几何与概率视角
  36. 36.极大似然:给最小二乘一个概率出身
  37. 37.逻辑回归(1):把线性模型接到分类上
  38. 38.逻辑回归(2):损失函数与多分类
  39. 39.---- 手造数据: 5 个样本, 2 个特征; x2 几乎 = 2*x1 (偏差手工指定, 无随机) ----
  40. 40.讲师例: 向量 "23014" -- 三把范数尺子量同一个向量
  41. 41.优化方法(1):坐标下降与前向选择
  42. 42.优化方法(2):前向策略与最小角回归
  43. 43.拉格朗日乘子法(1):从无约束到等式约束
  44. 44.拉格朗日乘子法(2):等式约束下的平行条件与拉格朗日函数
  45. 45.拉格朗日乘子法(3):不等式约束与 KKT 条件
  46. 46.最大间隔:把分类问题变成优化问题
  47. 47.拉格朗日对偶问题:把 w 和 b 全部换成 α
  48. 48.支持向量:边界上的少数派
  49. 49.SVM 计算过程:一笔到底算完,再走进核方法
  50. 50.贝叶斯公式:概率即信念
  51. 51.隐含变量和概率模型:给看不见的原因建模
  52. 52.EM 算法:期望与最大化的迭代
  53. 53.琴生不等式:EM 的数学钥匙
  54. 54.三个硬币问题:EM 的复盘与衔接
  55. 55.高斯混合模型:用隐变量解释双峰数据
  56. 56.隐马尔可夫模型
  57. 57.隐马尔可夫模型(2):前向算法与动态混合模型
  58. 58.隐马尔可夫模型在 NLP 中的运用
  59. 59.EM 算法:把「为什么收敛」推到底
  60. 60.HMM 在 NLP 中的运用:从分词到机器翻译
  61. 61.HMM 参数估计:Baum-Welch 的三块拉格朗日
  62. 62.高维下的高斯模型
  63. 63.主题模型:从词袋到隐含主题
  64. 64.Dirichlet 分布(1)
  65. 65.Dirichlet 分布(2)
  66. 66.统计学习内容回顾
  67. 67.K-means 算法
  68. 68.PCA 降维
  69. 69.SVD 降维
  70. 70.从聚类到流形
  71. 71.局部线性嵌入
  72. 72.随机邻域嵌入:SNE 与 t-SNE
  73. 73.无参模型:让数据自己说话
  74. 74.高斯过程:函数空间里的正态分布
  75. 75.高斯过程(2):噪声、正则化与核的线性组合
  76. 76.神经网络简介:从感知器到自编码器
  77. 77.反向传播:把误差一层层传回去
  78. 78.卷积神经网络(CNN):让特征自己学出来
  79. 79.循环神经网络(RNN):给网络装上记忆
  80. 80.深度学习回顾:静态一类,动态一类
  81. 81.增强学习(1):蒙特卡洛、树搜索与 Q-learning
  82. 82.强化学习(2):从乌鸦吃核桃到井字棋的 value 回传

ID3算法

约 13 分钟

📺 正在播放小象官方高清录播(支持倍速与清晰度调节)

小象实战讲义 · 机器学习算法精讲

本节我们将深入探讨决策树学习中的经典算法——ID3。ID3算法以信息增益为准则,通过自顶向下的贪心策略构建决策树,是理解决策树模型运作机制的关键。学完本节,你将能够手动计算信息增益,并理解如何利用它来选择最优特征进行数据划分。

💡 核心导读

  • 信息增益的计算:掌握如何基于信息熵计算特征分裂带来的信息增益。
  • ID3的贪心构建过程:理解算法如何递归地选择信息增益最大的特征来划分数据,直至满足停止条件。
  • 决策树的几何解释:从空间划分的角度理解决策树,它相当于在特征空间中进行一系列垂直切割。
  • 过拟合的直观体现:认识决策树生长过深(每个叶子节点只包含一个样本)所导致的过拟合现象。

信息增益与特征选择

决策树构建的核心在于,在每个节点上选择一个特征,使得按照该特征划分后,子节点的“纯度”最高,或者说“不确定性”降低得最多。在ID3算法中,我们使用信息熵(Entropy)来度量不确定性,使用信息增益(Information Gain)来度量不确定性降低的程度。

对于一个包含 pp 个正例和 nn 个负例的样本集合 SS,其信息熵定义为: Entropy(S)=−p⊕log⁡2p⊕−p⊖log⁡2p⊖\text{Entropy}(S) = -p_{\oplus} \log_2 p_{\oplus} - p_{\ominus} \log_2 p_{\ominus} 其中 p⊕=p/(p+n)p_{\oplus} = p/(p+n), p⊖=n/(p+n)p_{\ominus} = n/(p+n)。当所有样本属于同一类时,熵为0;当正负样本各占一半时,熵达到最大值1。

假设我们根据特征 AA 将 SS 划分为 vv 个子集 {S1,S2,...,Sv}\lbrace S_1, S_2, ..., S_v\rbrace,则划分后的加权平均熵为: EntropyA(S)=∑i=1v∣Si∣∣S∣Entropy(Si)\text{Entropy}_A(S) = \sum_{i=1}^{v} \frac{|S_i|}{|S|} \text{Entropy}(S_i) 特征 AA 带来的信息增益即为原始熵与划分后加权平均熵的差值: Gain(S,A)=Entropy(S)−EntropyA(S)\text{Gain}(S, A) = \text{Entropy}(S) - \text{Entropy}_A(S) ID3算法在每一步都选择信息增益最大的特征进行分裂。

ID3算法实战:Play-Tennis示例

我们以经典的Play-Tennis数据集为例,手动演示ID3算法的构建过程。数据包含四个特征:Outlook, Temperature, Humidity, Wind,目标是根据天气情况预测是否打网球。

首先,我们计算整个数据集的初始熵。数据共有14条,其中9个正例(Yes),5个负例(No)。

import math

def entropy(probabilities):
    """计算信息熵。probabilities是一个概率列表,例如[0.9, 0.1]"""
    # 对指数输入进行保护(虽然此处log2不涉及exp,但保持函数稳健性)
    total = 0.0
    for p in probabilities:
        if 0 < p < 1:  # 当p为0或1时,p*log2(p)定义为0
            total -= p * math.log2(p)
    return total

# 初始数据集:9正5负
p_pos = 9/14
p_neg = 5/14
initial_entropy = entropy([p_pos, p_neg])
print(f"整个数据集S的初始熵 Entropy(S): {initial_entropy:.3f}")
整个数据集S的初始熵 Entropy(S): 0.940

接下来,我们计算每个特征的信息增益。以特征Wind为例,它有两个取值:Weak和Strong。我们需要计算按Wind划分后的加权平均熵。

import math

def entropy(probabilities):
    """计算信息熵。probabilities是一个概率列表,例如[0.9, 0.1]"""
    total = 0.0
    for p in probabilities:
        if 0 < p < 1:
            total -= p * math.log2(p)
    return total

# 初始数据集:9正5负
p_pos = 9/14
p_neg = 5/14
initial_entropy = entropy([p_pos, p_neg])

# 计算Wind特征的信息增益
# Wind = Weak: 6正2负 (共8条)
# Wind = Strong: 3正3负 (共6条)
total_samples = 14

weight_weak = 8 / total_samples
entropy_weak = entropy([6/8, 2/8])

weight_strong = 6 / total_samples
entropy_strong = entropy([3/6, 3/6])

avg_entropy_wind = weight_weak * entropy_weak + weight_strong * entropy_strong
gain_wind = initial_entropy - avg_entropy_wind

print(f"Wind特征分裂后的加权平均熵: {avg_entropy_wind:.3f}")
print(f"Wind特征的信息增益 Gain(S, Wind): {gain_wind:.3f}")
Wind特征分裂后的加权平均熵: 0.892
Wind特征的信息增益 Gain(S, Wind): 0.048

类似地,我们可以计算出所有特征的信息增益:

  • Gain(S, Outlook) = 0.246
  • Gain(S, Humidity) = 0.151
  • Gain(S, Wind) = 0.048
  • Gain(S, Temperature) = 0.029

Outlook的信息增益最大,因此被选为根节点进行分裂。Outlook有三个取值(Sunny, Overcast, Rain),因此根节点产生三个分支。

递归构建:同一套流程逐层往下

选择 Outlook 为根、分出三个分支之后,算法在每个分支上递归地”重头再来”。讲师逐支检查:

  • Overcast 分支(第 3、7、12、13 条):四条全是正例,熵为 0——立即成为标记 Yes 的叶子,不需要再延伸;
  • Sunny 分支:剩 2 正 3 负,还不纯;
  • Rain 分支:剩 3 正 2 负,也不纯。

对不纯的分支,把”算各特征信息增益 → 挑最大者分叉”这套流程在子集上完整重做一遍。讲师特别强调两条规则:

  • 用过的特征不能再出现在同一路径上:Sunny 分支上不能再用 Outlook——该分支内所有样本的 Outlook 都是 Sunny,再按它分不会产生任何新的划分,候选特征只剩 Temperature、Humidity、Wind 三个。
  • 不同分支之间可以各选各的:Sunny 分支和 Rain 分支各自选中的下一个特征可以相同也可以不同,互不影响。

延伸到什么时候停?当某个分支内的样本全部属于同一类(全 Yes 或全 No)时,它就长成叶子。(标准 ID3 的完整停止条件还包括:特征用尽时以多数类作为叶子的标签;实践中还会人为限制树的深度——这些到讲剪枝时再展开。)

这个”每个节点算一遍信息增益、挑最大特征分叉、子集递归”的算法就是 ID3——对离散特征分类非常简单直接的贪心算法。树看起来建得很复杂,其实每一步都在做同一件事:算信息增益。

决策树的本质与过拟合

从几何视角看,决策树是在特征空间中进行一系列轴平行(axis-parallel) 的划分。每个特征测试(例如“Wind = Weak?”)相当于在垂直于该特征轴的超平面上进行切割。对于连续特征,测试如“Temperature < 25”同样产生一个垂直于Temperature轴的切割面。

通过这种垂直切割,决策树将高维特征空间划分成若干个超矩形区域。每个叶子节点对应一个这样的区域,区域内的样本被赋予相同的类别标签。ID3算法的目标就是找到一系列切割,使得最终每个区域内的样本尽可能“纯”。

这种机制也直观地揭示了决策树容易过拟合的原因。如果我们不加限制地让树生长,最终可以使得每个训练样本都落入自己独有的小矩形中(即每个叶子节点只包含一个样本)。这相当于完美地记住了所有训练数据,但对于未见过的数据,由于其特征值组合可能落入未被定义的区域,或者落入只由个别异常样本定义的区域,模型的泛化性能会急剧下降。因此,控制树的复杂度(如剪枝、限制深度)是决策树实践中至关重要的一环。

📝 动手练一练

  1. 概念辨析:在ID3算法的递归过程中,为什么在同一个分支路径上不能重复使用已经用过的特征(例如在根节点用了Outlook,在它的子节点就不能再用)?如果允许重复使用,可能会导致什么问题?
👉 点击查看参考答案

参考答案: 在同一个分支路径上禁止重复使用特征,主要是为了避免产生无意义的分裂和无限循环。决策树的一次分裂是基于某个特征的所有可能取值将数据分开。如果在一个分支上再次使用同一个特征,由于该分支上的所有样本在该特征上取值已经相同(例如,在Outlook=Sunny分支上,所有样本的Outlook都是Sunny),再次根据该特征分裂将无法进一步划分数据,不会产生新的信息增益,因此是无效操作。从几何角度看,这相当于在同一条垂直线上重复切割,不会产生新的区域。如果算法不检查这一点,可能会导致树产生冗余节点,甚至在某些实现中陷入逻辑错误。

  1. 动手计算:Outlook 为根之后,Rain 分支有 5 条数据(3 正 2 负)。已知在该分支内,Wind=Weak 的 3 条样本全为正例、Wind=Strong 的 2 条样本全为负例。请计算 Gain(Rain 分支, Wind)。
👉 点击查看参考答案

Rain 分支的初始熵:

Entropy(Srain)=−35log⁡235−25log⁡225≈0.971\text{Entropy}(S_{\text{rain}}) = -\frac{3}{5}\log_2\frac{3}{5} - \frac{2}{5}\log_2\frac{2}{5} \approx 0.971

两个子集都完全纯净(熵均为 0),加权平均熵 = 0,因此:

Gain(Srain,Wind)=0.971−0=0.971\text{Gain}(S_{\text{rain}}, \text{Wind}) = 0.971 - 0 = 0.971

一次完美分割。正因如此,Mitchell 书中 Rain 分支的分裂特征正是 Wind(Weak→Yes,Strong→No)。有意思的是:在根节点处 Wind 的信息增益只有 0.048,在四个特征里排倒数第二(仅高于 Temperature 的 0.029)——同一个特征在不同子集上价值天差地别,这正是”每层都要在剩余特征上重算信息增益”的意义。

本章小结

本节我们详细剖析了ID3决策树算法。它以信息增益为特征选择标准,采用自顶向下的贪心策略递归构建树结构。算法的核心在于每一步都选择能最大程度降低数据不确定性的特征进行划分。我们从具体计算示例入手,理解了信息熵和信息增益的运用,并认识到决策树本质上是特征空间的轴平行划分。同时,我们也看到了决策树不加控制时容易导致过拟合的直观原因。

📋 行动清单

  • 手动完成Play-Tennis示例中所有特征在根节点的信息增益计算,验证Outlook确实是最优选择。
  • 尝试编写一个简化版的ID3算法函数,能够处理小型离散数据集,并输出构建的决策树结构(可以用字典嵌套表示)。
  • 思考:如果某个特征有非常多的取值(例如给每条样本编一个”ID”号),按它分裂往往能算出很大的信息增益,但这真是好特征吗?(这是 ID3 偏好多取值特征的已知问题;下一节《决策树节点的划分》会介绍基尼指数等更多样的划分度量。)

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 第6章课件:经典机器学习模型 II(决策树)
    下载
  • 第6章代码包
    下载