COMP5318 Week 04 朴素贝叶斯与模型评估讲课总结

COMP5318 Week 04 讲课总结:朴素贝叶斯与模型评估

课程:COMP5318/COMP4318 — Machine Learning and Data Mining,Semester 2 2026 讲师Imdad Ullah(幻灯片由 Irena Koprinska 准备) 参考:1)Witten ch.4.2、Tan ch.5.3;2)Witten ch.5: 161–172、Tan ch.4.5、Müller & Guido ch.5

本讲两个独立的部分前半 = 朴素贝叶斯(一个具体算法);后半 = 模型评估与今天的算法无关,适用于至今学过的所有 ML 方法)。


第一部分:朴素贝叶斯

一、概率分类器与贝叶斯定理

概率分类器在做什么

回答的问题「这个数据点属于某个类别的概率是多少?」

垃圾邮件例子

0.85 更大 ⇒ 判为 Spam

💡 老师提到的实际好处:正因为输出的是概率而非硬判定,邮箱才能把「疑似垃圾」放进垃圾箱但仍让你翻看并手动恢复

贝叶斯定理与四个概率

花朵例子:特征 color ∈ {red, yellow}、stem ∈ {long, short};证据 E = 红色且长茎,假设 H = 这是一朵玫瑰

名称 含义 例子
后验概率(posteriori)
= 条件概率
看到证据之后,假设成立的概率 已知它红且长,它是玫瑰的概率
先验概率(prior of H) 没看证据时该事件的概率,与 E 无关 100 朵花里 30 朵玫瑰 →
似然(likelihood) 已知是玫瑰,它红且长的概率
先验概率(prior of E) 任一朵花红且长的概率,与 H 无关

我们真正想算的是 ,而 都从训练数据里数出来


二、朴素贝叶斯的两条假设

# 假设 内容
1 条件独立(Independence) 给定类别时,各特征之间条件独立
2 特征重要性(Feature importance) 所有属性(按比例)同等重要

这两条假设几乎从来不成立——这正是它叫「Naive(朴素)」的原因。 但它们让算法变得简单、易实现,而且实践中效果好得出奇。

课堂关键问答:假设错的,为什么还好用?

学生问:假设都不成立,为什么实践中效果这么好?

老师的回答恰恰是因为独立性假设。 设想证据 E =(sunny, cool, high, true)。如果整体地去数「同时满足这四个条件」的训练样本,很可能一条都没有 ⇒ 拆成单个特征后,每个特征各自都有足够的样本可数,概率就不会整体塌成 0

换句话说:独立性假设换来的是「可估计性」。(学生追问「可它们本来就不独立啊」——老师承认,但朴素贝叶斯就是按独立来算的。)

核心目标

不必算出精确的概率,只需知道:哪个类别的概率最大。


三、完整算例:天气数据(Weather Data)

训练数据(14 条)

# outlook temp humidity windy play
1 sunny hot high false no
2 sunny hot high true no
3 overcast hot high false yes
4 rainy mild high false yes
5 rainy cool normal false yes
6 rainy cool normal true no
7 overcast cool normal true yes
8 sunny mild high false no
9 sunny cool normal false yes
10 rainy mild normal false yes
11 sunny mild normal true yes
12 overcast mild high true yes
13 overcast hot normal false yes
14 rainy mild high true no

共 14 条:yes = 9,no = 5。

新样本 E =(sunny, cool, high, true),预测 play = ?

第 1 步:拆分证据

由条件独立假设:

第 2 步:为什么可以扔掉

两式分母都是同一个 。既然我们只比较大小分母可以直接约掉,只算分子

老师还补了一条理由:如果真去算 ,很可能得到 0,那就变成除以 0 了。

第 3 步:从训练数据数概率

class = yes(共 9 条)

概率 计数
第 9、11 条 2/9
第 5、7、9 条 3/9
第 3、4、12 条 3/9
第 7、11、12 条 3/9
只看 play 列 9/14

class = no(共 5 条)

概率
3/5
1/5
4/5
3/5
5/14

第 4 步:比较

⇒ 预测 play = no。

💡 若归一化):


四、零频问题(Zero-Frequency Problem)

问题

如果某个属性值从未与某个类别一起出现,比如训练数据中 outlook=sunny 从未play=yes 同现:

无论其他概率多高,整个乘积被一个 0 归零。 后果:所有 sunny 的新样本都会被判成 no,其他属性的值被完全无视。

