密度が計算できてもサンプリングできない:MCMCを自作した記録【番外編】

はじめに

第33回でベイズ法を扱ったとき、MCMC(Markov Chain Monte Carlo=マルコフ連鎖モンテカルロ法)の考え方を追いました。ただ、あのときはアルゴリズムを読んだだけでした。

そこで練習用のプロジェクトを作り、メトロポリス法の中核だけを自分で書くという課題をやりました。目標分布・診断図・簡易チェックは用意済みで、自分が書くのは受理判定のループだけ、という形です。

書き終えて分かったのは、自分がいちばん誤解していたのはアルゴリズムではなく「MCMCが何のための道具か」だったということです。とくに次の2つを混同していました。

  • 確率密度を点ごとに計算できること
  • その分布から標本を生成できること

この2つはまったく別です。そして、この区別が付いていなかったので「解析的に解ける正規分布に、なぜわざわざMCMCを使うのか」がずっと引っかかっていました。

なお用語について1つ。第33回では「受容」「受容率」と書きましたが、この記事では実装のコードに合わせて「受理」「受理率」で統一します。同じものです。

この記事は、その引っかかりを実装と数値で解いた記録です。ベイズの理屈やギブスサンプリング、R^\hat{R} による収束判定は第33回、逆関数法・棄却法・重点サンプリングそのものは第34回で扱ったので、ここでは重複を避けて「使い分け」に絞ります。

結論を先に3つ

① MCMCは確率密度関数を発見する方法ではありません。 目標分布に従う、互いに相関のある標本を生成する方法です。密度の式は最初から手元にあります(なければMCMCも動きません)。

② 目標分布から独立な標本を直接生成できるなら、通常は直接モンテカルロのほうが簡単で効率的です。 後で数値を出しますが、同じ標本数でも実質の情報量が20分の1近く違いました。

③ MCMCの利点は、正規化定数が分からなくても、正規化前の密度の相対値を評価できれば使えることです。 ベイズの事後分布がまさにその形をしています。(ただしこの性質自体はMCMC固有ではありません。後で触れます。)

以下、この3点を実装と数値で確かめていきます。

この記事で扱う用語

用語意味
目標分布 p(x)p(x)標本を得たい分布。この記事では正規分布と、ロジスティック回帰の事後分布
正規化定数 ZZ密度の積分を1にするための割り算の定数。多次元では多重積分になる
正規化前の密度ZZ で割る前の値。p(x)p(x) に比例する量。相対値だけが分かる
エネルギー関数 S(x)S(x)p(x)exp(S(x))p(x) \propto \exp(-S(x)) と書いたときの SSS=logp+定数S = -\log p + \text{定数}
提案分布 q(xnewx)q(x_{\text{new}} \mid x)次の候補をどこから引くかを決める分布。目標分布とは別物
ランダムウォーク・メトロポリス法提案分布に「現在位置を中心とする正規分布」を使う MCMC
受理比候補を採るかどうかを決める比。p(xnew)/p(x)p(x_{\text{new}}) / p(x)(対称提案のとき。一般形は本文で述べます)
burn-inチェーンの最初のほうを捨てる区間。初期値の影響を落とすため
自己相関標本が何歩前の自分と似ているか。MCMC標本は独立ではない
ESS(Effective Sample Size=有効サンプルサイズ)相関を考慮した「実質の標本数」
ランニング平均先頭から kk 個までの平均を kk の関数として描いたもの
受理率候補が採用された割合。高ければ良いというものではない

密度を評価できることと、サンプリングできることは別

まず、この記事の出発点になった混同をはっきりさせます。

「密度を評価できる」とは、xx を1つ渡せば p(x)p(x)(または正規化前の値)を計算して返せる、ということです。 関数に代入するだけなので、式が書けていれば必ずできます。

「サンプリングできる」とは、その分布に従う値を1つ生成できる、ということです。 これは代入では作れません。乱数の生成器が必要です。

密度を評価するサンプリングする
入力xx(知りたい点)一様乱数
出力数値 p(x)p(x)分布に従う値 xx
難しさ式に代入するだけ分布ごとに専用の仕掛けが必要
ベイズの事後分布ではできる(尤度 × 事前分布)一般にできない

ベイズの事後分布は、この表の右下に落ちます。 尤度と事前分布を掛ければ任意のパラメータ値での「もっともらしさ」は計算できます。しかし「事後分布から1個引く」ための専用の乱数生成器は、一般には存在しません。

MCMCはこの穴を埋める道具です。評価はできるがサンプリングできない分布から、標本を作る。

通常のモンテカルロ法・重点サンプリング・MCMCの違い

3つを並べて整理します。重点サンプリングはMCMCの一種ではありません。 別系統の手法です。

① 通常のモンテカルロ法② 重点サンプリング③ MCMC
標本をどこから生成するか目標分布そのものから自分で選んだ提案分布から提案分布で候補を作り、受理判定を通したものを鎖としてつなぐ
標本は独立か独立独立独立でない(前の値と相関する)
標本ごとの重みがあるかないあるp/qp/qない(重みなしだが相関あり)
必要な情報目標分布からの乱数生成器正規化前の ppqq の値、提案分布からの生成器正規化前の pp の値、提案分布からの生成器
正規化定数 ZZ生成器の中で解決済み自己正規化すれば不要不要
得意な問題直接引ける分布提案分布が目標に近く、まれな事象を狙うとき直接引けず、次元が高いとき
主な失敗要因生成器が作れない重みが1個のサンプルに集中する(次元が上がると起きる)混ざりが遅い、鎖が動かない、収束前に打ち切る

