03 贝叶斯分类器 (Bayesian Classifiers)

90 分钟学习安排:概率 → 损失 → 决策

  • 目标: 由先验和似然计算后验;用损失矩阵做决策;区分 MLE 与 MAP;评价概率排序与校准。

  • 学习顺序:

    • 贝叶斯更新 20 分钟 → 决策损失 20 分钟 → 估计与朴素假设 20 分钟 → 福耀玻璃案例 20 分钟 → 练习与总结 10 分钟。

    • GMM/EM 可在课后选学。

  • 先修先答: \(P(D)=0.1\)\(P(+|D)=0.8\)\(P(+|\neg D)=0.2\),先算 \(P(+)\)

  • 反馈: \(P(+)=0.8\times0.1+0.2\times0.9=0.26\),故 \(P(D|+)\approx0.308\),不是 0.8。

欢迎来到第三章:贝叶斯分类器

欢迎来到第三章:贝叶斯分类器 图中以“贝叶斯分类器工作流程 (Bayesian Classifier Workflow)、1. 输入数据 (Data Input)、X、2. 概率模型 (Probabilistic Model)、P(Y|X)”呈现“欢迎来到第三章:贝叶斯分类器”涉及的对象、方向或比较关系。 贝叶斯分类器工作流程 (Bayesian Classifier Workflow) 1. 输入数据 (Data Input) X 2. 概率模型 (Probabilistic Model) P(Y|X) 3. 输出决策 Y 学习 (Learn) 预测 (Predict)

核心问题:如何在不确定性中做出最优分类?

想象你是银行的信贷经理,每天都要面对一个关键决策:

是否批准一笔贷款?

这里包含两个相连但不同的问题:先做违约状态分类,再按损失做贷款动作选择

  • 输入数据 (X): 申请人的特征,如年收入、信用记录、债务水平等。
  • 真实状态 (\(Y\)): 不违约违约
  • 模型输出: 后验概率 \(P(Y=\text{违约}\mid X)\)(或预测标签 \(\hat Y\))。
  • 业务动作 (\(a\)): 批准拒绝;动作由后验概率与损失矩阵共同决定。

案例背景:信贷审批决策

我们来看看一个简化的申请人数据。

申请人 ID 年收入 (万美元) 信用评分 历史违约 我们的决策
001 15 720 ?
002 6 580 ?
003 9 650 ?

目标

先由 \(X\) 估计 \(P(Y\mid X)\),再选择使条件风险最小的动作 \(a^*(X)\);分类标签不等于审批动作。

为什么选择贝叶斯方法?

贝叶斯分类器提供了一个基于概率论的强大决策框架。

为什么选择贝叶斯方法? 图中以“贝叶斯方法的四大优势、贝叶斯、方法、处理不确定性、输出概率而非绝对答案”呈现“为什么选择贝叶斯方法?”涉及的对象、方向或比较关系。 贝叶斯方法的四大优势 贝叶斯 方法 处理不确定性 输出概率 而非绝对答案 融合先验知识 结合领域 专家经验 可解释性强 决策过程清晰透明 模型优雅 基于坚实的数学基础

本章学习内容概览

我们将循序渐进,构建完整的贝叶斯决策体系。

贝叶斯分类器学习内容概览 六个水平排列的步骤,展示从概率基础到实际应用的学习顺序。 1. 概率论回顾 (The Foundation) 2. 贝叶斯决策 (The Rule) 3. 参数估计 (The "How") 4. GMM模型 (The Complexity) 5. 朴素贝叶斯 (The Application) 6. 现实问题 (The Fine-tuning)

第一部分:概率论基础

The Language of Uncertainty

核心概念一:先验概率 (Prior Probability)

先验概率 \(P(y=c)\) 是在获得任何新数据之前,我们对某个类别 \(c\) 出现的固有信念或历史频率。

在信贷审批的例子中,先验概率指的是:

在不查看任何申请人具体信息的情况下,根据银行历史数据,一个客户会违约的概率是多少?

它是我们决策的基准起点

先验概率:一个具体的例子

假设银行在过去处理了 10,000 笔贷款申请,其中 500 笔最终违约。

先验概率:一个具体的例子 图中以“先验概率:贷款违约示例、(Prior Probability: Loan Default Example)、总申请 (Total)、10,000、P(y = 不违约) = 9,500 / 10,000 = 95%”呈现“先验概率:一个具体的例子”涉及的对象、方向或比较关系。 先验概率:贷款违约示例 (Prior Probability: Loan Default Example) 总申请 (Total) 10,000 P(不违约) = 95% P(违约) = 5% 基础比率

核心概念二:概率密度函数 (PDF)

对于连续型变量(如收入、年龄),我们使用概率密度函数 (Probability Density Function, p(x)) 来描述其分布规律。

  • PDF 本身不是概率,p(x) 的值可以大于1。
  • 变量落在某个区间 [a, b] 的概率是 PDF 在该区间上的积分\(P(a \le x \le b) = \int_a^b p(x) dx\)
  • 曲线下方的总面积为1。

PDF vs. PMF

一个重要的区分:

PDF vs. PMF 图中以“PDF (概率密度函数)、用于 连续 变量 (如:身高)、概率是区间的面积、a、b”呈现“PDF vs. PMF”涉及的对象、方向或比较关系。 PDF (概率密度函数) 连续变量(如身高) 区间概率 = 曲线下的面积 a b PMF (概率质量函数) 离散变量(如骰子点数) k 点概率 = 茎线高度

可视化:正态分布 (高斯分布)

正态分布是金融和商业领域最常用的PDF,它由均值 μ (中心位置) 和方差 σ² (离散程度) 决定。