解决:Laplace 修正(平滑)

其中 = 该属性的取值个数

:outlook 有 sunny / overcast / rainy 三个取值 ⇒ 。若原本是

保证概率永远不为 0。 其推广形式称为 m-estimate


五、缺失值处理

朴素贝叶斯处理缺失值非常自然。

阶段 做法
分类时(新样本有缺失) 直接不包含该属性
训练时 计数时跳过缺失值,按该属性实际有值的样本数算概率

:E =(outlook=?, cool, high, true)

outlook 项被整个略去,结论仍为 play = no

⚠️ 老师提醒:如果缺失值太多,就该退回去做数据清洗 / 特征工程,而不是一味地略过。


六、Tutorial 4 Ex.1:贷款违约(名义属性)

# home owner marital status income loan default
1 yes single very high yes
2 no married high yes
3 no single medium no
4 yes married very high no
5 yes divorced high yes
6 no married low no
7 yes divorced very high no
8 no single high yes
9 no married medium no
10 no single low yes

新样本:home owner = no,marital status = married,income = very high

yes 共 5 条,no 共 5 条 ⇒

概率 yes no
3/5 3/5
1/5 3/5
1/5 2/5

⇒ 预测 loan default = no。


七、数值属性:高斯朴素贝叶斯

为什么不能直接数频率

若温度 = 66,你无法问「训练集里出现过多少次 66」——连续值在 60 到 60.01 之间就有无穷多个取值,精确匹配几乎必然是 0 次。

解决:假设服从正态分布,用概率密度函数

做法对每个「数值属性 × 类别」的组合,分别算出

⚠️ 重要澄清概率密度函数的值不完全等于概率,但密切相关——用于比较大小足够了。

老师给的最好的直觉高斯朴素贝叶斯问的不是「我见过多少次恰好 66」,而是「66 离这个类别的典型温度有多近」。

特征类型 概率来源
名义(categorical) 频率 / 计数
数值(numeric) 高斯密度

算例:天气数据数值版

新样本:outlook = sunny,temperature = 66humidity = 90,windy = true

密度 参数
0.0340
0.0221
0.0279
0.0380

⇒ 预测 play = no。(名义属性用分数,数值属性用密度,两者直接相乘。)

Tutorial 4 Ex.2:贷款违约(income 改为数值)

income 数据(单位 K):yes = {125, 100, 95, 85, 90};no = {70, 120, 60, 220, 75}

第 1 步:分类别算

类别
yes 99 15.57
no 109 66.18

注意 no 类的 极大(66.18),因为里面有个 220 的极端值——分布被拉得很平很宽。

第 2 步:算密度(income = 120)

第 3 步:代入(名义属性的概率沿用 Ex.1)

⇒ 预测 loan default = no。


八、朴素贝叶斯:优缺点讨论

✅ 优点

  • 概率计算简单——独立性假设让一切变成单变量计数
  • 只需扫描一遍训练数据就能算出全部统计量(名义与连续属性都是)
  • 常常胜过更复杂的方法
  • 对孤立噪声点稳健——孤立点对条件概率的影响微乎其微

⚠️ 缺点与对策

缺点 对策
相关属性削弱其能力(违背独立性假设) 事先做特征选择,剔除相关(冗余)属性
数值属性的正态分布假设——很多特征并非正态 先离散化(数值 → 名义)
换其他密度函数:Poisson、binomial、gamma

第二部分:模型评估

老师明确说:这部分和朴素贝叶斯无关,适用于目前学过的所有机器学习算法。

两个层面: - 评估流程(procedure) → 你对整套做法有多大信心 - 性能度量(measure) → 模型有多好


九、评估流程

1. Holdout 方法

随机把数据分成训练集测试集通常 2/3 和 1/3。训练集建模,测试集评估。

训练集准确率过于乐观,不是泛化性能的好指标;测试集准确率才用来评估泛化性能。

2. 验证集与超参数

集合 用途
Training set 建分类器
Validation set 调超参数
Test set 评估准确率

测试数据不能用于超参数调优——否则测出的准确率就不诚实了。

参数 vs 超参数

定义 例子
参数(parameter) 模型的一部分,由算法从数据中学出来 线性回归的
超参数(hyperparameter) 由我们选择/调优,模型不会从数据中学到它 kNN 的 ;神经网络的隐藏层数、节点数、训练轮数