ZZ の行に注意が必要です。「正規化定数が不要」はMCMC固有の性質ではありません。 自己正規化した重点サンプリング(重みを合計1に直す形)も ZZ を必要としません。だから両者の本当の分かれ目は ZZ ではなく、重みが壊れるかどうかでした。

同じ推定対象を3手法で

目標分布を N(2,1.52)N(2, 1.5^2) とし、E[X]E[X](真値 2.0)を推定します。標本数はすべて 9000 に揃えました。

手法推定値実質の標本数標準誤差
① 直接モンテカルロ(目標分布から独立に生成)1.97259000(= nn0.0157
② 自己正規化重点サンプリング(提案 N(0,32)N(0, 3^2)1.97134571nn の 50.8%)0.0222(近似)
③ MCMC(自作のランダムウォーク・メトロポリス法、提案幅 1.0)2.0490526nn の 5.8%)0.0691

②の標準誤差は自己正規化のため近似値です。中身は「重み付き分散 ÷ 重みのESS」の平方根で、デルタ法の簡略形にあたります。①③は通常の標準誤差です。

この1次元の問題では ① が圧勝です。 同じ9000標本でも、実質の情報量が 9000 対 4571 対 526。目標分布から直接引けるなら、MCMCを使う理由はありません。

では差はどこで出るのか

同じ形の問題を dd 次元にします。目標を N(21,1.52I)N(2\mathbf{1}, 1.5^2 I)、重点サンプリングの提案を N(0,32I)N(0, 3^2 I) とすると、重みは各座標の比の積になります。

次元 dd重みのESS ÷ nn(重点サンプリング)最大の重みが占める割合MCMCのESS ÷ nn
10.51690.00010.1770
20.26610.00040.1056
50.03590.00650.0384
100.00190.10160.0287
200.00060.18380.0143
500.00010.73370.0055

(重点サンプリング側の分母は2万、MCMC側は burn-in 2000 を落とした1万8000です。)

d=50d = 50 では、2万個引いた重みのうち1個が全体の73%を占めます。 残りの 19,999 個を全部合わせても 27% ほどで、重みのESSは実質2個分(0.0001×200000.0001 \times 20000)しかありません。重点サンプリングは次元とともにこう壊れます。一方MCMCのESS比はゆるやかに下がるだけです。

(MCMCの側は提案幅を 2.4/d2.4/\sqrt{d} で調整しています。表の d=1d=1 の値 0.1770(17.70%)が、さきほどの3手法比較で出た 5.8% と違うのは提案幅が 2.4 と 1.0 で違うためです。
なお理論的な目安は 2.38σ/d2.38\,\sigma/\sqrt{d} で、σ=1.5\sigma = 1.5 なら d=1d=1 で約 3.6 になります。ここでは σ\sigma を掛けずに使ったので最適よりやや狭く、17.70% は後で出てくる最良の 22.02% に届いていません。なお2つは鎖の長さが違うので、厳密な比較ではなく目安の比較です。)

これが使い分けの分かれ目でした。 重点サンプリングとMCMCの違いは「ZZ が要るかどうか」ではなく、「重みで補正するか、受理判定で補正するか」の違いで、後者のほうが次元に強い。


なぜ既知の正規分布を教材にするのか

練習用プロジェクトの目標分布はこうなっています。

Target: Normal(mean=2.0, std=1.5)
log_target(x) = -0.5 * ((x - 2.0) / 1.5)^2

正規分布なら直接サンプリングできますし、平均も標準偏差も解析的に分かっています。 つまり実用上、この分布にMCMCを使う必要はまったくありません。

それでも教材にする理由は1つです。答えが分かっているので、実装が正しいかを確かめられる。

実際に、用意されていた簡易チェック(check_sampler.py)は次を検査します。

標本平均:   1.9811(理論値 2.0000)
標本標準偏差: 1.5147(理論値 1.5000)
受理率:     79.9%
OK: 平均
OK: 標準偏差
OK: 受理率
OK: チェーンが動いている

すべての簡易チェックを通過しました。

答えの無い分布で書いたら、この4行が出せません。「正しく動いているか分からないアルゴリズム」を書いてしまうのがいちばん怖いので、最初は答えのある分布で書くというのが教材の意図でした。

p(x)p(x)S(x)S(x)logp(x)\log p(x) の対応

ここで用語を1つ整理しておきます。物理由来の書き方で、目標分布を次の形に書くことがあります。

p(x)exp(S(x))p(x) \propto \exp\left(-S(x)\right)

この S(x)S(x) をエネルギー関数と呼びます。両辺の対数を取ると、

logp(x)=S(x)+定数\log p(x) = -S(x) + \text{定数}

つまり S(x)=logp(x)+定数S(x) = -\log p(x) + \text{定数} と置いただけで、特別な仮定は入っていません。正規分布なら

S(x)=12(x2.01.5)2logp(x)=S(x)logZ,Z=1.52π=3.7599424119\begin{aligned} S(x) &= \frac{1}{2}\left(\frac{x - 2.0}{1.5}\right)^2 \\ \log p(x) &= -S(x) - \log Z, \qquad Z = 1.5\sqrt{2\pi} = 3.7599424119 \end{aligned}

です。ZZ が正規化定数で、p=1\int p = 1 にするための割り算の分母です。

