想象你是银行的信贷经理,每天都要面对一个关键决策:
是否批准一笔贷款?
这本质上是一个分类 (Classification) 问题。
我们来看看一个简化的申请人数据。
申请人 ID | 年收入 (万美元) | 信用评分 | 历史违约 | 我们的决策 |
---|---|---|---|---|
001 | 15 | 720 | 否 | ? |
002 | 6 | 580 | 是 | ? |
003 | 9 | 650 | 否 | ? |
… | … | … | … | … |
目标: 构建一个模型 \(f(X)\),输入申请人信息 \(X\),输出最优决策 \(Y\)。
贝叶斯分类器提供了一个基于概率论的强大决策框架。
我们将循序渐进,构建完整的贝叶斯决策体系。
The Language of Uncertainty
先验概率 \(P(y=c)\) 是在获得任何新数据之前,我们对某个类别 \(c\) 出现的固有信念或历史频率。
在信贷审批的例子中,先验概率指的是:
在不查看任何申请人具体信息的情况下,根据银行历史数据,一个客户会违约的概率是多少?
它是我们决策的基准或起点。
假设银行在过去处理了 10,000 笔贷款申请,其中 500 笔最终违约。
对于连续型变量(如收入、年龄),我们使用概率密度函数 (Probability Density Function, p(x)
) 来描述其分布规律。
p(x)
的值可以大于1。[a, b]
的概率是 PDF 在该区间上的积分:\(P(a \le x \le b) = \int_a^b p(x) dx\)。一个重要的区分:
正态分布是金融和商业领域最常用的PDF,它由均值 μ
(中心位置) 和方差 σ²
(离散程度) 决定。
类条件概率 \(p(x | y=c)\) 回答了这样一个问题:“如果我们已经知道样本属于类别 \(c\),那么观察到数据 \(x\) 的概率密度是多少?”
在信贷审批的例子中:
p(收入 | y = 违约)
: 给定一个客户是违约客户,他的收入分布是怎样的?p(收入 | y = 不违约)
: 给定一个客户是优质客户,他的收入分布又是怎样的?这是连接我们的观察 (数据 x
) 和未知状态 (类别 y
) 的桥梁。我们称之为似然 (Likelihood)。
假设我们从历史数据中发现,不违约客户的收入(蓝色)普遍高于违约客户(红色)。
后验概率 \(P(y=c | x)\) 是贝叶斯决策的核心。它是在我们观察到数据 \(x\) 之后,对样本属于类别 \(c\) 的概率的更新信念。
它回答了我们最关心的问题:
“给定这位申请人的收入是9.5万美元,他是违约客户的概率有多大?”
这就是我们做决策的直接依据!
贝叶斯定理是连接这四个核心概念的数学基石。
\[ \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{证据}}}} \]
p(x)
的计算:全概率公式分母 p(x)
是观察到特定数据 x
的总概率,无论它属于哪个类别。我们使用全概率公式计算它。
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准则隐含了一个非常强的假设:所有类型的错误,其代价都是相同的。
在现实世界中,这个假设往往不成立。
在信贷审批中,有两种错误:
L(i, j)
我们用一个损失矩阵 (Loss Matrix) L(i, j)
来量化将真实类别为 j
的样本误判为类别 i
的代价。
对于一个给定的观测数据 \(x\),如果我们将其分类为类别 \(i\),其期望损失 (Expected Loss) 或 条件风险 (Conditional Risk) \(R(i|x)\) 是所有可能真实情况 \(j\) 的损失的加权平均,权重就是后验概率。
\[ \large{R(i \mid \mathbf{x}) = \sum_{j=1}^{C} L(i, j) P(y=j \mid \mathbf{x})} \]
这个公式计算的是:“如果我做出决策 \(i\),我平均下来要承担多大的损失?”
假设对于某个申请人 x
,我们算出的后验概率是:
P(y=不违约 | x) = 0.8
P(y=违约 | x) = 0.2
再回顾我们的损失矩阵 (简化为数值):
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) \times 0.8 + (0) \times 0.2 = 0} \] 选择“拒绝”的期望损失是 0万元。
最优决策 \(f*(x)\) 就是对每一个 \(x\),都选择能使期望损失 \(R(i|x)\) 最小的那个类别 \(i\)。
\[
\large{f^*(\mathbf{x}) = \underset{i}{\arg\min} \ R(i \mid \mathbf{x})}
\] 在我们的例子中: R(批准|x) = 8.4
vs R(拒绝|x) = 0
。 因为 0 < 8.4
,所以最优决策是“拒绝”。
尽管该申请人有80%的概率是不违约的优质客户!但20%的违约风险和高昂的损失使得拒绝成为更理性的选择。
如果所有误判的代价都相等(设为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 损失下,期望损失 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损失函数下的一个特例。
决策准则在特征空间中划分出了不同的区域,每个区域对应一个决策类别。这些区域的边界被称为决策边界。
对于MAP准则,决策边界就是后验概率相等的地方,例如 P(y=1|x) = P(y=2|x)
。
Learning from Data: The Estimation Challenge
到目前为止,我们都假设 P(y=c)
和 p(x|y=c)
是已知的。
但在现实中,我们无法预知它们。我们拥有的只是一堆历史数据 (训练集)。
核心任务:如何从数据中估计出这些概率分布的参数?
极大似然估计 (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)}
\]
由于连乘积的计算和求导都非常复杂,我们通常最大化对数似然函数 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)}
\] 这样,连乘就变成了求和,大大简化了计算。
假设我们的数据 \(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的结果可能很差。
经典例子:抛硬币。
我们需要一种方法来融入我们对世界的先验知识(比如,硬币通常是公平的)。
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)]}
\]
同样使用对数可以简化计算: \[ \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]} \]
\[ \large{\underbrace{\log p(\theta|X)}_{\text{后验}} \propto \underbrace{\sum \log p(x_n|\theta)}_{\text{数据似然}} + \underbrace{\log p(\theta)}_{\text{先验信念}}} \]
一个天平,左边是数据似然,右边是先验信念,中间的指针是最终的MAP估计。
When Reality is Messy: Mixture Models
到目前为止,我们都假设一个类别的数据可以用一个简单的分布(如单个高斯分布)来描述。但如果数据分布更复杂呢?
如果我们的数据分布是由多个“集群”混合而成呢?
例如,客户的消费行为可能分为“高消费”、“中等消费”和“低消费”三个群体,每个群体内部都近似正态分布。
高斯混合模型 (Gaussian Mixture Model, GMM) 正是为此而生。
GMM 将一个复杂的概率分布建模为 K
个高斯分量的加权和。
\[ \large{p(\mathbf{x}) = \sum_{k=1}^{K} \pi_k \mathcal{N}(\mathbf{x} \mid \mu_k, \Sigma_k)} \]
其中:
让我们用Python生成一些由3个集群构成的数据,并用GMM来拟合它。
GMM的参数估计(\(π_k, μ_k, Σ_k\))比单个高斯要复杂得多。
因为我们不知道每个数据点 \(x_n\) 究竟属于哪个高斯分量。这个“归属”信息是一个隐变量 (latent variable)。
这是一个“鸡生蛋,蛋生鸡”的问题:
期望最大化 (Expectation-Maximization, EM) 算法 是一种迭代算法,专门用来解决含有隐变量的参数估计问题。
它优雅地解决了“鸡生蛋,蛋生鸡”的困境,通过交替执行两个步骤直到收敛。
E-步 (期望): 基于当前的模型参数,计算每个数据点 \(x_n\) 由每个高斯分量 \(k\) 生成的后验概率(也叫“责任” \(r_{nk}\))。
\[ \large{r_{nk} = P(z_n=k \mid x_n; \theta_{old})} \]
通俗地说,就是对每个数据点进行“软分配”,猜测它有多大可能性来自每个集群。
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}}} \]
Putting it all Together: The Naive Bayes Classifier
当我们的数据 x
有多个特征时,直接估计 d
维的联合概率分布 p(x|y=c)
非常困难,需要海量数据,这就是所谓的“维度灾难”。
朴素贝叶斯 (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)\),这比估计高维联合分布容易得多!
这个假设可以用一个简单的图模型来表示。
我们来用一个经典数据集——鸢尾花 (Iris) 数据集——来实践朴素贝叶斯。
首先,我们使用 scikit-learn
加载数据并将其分割为训练集和测试集。
# 导入必要的库
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score
# 加载数据: X是特征, y是标签(花的品种)
X, y = load_iris(return_X_y=True)
# 将数据分为训练集(70%)和测试集(30%)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
print(f'训练集大小: {X_train.shape}')
print(f'测试集大小: {X_test.shape}')
训练集大小: (105, 4)
测试集大小: (45, 4)
训练朴素贝叶斯模型非常快,因为它只需要为每个类别和每个特征计算均值和方差,无需复杂的迭代优化。
# 初始化高斯朴素贝叶斯模型
gnb = GaussianNB()
# 使用训练数据来“学习”模型参数
# 这里就是计算每个类别下每个特征的均值和方差
gnb.fit(X_train, y_train)
# 使用训练好的模型在测试集上进行预测
y_pred = gnb.predict(X_test)
# 打印部分预测结果与真实标签进行对比
print(f'真实标签 (前10个): {y_test[:10]}')
print(f'预测标签 (前10个): {y_pred[:10]}')
真实标签 (前10个): [1 0 2 1 1 0 1 2 1 1]
预测标签 (前10个): [1 0 2 1 1 0 1 2 1 1]
我们使用准确率 (Accuracy) 来评估模型的表现,即正确分类的样本占总样本的比例。
高斯朴素贝叶斯分类器的准确率是: 0.9778
尽管“朴素”的特征独立假设在现实中几乎不成立(花瓣的长和宽很可能相关),但分类器的表现依然非常出色!
From Theory to Practice: Final Touches
考虑一个文本分类任务(如垃圾邮件检测),特征是离散的词汇。
我们用 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} \]
仅仅因为一个词在训练集中没见过,就完全排除了一个类别的可能性,这是非常脆弱和不合理的。模型“见过”的太少,太绝对了。
拉普拉斯平滑,也叫加法平滑 (Additive Smoothing),是一种简单而有效的处理零概率问题的方法。
它的核心思想是:在计算概率时,为所有可能事件的计数都人为地加上一个小常数 λ
(通常为1)。
这相当于给每个可能出现的事件一个“基础票”,保证即使某个事件在样本中从未出现,其估计出的概率也不会是零。
对于离散特征,没有平滑的MLE估计是: \[ \large{P(x_i = v \mid y=c) = \frac{N_{cv}}{N_c}} \]
加入拉普拉斯平滑(λ
> 0)后: \[
\large{P_{\lambda}(x_i = v \mid y=c) = \frac{N_{cv} + \lambda}{N_c + \lambda S_i}}
\]
假设一个特征有两个取值 {Yes, No},在类别 c
下有10个样本。
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
(问题解决!)今天我们深入探讨了生成式模型 (Generative Models) 的一种经典方法——贝叶斯分类器。
我们学习了如何对 p(x|y)
和 P(y)
进行建模。
接下来,我们将学习另一大类模型:判别式模型 (Discriminative Models),例如逻辑回归。这类模型将跳过对 p(x|y)
的建模,直接对后验概率 P(y|x)
进行建模。
Q & A