Mímisbrunnr知恵の泉

← ベイズ統計 一覧

🎓 レベル:発展 | 重要度:B(標準)

📎 前提:ベイズ線形回帰 | 関連:正規正規モデル

要点(BLUF)

1. 関数への事前:ガウス過程

これまでは有限個のパラメータ(係数 ww など)に事前を置きました。GP は発想が違い、関数 ff 全体に事前を置きます。

定義:関数 ff がガウス過程 fGP(m(x),k(x,x))f\sim\mathcal{GP}(m(x),k(x,x')) に従うとは、任意の有限個の入力 x1,,xnx_1,\dots,x_n について、関数値のベクトル [f(x1),,f(xn)][f(x_1),\dots,f(x_n)]多変量正規 N(m,K)\mathcal N(\mathbf m,K) に従うこと(Kij=k(xi,xj)K_{ij}=k(x_i,x_j))。

平均関数 m(x)m(x) は通常 00。鍵は共分散関数(カーネル) k(x,x)k(x,x') で、「近い入力の関数値ほど強く相関する」という滑らかさの仮定を表します。

2. RBF カーネルと滑らかさ

最もよく使う RBF カーネル(ガウスカーネル)

k(x,x)=σf2exp ⁣((xx)222)k(x,x')=\sigma_f^2\exp\!\left(-\frac{(x-x')^2}{2\ell^2}\right)

x=xx=x'k=σf2k=\sigma_f^2(最大)、離れると指数的に 00 へ。だから近い点は強く連動し、遠い点は独立——これが「滑らかな関数」の事前になります。

3. GP 回帰の事後(閉形式)

観測 yi=f(xi)+εi, εN(0,σn2)y_i=f(x_i)+\varepsilon_i,\ \varepsilon\sim\mathcal N(0,\sigma_n^2)。新しい点 XX_* での予測は、訓練点と XX_* の関数値の同時正規分布を条件付けるだけ——多変量正規の条件付き公式(正規正規モデル の多変量版)で閉形式です。

fˉ=K(K+σn2I)1y,Cov(f)=KK(K+σn2I)1K\bar f_*=K_{*}\,(K+\sigma_n^2 I)^{-1}y,\qquad \mathrm{Cov}(f_*)=K_{**}-K_{*}\,(K+\sigma_n^2 I)^{-1}K_{*}^\top

ここで K=k(X,X)K=k(X,X)K=k(X,X)K_*=k(X_*,X)K=k(X,X)K_{**}=k(X_*,X_*)。実装します。

import numpy as np

def rbf(a, b, ell=1.0, sf=1.0):                  # RBFカーネル
    d2 = (a[:,None]-b[None,:])**2
    return sf**2*np.exp(-0.5*d2/ell**2)

rng = np.random.default_rng(0)
f = lambda x: np.sin(2*x) + 0.3*x
Xtr = np.array([-3, -2, -1.2, 0.5, 1.5, 2.5, 3.5])    # 訓練入力
sigma_n = 0.1
ytr = f(Xtr) + rng.normal(0, sigma_n, len(Xtr))
Xte = np.linspace(-5, 6, 200)

# 事後:mean=K*(K+σ²I)⁻¹y, var=diag(K**) - 行ごとの K*(K+σ²I)⁻¹K*ᵀ
K  = rbf(Xtr, Xtr) + sigma_n**2*np.eye(len(Xtr))
Ks = rbf(Xte, Xtr); Kss = rbf(Xte, Xte)
L = np.linalg.cholesky(K)
alpha = np.linalg.solve(L.T, np.linalg.solve(L, ytr))
mean = Ks @ alpha
v = np.linalg.solve(L, Ks.T)
sd = np.sqrt(np.maximum(np.diag(Kss) - np.sum(v**2, axis=0), 0))

def at(x0):
    i = np.argmin(np.abs(Xte - x0)); return mean[i], sd[i]
for x0 in [0.5, 0.0, 5.5]:
    m, s = at(x0)
    tag = "訓練点上" if min(abs(Xtr-x0))<0.1 else ("データ内" if -3<=x0<=3.5 else "外挿")
    print(f"x={x0:>4}: 予測平均={m:+.3f} 予測SD={s:.3f}{tag})")
print(f"訓練点の平均SD={np.mean([at(x)[1] for x in Xtr]):.3f}(≈雑音{sigma_n}), 外挿x=5.5でSD={at(5.5)[1]:.3f}")

出力:

x= 0.5: 予測平均=+0.955 予測SD=0.101 (訓練点上)
x= 0.0: 予測平均=+0.045 予測SD=0.261 (データ内)
x= 5.5: 予測平均=+0.451 予測SD=0.985 (外挿)
訓練点の平均SD=0.100(≈雑音0.1), 外挿x=5.5でSD=0.985

出力の意味:訓練点の上では予測 SD が雑音レベル 0.100.10 まで縮み(データを信じて補間)、訓練点の間(x=0x=0)では 0.260.26 とやや広く、データの全くない外挿(x=5.5x=5.5)では 0.990.99事前の振幅 σf=1\sigma_f=1 へ戻ります。GP は「知っている所では自信を持ち、知らない所では正直に分からないと言う」——ベイズ線形回帰(ベイズ線形回帰)の予測帯が外挿で広がったのと同じ性質を、関数の形を仮定せずに実現します。

4. 図:補間と外挿の不確実性

事後平均・±2\pm2SD 帯と、事後からサンプルした関数を描きます。

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

def rbf(a, b, ell=1.0, sf=1.0):
    return sf**2*np.exp(-0.5*(a[:,None]-b[None,:])**2/ell**2)
rng = np.random.default_rng(0)
f = lambda x: np.sin(2*x) + 0.3*x
Xtr = np.array([-3,-2,-1.2,0.5,1.5,2.5,3.5]); sn = 0.1
ytr = f(Xtr) + rng.normal(0, sn, len(Xtr)); Xte = np.linspace(-5, 6, 200)
K = rbf(Xtr,Xtr)+sn**2*np.eye(len(Xtr)); Ks = rbf(Xte,Xtr); Kss = rbf(Xte,Xte)
L = np.linalg.cholesky(K); alpha = np.linalg.solve(L.T, np.linalg.solve(L, ytr))
mean = Ks@alpha; V = np.linalg.solve(L, Ks.T)
cov = Kss - V.T@V; sd = np.sqrt(np.maximum(np.diag(cov), 0))

plt.figure(figsize=(8, 4.5))
for s in rng.multivariate_normal(mean, cov + 1e-9*np.eye(len(Xte)), 8):
    plt.plot(Xte, s, color="C1", alpha=0.25, lw=0.8)
plt.fill_between(Xte, mean-2*sd, mean+2*sd, alpha=0.2, color="C0", label="予測 ±2SD")
plt.plot(Xte, mean, color="C0", lw=2, label="予測平均")
plt.scatter(Xtr, ytr, color="black", zorder=5, label="データ")
plt.xlabel("x"); plt.ylabel("f(x)"); plt.legend(fontsize=9)
plt.title("ガウス過程回帰:データを補間し外挿で帯が広がる")
plt.tight_layout(); plt.show()

グラフの意味:事後からサンプルした関数(橙)はデータ点を通り、データのある [3,3.5][-3,3.5] では互いに揃って予測帯(青)が細く、外側へ出ると関数がばらけて帯が事前の幅へ広がります。関数の明示式を仮定せず、カーネルの滑らかさだけでこの推論ができるのが GP の強みです。

5. ベイズ線形回帰との関係:無限次元の極限

GP はベイズ線形回帰(ベイズ線形回帰)と地続きです。基底関数 ϕ(x)\phi(x) を使った線形回帰 f(x)=ϕ(x)wf(x)=\phi(x)^\top wwN(0,Σp)w\sim\mathcal N(0,\Sigma_p) では、ff は GP になり、そのカーネルは k(x,x)=ϕ(x)Σpϕ(x)k(x,x')=\phi(x)^\top\Sigma_p\phi(x')。基底を無限個にした極限が RBF カーネル GP に対応します。GP は明示的な ϕ\phi を持たず、カーネル(内積)だけで計算するので、無限次元の特徴を扱えます(カーネルトリック)。

ハイパーパラメータ(,σf,σn\ell,\sigma_f,\sigma_n)は、周辺尤度 p(yX)=N(y0,K+σn2I)p(y\mid X)=\mathcal N(y\mid 0,K+\sigma_n^2I) を最大化して学習します(経験ベイズ=経験ベイズ の GP 版)。計算コストは KK の逆行列で O(n3)O(n^3) ——大規模データでは疎近似・誘導点などの手法が要ります(この領域は実装が速く動くので要最新確認)。

⚠️ よくある誤解

関連ノート