3パネルの図。左は正規化済み密度 p(x) の青い実線と exp(-S(x)) の赤い破線を重ねたもので、赤は最大値1、青は最大値0.266。縦の縮尺が Z=3.7599 倍違うだけで形は同じと注釈されている。中央はエネルギー S(x) の緑の放物線で、x=2.0 で最小値0を取り、そこが密度最大の点だと注釈されている。右は対数密度で、-S(x) の紫の実線と正規化済み log p(x) の橙の破線が上下に平行に並び、差は定数 -log Z = -1.3244 だと注釈されている

3枚とも同じ分布を描いています。左は縦の縮尺が ZZ 倍違うだけ、右は上下に logZ\log Z だけ平行移動しているだけです。

数値で確かめます。

xxS(x)S(x)log_target(x)exp(S(x))\exp(-S(x))正規化済み p(x)p(x)exp(S)/Z\exp(-S)/Z と一致するか
2.00.00000−0.000001.0000000.265962一致
0.50.50000−0.500000.6065310.161314一致
−1.02.00000−2.000000.1353350.035994一致
3.50.50000−0.500000.6065310.161314一致
5.02.00000−2.000000.1353350.035994一致

密度では「比」、エネルギーと対数密度では「差」

ここが実装で間違えやすいところです。受理判定に使うのはです。

p(xnew)p(x)=exp(S(xnew))/Zexp(S(x))/Z=exp(S(x)S(xnew))\frac{p(x_{\text{new}})}{p(x)} = \frac{\exp(-S(x_{\text{new}}))/Z}{\exp(-S(x))/Z} = \exp\left(S(x) - S(x_{\text{new}})\right)

ZZ が約分されて消えます。 そして指数の中は SSです。3通りの移動で確かめました。

現在 → 候補S(現在)S(\text{現在})S(候補)S(\text{候補})受理確率密度の比で検算参考:差 p(候補)p(現在)p(\text{候補}) - p(\text{現在})
0.5 → 1.50.500000.055560.444441.0000001.5596230.090275
0.5 → −1.00.500002.00000−1.500000.2231300.223130−0.125320
−1.0 → 2.02.000000.000002.000001.0000007.3890560.229968

読み取れることが3つあります。

  • 密度が上がる移動(SS が下がる移動)は比が1以上になり、必ず受理されます。 1行目と3行目です
  • 密度が下がる移動でも、比の分だけの確率で受理されます。2行目は 22.3% で受理
  • 右端の「差」の列は受理判定に使いません。 p(xnew)p(x)p(x_{\text{new}}) - p(x)ZZ が約分されないので、正規化定数が必要になってしまいます

確率密度そのものでは「比」を取り、エネルギーまたは対数密度では「差」を取る。 これが対応関係です。実装では対数で持って差を取るので、桁溢れも起きません。


ランダムウォーク・メトロポリス法:自分で書いた部分

私が書いたのは次の5ステップだけです。目標分布・診断図・チェックは用意されていました。

current = initial_state
current_log_density = log_target(current)

for i in range(n_samples):
    dx = rng.normal(loc=0.0, scale=proposal_std)   # 対称な正規ランダムウォーク
    candidate = current + dx
    candidate_log_density = log_target(candidate)

    log_alpha = candidate_log_density - current_log_density   # 対数受理比

    r = rng.random()
    if min(0.0, log_alpha) > np.log(r):             # log(U) < min(0, log_alpha)
        accepted_count += 1
        current = candidate
        current_log_density = candidate_log_density

    samples[i] = current      # 受理・棄却にかかわらず、現在の状態を保存する

書いてみて引っかかった点が3つありました。

① 棄却したときも標本に記録する。 ここを「受理したときだけ記録」にすると別の分布になります。棄却は「同じ場所にもう1歩ぶんの滞在時間を与える」という意味を持っているので、記録しないと滞在時間の情報が消えます。

② 比較は対数で行う。 α=exp(logα)\alpha = \exp(\log\alpha) を計算して U<αU < \alpha と比べても数学的には同じですが、logα\log\alpha が大きな負の数のとき exp\exp が 0 に潰れます。logU<min(0,logα)\log U < \min(0, \log\alpha) の形なら潰れません。

min(0, ...) は要るのか。 受理確率は min(1,α)\min(1, \alpha) なので、対数では min(0,logα)\min(0, \log\alpha) です。logU\log U は必ず負なので、logα>0\log\alpha > 0 のときは min\min を取らなくても常に受理されます。つまり結果は同じですが、式が受理確率の定義と1対1に対応しているので付けたままにしました。

対称な提案分布だから Hastings 補正が消えている

一般のメトロポリス–ヘイスティングス法の受理確率は次の形です。

α=min(1,  p(xnew)p(x)q(xxnew)q(xnewx))\alpha = \min\left(1,\; \frac{p(x_{\text{new}})}{p(x)} \cdot \frac{q(x \mid x_{\text{new}})}{q(x_{\text{new}} \mid x)}\right)

右側の分数が Hastings 補正です。今回の提案分布は「現在位置を中心とする正規分布」なので対称で、

q(xxnew)=q(xnewx)q(x \mid x_{\text{new}}) = q(x_{\text{new}} \mid x)

が成り立ちます。だから補正が1になって消え、古典的なメトロポリス法(Metropolis et al. 1953)の形になります。

非対称な提案を使うときは補正が必要です。 たとえば正の値しか取らないパラメータに対して対数正規の提案を使う場合や、現在位置に応じて提案の幅を変える場合です。補正を忘れると別の分布に収束します。しかも「動いてはいる」ので、気づきにくい。

