Mímisbrunnr知恵の泉

← ベイズ統計 一覧

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

📎 前提:正則化との関係 | 数理:指数型分布族と共役事前

要点(BLUF)

1. GLM とリンク関数:なぜ共役が崩れるか

線形回帰(ベイズ線形回帰)は出力が連続でガウスでした。GLM は出力が二値・カウントなどのとき、指数型分布族(指数型分布族と共役事前)の尤度にリンク関数を挟みます。

これらの尤度にガウス事前 wN(0,α1I)w\sim\mathcal N(0,\alpha^{-1}I) を掛けても、σ\sigmaexp\exp が非線形に絡むため、事後が標準分布になりません(共役でない)。事後を解析的に書けないので近似が要ります。

2. ラプラス近似:MAP 周りをガウスで

最も手軽な近似がラプラス近似。対数事後 logp(wD)\log p(w\mid D) を MAP wMAPw_{\mathrm{MAP}} の周りで2次までテイラー展開すると、対数が2次関数=ガウスのカーネルになります。

p(wD)N(wMAP, H1),H=2logp(wD)wMAPp(w\mid D)\approx\mathcal N\big(w_{\mathrm{MAP}},\ H^{-1}\big),\qquad H=-\nabla^2\log p(w\mid D)\big|_{w_{\mathrm{MAP}}}

HH は負の対数事後のヘッセ行列(曲率)。ロジスティック回帰では H=ΦSΦ+αIH=\Phi^\top S\Phi+\alpha IS=diag(pi(1pi))S=\mathrm{diag}(p_i(1-p_i)))。MAP はニュートン法(=IRLS)で速く求まります。事後の山を1つのガウスで近似するので、単峰でほぼ対称な事後によく当たります。

3. コード:ベイズロジスティック回帰(ラプラス vs MCMC)

ラプラス近似が、計算の重いフル MCMC(メトロポリスヘイスティングス)とどれだけ一致するか確かめます。

import numpy as np

rng = np.random.default_rng(0)
n = 200
true_w = np.array([0.4, 1.5, -1.0])                      # 切片, x1, x2
X = np.c_[np.ones(n), rng.standard_normal((n, 2))]
y = (rng.uniform(size=n) < 1/(1+np.exp(-X@true_w))).astype(float)
alpha = 1.0                                              # 事前 N(0, 1/α)

sig = lambda z: 1/(1+np.exp(-z))
def neg_logpost(w):
    pz = sig(X@w)
    return -(y@np.log(pz+1e-12) + (1-y)@np.log(1-pz+1e-12)) + 0.5*alpha*w@w

# MAP(ニュートン法)→ ラプラス近似 事後≈N(w_map, H⁻¹)
w = np.zeros(3)
for _ in range(50):
    pz = sig(X@w)
    grad = X.T@(pz - y) + alpha*w
    H = X.T@(X*(pz*(1-pz))[:,None]) + alpha*np.eye(3)
    w = w - np.linalg.solve(H, grad)
w_map = w
pz = sig(X@w_map)
H = X.T@(X*(pz*(1-pz))[:,None]) + alpha*np.eye(3)
sd_laplace = np.sqrt(np.diag(np.linalg.inv(H)))
print(f"ラプラス: 事後平均={np.round(w_map,3)}  事後SD={np.round(sd_laplace,3)}")

# MH で検証
def mh(N=120000, burn=20000, step=0.15, seed=1):
    rng = np.random.default_rng(seed); w = w_map.copy(); lp = -neg_logpost(w)
    out = np.empty((N,3))
    for i in range(N):
        cand = w + rng.normal(0, step, 3); lc = -neg_logpost(cand)
        if np.log(rng.uniform()) < lc-lp: w, lp = cand, lc
        out[i] = w
    return out[burn:]
s = mh()
print(f"MH      : 事後平均={np.round(s.mean(0),3)}  事後SD={np.round(s.std(0),3)}  (真{true_w})")

出力:

ラプラス: 事後平均=[ 0.381  1.652 -1.104]  事後SD=[0.18  0.246 0.219]
MH      : 事後平均=[ 0.385  1.688 -1.13 ]  事後SD=[0.182 0.251 0.223]  (真[ 0.4  1.5 -1. ])

出力の意味:ラプラス近似の事後平均 [0.38,1.65,1.10][0.38,1.65,-1.10]・SD [0.18,0.25,0.22][0.18,0.25,0.22] が、フル MCMC の結果とほぼ一致します(差は小数第2位)。どちらも真の係数 [0.4,1.5,1.0][0.4,1.5,-1.0] を回収。ロジスティック回帰の事後はこの規模のデータでほぼ単峰・準対称なので、MAP とヘッセ行列だけで MCMC 並みの事後が得られる——ニュートン法数十回 vs MH 十数万回で、ラプラスが圧倒的に軽い。係数の SD(不確実性)まで出るのが点推定の最尤ロジスティックとの違いです。

4. ポアソン回帰も同じ枠組み

カウントデータのポアソン回帰 λ=exp(xw)\lambda=\exp(x^\top w) も同様です。対数事後の MAP をニュートン法で求め、ヘッセ行列でラプラス近似——リンク関数と尤度が変わるだけで、手順は共通。GLM はすべて指数型分布族(指数型分布族と共役事前)の尤度+リンク関数で、自然パラメータ η=xw\eta=x^\top w を線形予測子に結ぶ構造を共有します。だから「指数型分布族の自然パラメータを線形にする」のが GLM、と一言で言えます。

精度がもっと要る・事後が非対称や多峰なら、ラプラスでなく MCMC(第4章)や変分推論(第6章)を使います。実務では PyMC などで pm.Bernoullipm.Poisson を宣言して NUTS で解くのが定番(要最新確認確率的プログラミング概観)。

⚠️ よくある誤解

関連ノート