可视化:正态分布 (高斯分布) 图中以“正态分布概率密度函数 (PDF)、0.0、0.2、0.4、0.6”呈现“可视化:正态分布 (高斯分布)”涉及的对象、方向或比较关系。 正态分布概率密度函数 (PDF) 0.0 0.2 0.4 0.6 -2 0 2 4 x (值) p(x) (概率密度) N(μ=0, σ²=1) N(μ=2, σ²=0.36)

核心概念三:类条件概率 (Class-Conditional)

类条件概率 \(p(x | y=c)\) 回答了这样一个问题:“如果我们已经知道样本属于类别 \(c\),那么观察到数据 \(x\) 的概率密度是多少?”

在信贷审批的例子中:

  • p(收入 | y = 违约): 给定一个客户是违约客户,他的收入分布是怎样的?
  • p(收入 | y = 不违约): 给定一个客户是优质客户,他的收入分布又是怎样的?

这是连接我们的观察 (数据 x)未知状态 (类别 y) 的桥梁。我们称之为似然 (Likelihood)

可视化:不同类别客户的收入分布

假设我们从历史数据中发现,不违约客户的收入(蓝色)普遍高于违约客户(红色)。

可视化:不同类别客户的收入分布 图中以“5、10、15、20、25”呈现“可视化:不同类别客户的收入分布”涉及的对象、方向或比较关系。 5 10 15 20 25 年收入 (万美元) 概率密度 新申请人收入: 12万 违约似然 ≈ 0.18 不违约似然 ≈ 0.08 p(收入 | y=违约) p(收入 | y=不违约) 不同客户群体的收入分布

核心概念四:后验概率 (Posterior Probability)

后验概率 \(P(y=c | x)\) 是贝叶斯决策的核心。它是在我们观察到数据 \(x\) 之后,对样本属于类别 \(c\) 的概率的更新信念。

它回答了我们最关心的问题:

“给定这位申请人的收入是12万美元,他是违约客户的概率有多大?”

  • 图中的似然曲线与数值只用于演示“先验 × 似然 → 后验”的计算关系,并非由真实贷款样本估计;

  • 实证应用必须另行说明样本、单位与密度估计方法。

这就是我们做决策的直接依据!

贝叶斯定理:从先验到后验的魔法公式

贝叶斯定理是连接这四个核心概念的数学基石。

\[ \large{P(y=c \mid \mathbf{x}) = \frac{p(\mathbf{x} \mid y=c) P(y=c)}{p(\mathbf{x})}} \]

这个公式告诉我们如何用数据来更新我们的信念。

贝叶斯定理的直观解读

\[ \large{\underbrace{P(y=c \mid \mathbf{x})}_{\text{后验概率}} = \frac{\overbrace{p(\mathbf{x} \mid y=c)}^{\text{似然}} \times \overbrace{P(y=c)}^{\text{先验概率}}}{\underbrace{p(\mathbf{x})}_{\text{证据}}}} \]

  • 后验概率 (Posterior): 看到证据后,我们更新的信念。
  • 似然 (Likelihood): 在某个类别下,看到这个证据的可能性。
  • 先验概率 (Prior): 我们开始时的信念。
  • 证据 (Evidence): 看到这个证据的总概率,用于归一化。

贝叶斯定理各部分可视化

贝叶斯定理各部分可视化 图中以“P(y|x)、后验概率、最终答案、=、×”呈现“贝叶斯定理各部分可视化”涉及的对象、方向或比较关系。 P(y|x) 后验概率 最终答案 = × p(x|y) 似然 P(y) 先验概率 p(x) 证据 归一化因子 数据证据 初始信念

“证据” p(x) 的计算:全概率公式

分母 p(x) 是观察到特定数据 x 的总概率,无论它属于哪个类别。我们使用全概率公式计算它。

"证据" p(x) 的计算:全概率公式 图中以“全概率定律 (Law of Total Probability)、C₁: 不违约、(Prior: P(C₁))、C₂: 违约、(Prior: P(C₂))”呈现“"证据" p(x) 的计算:全概率公式”涉及的对象、方向或比较关系。 全概率定律 (Law of Total Probability) C₁: 不违约 (Prior: P(C₁)) C₂: 违约 (Prior: P(C₂)) 事件 x p(x|C₁)P(C₁) p(x|C₂)P(C₂) p(x) = p(x|C₁)P(C₁) + p(x|C₂)P(C₂)

第二部分:贝叶斯决策论

From Probabilities to Profits: The Art of Optimal Decision

拥有后验概率后,如何决策?

我们已经能够计算出 P(y=违约 | x)P(y=不违约 | x)

一个看似简单直观的规则是: 选择后验概率最大的那个类别。

\[ \large{f(\mathbf{x}) = \underset{c}{\arg\max} \ P(y=c \mid \mathbf{x})} \]

这被称为最大后验概率 (MAP) 决策准则。

MAP准则的隐藏假设

MAP准则隐含了一个非常强的假设:所有类型的错误,其代价都是相同的。

在现实世界中,这个假设往往不成立。

误判的代价是不同的:引入损失函数

在信贷审批中,有两种错误:

  1. 第一类错误 (False Negative): 把违约客户误判为“不违约” (批准了坏账贷款)。
    • 后果: 银行损失了本金,代价巨大
  2. 第二类错误 (False Positive): 把不违约客户误判为“违约” (拒绝了优质客户)。
    • 后果: 银行损失了一笔潜在的利息收入,代价较小

量化代价:损失矩阵 L(a, y)

我们用损失矩阵 L(a, y)量化“真实状态为 \(y\) 时采取动作 \(a\)”的代价。

