Mímisbrunnr知恵の泉

← ベイズ統計 一覧

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

📎 前提:メトロポリスヘイスティングス | 数理:MCMC(マルコフ連鎖モンテカルロ)(統計)・正規正規モデル

要点(BLUF)

1. アイデア:1変数ずつの条件付きに分解する

dd 次元の同時事後 p(θ1,,θdD)p(\theta_1,\dots,\theta_d\mid D) を直接サンプリングするのは難しい。ギブスは「他の成分を今の値に固定したときの θj\theta_j の条件付き分布」=**完全条件付き分布(full conditional)**から、j=1,,dj=1,\dots,d と順に引きます。

θj(t+1)p(θjθj(最新),D)(θj=θ から θj を除いたもの)\theta_j^{(t+1)}\sim p\big(\theta_j\mid \theta_{-j}^{(\text{最新})},\,D\big)\qquad(\theta_{-j}=\theta\ \text{から}\ \theta_j\ \text{を除いたもの})

これを1サイクルとして繰り返すと、点列が同時事後 p(θD)p(\theta\mid D) からの標本になります(なぜ正しいか=完全条件付きから引く操作が受容確率1の MH に当たる、は MCMC(マルコフ連鎖モンテカルロ))。

2. 正規モデルの完全条件付き(共役が効く)

データ x1,,xnN(μ,σ2)x_1,\dots,x_n\sim\mathcal N(\mu,\sigma^2) で、μ\muσ2\sigma^2両方を推定します。事前は μN(μ0,1/τ0)\mu\sim\mathcal N(\mu_0,1/\tau_0)σ2Inv-Gamma(a0,b0)\sigma^2\sim\mathrm{Inv\text{-}Gamma}(a_0,b_0)(独立)。同時事後は閉形式で出ませんが、各成分の完全条件付きは第2章の共役そのものです。

μσ2,D  N ⁣(τ0μ0+(n/σ2)xˉτ0+n/σ2, 1τ0+n/σ2)\mu\mid\sigma^2,D\ \sim\ \mathcal N\!\left(\frac{\tau_0\mu_0+(n/\sigma^2)\bar x}{\tau_0+n/\sigma^2},\ \frac{1}{\tau_0+n/\sigma^2}\right) σ2μ,D  Inv-Gamma ⁣(a0+n2, b0+12i(xiμ)2)\sigma^2\mid\mu,D\ \sim\ \mathrm{Inv\text{-}Gamma}\!\left(a_0+\frac{n}{2},\ b_0+\frac12\sum_i (x_i-\mu)^2\right)

どちらも標準分布なので直接サンプリングでき、交互に引くだけ。これがギブスの気持ちよさです。

3. numpy で実装し、2次元グリッドの真値と一致させる

import numpy as np
from scipy import stats
from scipy.integrate import trapezoid          # numpy 2.0+ で np.trapz は廃止

rng = np.random.default_rng(3)
data = rng.normal(5.0, 2.0, size=30)             # 真は μ=5, σ²=4
n = len(data); xbar = data.mean()
mu0, s0 = 0.0, 10.0; tau0 = 1/s0**2              # 事前 μ~N(0,10²)
ag, bg = 2.0, 2.0                                # 事前 σ²~InvGamma(2,2)

def gibbs(N=60000, burn=5000, seed=0):
    rng = np.random.default_rng(seed)
    mu, s2 = xbar, data.var()
    M = np.empty(N); S = np.empty(N)
    for i in range(N):
        # μ | σ², data ~ Normal(精度の加重平均)
        tau_n = tau0 + n/s2
        mu_n  = (tau0*mu0 + (n/s2)*xbar)/tau_n
        mu = rng.normal(mu_n, np.sqrt(1/tau_n))
        # σ² | μ, data ~ InvGamma(a0+n/2, b0+½Σ(x-μ)²)
        a_n = ag + n/2
        b_n = bg + 0.5*np.sum((data - mu)**2)
        s2 = stats.invgamma(a=a_n, scale=b_n).rvs(random_state=rng)
        M[i], S[i] = mu, s2
    return M[burn:], S[burn:]

mu_s, s2_s = gibbs()
print(f"ギブス:     E[μ]={mu_s.mean():.4f}  E[σ²]={s2_s.mean():.4f}  "
      f"μ95%=[{np.quantile(mu_s,0.025):.3f}, {np.quantile(mu_s,0.975):.3f}]")

# 真値:2次元グリッドで同時事後を数値積分して周辺平均を出す
mug = np.linspace(2, 8, 400); s2g = np.linspace(0.5, 12, 400)
MU, S2 = np.meshgrid(mug, s2g, indexing='ij')
logpost = (-0.5*n*np.log(S2)
           - 0.5*((data[:,None,None]-MU[None,:,:])**2).sum(0)/S2
           - 0.5*tau0*(MU-mu0)**2
           + (-(ag+1))*np.log(S2) - bg/S2)
post = np.exp(logpost - logpost.max())
post /= trapezoid(trapezoid(post, s2g, axis=1), mug)
Emu = trapezoid(trapezoid(post*MU, s2g, axis=1), mug)
Es2 = trapezoid(trapezoid(post*S2, s2g, axis=1), mug)
print(f"グリッド真値: E[μ]={Emu:.4f}  E[σ²]={Es2:.4f}")

出力:

ギブス:     E[μ]=5.1073  E[σ²]=5.1068  μ95%=[4.286, 5.923]
グリッド真値: E[μ]=5.1076  E[σ²]=5.1067

出力の意味:ギブスの事後平均 E[μ]=5.107E[\mu]=5.107E[σ2]=5.107E[\sigma^2]=5.107 が、2次元グリッドで数値積分した真値とほぼ完全に一致します。同時事後は閉形式で書けないのに、完全条件付き(正規・逆ガンマ)を交互に引くだけで正しい事後を再現できました。共役(第2章)が「条件付きを標準分布にする」形でここに効いています。

4. ギブスの利点と前提

サンプルが2次元事後をどう埋めるかを散布図で見ます。

import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
import japanize_matplotlib  # 日本語ラベル用

rng = np.random.default_rng(3)
data = rng.normal(5.0, 2.0, size=30); n = len(data); xbar = data.mean()
mu0, tau0, ag, bg = 0.0, 1/100, 2.0, 2.0
mu, s2 = xbar, data.var()
M = np.empty(20000); S = np.empty(20000)
for i in range(20000):
    tau_n = tau0 + n/s2; mu = rng.normal((tau0*mu0+(n/s2)*xbar)/tau_n, np.sqrt(1/tau_n))
    s2 = stats.invgamma(a=ag+n/2, scale=bg+0.5*np.sum((data-mu)**2)).rvs(random_state=rng)
    M[i], S[i] = mu, s2

plt.figure(figsize=(6, 5))
plt.scatter(M[::5], S[::5], s=3, alpha=0.15)
plt.xlabel("μ"); plt.ylabel("σ²")
plt.title("ギブス標本が描く同時事後 p(μ, σ² | D)")
plt.tight_layout(); plt.show()

グラフの意味:点群は μ5.1\mu\approx5.1σ25\sigma^2\approx5 を中心に広がり、同時事後の形を埋めます。μ\mu の散らばりは σ2\sigma^2 が大きい行ほど横に広い(分散が大きいと平均の不確実性も増す)——2変数の依存が散布図に表れます。

⚠️ よくある誤解

関連ノート