10.5 马尔可夫链蒙特卡洛方法¶
前几节的例子很幸运:Beta-Binomial 和 Dirichlet-Multinomial 都能直接算出后验。但现实里,很多模型的后验没有漂亮公式。均哥带小率到夜晚的公园,用“在地图上走很多步”的方式讲 MCMC。
如果后验算不出来,那贝叶斯是不是就卡住了?
不一定要把整条后验公式算出来。MCMC 的想法是:从后验里抽很多样本,用样本描出它的形状。
10.5.1 MCMC 用很多相关样本描出后验¶
MCMC 是 Markov Chain Monte Carlo 的缩写。它由两部分组成:
- Markov Chain:下一步只依赖当前所在位置。
- Monte Carlo:用大量随机样本近似计算。
如果某个参数区域后验概率高,链就会更常停在那里;如果某个区域后验概率低,链也会偶尔经过,但停留较少。走得足够久以后,留下的点云就近似后验分布。
10.5.2 Metropolis 算法先提议再决定¶
最经典的 Metropolis 思路是:
- 从当前位置 \(\theta\) 出发。
- 随机提议一个新位置 \(\theta'\)。
- 比较新位置和旧位置的后验密度。
- 新位置更好就接受;更差也可能接受,只是概率较低。
- 重复很多次。
接受概率可以写成:
\[
\alpha=\min\left(1,\frac{p(\theta'\mid D)}{p(\theta\mid D)}\right)
\]
关键是:我们只需要后验密度的比例,不一定需要知道归一化常数。
为什么能绕开难积分
贝叶斯后验里的分母常常很难算。MCMC 比较两个位置的相对高低时,分母会相互抵消,因此可以不直接计算完整积分。
10.5.3 MCMC 样本不是独立样本¶
MCMC 生成的是一条链,相邻样本通常相关。所以诊断很重要:
| 诊断 | 看什么 |
|---|---|
| 轨迹图 | 链是否在稳定区域来回探索 |
| 自相关 | 相邻样本是否太像 |
| 有效样本量 | 相关样本相当于多少独立信息 |
| 多条链 | 不同起点是否收敛到同一后验 |
不要只看一条漂亮曲线
后验图看起来平滑,不代表采样可靠。链可能还没收敛,也可能只卡在一个局部区域。
10.5.4 HMC 和 NUTS 让现代贝叶斯更好用¶
简单随机游走在高维空间里会很慢。现代贝叶斯工具常用更聪明的采样器:
- HMC:Hamiltonian Monte Carlo,利用梯度信息在参数空间里走得更远。
- NUTS:No-U-Turn Sampler,自动决定每次走多远,避免来回折返。
- PyMC / Stan / NumPyro:常见的现代贝叶斯建模工具。
本书不要求你手写 NUTS,但要知道:复杂贝叶斯模型之所以能落地,离不开这些采样算法。
10.5.5 用 Python 写一个简化 Metropolis¶
配套脚本放在:
import numpy as np
from scipy import stats
rng = np.random.default_rng(42)
def log_posterior(p):
if p <= 0 or p >= 1:
return -np.inf
return stats.beta.logpdf(p, 8, 6)
samples = []
current = 0.5
for _ in range(20_000):
proposal = current + rng.normal(0, 0.06)
log_accept = log_posterior(proposal) - log_posterior(current)
if np.log(rng.random()) < log_accept:
current = proposal
samples.append(current)
samples = np.array(samples[2_000:])
print(f"样本均值: {samples.mean():.3f}")
print("95% 区间:", np.quantile(samples, [0.025, 0.975]))
所以 MCMC 不是把公式解出来,而是让点按照后验形状分布起来。
对。它用“走很多步”换掉了“算一个难积分”。
小率的笔记本
MCMC 用马尔可夫链产生大量样本,让样本的分布近似目标后验。它的优势是绕开难积分,代价是样本相关、需要诊断收敛。复杂贝叶斯模型常依赖 HMC、NUTS 等现代采样器。