信贷审批的损失矩阵 一个2x2的表格,展示了将违约/不违约客户正确或错误分类的代价。 如果我们的决策是... 真实情况是... 决策: 批准 决策: 拒绝 不违约 违约 损失: -¥20k (获得利息) 损失: ¥1k (机会成本) 损失: ¥500k (本金损失) 损失: ¥0 (避免损失)

期望损失:衡量决策的长期平均成本

对于观测 \(x\),若采取动作 \(a\),其期望损失 (Expected Loss)条件风险 (Conditional Risk) \(R(a|x)\) 是所有真实状态 \(y\) 的损失加权平均,权重为后验概率。

\[ \large{R(a \mid \mathbf{x}) = \sum_{y} L(a, y) P(Y=y \mid \mathbf{x})} \]

这个公式计算的是:“如果我采取动作 \(a\),平均要承担多大损失?”

期望损失计算:一步步来

假设对于某个申请人 x,我们算出的后验概率是:

  • P(y=不违约 | x) = 0.8
  • P(y=违约 | x) = 0.2

再回顾我们的损失矩阵 (简化为数值):

  • L(批准, 不违约) = -2 (赚2万)
  • L(批准, 违约) = 50 (亏50万)
  • L(拒绝, 不违约) = 0.1 (机会成本0.1万)
  • L(拒绝, 违约) = 0

计算 R(批准 | x)

如果我们选择“批准”这笔贷款:

R(批准 | x) = L(批准, 不违约) * P(不违约|x) + L(批准, 违约) * P(违约|x)

\[ \large{R(\text{批准} \mid \mathbf{x}) = (-2) \times 0.8 + (50) \times 0.2 = -1.6 + 10 = 8.4} \]

选择“批准”的期望损失是 8.4万元

计算 R(拒绝 | x)

如果我们选择“拒绝”这笔贷款:

R(拒绝 | x) = L(拒绝, 不违约) * P(不违约|x) + L(拒绝, 违约) * P(违约|x)

\[ \large{R(\text{拒绝} \mid \mathbf{x}) = (0.1) \times 0.8 + (0) \times 0.2 = 0.08} \]

选择“拒绝”的期望损失是 0.08万元

贝叶斯决策准则:选择期望损失最小的决策

最优动作 \(a^*(x)\) 是对每一个 \(x\),选择使条件风险 \(R(a|x)\) 最小的动作。

\[ \large{a^*(\mathbf{x}) = \underset{a}{\arg\min} \ R(a \mid \mathbf{x})} \]

在我们的例子中: R(批准|x) = 8.4 vs R(拒绝|x) = 0.08。 因为 0.08 < 8.4,所以最优决策是“拒绝”

尽管该申请人有80%的概率是不违约的优质客户!但20%的违约风险和高昂的损失使得拒绝成为更理性的选择。

一个特例:0-1 损失函数

如果所有误判的代价都相等(设为1),正确分类的代价为0,这就是 0-1 损失函数

\[ \large{L(i, j) = \begin{cases} 0, & \text{if } i = j \\ 1, & \text{if } i \neq j \end{cases}} \]

0-1 损失下的决策规则

在 0-1 损失下,期望损失 R(i|x) 变为:

\[ \large{R(i \mid \mathbf{x}) = \sum_{j=1}^{C} L(i, j) P(y=j \mid \mathbf{x}) = \sum_{j \neq i} P(y=j \mid \mathbf{x})} \]

\[ \large{= 1 - P(y=i \mid \mathbf{x})} \]

最小化 R(i|x) 就等价于最小化 1 - P(y=i|x),也就是最大化后验概率 P(y=i|x)

因此,MAP决策准则是最小化期望损失在0-1损失函数下的一个特例。

可视化:决策边界

  • 决策准则在特征空间中划分出不同的动作区域,每个区域对应一个最优动作;区域边界称为决策边界

  • 在 0-1 损失下动作恰与类别标签一一对应,才可直接写成类别区域。

对于MAP准则,决策边界就是后验概率相等的地方,例如 P(y=1|x) = P(y=2|x)

决策边界示意图 两个重叠的正态分布曲线,代表两个类别的类条件概率。它们的交点决定了决策边界。 x p(x | y=1)P(y=1) p(x | y=2)P(y=2) 决策边界 决策: 类别1 决策: 类别2

第三部分:参数估计

Learning from Data: The Estimation Challenge

现实挑战:我们并不知道真实的概率分布

到目前为止,我们都假设 P(y=c)p(x|y=c) 是已知的。

但在现实中,我们无法预知它们。我们拥有的只是一堆历史数据 (训练集)

核心任务

如何从数据中估计出这些概率分布的参数?

参数估计的思路

  1. 选择模型: 我们先假设数据服从某种特定形式的概率分布,例如高斯分布 \(\mathcal{N}(\mu, \sigma^2)\)
  2. 估计参数: 我们的任务就变成了从数据中估计出这个模型的未知参数 \(\theta = (\mu, \sigma^2)\)
参数估计的思路 图中以“参数估计流程 (Parameter Estimation Flow)、1. 训练数据 (Training Data)、2. 参数估计器 (Estimator)、θ̂ = ?、3. 概率模型 (Prob. Model)”呈现“参数估计的思路”涉及的对象、方向或比较关系。 参数估计流程 (Parameter Estimation Flow) 1. 训练数据 2. 参数估计 θ̂ = ? 3. 概率模型 p(x | θ̂)

方法一:极大似然估计 (MLE)

极大似然估计 (Maximum Likelihood Estimation, MLE) 的核心思想是:

选择一组参数 \(θ\),使得我们观测到的这组数据 \(X = {x_1, ..., x_N}\) 出现的联合概率最大。

