Mímisbrunnr知恵の泉

← ベイズ統計 一覧

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

📎 前提:確率的プログラミング概観 | 関連:ベイズ線形回帰

⚠️ 要最新確認:PyMC 6.0.1 / ArviZ 1.2.0 で検証。sample_prior_predictivesample_posterior_predictive の引数は版で変わります。

要点(BLUF)

1. ベイズワークフロー全体

良いベイズ分析は、いきなり結果を出さず、段階を踏んで点検します。

flowchart LR
  M["モデル記述<br/>事前 + 尤度"] --> PR["事前予測チェック<br/>含意が常識的か(第3章)"]
  PR --> S["サンプリング<br/>NUTS で事後を得る"]
  S --> D["収束診断<br/>R-hat・ESS(第4章)"]
  D --> PO["事後の要約<br/>平均・区間・確率(第3章)"]
  PO --> PP["事後予測チェック<br/>当てはまり診断(第8章)"]

第3〜8章で個別に学んだ道具(事前予測・収束診断・事後要約・事後予測チェック)が、PPL では一つの流れにつながります。

2. PyMC で線形回帰を一気通貫に書く

データ y=a+bx+εy=a+bx+\varepsilon を、PyMC で宣言して推論します。

import numpy as np, pymc as pm, arviz as az

rng = np.random.default_rng(1)
a_true, b_true, sig = 1.0, -2.0, 0.5
x = np.sort(rng.uniform(-2, 2, 30))
y = a_true + b_true*x + rng.normal(0, sig, len(x))

with pm.Model() as model:
    a = pm.Normal("a", 0, 5)                            # 弱情報事前
    b = pm.Normal("b", 0, 5)
    sigma = pm.HalfNormal("sigma", 2)                  # 尺度は正の半正規
    mu = a + b*x                                        # 線形予測子
    pm.Normal("y", mu=mu, sigma=sigma, observed=y)     # 尤度(observed でデータを結ぶ)

    prior = pm.sample_prior_predictive(200, random_seed=0)        # ① 事前予測
    idata = pm.sample(2000, tune=1000, chains=4, cores=1,         # ② サンプリング
                      random_seed=0, progressbar=False)
    pm.sample_posterior_predictive(idata, random_seed=0,         # ③ 事後予測
                                   progressbar=False, extend_inferencedata=True)

for nm, tv in [("a", a_true), ("b", b_true), ("sigma", sig)]:    # ④ 事後の要約
    d = idata.posterior[nm].values.flatten()
    lo, hi = np.percentile(d, [5.5, 94.5])
    print(f"{nm}: 事後平均={d.mean():+.3f} SD={d.std():.3f} 89%=[{lo:+.3f},{hi:+.3f}]  (真={tv})")
print(f"r_hat(b)={float(az.rhat(idata)['b'].values):.3f}  ESS(b)={float(az.ess(idata)['b'].values):.0f}")

pp = idata.posterior_predictive["y"].values.reshape(-1, len(x))  # ⑤ 事後予測チェック
cover = np.mean((y >= np.percentile(pp,2.5,0)) & (y <= np.percentile(pp,97.5,0)))
print(f"事後予測95%帯がデータを覆う割合={cover:.2f}")

出力:

a: 事後平均=+0.988 SD=0.091 89%=[+0.841,+1.132]  (真=1.0)
b: 事後平均=-2.032 SD=0.078 89%=[-2.155,-1.907]  (真=-2.0)
sigma: 事後平均=+0.484 SD=0.069 89%=[+0.388,+0.603]  (真=0.5)
r_hat(b)=1.000  ESS(b)=8580
事後予測95%帯がデータを覆う割合=0.97

出力の意味:宣言したモデルから、真の係数 a=1.0,b=2.0,σ=0.5a=1.0,b=-2.0,\sigma=0.5 をすべて 89% 区間内に回収。R^=1.000\hat R=1.000・ESS 85808580 で収束も良好。事後予測の 95% 帯がデータ点の 97% を覆い(理想は 95%)、モデルがデータをうまく説明できていると分かります。第7章で行列計算で書いた事後(ベイズ線形回帰)が、ここではモデルを宣言するだけで得られました。

3. 各ステップの役割

この5段が、PPL を使うときの基本動作です。モデル(事前+尤度)を差し替えれば、GLM・階層・GP でも同じ流れが回ります。

4. 手実装との対応

第7章のベイズ線形回帰は、計画行列・事後共分散 SNS_N・事後平均 mNm_N を手で計算しました。PyMC では a = pm.Normal(...)mu = a + b*xpm.Normal("y", mu, sigma, observed=y)生成過程を書くだけ。共役でない尤度(ロジスティック・ポアソン、ベイズGLM)でも、尤度の行を変えるだけで同じワークフローが使えます——ここが手実装にない PPL の強みです。

⚠️ よくある誤解

関連ノート