抛硬币模拟贝叶斯更新
模拟不断抛硬币的过程,用贝叶斯公式实时更新「硬币是否作弊」的信念分布。
学完本案例你将理解:贝叶斯方法的核心——每观察一次新数据,就用似然函数更新一次信念。
生活引入
新同事靠不靠谱?
第一天,你不了解新同事(先验:ta 可能靠谱也可能不靠谱,各 50%)。第一周,ta 每次都准时完成任务(新证据),你开始觉得「ta 大概率靠谱」。第二周,ta 又准时完成(更多证据),你的判断更加确信。
你的判断就是后验概率——用新证据不断修正初始判断的结果。这就是贝叶斯更新的直觉。
直观理解
我们有一个硬币,但不清楚它的正面概率是多少。先验:抛之前,认为任何正面概率(0 到 1)都有可能。似然:每次看到结果,就用「如果正面概率是 theta,看到这个结果的可能性」来更新。后验:更新后的信念分布——数据越多,分布越集中在真实值附近。
数学定义
\[ P(\theta \mid \text{data}) = \frac{P(\text{data} \mid \theta) \cdot P(\theta)}{P(\text{data})} \] \[ \text{后验}_t \propto \text{似然}(\text{第 }t\text{ 次结果} \mid \theta) \times \text{后验}_{t-1} \]Python 动手实践
实例
import numpy as np
np.random.seed(1)
true_p = 0.75 # 真实的硬币正面概率(假装不知道)
theta_grid = np.linspace(0, 1, 200)
# 先验:对所有 theta 一视同仁
prior = np.ones_like(theta_grid)
prior /= prior.sum()
# 模拟抛 40 次硬币
flips = np.random.binomial(1, true_p, size=40)
posterior = prior.copy()
print("RUNOOB 贝叶斯更新过程 (真实 theta=0.75):\n")
for i, outcome in enumerate(flips, start=1):
likelihood = theta_grid if outcome == 1 else (1 - theta_grid)
posterior = posterior * likelihood
posterior /= posterior.sum()
if i % 10 == 0:
est = theta_grid[np.argmax(posterior)]
print(f" 抛 {i:2d} 次后,最可能的 theta={est:.3f}")
# 不确定性对比
prior_std = np.sqrt(np.sum(theta_grid**2 * prior) - np.sum(theta_grid * prior)**2)
post_std = np.sqrt(np.sum(theta_grid**2 * posterior) - np.sum(theta_grid * posterior)**2)
print(f"\nRUNOOB 先验标准差: {prior_std:.4f} -> 后验标准差: {post_std:.4f} (缩小了 {prior_std/post_std:.1f} 倍)")
np.random.seed(1)
true_p = 0.75 # 真实的硬币正面概率(假装不知道)
theta_grid = np.linspace(0, 1, 200)
# 先验:对所有 theta 一视同仁
prior = np.ones_like(theta_grid)
prior /= prior.sum()
# 模拟抛 40 次硬币
flips = np.random.binomial(1, true_p, size=40)
posterior = prior.copy()
print("RUNOOB 贝叶斯更新过程 (真实 theta=0.75):\n")
for i, outcome in enumerate(flips, start=1):
likelihood = theta_grid if outcome == 1 else (1 - theta_grid)
posterior = posterior * likelihood
posterior /= posterior.sum()
if i % 10 == 0:
est = theta_grid[np.argmax(posterior)]
print(f" 抛 {i:2d} 次后,最可能的 theta={est:.3f}")
# 不确定性对比
prior_std = np.sqrt(np.sum(theta_grid**2 * prior) - np.sum(theta_grid * prior)**2)
post_std = np.sqrt(np.sum(theta_grid**2 * posterior) - np.sum(theta_grid * posterior)**2)
print(f"\nRUNOOB 先验标准差: {prior_std:.4f} -> 后验标准差: {post_std:.4f} (缩小了 {prior_std/post_std:.1f} 倍)")
RUNOOB 贝叶斯更新过程 (真实 theta=0.75): 抛 10 次后,最可能的 theta=0.754 抛 20 次后,最可能的 theta=0.769 抛 30 次后,最可能的 theta=0.759 抛 40 次后,最可能的 theta=0.774 RUNOOB 先验标准差: 0.2890 -> 后验标准差: 0.0642 (缩小了 4.5 倍)
AI 中的应用场景
| 场景 | 贝叶斯方法的作用 |
|---|---|
| 朴素贝叶斯分类 | 贝叶斯公式 + 特征独立假设 → 经典分类器 |
| 贝叶斯优化 | 用先验 + 观测数据 → 后验高斯过程 → 指导超参数搜索 |
| 变分推断 | 用简单分布近似复杂后验——VAE 的数学基础 |