换句话说,哪组参数对我们手头数据的“解释”最好?

似然函数 L(θ|X)

我们定义似然函数 L(θ|X),它表示在参数 θ 下,观测到数据 X 的概率。

假设样本是独立同分布的(i.i.d.),联合概率就是每个样本概率的乘积:

\[ \large{L(\theta \mid X) = p(X \mid \theta) = \prod_{n=1}^{N} p(x_n \mid \theta)} \]

我们的目标是找到使 L(θ|X) 最大的 θ*

\[ \large{\theta^*_{MLE} = \underset{\theta}{\arg\max} \ L(\theta \mid X)} \]

MLE的技巧:使用对数似然函数

由于连乘积的计算和求导都非常复杂,我们通常最大化对数似然函数 LL(θ|X)

因为对数函数是单调递增的,最大化 L 和最大化 log(L) 的结果是相同的。

\[ \large{LL(\theta \mid X) = \log p(X \mid \theta) = \sum_{n=1}^{N} \log p(x_n \mid \theta)} \]

这样,连乘就变成了求和,大大简化了计算。

MLE示例:估计正态分布的均值

假设我们的数据 \(x_1, ..., x_N\) 来自一个方差 \(σ²\) 已知,但均值 \(μ\) 未知的正态分布。

对数似然函数为:

\[ \large{LL(\mu) = \sum_{n=1}^{N} \log \left( \frac{1}{\sqrt{2\pi\sigma^2}} e^{-\frac{(x_n - \mu)^2}{2\sigma^2}} \right)} \]

\(μ\) 求导并令其为0,我们可以解出:

\[ \large{\hat{\mu}_{MLE} = \frac{1}{N} \sum_{n=1}^{N} x_n} \]

结果非常直观:样本均值就是对总体均值的极大似然估计

MLE的局限性:过拟合

MLE完全“相信”数据。如果数据量很小或有偏差,MLE的结果可能很差。

经典例子:抛硬币。

  • 你抛了3次硬币,结果都是正面。
  • MLE会估计正面的概率 \(p(H) = 3/3 = 1\)
  • 这意味着你将永远不会预测出反面。这显然是不合理的。

我们需要一种方法来融入我们对世界的先验知识(比如,硬币通常是公平的)。

方法二:最大后验概率估计 (MAP)

MAP (Maximum a Posteriori) 估计在MLE的基础上,引入了对参数 θ 本身的先验分布 p(θ)

它不再是最大化似然 p(X|θ),而是最大化参数的后验概率 p(θ|X)

\[ \large{p(\theta \mid X) \propto p(X \mid \theta) p(\theta)} \]

MAP的目标是:

\[ \large{\theta^*_{MAP} = \underset{\theta}{\arg\max} \ [p(X \mid \theta) p(\theta)]} \]

MAP的对数形式

同样使用对数可以简化计算:

\[ \large{\theta^*_{MAP} = \underset{\theta}{\arg\max} \ [\log p(X \mid \theta) + \log p(\theta)]} \]

\[ \large{= \underset{\theta}{\arg\max} \left[ \sum_{n=1}^{N} \log p(x_n \mid \theta) + \log p(\theta) \right]} \]

MAP:数据证据与先验信念的平衡

\[ \large{\underbrace{\log p(\theta\mid X)}_{\text{对数后验}} = \underbrace{\sum_n \log p(x_n\mid\theta)}_{\text{对数似然}} + \underbrace{\log p(\theta)}_{\text{对数先验}} + \text{constant}} \]

MAP:数据证据与先验信念的平衡 图中以“MAP 估计、数据似然、log p(X|θ)、先验信念、log p(θ)”呈现“MAP:数据证据与先验信念的平衡”涉及的对象、方向或比较关系。 MAP 估计 数据似然 log p(X|θ) 先验信念 log p(θ)

MAP 解释检查

  • 一个天平,左边是数据似然,右边是先验信念,中间的指针是最终的 MAP 估计。

  • 数据量增加时似然项通常更强;先验不是“额外样本”,而是独立写入的约束信息。

第四部分:处理复杂分布

When Reality is Messy: Mixture Models

单一模型的局限性

到目前为止,我们都假设一个类别的数据可以用一个简单的分布(如单个高斯分布)来描述。但如果数据分布更复杂呢?

单峰与多峰数据分布 左侧是一个单峰的正态分布,右侧是一个双峰的复杂分布,单一正态曲线无法很好地拟合它。 简单分布 单一高斯拟合良好 复杂 (多峰) 分布 单一高斯拟合效果差

核心内容提示:GMM/EM 为拓展内容;核心内容从 MLE/MAP 直接进入朴素贝叶斯

复杂情况:高斯混合模型 (GMM)

拓展内容提示:核心内容从 MLE/MAP 直接进入朴素贝叶斯的高维挑战;GMM/EM 完成主要练习与总结后再返回选讲。

如果我们的数据分布是由多个“集群”混合而成呢?

例如,客户的消费行为可能分为“高消费”、“中等消费”和“低消费”三个群体,每个群体内部都近似正态分布。

高斯混合模型 (Gaussian Mixture Model, GMM) 正是为此而生。

GMM的定义:多个高斯的加权和

GMM 将一个复杂的概率分布建模为 K 个高斯分量的加权和。

\[ \large{p(\mathbf{x}) = \sum_{k=1}^{K} \pi_k \mathcal{N}(\mathbf{x} \mid \mu_k, \Sigma_k)} \]