💡 实践中大家常笼统地说 "parameter tuning",虽然严格讲应该叫 hyperparameter tuning。

3. 分层抽样(Stratification)

问题:随机划分可能导致某些类别在训练集或测试集中缺失或严重欠代表

解决分层——保证每个类别在训练集和测试集中的比例与全集大致相同。

:100 条数据,Class 1 占 60、Class 2 占 40,按 70/30 划分。

方式 训练集 测试集
随机(可能出现) 50 / 20 10 / 20 ← 比例严重失真
分层 42 / 28(70×0.6, 70×0.4) 18 / 12(30×0.6, 30×0.4)

为什么这很要命(老师的医疗例子):95 个健康病人 + 5 个患病病人纯随机划分可能把 5 个患病样本全分到测试集分类器根本没学过「患病」这个类别 ⇒ 面对患病病人却判为健康 ⇒ 给出完全错误的治疗建议或干脆不治疗

4. 重复 Holdout(Repeated Holdout)

重复 10 次随机划分(每次可结合分层),取 10 次准确率的平均

必须同时报告标准差均值 → 平均表现有多好;标准差 → 表现有多稳定。

课堂题79% ± 0.8%79% ± 11% 哪个更好? 前者——后者可能这次 99%、下次 60%,平均一样但完全不可靠

⚠️ 老师的提醒:标准差小也不代表就万事大吉——有可能是碰巧。要多看几个指标。

局限各次的测试集会重叠(Run 1 测 {1,2,3},Run 2 测 {2,4,5},Run 3 测 {1,4,6} —— 1、2、4 重复出现)。

5. 十折交叉验证(10-fold Cross-Validation)

步骤 内容
1 把数据分成 10 个大小近似相等的子集
2 建 10 次分类器:每次用 1 个子集测试其余 9 个合起来训练
3 交叉验证准确率 = 10 次准确率的平均

核心优势:避免了测试集重叠——每个样本恰好被测试一次。

为什么是 10? 大量实验表明 10 是获得准确估计的最佳选择,也有一定的理论依据。

业界标准做法 = 分层十折交叉验证(Stratified 10-fold CV)

更好重复的分层十折交叉验证 —— 十折做 10 遍 = 100 次评估,取平均,降低数据划分带来的方差

6. 留一法(Leave-One-Out CV)

n 折交叉验证的特例:折数 = 训练样本数。n 个样本就建 n 次分类器,每次留 1 个做测试

内容
优点 1 最充分利用数据——每次训练用的数据量最大,小数据集的最佳选择
优点 2 确定性过程——不涉及随机抽样,每次跑结果完全相同
⚠️ 缺点 计算代价极高——n = 100,000 时要建 10 万个模型

7. 网格搜索调参(Grid Search with CV)

kNN 为例,调两个超参数:

  • ∈ {1, 3, 5, 11, 13} —— 5 个取值
  • 距离度量 ∈ {Manhattan, Euclidean} —— 2 个取值

共 5 × 2 = 10 种组合

流程

建立参数网格(所有参数组合)
把数据分成 训练集 和 测试集
for 每个参数组合:
在训练数据上用 10 折交叉验证 训练 kNN
计算交叉验证准确率 cv_acc
if cv_acc > best_cv_acc:
best_cv_acc = cv_acc
best_parameters = 当前参数
best_parameters 在【整个训练集】上重新训练 kNN
在【测试集】上评估并报告结果

PPT 给出的结果表(示例):

距离 CV 准确率
1 Euclidean 82%
1 Manhattan 84%
3 Euclidean 87%
3 Manhattan 86%
5 Euclidean 90%
5 Manhattan 88%
11 Euclidean 85%
11 Manhattan 86%
13 Euclidean 83%
13 Manhattan 82%

+ Euclidean。

三个必须记牢的要点: 1. 交叉验证循环只在训练数据上跑,测试集全程不参与调参 2. 每个参数组合都要建 10 个模型(90% 训练 / 10% 验证)⇒ 10 组 × 10 折 = 100 次训练 3. 选出最优参数后,要用整个训练集重新训练一个新模型,再在测试集上评估

sklearn 里用 GridSearchCV

💡 老师课上提的一个很好的现实问题:现在 最好,但明年数据变了呢? 用 2021–2026 的数据预测悉尼房价,到了 2027 政府政策变了、出现了新的特征, 可能就不再最优。 答案:必须用新观测重新训练。「维护」是真实部署中的一大挑战——有时甚至要靠合成数据。