なお、対称性は必須条件ではありません。目標分布を不変分布にするための十分条件は詳細釣り合いで、「対称な提案+メトロポリスの受理則」はそれを満たす組み合わせの一例にすぎません。 詳細釣り合いを満たすのは提案分布単体ではなく、提案と受理則を合わせた遷移全体です。詳細釣り合いそのものは第33回で扱ったので、ここでは深追いしません。

提案分布を変えても同じ分布に収束するのはなぜか

これも引っかかった点でした。提案分布はまったく違うものを使えるのに、なぜ同じ目標分布に行き着くのか。

理由は、提案分布は「どこを次に見るか」しか決めておらず、「そこに留まる割合」は受理判定が決めているからです。受理確率に pp の比が入っているので、最終的な滞在時間の比が pp の比に一致します。提案分布は探索の効率だけを変えます。

ただし無条件ではありません。次の条件が必要です。

条件意味破ると何が起きるか
正しい受理確率提案が非対称なら Hastings 補正を入れる別の分布に収束する
既約性正の確率を持つどの領域へも(有限歩で)到達できる分布の一部に到達できず、その領域が欠ける
非周期性決まった周期で同じ場所に戻る構造がないnn 歩目の分布が1つに落ち着かない(時間平均は収束するが、任意の時点の分布としては使えない)

ランダムウォーク・メトロポリス法では、提案が全域に正の密度を持つ正規分布なので既約性と非周期性は自動的に満たされます。だから実務で気をつけるのは1行目、受理確率を正しく書くことだけになります。


診断図の読み方

固定シードで実行した結果を見ます。設定は --samples 10000 --burn-in 1000 --proposal-std 1.0 --seed 42(初期値 0)です。

4パネルの診断図。左上はburn-in後9000標本のヒストグラム(緑)と理論密度N(2, 1.5²)の赤い曲線が重なっている。右上はトレースプロットで、初期値0から数十歩で目標付近へ上がり、以後2付近を上下しており、burn-in の終わり1000に赤い縦破線が入っている。左下は自己相関で lag1 が 0.8779、0.05 を下回るのは lag 26、ESS は 526(9000標本の5.8%)と注釈されている。右下はランニング平均で、理論平均2.0の赤い破線と±0.05の帯に対し、144標本目で一度帯に入るが8451標本目まで出入りを繰り返すと注釈されている。図全体の見出しは「自作 Metropolis 法の診断(提案幅 1.0・受理率 79.5%・seed 42)」

4枚それぞれの読み方を書きます。

① ヒストグラムと理論密度

見るのは「形が合っているか」だけです。 ここが合っていなければ実装が間違っています。合っていても収束の証明にはなりません(後述)。

確かめた量burn-in後 9000 標本理論値
平均2.04902.0000
標準偏差1.58371.5000

② トレースプロット

縦軸が状態、横軸が反復回数です。 見るポイントは3つ。

  • 初期値からの立ち上がり:0 から始めて、最初の20歩は 0.305, 1.055, 1.055, 1.183, 1.166, 2.046, … と目標付近へ上がっていきます。同じ値が2回続いているところ(1.055 が2回)は棄却された歩です
  • 同じ場所に長く留まっていないか:水平な線が長く続くのは棄却が連続しているサインです
  • 帯の太さが一定か:途中で急に幅が変わるなら、分布の別の領域に移った可能性があります

赤い縦破線が burn-in の終わりですが、これはグラフから自動検出した値ではありません。 コマンドラインで --burn-in 1000 と指定した値をそのまま描いているだけです。この実装に自動判定は入っていません。

③ 自己相関

MCMC標本は独立ではありません。 ここが通常のモンテカルロ法との最大の実務的な違いです。

lag 1 の自己相関は 0.8779。1歩前の自分と 88% 相関しています。0.05 を下回るのは lag 26 で、26歩離れてようやく「ほぼ無関係」になります。

これを1つの数にまとめたのがESSです。

ESS=n1+2k1ρk\text{ESS} = \frac{n}{1 + 2\sum_{k \ge 1} \rho_k}

ρk\rho_k が lag kk の自己相関です。自己相関が全部 0 なら ESS =n= n。相関が強いほど小さくなります。今回は ESS = 526、つまり9000標本が実質526個分の情報しかありませんでした。

(無限和は打ち切る必要があります。この記事では Geyer (1992) の「連続する2つの自己相関の和が負になったら止める」という方式を使っています。)

ESSが分かると平均のズレが解釈できます。 モンテカルロ標準誤差は標準偏差 ÷ ESS\sqrt{\text{ESS}} なので、1.5837/526=0.06911.5837 / \sqrt{526} = 0.0691。実測の平均 2.0490 は理論値から 0.0490 離れていますが、これは 0.71 標準誤差ぶんです。偏りではなく誤差の範囲でした。

④ ランニング平均

先頭から kk 個までの平均を kk の関数として描いたものです。理論平均 2.0 に近づいていく様子が見えます。

ただし、ここが最も誤解しやすい図です。 ランニング平均が横ばいになっても、それは収束の証明になりません。実測すると、±0.05\pm 0.05 の帯に

  • はじめて入るのは 144 標本目
  • それ以降ずっと帯の中に留まるのは 8451 標本目

でした。144 標本目のグラフを見て「安定した」と判断すると間違えます。横ばいに見えるのは、単に分母が大きくなって新しい標本の影響が薄まっているからでもあります。

受理率

今回は 79.5% でした。4枚のパネルには出ませんが、図全体の見出しに表示されています。この数字の読み方は次の節でまとめます。

実務での収束判定