其中:

  • \(K\): 混合分量的数量 (超参数)。
  • \(π_k\): 第 \(k\) 个分量的混合系数 (权重),且 \(\sum_{k=1}^{K} \pi_k = 1\)
  • \(μ_k, Σ_k\): 第 \(k\) 个高斯分量的均值和协方差矩阵。

GMM的挑战:隐变量问题

GMM的参数估计(\(π_k, μ_k, Σ_k\))比单个高斯要复杂得多。

因为我们不知道每个数据点 \(x_n\) 究竟属于哪个高斯分量。这个“归属”信息是一个隐变量 (latent variable)

这是一个“鸡生蛋,蛋生鸡”的问题:

  • 如果知道了每个点属于哪个集群,我们就可以轻松估计每个集群的参数。
  • 如果知道了每个集群的参数,我们就可以计算每个点属于哪个集群的概率。

解决方法:期望最大化算法 (EM)

期望最大化 (Expectation-Maximization, EM) 算法 是一种迭代算法,专门用来解决含有隐变量的参数估计问题。

它优雅地解决了“鸡生蛋,蛋生鸡”的困境,通过交替执行两个步骤直到收敛。

EM算法:E-步 (Expectation)

E-步 (期望)

基于当前的模型参数,计算每个数据点 \(x_n\) 由每个高斯分量 \(k\) 生成的后验概率(也叫“责任” \(r_{nk}\))。

\[ \large{r_{nk} = P(z_n=k \mid x_n; \theta_{old})} \]

通俗地说,就是对每个数据点进行“软分配”,猜测它有多大可能性来自每个集群。

EM算法:M-步 (Maximization)

M-步 (最大化)

基于 E-步计算出的“责任” \(r_nk\)更新模型参数 \(π_k, μ_k, Σ_k\),以最大化期望对数似然。

这相当于对每个集群进行加权的MLE估计,权重就是 \(r_nk\)

例如,新的均值是所有数据点的加权平均:

\[ \large{\mu_k^{new} = \frac{\sum_{n=1}^N r_{nk} x_n}{\sum_{n=1}^N r_{nk}}} \]

EM算法流程

EM算法流程 图中以“期望最大化 (EM) 算法流程、1. 初始化参数、Initialize Parameters (θ₀)、E-步 (Expectation)、计算潜在变量的期望”呈现“EM算法流程”涉及的对象、方向或比较关系。 期望最大化 (EM) 算法流程 1. 初始化参数 θ₀ E-步 (Expectation) 计算责任度 E[z | x, θ] M-步 (Maximization) 更新模型参数 最大化期望 迭代直至收敛

拓展内容结束:结束 GMM/EM 后,进入最终总结,不重放已经完成的 核心内容。

第五部分:朴素贝叶斯分类器

Putting it all Together: The Naive Bayes Classifier

挑战:高维数据的诅咒

当我们的数据 x 有多个特征时,直接估计 d 维的联合概率分布 p(x|y=c) 非常困难,需要海量数据,这就是所谓的“维度灾难”。

挑战:高维数据的诅咒 图中以“维度灾难 (Curse of Dimensionality)、一维空间 (1-D)、10个点,覆盖良好、二维空间 (2-D)、需要 10² = 100个点”呈现“挑战:高维数据的诅咒”涉及的对象、方向或比较关系。 维度灾难 (Curse of Dimensionality) 一维空间 (1-D) 10个点,覆盖良好 二维空间 (2-D) 100 个点(10²) 数据变得稀疏 三维空间 (3-D) 1000 个点(10³) 数据极其稀疏

“朴素”的假设:特征条件独立性

朴素贝叶斯 (Naïve Bayes) 分类器做了一个非常大胆(但常常有效)的简化假设:

给定类别 \(y\),所有特征 \(x_i\) 之间是相互独立的。

这意味着:知道了客户是“违约”客户后,他的“收入”高低和他的“年龄”大小是两个独立的信息。

独立性假设的威力

这个“朴素”的假设让联合概率的计算变得异常简单:

原本复杂的联合概率:

\[ \large{p(\mathbf{x}|y=c) = p(x_1, x_2, \ldots, x_d | y=c)} \]

在独立性假设下,可以分解为各个特征的类条件概率的乘积

\[ \large{p(\mathbf{x}|y=c) = \prod_{i=1}^{d} p(x_i | y=c)} \]

现在我们只需要为每个特征单独估计一维的 \(p(x_i|y=c)\),这比估计高维联合分布容易得多!

朴素贝叶斯的图模型

这个假设可以用一个简单的图模型来表示。

朴素贝叶斯的图模型 图中以“朴素贝叶斯 (Naive Bayes)、特征条件独立假设 (Conditional Independence)、Y、X₁、X₂”呈现“朴素贝叶斯的图模型”涉及的对象、方向或比较关系。 朴素贝叶斯 (Naive Bayes) 给定 Y 后,特征条件独立 Y X₁ X₂ X₃ Xₙ 一般贝叶斯网络 (General) 特征间可以存在依赖 Y X₁ X₂ X₃ Xₙ

另一个现实问题:零概率

考虑一个文本分类任务(如垃圾邮件检测),特征是离散的词汇。

我们用 MLE 估计类条件概率 p(单词="offer" | 类别="垃圾邮件"),即计算训练集中垃圾邮件里 “offer” 出现的频率。

问题

如果在训练集的垃圾邮件中,“wanli” 这个词从未出现过,那么:

\[ \large{p(\text{单词}="\text{wanli}" \mid y=\text{垃圾邮件}) = 0} \]

零概率的致命后果

如果 p("wanli" | 垃圾邮件) = 0,那么对于任何包含 “wanli” 的新邮件,其被分类为垃圾邮件的后验概率将直接变为0!

