Mímisbrunnr知恵の泉

← ベイズ統計 一覧

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

📎 前提:ベイズファクターとモデル平均化 | 数理:MCMC(マルコフ連鎖モンテカルロ)(統計)

⚠️ 要最新確認:PPL の API は速く変わります。本ノートは PyMC 6.0.1 / ArviZ 1.2.0 で実行検証しました。バージョンが違うと関数名・既定値・出力列が変わるので、必ず手元の版で確認してください。

要点(BLUF)

1. PPL とは:宣言的モデリング

第4章では MH やギブスを numpy で手実装し、第7章ではラプラス近似を自分で書きました。PPL はこれを自動化します。やることは「データがどう生成されたか(事前+尤度)を宣言する」だけ。あとは:

推論アルゴリズムを書かずにモデルだけ書けるので、複雑な階層モデル・GLM も宣言的に組めます。

2. 主要 PPL の位置づけ

PPL特徴備考
PyMCPython ネイティブ。PyTensor で自動微分、NUTS が既定本ノートで使用。記述が直感的
Stan独自言語(C++ にコンパイル)。高速・実績豊富R/Python から呼ぶ。HMC/NUTS の本家的存在
NumPyroJAX ベース。GPU/TPU・大規模で高速関数型スタイル。研究で人気

どれも「モデル宣言 → NUTS で推論 → ArviZ で診断・可視化」という流れは共通(ArviZ は推論結果を扱う共通ライブラリ)。以下は PyMC で示しますが、考え方は移植できます(具体的 API は要最新確認)。

3. コード:最小の PyMC モデルが閉形式と一致する

コイン(ベルヌーイ)の成功確率 θ\theta を推定します。事前 Beta(1,1)\mathrm{Beta}(1,1)・尤度ベルヌーイなら、第2章の共役で事後は閉形式 Beta(1+k,1+nk)\mathrm{Beta}(1+k,1+n-k)ベータ二項モデル)。PyMC の NUTS がこれを再現するか確かめます。

import numpy as np, pymc as pm, arviz as az
from scipy import stats

rng = np.random.default_rng(0)
y = rng.binomial(1, 0.7, size=40); n, k = len(y), int(y.sum())

with pm.Model() as model:
    theta = pm.Beta("theta", alpha=1, beta=1)          # 事前 Beta(1,1)
    pm.Bernoulli("obs", p=theta, observed=y)           # 尤度(データを observed で渡す)
    idata = pm.sample(2000, tune=1000, chains=4, cores=1,   # ← Windowsは cores=1 推奨
                      random_seed=0, progressbar=False)

draws = idata.posterior["theta"].values.flatten()      # 事後サンプルを取り出す
lo, hi = np.percentile(draws, [5.5, 94.5])             # 89%区間
rhat = float(az.rhat(idata)["theta"].values)
ess  = float(az.ess(idata)["theta"].values)
post = stats.beta(1+k, 1+n-k)                          # 閉形式の事後
print(f"データ: n={n}, k={k}")
print(f"PyMC : 平均={draws.mean():.4f} SD={draws.std():.4f} 89%=[{lo:.3f},{hi:.3f}] r_hat={rhat:.3f} ESS={ess:.0f}")
print(f"閉形式: 平均={post.mean():.4f} SD={post.std():.4f} 89%=[{post.ppf(.055):.3f},{post.ppf(.945):.3f}] Beta({1+k},{1+n-k})")

出力:

データ: n=40, k=27
PyMC : 平均=0.6654 SD=0.0722 89%=[0.546,0.776] r_hat=1.000 ESS=3396
閉形式: 平均=0.6667 SD=0.0719 89%=[0.548,0.777] Beta(28,14)

出力の意味:PyMC の事後(平均 0.6650.665・89%区間 [0.546,0.776][0.546,0.776])が、手計算の閉形式 Beta(28,14)\mathrm{Beta}(28,14)(平均 0.6670.667[0.548,0.777][0.548,0.777])と小数第2位までぴたり一致。R^=1.000\hat R=1.000・ESS 33963396 で収束も良好。with pm.Model() の中で事前と尤度を2行宣言しただけで、NUTS が事後を正しくサンプリングしました。第4章で苦労して書いた MCMC が、ここでは自動です。

4. 何が自動化されたのか

宣言と推論が分離されるので、モデルを差し替えるだけで階層モデル・GLM・GP まで同じ流れで扱えます(モデルの書き方から事後予測までは モデル記述から推論まで)。

5. 実行上の注意(要最新確認)

⚠️ よくある誤解

関連ノート