🎓 レベル:基礎 | 重要度:A(必須)
📎 前提:擬似乱数(線形合同法・メルセンヌツイスタ) | 関連:棄却法(受理・棄却サンプリング)
要点(BLUF)
- 逆関数法:一様乱数 を、目的分布の累積分布関数 の逆関数に通すと、 が目的分布に従います。
- 仕組みは「確率積分変換」—— が一様分布になることの逆を使うだけ。 が閉形式で書ければ最速・最も無駄のない変換です。
- 指数分布 と離散分布(イカサマサイコロ)の両方で、理論値と一致することを確かめます。
1. 原理:確率積分変換
連続な累積分布関数(CDF) を持つ確率変数 について、 は に従います(確率積分変換)。これを逆に使うのが逆関数法です。
とし、 と定義すると、
最後の等号は が一様だから()。つまり の CDF はちょうど になり、 は目的の分布に従います。手順は2ステップだけ:
- を引く
- を返す
flowchart LR
U["一様乱数 U ~ U(0,1)"] -->|"X = Finv(U)"| X["目的分布のサンプル X"]
2. 連続分布の例:指数分布
指数分布 の CDF は 。これを について解くと逆関数が得られます。
import numpy as np
# 乱数シードを固定
rng = np.random.default_rng(2)
lam = 1.5
u = rng.random(500_000) # 一様乱数
x = -np.log(1 - u) / lam # 指数分布の逆関数 Finv(u)
print(f"逆関数法 Exp の平均 = {x.mean():.4f} (理論 {1/lam:.4f})")
print(f"逆関数法 Exp の分散 = {x.var():.4f} (理論 {1/lam**2:.4f})")
出力:
逆関数法 Exp の平均 = 0.6669 (理論 0.6667)
逆関数法 Exp の分散 = 0.4432 (理論 0.4444)
出力の意味:一様乱数を に通すだけで、平均 0.6669・分散 0.4432 が指数分布の理論値 ・ と一致。CDF の逆が解析的に書けるので、棄却もループも要らず1サンプルにつき一様乱数1個で済む——これが逆関数法の効率です。(実装では も も同分布なので -np.log(u)/lam でも可。)
3. 離散分布の例:イカサマサイコロ
離散分布でも、CDF を階段関数として「累積確率を超える最初の値」を返せば逆関数法になります。確率 のサイコロを作ります。
import numpy as np
# 乱数シードを固定
rng = np.random.default_rng(3)
p = np.array([0.1, 0.2, 0.3, 0.15, 0.15, 0.1])
cdf = np.cumsum(p) # 累積確率(階段)
u = rng.random(300_000)
faces = np.searchsorted(cdf, u) + 1 # u が入る区間 = 目の値
freq = np.bincount(faces, minlength=7)[1:] / len(u)
print(f"生成された頻度 = {np.round(freq, 3)}")
print(f"目標の確率 = {p}")
出力:
生成された頻度 = [0.1 0.199 0.301 0.15 0.15 0.1 ]
目標の確率 = [0.1 0.2 0.3 0.15 0.15 0.1 ]
出力の意味:searchsorted で「一様乱数が累積確率のどの段に落ちるか」を引くだけで、生成頻度が目標確率と小数3桁まで一致。離散版の逆関数法は、各カテゴリの確率を区間幅として を分割し、一様乱数がどの区間に落ちたかで分類する操作です。
4. 長所と限界
- 長所: が書ければ最速。1サンプル=一様乱数1個で無駄がなく、準モンテカルロの低食い違い列とも相性が良い(一様点を素直に変換できる)。
- 限界: が閉形式で書けない分布(標準正規など)には直接使えない。CDF はあっても逆が初等関数で表せないことが多い。その場合は変数変換(Box–Muller)や棄却法(棄却法(受理・棄却サンプリング))に頼ります。
数式の直観的意味
逆関数法は「確率の目盛り()を、値の目盛り()に翻訳する」操作です。CDF は「値 → 累積確率」、その逆 は「累積確率 → 値」。一様乱数で累積確率を等確率に選べば、 が確率密度の高いところを密に、低いところを疎に値へ割り当てる——だから自然に目的分布が再現されます。離散版で確率を区間幅にするのも、まったく同じ「確率を値に翻訳する」発想です。
⚠️ よくある誤解・落とし穴
- 「どんな分布も逆関数法で作れる」ではない: が閉形式で書けないと使えません(正規分布が典型)。数値的に逆を解く手はありますが高コスト。
- 「 と で結果が変わる」ではない:どちらも なので同分布。
-log(1-u)も-log(u)も正しい。 - 「離散も連続と同じ式」ではない:離散では一般化逆 (累積を超える最初の値)を使います。
searchsortedがこれです。 - 「CDF があれば常に高速」ではない:CDF はあっても逆が数値計算でしか出せないなら、棄却法の方が速いこともあります。
対応シミュレーション参照
本文の指数分布(連続)・イカサマサイコロ(離散)の逆関数法コード(default_rng(2) と default_rng(3))。
関連ノート
- 擬似乱数(線形合同法・メルセンヌツイスタ)(前提・元になる一様乱数)
- 棄却法(受理・棄却サンプリング)(次のトピック・逆関数が書けない場合)
- 合成法・変数変換法(正規分布の生成)
- 代表的分布の生成(正規・指数・ポアソン)(実用ライブラリ)
- 第2章 乱数生成 目次
- シミュレーション・モンテカルロ法 全体目次