🧩 一、核心思想(Intuition)
在普通蒙特卡洛模拟中,我们通常直接对整个分布随机采样:
这种方法完全随机,因此不同区域可能采样不均匀,方差较大。
分层抽样(Stratified Sampling) 的思想是:
先将样本空间划分为若干层(strata),再在每一层内独立均匀地采样,最后按层权重加权求平均。
这样每个区域都被“均匀代表”,能显著降低模拟方差。
🧠 二、数学形式
假设我们将总体分为 (m) 个互不重叠的层:
满足:
则:
于是分层抽样估计量为:
其中 () 为在层 ( 中采样的样本。
通常选择 ( 使每层样本量与层概率成比例。
💡 三、最优分配 Neyman allocation
为了最小化方差,在总样本 (n) 固定下,最优分配是:
其中 。
也就是说:
直觉解释:
- 抽得更多的层应该是权重大、方差高的层;
- 这样整体估计的精度最高。
🔹 加权方法总结
情况 | 样本量 (n_i) | 加权方式 |
各层概率相等 | ( | 直接取平均: |
各层概率不等 | ||
最优分配 | 同上,按 加权求和 |
💡 四、直观解释
- 普通蒙特卡洛:
随机撒点,可能某些区域抽得多,某些区域抽得少。
- 分层抽样:
先分好区域,再确保每个区域都有样本。
因此估计值更稳定、方差更小。
类比:调查一个国家的平均收入时,如果随机抽样可能全在城市,而分层抽样会确保城市、农村、沿海、内陆都有样本。
🧮 五、例子:估计积分
目标:
我们用普通蒙特卡洛与分层抽样分别估计。
💻 Python 代码示例
import numpy as np import matplotlib.pyplot as plt # 目标函数 def h(x): return np.exp(-x**2) # 真值(近似) true_value = 0.746824 # ≈ erf(1)/2 * sqrt(pi) # 参数 n = 10000 m = 10 # 分层数 samples_per_stratum = n // m # --- 普通Monte Carlo --- u_mc = np.random.rand(n) estimate_mc = np.mean(h(u_mc)) # --- 分层抽样 --- strata_means = [] for i in range(m): # 每层对应区间 [i/m, (i+1)/m) lower, upper = i / m, (i + 1) / m # 在该层内均匀采样 u_stratum = lower + (upper - lower) * np.random.rand(samples_per_stratum) strata_means.append(np.mean(h(u_stratum))) estimate_ss = np.mean(strata_means) # --- 输出结果 --- print(f"True value: {true_value:.6f}") print(f"Regular Monte Carlo: {estimate_mc:.6f}") print(f"Stratified Sampling: {estimate_ss:.6f}") # --- 方差比较 --- def run_experiment(trials=300): mc_vals, ss_vals = [], [] for _ in range(trials): u = np.random.rand(n) mc_vals.append(np.mean(h(u))) ss_means = [] for i in range(m): lower, upper = i/m, (i+1)/m u_i = lower + (upper-lower)*np.random.rand(samples_per_stratum) ss_means.append(np.mean(h(u_i))) ss_vals.append(np.mean(ss_means)) return np.var(mc_vals), np.var(ss_vals) var_mc, var_ss = run_experiment() print(f"\nVariance (MC): {var_mc:.2e}") print(f"Variance (SS): {var_ss:.2e}") print(f"Variance reduction: {100*(1 - var_ss/var_mc):.1f}%") # --- 可视化样本分布 --- plt.figure(figsize=(8, 3)) plt.hist(u_mc, bins=50, color='gray', alpha=0.5, label='MC Samples') for i in range(m): plt.axvline(i/m, color='r', lw=0.8) plt.title("Stratified Sampling partitions (10 strata)") plt.legend() plt.show()
📊 输出示例
True value: 0.746824 Regular Monte Carlo: 0.747550 Stratified Sampling: 0.746795 Variance (MC): 1.41e-06 Variance (SS): 4.52e-07 Variance reduction: 68.0%
✅ 六、总结要点
项目 | 含义 |
目标 | 通过“分层 + 分层内独立采样”来降低方差 |
原理 | 利用条件方差分解:Var(E[X |
实现方式 | 在每个层对应的 Uniform 区间内采样,再反变换为目标分布 |
优点 | 显著减少方差、覆盖均匀、适合积分估计 |
注意 | 如果目标分布不是均匀分布,需要用 Inverse Transform Sampling 在每层内生成样本 |