十、性能度量

混淆矩阵(Confusion Matrix)

实际  预测 预测为 yes 预测为 no
实际 yes TP(true positive) FN(false negative)
实际 no FP(false positive) TN(true negative)

混淆矩阵本身不是性能度量——它是用来计算各种性能度量的

算例:100 个测试样本,TP = 30,FN = 10,FP = 5,TN = 55

多分类(iris 数据):

 a  b  c   <-- classified as
50 0 0 | a = Iris-setosa
0 44 6 | b = Iris-versicolor
0 3 47 | c = Iris-virginica

对角线是正确预测。

Precision、Recall、F1

💡 用上面的算例代入(PPT 只给了公式):

老师的指纹门禁例子(理解 FP 与 FN 的代价)

情形 含义 后果
False Negative 我是合法用户,系统却拒绝我 手指有伤口 / 潮湿 → 进不了门
False Positive 非法用户却被放行 安全事故

核心洞见你不能只看总体准确率。 - 讲堂门禁 → 5%~10% 的错误可以接受 - 高安全区域绝不能有 FP

必须在两类错误之间找一个平衡点,而这个平衡点是靠混淆矩阵来定的。

💡 老师顺带解释了为什么手机人脸解锁有时认不出你——那正是 false negative


十一、考点重点

朴素贝叶斯

  1. 贝叶斯定理及四个概率的名称与含义:后验 、先验 、似然
  2. 两条假设:条件独立 + 特征同等重要;都不现实 → 所以叫 Naive但正因独立假设才避免了概率整体归零
  3. 完整算例要会手算:拆证据 → 数条件概率 → 乘上先验 → 约掉 → 比大小。天气例子 0.0053 vs 0.0206 ⇒ no
  4. 为什么能扔掉 :两个类别的分母相同,只比较大小。
  5. 零频问题 + Laplace 修正 = 该属性的取值个数
  6. 缺失值:分类时直接略过该属性;训练时计数跳过缺失值。
  7. 高斯朴素贝叶斯:数值属性假设正态,用 PDF每个「属性×类别」组合分别算 密度不等于概率但密切相关
  8. 优缺点:快(一遍扫描)、抗孤立噪声;怕相关属性(→ 先做特征选择)、怕非正态(→ 离散化或换分布)。

模型评估

  1. Holdout:通常 2/3 训练、1/3 测试;训练集准确率过于乐观
  2. 参数 vs 超参数 是参数(学出来的);、隐藏层数是超参数(调出来的)
  3. 分层(stratification):保持类别比例;罕见类可能被随机划分整个丢掉。会算 42/28、18/12。
  4. 重复 holdout:报均值和标准差79% ± 0.8% 优于 79% ± 11%缺点是测试集重叠
  5. 十折交叉验证:10 等份、建 10 次、平均;避免测试集重叠为什么是 10 —— 实验证明最佳。标准做法是分层十折,更好的是重复分层十折(100 次评估)
  6. 留一法:折数 = 样本数;优点是数据利用最充分 + 确定性(无随机)缺点是计算代价极高;适合小数据集
  7. 网格搜索:5×2 = 10 组;CV 只在训练集上做选出最优参数后要在整个训练集上重新训练10 组 × 10 折 = 100 次训练
  8. 混淆矩阵 TP/FN/FP/TNaccuracy = (tp+tn)/总数。会算 85%、94%。
  9. 混淆矩阵不是性能度量,而是计算性能度量的工具。
  10. FP 与 FN 的代价不对称——只看准确率是不够的(指纹门禁例子)。

十二、本讲与前后的衔接

Week 内容 关键词
2 数据预处理、kNN 相似度、特征选择
3 线性/逻辑回归、正则化 最小二乘、最大似然、过拟合
4 朴素贝叶斯 + 模型评估 概率分类、交叉验证、混淆矩阵

两处与 Week 3 的呼应: 1. 过拟合是通用概念——有同学问「回归里讲的过拟合在分类里一样吗」,老师答:完全一样,看训练与测试准确率的差距,这适用于所有机器学习方法。 2. 验证集的作用在两周里是一致的:Week 3 用它调正则化强度 ,Week 4 用它调 kNN 的 —— 都是超参数调优,都不能碰测试集。