この記事の診断(1本の鎖のトレース・自己相関・ランニング平均)は、どれも「明らかに壊れている」ことを見つける道具です。 「収束した」ことの証明にはなりません。

実務では次を併用します。

道具何を見るか
複数の鎖を別の初期値から走らせる別々の場所に落ち着いていないか(1本では絶対に分からない)
R^\hat{R}(Gelman–Rubin の収束診断とその改良版)鎖の間のばらつきと鎖の中のばらつきの比。1に近いか
ESS推定に使える実質の標本数が足りているか

R^\hat{R}第33回で扱いました。今回のプロジェクトは1本の鎖しか走らせないので、原理的に R^\hat{R} が計算できません。 そこは教材の範囲外だと理解しておく必要があります。


提案幅を変えると何が変わるのか

同じ目標分布・同じシード・同じ標本数で、提案分布の標準偏差だけを変えます。

上下2段・左右4列の図。上段は提案幅0.2, 1.0, 3.0, 10.0 の最初の2000歩のトレース。0.2 はゆっくり漂うだけで全域を回りきれず、10.0 は水平な段差が目立つ。下段は同じ4条件の自己相関で、0.2 は lag100 でも0.4以上、3.0 は lag10 付近で0に落ちる。各パネルの見出しに受理率(95.8%, 79.5%, 49.8%, 18.0%)と lag1 の自己相関・ESSが表示されている。図全体の見出しは「提案幅だけを変えた4本のチェーン(seed 42・n=10000・burn-in 1000 は共通)/受理率が最も高い 0.2 が最悪で、ESS が最大なのは受理率 49.8% の 3.0」

提案幅受理率burn-in後の平均同 標準偏差lag1 の自己相関ESSESS ÷ 標本数
0.295.8%2.20241.55170.992132.10.4%
1.079.5%2.04901.58370.8779525.75.8%
3.049.8%2.01871.49440.64961800.020.0%
10.018.0%2.00151.43240.77531071.011.9%
理論値2.00001.5000

(上の図の見出しには「ESSが最大なのは 3.0」と書いてありますが、これは1万標本での比較です。あとでもっと細かく探すと 3.5 が最良になります。)

受理率が最も高い 0.2 が、いちばん効率が悪いです。 ESSが 32 しかありません。9000歩使って実質32個分。

理由はトレースを見れば分かります。提案幅 0.2 では、ほとんどの候補が受理されるかわりに、1歩で 0.2 程度しか動きません。 ゆっくり漂うだけで、2000歩でも分布の全域を回りきれない。「受理された」のと「進んだ」のは別です。

逆に提案幅 10.0 では、82% の反復が棄却されます。棄却は「同じ場所で足踏み」なので、これも効率を落とします。

つまり効率には山があります。 もっと細かく探しました(10万標本)。

提案幅受理率ESSESS ÷ 標本数
0.589.6%2168.12.41%
1.079.5%6194.06.88%
2.062.4%14115.815.68%
3.049.9%19428.221.59%
3.545.0%19819.022.02%
4.040.9%19694.021.88%
6.029.4%16729.918.59%
10.018.3%11398.912.67%
15.012.5%7889.68.77%

この1次元の問題では、提案幅 3.5(受理率 45.0%)が最良でした。 目標分布の標準偏差 1.5 に対して 2.33 倍です。

高次元では漸近的に最適な受理率が 0.234 であることが知られています(Roberts, Gelman & Gilks 1997)。この実測はそれよりずっと高い受理率で最良になりました。 ただしこれは理論と食い違っているわけではありません。1次元での最適な受理率は約 0.44 とされており(Roberts & Rosenthal 2001)、実測の 45.0% はそちらとよく一致しています。

つまり「受理率を 0.234 に合わせる」は高次元での目安で、低次元ではもっと高いほうが良い。 どちらにしても受理率だけを見て調整せず、ESSで比べるのが確実です。

極限の分布は変わらない

「提案幅で結果が変わるなら、正しい分布に収束していないのでは」と思うかもしれません。標本数を10倍にして確かめました。

提案幅受理率平均標準偏差ESS
0.296.0%1.99031.4463431.7
1.079.5%1.97481.51456194.0
3.049.9%1.98951.504819428.2
10.018.3%1.98201.495111398.9

どの提案幅でも平均が 2.0 に、標準偏差が 1.5 に近づきます。 提案分布は極限の目標分布を変えません。変えるのは有限標本での探索効率だけです。

さらに、1万標本のときの平均のズレも誤差として説明できます。

提案幅平均理論との差ESSモンテカルロ標準誤差差 ÷ 標準誤差
0.22.20240.202432.10.27410.74
1.02.04900.0490525.70.06910.71
3.02.01870.01871800.00.03520.53
10.02.00150.00151071.00.04380.03

どれも1標準誤差以内です。 提案幅 0.2 の 2.2024 は偏りではなく、ESSが32しかないための誤差でした。平均のズレはESSを見ないと解釈できません。


密度は評価できるが直接サンプリングできない例

ここまでは正規分布でしたが、そこにMCMCを使う実用上の理由はありませんでした。実際に必要になる形を1つ見ます。ロジスティック回帰のベイズ事後分布です。

設定

説明変数 xx と二値の応答 yy を20組用意しました。

x = -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.0 0.5 1.0 1.5 2.0 2.5 -1.2 0.7 1.8 -0.3 1.1 -2.2 0.2 2.2
y =  0    0    0    0    1   0   1   1   1   1   1   1    0   0   1    1   1    0   0   1

