Mímisbrunnr知恵の泉

← シミュレーション 一覧

🎓 レベル:標準 | 重要度:A(必須)

📎 前提:対照変量法(アンチセティック) | 関連:層化サンプリング

要点(BLUF)

1. アイデア:既知の答えで答え合わせ

推定したいのは θ=E[f(X)]\theta = E[f(X)]。ここで、ff と相関し期待値 E[c]=μcE[c] = \mu_c が分かっている別の関数 c(X)c(X) があるとします。新しい推定量を

θ^cv=1ni=1n(f(Xi)b(c(Xi)μc))\hat{\theta}_{\text{cv}} = \frac{1}{n}\sum_{i=1}^n \Big( f(X_i) - b\,(c(X_i) - \mu_c) \Big)

と作ります。E[c(X)μc]=0E[c(X) - \mu_c] = 0 なので、どんな係数 bb でも E[θ^cv]=θE[\hat{\theta}_{\text{cv}}] = \theta不偏)。狙いは「cc の標本平均が μc\mu_c からどれだけずれたか」を見て、ff の推定の同じ向きのずれを差し引くことです。ffcc が強く相関していれば、cc のずれは ff のずれの良い予測子になり、誤差が消えます。

2. 最適係数と分散

θ^cv\hat{\theta}_{\text{cv}} の分散は bb の2次式で、最小化すると

b\*=Cov(f,c)Var(c),Var(θ^cv)=Var(f)(1ρ2)b^\* = \frac{\text{Cov}(f, c)}{\text{Var}(c)},\qquad \text{Var}(\hat{\theta}_{\text{cv}}) = \text{Var}(f)\,(1 - \rho^2)

ここで ρ=Corr(f,c)\rho = \text{Corr}(f, c)分散は (1ρ2)(1-\rho^2)になります。ρ=0.99\rho = 0.99 なら 1ρ2=0.01991-\rho^2 = 0.0199、すなわち約50倍の改善。b\*b^\*ffcc に回帰したときの傾きそのもので、制御変量法は「ff から、cc で線形に説明できる部分を取り除く」回帰だと見られます。実務では b\*b^\* を標本から推定します(わずかなバイアスが入るが nn 大で無視可能)。

3. 実測

01exdx\int_0^1 e^x dxf=eUf = e^U)の制御変量に c=Uc = U(期待値 μc=0.5\mu_c = 0.5)を使います。eUe^UUU はどちらも単調増加で強く相関します。

import numpy as np

# 乱数シードを固定
rng = np.random.default_rng(31)
n = 100_000
reps = 2000

def plain(rng):
    u = rng.random(n)
    return np.exp(u).mean()

def control_variate(rng):
    u = rng.random(n)
    f = np.exp(u)
    c = u                                 # 制御変量(期待値0.5)
    b = np.cov(f, c)[0,1] / c.var()       # 最適係数 b* を標本推定
    return (f - b*(c - 0.5)).mean()

p_ests = np.array([plain(rng) for _ in range(reps)])
c_ests = np.array([control_variate(rng) for _ in range(reps)])

print(f"プレーン   平均={p_ests.mean():.5f}  分散={p_ests.var():.2e}")
print(f"制御変量   平均={c_ests.mean():.5f}  分散={c_ests.var():.2e}")
print(f"分散減少率 = {p_ests.var()/c_ests.var():.2f} 倍")

u = rng.random(500_000)
print(f"corr(e^U, U) = {np.corrcoef(np.exp(u), u)[0,1]:.4f}")

出力:

プレーン   平均=1.71830  分散=2.38e-06
制御変量   平均=1.71828  分散=4.34e-08
分散減少率 = 54.82 倍
corr(e^U, U) = 0.9918

出力の意味:両者とも真値 1.71828 を不偏に推定しつつ、分散はプレーン 2.38×1062.38\times10^{-6} に対し制御変量 4.34×1084.34\times10^{-8}約55倍減。理論の 1/(1ρ2)=1/(10.99182)=611/(1-\rho^2) = 1/(1-0.9918^2) = 61 にほぼ届きます(b\*b^\* を標本推定したぶん少し届かない)。相関 0.99 という強い線形関係が効いています。

4. 制御変量の選び方

数式の直観的意味

制御変量は「カンニングできる似た問題で答え合わせをする」発想です。cc は答え(μc\mu_c)が分かっている問題。同じ乱数でそれを解いてみて、μc\mu_c から Δ\Delta ずれていたら、相関する本命 ff もおおよそ b\*Δb^\*\Delta ずれているはず——だから差し引く。(1ρ2)(1-\rho^2) は回帰の「説明できなかった残差の割合」そのもので、相関が強いほど残差が小さく、分散が消えます。対照変量(対照変量法(アンチセティック))が「入力に負相関ペアを仕込む」のに対し、制御変量は「既知の答えを持つ相棒で補正する」——どちらも相関を使う点は共通です。

⚠️ よくある誤解・落とし穴

対応シミュレーション参照

本文の制御変量(default_rng(31)、55倍減、c=Uc=U)。

関連ノート