WARNING
🧪 Beta公测版本提示:教程主体已完成,正在优化细节,欢迎大家提Issue反馈问题或建议。
ml10 蒙特卡洛方法 — demo.py 代码详解
运行方式
cd docs/ml/advanced/monte-carlo/code
python demo.py代码逐段详解
第1步:蒙特卡洛估计
def estimate_pi_mc(N=10000):
points = np.random.uniform(-1, 1, size=(N, 2)) # U(-1,1)^2 均匀采样
inside = (points[:, 0]**2 + points[:, 1]**2) <= 1 # 判断是否在单位圆内
pi_est = 4.0 * inside.sum() / N # π ≈ 4 × 比例数学原理:
这是一个从几何直觉到统计估计的优雅转换:单位圆的面积是
收敛性:右侧的收敛图展示了估计值随
第2步:重要性采样 —— 尾部概率估计
def importance_sampling_demo():
# 提议分布: N(5, 1)
samples_is = np.random.randn(N) + 5
# 重要性权重: p(x)/q(x) = phi(x) / phi(x-5)
log_weights = -0.5 * (samples_is**2 - (samples_is - 5)**2)
weights = np.exp(log_weights)
# 加权估计: (1/N) sum w(x_i) * I(x_i > 5)
is_estimates = np.cumsum(weights * (samples_is > 5)) / np.arange(1, N + 1)这是重要性采样最经典的演示案例。目标是估计
普通 MC 的灾难:从
重要性采样的解法:从
方差缩减:重要性采样的方差远小于普通 MC(在本次设置中通常缩减 100 倍以上)。
第3步:Metropolis-Hastings 采样
def metropolis_hastings(n_iter=5000, proposal_std=1.0):
for t in range(n_iter):
# 提议: x' ~ N(x_current, proposal_std^2 I)
x_proposal = x_current + rng.randn(d) * proposal_std
# 接受率: α = min(1, p(x')/p(x))
log_alpha = log_p_proposal - log_p_current
alpha = min(1.0, np.exp(log_alpha))
# 接受/拒绝
if rng.rand() < alpha:
x_current = x_proposalMH 算法的三个关键部分:
提议分布(Proposal):这里使用对称的随机游走提议
。因为是对称的( ),接受率简化为 。 接受率(Acceptance Ratio):
。如果新点概率更高( ), (总是接受,向高概率区域移动)。如果新点概率更低,以相应较小的概率接受(保证在低概率区域也能"逃离")。 细致平衡:接受/拒绝机制保证了
,从而目标分布是链的平稳分布。
提议标准差的选择:
第4步:Gibbs 采样二元正态
def gibbs_sampling_bivariate_normal(n_iter=5000, rho=0.8):
for t in range(n_iter):
# x1 | x2 ~ N(rho * x2, 1 - rho^2)
x1 = rng.normal(rho * x2, np.sqrt(1 - rho**2))
# x2 | x1 ~ N(rho * x1, 1 - rho^2)
x2 = rng.normal(rho * x1, np.sqrt(1 - rho**2))二元正态分布的 Gibbs 采样的优雅之处在于条件分布有解析形式:
注意:
- 接受率恒为 1(因为是直接从条件分布采样,MH 接受率
) - 当
接近 1 时(强相关),Gibbs 效率下降——因为每次只能沿坐标轴移动,在强相关的狭窄山谷中只能"之字形"爬行 - 自相关图(ACF)显示 Gibbs 产生的样本存在自相关性——lag 越大相关性越低,收敛到零。高自相关意味着有效样本量(ESS)远小于总迭代数
第5步:MCMC 诊断
代码中包含了几个关键的诊断工具:
- Trace Plot:展示采样值随迭代的变化,用于判断 burn-in 和链的混合
- 接受率时序:展示 MH 接受率的滑动平均,应在 0.2-0.5 之间稳定
- 自相关函数:展示样本间的相关性,显示 thinning 的必要性
- 有效样本量(ESS):
,量化了自相关造成的"样本浪费"
关键概念速查表
| 概念 | 数学形式 | 代码位置 | 关键说明 |
|---|---|---|---|
| MC 积分 | estimate_pi_mc() | 收敛率 | |
| 重要性采样 | importance_sampling_demo() | 减少方差的关键技术 | |
| MH 算法 | metropolis_hastings() | 提议 + 接受/拒绝 | |
| 细致平衡 | 隐含在接受率中 | 平稳分布的充分条件 | |
| Gibbs 采样 | $x_i \sim p(x_i | \mathbf{x}_{-i})$ | gibbs_sampling_*() |
| Burn-in | 丢弃前 N 个样本 | n_burnin 参数 | 避免初始值偏差 |
| ESS | ACF 计算 | 考虑自相关的有效样本数 |
源码位置
clone 后打开(相对仓库根目录):
docs/ml/advanced/monte-carlo/code/demo.py