\[ \large{P(\text{垃圾} \mid \text{邮件}) \propto \ldots \times \overbrace{p(\text{"wanli"} \mid \text{垃圾})}^{=0} \times \ldots = 0} \]

仅仅因为一个词在训练集中没见过,就完全排除了一个类别的可能性,这是非常脆弱和不合理的。模型“见过”的太少,太绝对了。

解决方案:拉普拉斯平滑 (Laplace Smoothing)

拉普拉斯平滑,也叫加法平滑 (Additive Smoothing),是一种简单而有效的处理零概率问题的方法。

它的核心思想是:在计算概率时,为所有可能事件的计数都人为地加上一个小常数 λ (通常为1)。

这相当于给每个可能出现的事件一个“基础票”,保证即使某个事件在样本中从未出现,其估计出的概率也不会是零。

拉普拉斯平滑的公式

对于离散特征,没有平滑的MLE估计是:

\[ \large{P(x_i = v \mid y=c) = \frac{N_{cv}}{N_c}} \]

  • \(N_cv\): 类别c中特征值为v的样本数
  • \(N_c\): 类别c的总样本数

加入拉普拉斯平滑(λ > 0)后:

\[ \large{P_{\lambda}(x_i = v \mid y=c) = \frac{N_{cv} + \lambda}{N_c + \lambda S_i}} \]

  • \(S_i\): 特征 \(i\) 可能取值的总数量(如词汇表大小)
  • \(λ\): 平滑参数(\(λ=1\) 时称为“加一平滑”)

平滑效果:一个例子

假设一个特征有两个取值 {Yes, No},在类别 c 下有10个样本。

  • 观察到 10 次 ‘Yes’,0 次 ‘No’。
  • \(S_i = 2\) (两个可能取值)

MLE 估计:

  • P('Yes'|c) = 10/10 = 1
  • P('No'|c) = 0/10 = 0 (危险!)

拉普拉斯平滑 (λ=1):

  • P('Yes'|c) = (10+1)/(10+1*2) = 11/12 ≈ 0.917
  • P('No'|c) = (0+1)/(10+1*2) = 1/12 ≈ 0.083 (问题解决!)

进入主要案例前的学习目标回顾

回顾开场目标:①由先验、似然计算后验;②用损失矩阵而非最大概率作决策;③区分 MLE 与 MAP;④检验朴素条件独立假设并评价概率预测。

  • 回顾题: 已知 \(P(D)=0.1\)\(P(+|D)=0.8\)\(P(+|\neg D)=0.2\),先算 \(P(+)\)
  • 答案: \(P(+)=0.8\times0.1+0.2\times0.9=0.26\);因此 \(P(D|+)=0.08/0.26\approx0.308\),不是 0.8。

形成性检查 1:概率还是决策?

客户违约后验概率为 0.30;“批准后违约”损失为 10,“拒绝但不违约”损失为 1。应批准还是拒绝?

答案

批准风险 \(0.30\times10=3\);拒绝风险 \(0.70\times1=0.7\),故拒绝。最大后验类别与最小期望损失决策不必一致。

主要案例:福耀玻璃高斯朴素贝叶斯

  • 本例数据: data/stock/stock_price_pre_adjusted.h5;key=data;福耀玻璃 600660.XSHG;2018–2024;closevolume;用 \(t\) 时点收益、绝对收益与成交量增速预测 \(t+1\) 是否下跌;前 80% 训练、后 20% 测试。

  • 邻近方法来源: scikit-learn GaussianNB 文档;本例同时报告阈值判断与概率排序证据。

Code
from pathlib import Path  # 使用统一路径对象定位数据文件

import pandas as pd  # 导入表格工具以读取本地行情
from sklearn.naive_bayes import GaussianNB  # 使用高斯朴素贝叶斯估计类条件密度
from sklearn.metrics import balanced_accuracy_score, roc_auc_score  # 同时评价类别判断与概率排序
# 公网下载:https://assets.qiufei.site/data/stock/stock_price_pre_adjusted.h5
# 下载后把下一行改为本机文件位置;按课程结构存放时可用 Path("data/stock/stock_price_pre_adjusted.h5")。
# Windows:Path(r"C:\qiufei\data\stock\stock_price_pre_adjusted.h5")
# macOS:Path("/Users/你的用户名/data/stock/stock_price_pre_adjusted.h5")
# Linux:Path("/home/你的用户名/data/stock/stock_price_pre_adjusted.h5")
price_path = Path("/home/ubuntu/r2_data_mount/data/stock/stock_price_pre_adjusted.h5")
price_rows = pd.read_hdf(price_path, key='data', where=['order_book_id=="600660.XSHG"', 'date>=Timestamp("2018-01-01")', 'date<=Timestamp("2024-12-31")'], columns=['close', 'volume'])  # 只载入目标公司、时期和字段
bayes_frame = price_rows.reset_index().sort_values('date')  # 按预测可用时间排序
bayes_frame['return_t'] = bayes_frame['close'].pct_change()  # 构造当日收益率特征
bayes_frame['abs_return_t'] = bayes_frame['return_t'].abs()  # 用绝对收益代理当日波动冲击
bayes_frame['volume_growth_t'] = bayes_frame['volume'].pct_change()  # 构造成交量增速特征
bayes_frame['future_return_t1'] = bayes_frame['return_t'].shift(-1)  # 先保留连续未来收益,避免把未知末日静默编码为零
bayes_frame['target_date_t1'] = bayes_frame['date'].shift(-1)  # 保存标签实现日以清除跨窗口样本
bayes_frame = bayes_frame.replace([float('inf'), float('-inf')], pd.NA).dropna()  # 在标签转整数前删除所有不可观测或非有限记录
Code
bayes_frame['down_t1'] = (bayes_frame['future_return_t1'] < 0).astype(int)  # 仅对已观测未来收益构造二元标签
assert bayes_frame['future_return_t1'].notna().all() and bayes_frame['date'].max() < price_rows.reset_index()['date'].max()  # 确认每个特征日都对应更晚的真实标签实现日
split_row = int(len(bayes_frame) * 0.8)  # 事先确定时间切分位置
test_start_date = bayes_frame.iloc[split_row]['date']  # 从完整序列确定测试起点
train_rows = bayes_frame[(bayes_frame['date'] < test_start_date) & (bayes_frame['target_date_t1'] < test_start_date)]  # 清除到测试期才实现的训练标签
test_rows = bayes_frame[bayes_frame['date'] >= test_start_date]  # 确定测试特征窗口
assert train_rows['target_date_t1'].max() < test_rows['date'].min()  # 确认标签实现边界
feature_names = ['return_t', 'abs_return_t', 'volume_growth_t']  # 声明模型实际使用的语义字段
bayes_model = GaussianNB().fit(train_rows[feature_names], train_rows['down_t1'])  # 在训练期估计先验和类条件分布
down_probability = bayes_model.predict_proba(test_rows[feature_names])[:, 1]  # 输出测试期下跌后验概率
pd.Series({'balanced_accuracy': balanced_accuracy_score(test_rows['down_t1'], down_probability >= 0.5), 'roc_auc': roc_auc_score(test_rows['down_t1'], down_probability), 'test_rows': len(test_rows)})  # 报告样本外指标与样本数
balanced_accuracy      0.486806
roc_auc                0.448681
test_rows            340.000000
dtype: float64