モデルは次の形です。θ=(intercept,slope)\theta = (\text{intercept}, \text{slope}) の2次元です。

P(y=1x,θ)=11+exp((intercept+slopex))p(θdata)p(dataθ)p(θ)\begin{aligned} P(y = 1 \mid x, \theta) &= \frac{1}{1 + \exp\left(-(\text{intercept} + \text{slope} \cdot x)\right)} \\ p(\theta \mid \text{data}) &\propto p(\text{data} \mid \theta) \cdot p(\theta) \end{aligned}

事前分布は intercept・slope ともに N(0,2.52)N(0, 2.5^2) の独立としました。これは固有な(proper な)事前分布です。

事前分布を固有にしたのには理由があります。ロジスティック回帰では完全分離(ある閾値で yy が完全に 0 と 1 に分かれる状態)が起きると、平坦な事前分布のもとで事後分布が発散して不適切になります。今回のデータは xx の順に並べると

0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1

で、どの閾値でも完全には分かれません。そのうえ固有な事前分布を置いているので、事後分布は二重に安全に proper です。

密度は必ず計算できる

対数事後密度は「対数尤度 + 対数事前」です。θ\theta を渡せば必ず値が返ります。

interceptslope対数尤度対数事前(定数省略)対数事後(正規化前)
0.00.0−13.8629−0.0000−13.8629
0.31.5−7.2738−0.1872−7.4610
1.03.0−8.5311−0.8000−9.3311
−1.00.5−12.7410−0.1000−12.8410

しかし「この事後分布から θ\theta を1つ引く」ための専用の乱数生成器は存在しません。 正規分布やベータ分布のようには作れない。ここが表の右下でした。

正規化定数は二重積分になる

正規化定数は

Z=p(dataθ)p(θ)d(intercept)d(slope)Z = \iint p(\text{data} \mid \theta)\, p(\theta)\, d(\text{intercept})\, d(\text{slope})

です。2次元なら格子で数値積分できます。ただしここで1つ落とし穴を踏みました。

実装の log_prior は事前分布の正規化定数を省いています(受理判定では消えるので不要だからです)。1成分あたり 12log(2π2.52)=1.835229-\frac{1}{2}\log(2\pi \cdot 2.5^2) = -1.835229、intercept と slope の2成分で log(2π2.52)=3.670459-\log(2\pi \cdot 2.5^2) = -3.670459 です。そのまま格子で積分すると log=6.341098\log = -6.341098、値 =1.762367×103= 1.762367 \times 10^{-3} になりますが、これは上の式の ZZ ではありません。この 3.670459-3.670459 を足すと

logZ=10.011556,Z=4.487830×105\log Z = -10.011556, \qquad Z = 4.487830 \times 10^{-5}

で、これが上の式が意味する値(ベイズの周辺尤度)です。2つは 2π2.52=39.26992\pi \cdot 2.5^2 = 39.2699 倍違います。
なお厳密には、これも格子の範囲(intercept は [6,6][-6,6]、slope は [6,10][-6,10])で打ち切った数値積分の値です。

受理判定では消える定数が、正規化定数そのものを求めるときには消えない。 この記事の主題(比では ZZ が消える)の裏返しで、自分で1回踏みました。

ただしMCMCはこの値を一切使いません。 そしてパラメータが10個あれば10重積分になり、この方法は使えなくなります(第34回で見たグリッド法の次元の壁と同じ話です)。

2次元のランダムウォーク・メトロポリス法

1次元のときと同じ受理判定を、2次元にしただけです。提案は各成分に独立な正規分布(標準偏差 0.55)、6万反復、burn-in 1万、初期値 (0,0)(0, 0)

3パネルの図。左は正規化前の対数事後の等高線(青い破線、値は最大からの差)に最初の400歩の軌跡を赤で重ねたもので、初期値(0,0)から等高線の中心へ向かって歩いている。中央はburn-in後5万標本のうち20個に1個(2500点)を描いた散布図(緑)で等高線に沿った楕円状の雲になり、slope=0の赤い破線より上に99.99%が入っている。右は係数の標本を通した予測曲線の束(水色の細線150本)と事後平均の係数による曲線(赤い太線)、および y=1 と y=0 の観測点が縦棒で示されている

受理率は 62.9% でした。

パラメータ事後平均事後標準偏差95%信用区間ESS
intercept0.14780.6858[−1.1971, 1.5330]3909.2
slope2.04480.7952[0.7655, 3.8875]2662.6

格子による数値積分と照合しました。

MCMC格子(数値積分)
intercept の事後平均0.14780.1416
intercept の事後標準偏差0.68580.6758
slope の事後平均2.04482.0195
slope の事後標準偏差0.79520.7830
P(slope>0)P(\text{slope} > 0)0.99990.9999

一致しています。 2次元だから格子と比べられるので、これも「答えのある問題で実装を確かめる」の一例です。

標本があると何ができるか

事後分布の標本が手に入ると、知りたい量を標本に対して計算して数えるだけで済みます。

  • 傾きが正である事後確率P(slope>0)=0.9999P(\text{slope} > 0) = 0.9999。標本のうち slope が正だったものの割合を数えただけ
  • x=1.0x = 1.0 での予測確率:各標本の θ\theta をシグモイド関数に通して平均すると 0.8655、95%区間は [0.6095, 0.9889]

右のパネルの水色の束がこれです。係数の標本1個ごとに予測曲線が1本引けるので、予測の不確実性がそのまま束の太さになります。 点推定1つでは出てこない情報です。