形成性检查 2:朴素假设

return_tabs_return_t 显然相关,朴素贝叶斯还能运行吗?输出能否直接当因果效应?

答案

能运行,但条件独立假设失配可能导致概率校准较差;应检查校准曲线并与基准比较。后验是观测预测,不是干预效应。

分步练习:损失敏感阈值

  • 任务: 假设漏报下跌损失为误报的 4 倍,推导最优概率阈值并重新报告混淆矩阵。
  • 完整解答:
    • 预测“下跌”的风险为 \((1-p)\times1\),预测“不跌”的风险为 \(p\times4\);当 \((1-p)<4p\)\(p>0.2\) 时预测下跌。

    • 把代码中的 down_probability >= 0.5 改为 >= 0.2,并比较召回率上升与精确率下降。

Code
from sklearn.metrics import confusion_matrix, precision_score, recall_score  # 计算成本阈值下的可核对分类结果
threshold_rows = []  # 收集两个阈值的完整比较
for probability_threshold in [0.5, 0.2]:  # 对照默认阈值与四比一成本阈值
    threshold_prediction = down_probability >= probability_threshold  # 将同一测试概率转为类别决策
    threshold_matrix = confusion_matrix(test_rows['down_t1'], threshold_prediction)  # 固定标签顺序得到 TN、FP、FN、TP
    threshold_rows.append({'threshold': probability_threshold, 'precision': precision_score(test_rows['down_t1'], threshold_prediction), 'recall': recall_score(test_rows['down_t1'], threshold_prediction), 'tn': threshold_matrix[0, 0], 'fp': threshold_matrix[0, 1], 'fn': threshold_matrix[1, 0], 'tp': threshold_matrix[1, 1]})  # 保存指标与四格计数
pd.DataFrame(threshold_rows)  # 展示阈值降低后的召回—精确率权衡
Table 1
threshold precision recall tn fp fn tp
0 0.5 0.463087 0.86250 20 160 22 138
1 0.2 0.471810 0.99375 2 178 1 159

综合练习

将对象改为恒瑞医药 600276.XSHG,用 2023–2024 作为固定测试期;比较 GaussianNB 与只使用类别先验的基准,并绘制 5 组概率分箱校准表。

完整答案提醒

  • 说明时间切分、字段与单位、比较基准,以及 AUC、平衡准确率和校准结果;同时明确“相关不等于因果”。

  • 除非报告重复时间切分的不确定性,否则不要声称某个指标显著更优。

综合练习完整答案:恒瑞医药数据分析步骤

Table 2
Code
from pathlib import Path  # 使用统一路径对象定位数据文件

import pandas as pd  # 读取并整理本地真实 A 股行情
from sklearn.naive_bayes import GaussianNB  # 估计高斯朴素贝叶斯概率
from sklearn.metrics import balanced_accuracy_score, roc_auc_score  # 评价类别判断与概率排序
# 公网下载:https://assets.qiufei.site/data/stock/stock_price_pre_adjusted.h5
# 下载后把下一行改为本机文件位置;按课程结构存放时可用 Path("data/stock/stock_price_pre_adjusted.h5")。
# Windows:Path(r"C:\qiufei\data\stock\stock_price_pre_adjusted.h5")
# macOS:Path("/Users/你的用户名/data/stock/stock_price_pre_adjusted.h5")
# Linux:Path("/home/你的用户名/data/stock/stock_price_pre_adjusted.h5")
transfer_path = Path("/home/ubuntu/r2_data_mount/data/stock/stock_price_pre_adjusted.h5")
transfer_rows = pd.read_hdf(transfer_path, key='data', where=['order_book_id=="600276.XSHG"', 'date>=Timestamp("2018-01-01")', 'date<=Timestamp("2024-12-31")'], columns=['close', 'volume'])  # 选择恒瑞医药、时期和字段
transfer_frame = transfer_rows.reset_index().sort_values('date')  # 按预测发生顺序排列交易日
transfer_frame['return_t'] = transfer_frame['close'].pct_change()  # 构造当日收益率
transfer_frame['return_5d_t'] = transfer_frame['close'].pct_change(5)  # 构造五日收益率
transfer_frame['volatility_5d_t'] = transfer_frame['return_t'].rolling(5).std()  # 构造历史五日波动率
transfer_frame['volume_growth_t'] = transfer_frame['volume'].pct_change()  # 构造成交量增速
transfer_frame['future_return_t1'] = transfer_frame['return_t'].shift(-1)  # 先保留连续未来收益
transfer_frame['target_date_t1'] = transfer_frame['date'].shift(-1)  # 保存标签实现日
transfer_frame = transfer_frame.replace([float('inf'), float('-inf')], pd.NA).dropna()  # 删除未知未来与不可计算记录
transfer_frame['down_t1'] = (transfer_frame['future_return_t1'] < 0).astype(int)  # 仅对已观测未来收益整数化
transfer_train = transfer_frame[(transfer_frame['date'] <= '2022-12-31') & (transfer_frame['target_date_t1'] < '2023-01-01')]  # 清除到测试期才实现的训练标签
transfer_test = transfer_frame[transfer_frame['date'] >= '2023-01-01']  # 确定 2023—2024 测试期
assert transfer_train['target_date_t1'].max() < transfer_test['date'].min()  # 确认标签实现边界