そしてこの計算のどこにも正規化定数 ZZ は出てきません。 受理判定が比しか使わないので、ZZ を知らないまま標本が得られ、標本から期待値も確率も出せます。

ただし ZZ そのものは出ません。 通常のMCMCは正規化定数を推定しません。ZZ(ベイズでは周辺尤度)が欲しい場合は、ブリッジサンプリングや熱力学的積分といった別の工夫が必要です。


通常のモンテカルロ法で十分な例

逆の方向も見ておきます。球の体積を求める問題です。

球の条件は

x2+y2+z2r2x^2 + y^2 + z^2 \le r^2

で、立方体 [r,r]3[-r, r]^3 から一様に点を打って、球の中に入った割合を数えます。

P(球内)=VsphereVcube=43πr38r3=π6=0.5235987756Vsphere=8r3P(球内)\begin{aligned} P(\text{球内}) &= \frac{V_{\text{sphere}}}{V_{\text{cube}}} = \frac{\frac{4}{3}\pi r^3}{8 r^3} = \frac{\pi}{6} = 0.5235987756 \\ V_{\text{sphere}} &= 8 r^3 \cdot P(\text{球内}) \end{aligned}

3パネルの図。左は立方体に一様に打った点の3次元散布図で、球の中に入った点が緑、外が灰色。中央は z の絶対値が 0.1 未満の薄いスライスで見た断面で、青い円の内側が緑、外側が灰色に分かれ、赤い破線の正方形が立方体の断面を示す。右は標本数を100から100万まで増やしたときの体積の推定値で、真値4.188790の赤い破線に収束していく

標本数命中数推定した P(球内)P(\text{球内})推定した体積 8P8P真値
10,0005,2260.5226004.1808004.188790
1,000,000523,0140.5230144.1841124.188790
20,000,00010,473,8330.5236924.1895334.188790

3次元ではMCMCを使う必要がありません。 理由を正確に書きます。

「中心に確率が集中していないから」ではありません。 正しい理由は次の2つです。

  1. 基準となる一様分布から独立標本を直接生成できるrng.uniform で済む)
  2. 球内に入る事象が希少ではない(命中率 52.4%)

このどちらかが崩れると話が変わります。

高次元では崩れる

球と超立方体の体積比は次元とともに急減します(第34回でも同じ比率を見ました)。

次元 dd球 ÷ 立方体1個採るのに引く回数
35.235988e−011.910 回
51.644934e−016.079 回
102.490395e−03401.5 回
202.461137e−084.063e+07 回
302.041026e−144.899e+13 回

d=20d = 20 では 4000万回引いて1個です。上の条件2(希少でない)が崩れています。

ただし「単純なMCMCに替えれば自動的に体積が求まる」わけではありません。 ここは私が最初に誤解しかけた点です。通常のMCMCは目標分布の標本を作るだけで、正規化定数を出しません。そして球の体積はまさに正規化定数の側にある量です。高次元の体積を求めるには、重点サンプリング・逐次的に領域を分割する方法・熱力学的積分といった、別の枠組みが必要になります。


使い分けの判断フロー

ここまでを1本の流れにまとめます。

目標分布から独立標本を直接生成できる?
  Yes → 通常のモンテカルロ法
  No  → 良い提案分布と安定した重みを作れる?
           Yes → 重点サンプリング/棄却サンプリングを検討
           No  → 正規化前の目標密度を評価できる?
                    Yes → MCMC を検討
                    No  → 通常の MCMC も困難

別枠の注意が1つあります。 上のフローの1行目が Yes でも、通常のモンテカルロ法が実用にならない場合があります。知りたい事象がまれなときです。

たとえば「確率 10810^{-8} の事象の確率を推定したい」なら、直接生成できても素朴に数えるだけでは1億回引いて1回しか当たりません。この場合は重点サンプリングなどで「まれな事象を起きやすくして重みで割り戻す」必要があります。第34回102310^{-23} の確率を10万回で推定した例がこれです。

つまり判断は2軸で見るのが正確です。

事象が希少でない事象が希少
直接生成できる通常のモンテカルロ法重点サンプリングなど
直接生成できないMCMCMCMC + まれな事象向けの工夫

技術的に混同しやすい点のまとめ

自分が実際に混同していた点、あるいは書きながら怖くなって確認した点を並べます。

混同正しい理解
MCMCと重点サンプリングは似た手法別系統の手法。 MCMCは鎖をつなぐ、重点サンプリングは独立標本に重みを付ける
MCMCは確率密度関数を求めてくれる求めない。 密度の式は最初から必要。MCMCが出すのは標本
MCMC標本には重みが付いている付かない。 重みなしだが相関がある
密度が計算できればサンプリングもできる別問題。 事後分布は前者ができて後者ができない典型
メトロポリス法は指数関数の形の分布専用違う。 pexp(S)p \propto \exp(-S)S=logp+定数S = -\log p + \text{定数} と置いた一般的な書き方
正規化定数が要らないのはMCMCだけの特徴違う。 自己正規化した重点サンプリングも ZZ を必要としない
MCMCなら正規化定数も分かる分からない。 標本と期待値・確率は出るが ZZ は別の工夫が必要
詳細釣り合いのために提案は対称でなければならない違う。 非対称でも Hastings 補正を入れれば詳細釣り合いを満たす。さらに詳細釣り合い自体が十分条件にすぎず、満たさなくても不変分布にできる(第33回の決定的スキャンのギブスサンプリング)
非対称な提案でもそのまま使える使えない。 Hastings 補正 q(xxnew)/q(xnewx)q(x \mid x_{\text{new}}) / q(x_{\text{new}} \mid x) が必要
自己相関が0なら独立同義ではない。 無相関は独立より弱い条件
提案分布を変えても収束するから何でもよい条件つき。 正しい受理確率・既約性・非周期性が必要
受理率は高いほど良い違う。 同じ1万反復(burn-in後9000標本)で、受理率 95.8% は ESS 32.1、49.8% は ESS 1800.0(56倍の差)
高次元なら常にMCMCが最適違う。 問題によっては別の手法が要る。体積の計算はMCMC単体では解けない
ランニング平均が横ばいなら収束した証明にならない。 帯に入り続けるのは 8451 標本目からだった
burn-in はグラフから自動で決まる今回の実装では指定値。 自動判定は入っていない

参考文献

一次資料と標準的な教科書を挙げます。

内容文献
メトロポリス法の原論文Metropolis, N., Rosenbluth, A. W., Rosenbluth, M. N., Teller, A. H., & Teller, E. (1953). Equation of State Calculations by Fast Computing Machines. The Journal of Chemical Physics, 21(6), 1087–1092.
非対称提案への一般化(メトロポリス–ヘイスティングス法)Hastings, W. K. (1970). Monte Carlo sampling methods using Markov chains and their applications. Biometrika, 57(1), 97–109.
提案幅の最適化と受理率 0.234Roberts, G. O., Gelman, A., & Gilks, W. R. (1997). Weak convergence and optimal scaling of random walk Metropolis algorithms. The Annals of Applied Probability, 7(1), 110–120.
1次元を含む各種アルゴリズムの最適な受理率Roberts, G. O., & Rosenthal, J. S. (2001). Optimal scaling for various Metropolis-Hastings algorithms. Statistical Science, 16(4), 351–367.
複数の鎖による収束診断Gelman, A., & Rubin, D. B. (1992). Inference from Iterative Simulation Using Multiple Sequences. Statistical Science, 7(4), 457–472.
自己相関の打ち切りとESSGeyer, C. J. (1992). Practical Markov Chain Monte Carlo. Statistical Science, 7(4), 473–511.
改良版の収束診断とESSVehtari, A., Gelman, A., Simpson, D., Carpenter, B., & Bürkner, P.-C. (2021). Rank-Normalization, Folding, and Localization: An Improved R^\hat{R} for Assessing Convergence of MCMC. Bayesian Analysis, 16(2), 667–718.
重点サンプリングとMCMCの位置づけRobert, C. P., & Casella, G. (2004). Monte Carlo Statistical Methods (2nd ed.). Springer.
ロジスティック回帰のベイズ事後分布・弱情報事前分布Gelman, A., Carlin, J. B., Stern, H. S., Dunson, D. B., Vehtari, A., & Rubin, D. B. (2013). Bayesian Data Analysis (3rd ed.). CRC Press.

再現方法

この記事の数値と図は、すべて固定シードで再現できます。スクリプトは site/scripts/mcmc-column/ に置いてあります。

ファイル内容
mcmc_common.py練習用プロジェクトの sampler.py を呼び出す共通部分とESSの計算
v1_normal.pyエネルギー関数との対応、簡易チェックと同じ設定、診断の数値
v2_sweep.py提案幅を変えたときの受理率・ESS・平均のズレ
v3_logit.pyロジスティック回帰の事後分布と格子による照合
v4_three.py3手法の比較、次元による重みの崩壊、球の体積
v5_optimal.py1次元での最適な提案幅の探索
f_common.py図の共通設定(日本語フォント・文字サイズ)
f1.pyf5.py記事の5枚の図
mcmc_verify_output.txtv1v5 の実行結果。記事の数値はこれと f1.pyf5.py の出力に一致します

mcmc_common.py は練習用プロジェクトのパスを絶対パスで直書きしているので、別の環境で動かすときはそこを書き換えてください。

主な設定は次のとおりです。

  • 目標分布:N(2.0,1.52)N(2.0, 1.5^2)target.pylog_target が返すのは 12(x2.01.5)2-\frac{1}{2}\left(\frac{x-2.0}{1.5}\right)^2(正規化定数を省いた対数密度)
  • 診断図:--samples 10000 --burn-in 1000 --proposal-std 1.0 --seed 42(初期値 0)
  • 簡易チェック:n_samples=30000, burn_in=3000, proposal_std=1.0, initial_state=-5.0, seed=2026
  • ロジスティック回帰:提案の標準偏差 0.55、6万反復、burn-in 1万、seed 20260816、事前分布 N(0,2.52)N(0, 2.5^2)

この記事の位置づけ

連載の中での位置を書いておきます。

記事何を扱っているか
第33回ベイズ法の全体。事後分布・共役事前分布・MCMCの導入・ギブスサンプリング・R^\hat{R}・階層ベイズ
第34回乱数を「作る」技術と「使う」技術の地図。逆関数法・棄却法・モンテカルロ積分・分散減少法
この番外編その2つの境目。 密度を評価できることとサンプリングできることの区別、3手法の使い分け、実装して分かったこと

準1級の試験対策としては、この記事の内容は「用語と使いどころ」のレベルで十分です。 MCMCを実装させる問題は出ません。ただ、自分で書いてみると「棄却したときも記録する」「対数で比較する」「受理率が高いほど良いのではない」といった、読むだけでは通り過ぎる点が体に入りました。

この連載の全体像は統計検定準1級・独学連載のまとめにあります。