综合练习完整答案:基准与五组校准

Code
transfer_features = ['return_t', 'return_5d_t', 'volatility_5d_t', 'volume_growth_t']  # 固定四个 t 时点可得特征
transfer_bayes = GaussianNB().fit(transfer_train[transfer_features], transfer_train['down_t1'])  # 只在训练期拟合模型
transfer_probability = transfer_bayes.predict_proba(transfer_test[transfer_features])[:, 1]  # 对测试期生成下跌概率
prior_probability = pd.Series(transfer_train['down_t1'].mean(), index=transfer_test.index)  # 构造只含训练期类别先验的基准
transfer_metrics = pd.DataFrame({'model': ['GaussianNB', 'class-prior baseline'], 'roc_auc': [roc_auc_score(transfer_test['down_t1'], transfer_probability), roc_auc_score(transfer_test['down_t1'], prior_probability)], 'balanced_accuracy': [balanced_accuracy_score(transfer_test['down_t1'], transfer_probability >= 0.5), balanced_accuracy_score(transfer_test['down_t1'], prior_probability >= 0.5)]})  # 汇总同一测试期指标
calibration_frame = pd.DataFrame({'observed': transfer_test['down_t1'].to_numpy(), 'probability': transfer_probability})  # 对齐概率与真实结果
calibration_frame['probability_bin'] = pd.cut(calibration_frame['probability'], bins=[0, .2, .4, .6, .8, 1], include_lowest=True)  # 按预先声明边界划分五组
calibration_table = calibration_frame.groupby('probability_bin', observed=False).agg(n=('observed', 'size'), mean_probability=('probability', 'mean'), observed_rate=('observed', 'mean')).reset_index()  # 计算每组预测均值与真实频率
display(transfer_metrics)  # 输出模型与先验基准的关键指标
calibration_table  # 输出完整五组校准表
Table 3
model roc_auc balanced_accuracy
0 GaussianNB 0.522642 0.52633
1 class-prior baseline 0.500000 0.50000
probability_bin n mean_probability observed_rate
0 (-0.001, 0.2] 0 NaN NaN
1 (0.2, 0.4] 20 0.333113 0.650000
2 (0.4, 0.6] 431 0.487905 0.522042
3 (0.6, 0.8] 23 0.657749 0.521739
4 (0.8, 1.0] 9 0.951448 0.444444
  • 真实测试输出为:GaussianNB AUC 0.522642、平衡准确率 0.526330;先验基准均为 0.500000。

  • 五个概率组的样本数依次为 0、20、431、23、9;中间 0.4–0.6 组预测均值 0.487905、真实下跌率 0.522042。

综合练习完整答案:校准边界

  • 最后特征日为 2024-12-30;已删除未知未来标签。

  • 空组和小尾部组不支持稳定校准,更不支持因果结论。

形成性检查 3:MLE 与 MAP

样本很少且先验集中时,MLE 与 MAP 哪个更容易被先验收缩?样本量增大后差异如何?

答案

MAP 直接加入先验,因而小样本时更受收缩;在常规正则条件下,样本量增大后似然占主导,两者通常接近。

来源与延伸阅读

  • Berger, Statistical Decision Theory and Bayesian Analysis
  • Murphy, Probabilistic Machine Learning: An Introduction, classification chapters。
  • McCallum & Nigam (1998), naive Bayes event models。
  • 数据:本地 A 股前复权行情数据;字段与筛选如 前面的案例 所列。

本章总结:贝叶斯分类器的核心思想

课后选学:完成核心内容后,可以继续学习GMM/EM,随后进入最终总结

贝叶斯分类器核心思想总结 五个关键概念的总结,每个概念都有一个图标和简短描述。 P(y|x) 决策框架 先验 × 似然更新为后验 最优决策 按期望损失选择动作 模型学习 MLE / MAP估计参数 实用性 条件独立假设带来高效分类 稳健性 平滑缓解数据稀疏

课程预告

今天我们深入探讨了生成式模型 (Generative Models) 的一种经典方法——贝叶斯分类器。

我们学习了如何对 p(x|y)P(y) 进行建模。

接下来,我们将学习另一大类模型:判别式模型 (Discriminative Models),例如逻辑回归。这类模型将跳过对 p(x|y) 的建模,直接对后验概率 P(y|x) 进行建模。

谢谢!

Q & A