ベイズ推定とは?仕組みについてわかりやすく解説

ベイズ推定は、機械学習や統計学で広く使われている推定手法です。しかし、ベイズ推定を学ぶには条件付き確率やベータ分布、ディリクレ分布といった確率分布の知識も必要で、参考書で勉強してもなかなかとっつきにくいのが実情です。

今回はベイズ推定がやっていることのイメージを理解できるよう、分かりやすく解説します。

本記事の内容

  • ベイズ推定の直感的な理解
  • 事前分布・尤度・事後分布の関係
  • ベイズの定理を使った定式化
  • Python でのコイントスの例題

前提知識

この記事を読む前に、以下の記事を読んでおくと理解が深まります。

ベイズ推定がやろうとしていること

ベイズ推定のイメージを具体例で考えましょう。今、車が向いている方向 $a$ を推定する問題を考えます。

何も事前の知識がない場合、車が向いている方向は0〜360度のどの方向も等しく可能性があり、完全にランダムです。しかし、1秒前に東南の方向を向いていたという事前知識があったとすると、現在も東南の方向を向いている可能性が高いと推測できます。

このように、事前の知識(事前分布)をデータ(観測)で更新して、より確からしい推定(事後分布)を得るのがベイズ推定の基本的な考え方です。

別の例として、交通事故に遭遇する確率 $P(A)$ を考えましょう。その日に雪が降っているという事前情報がある場合、$P(A)$ の確率は高くなることは想像できるでしょう。ベイズ推定では、このように新しい情報が加わると確率が更新されます。

ベイズ推定の数学的定式化

ベイズの定理

ベイズ推定の核心はベイズの定理です。パラメータ $\theta$ をデータ $\mathcal{D}$ から推定する場合、

$$ \begin{equation} p(\theta|\mathcal{D}) = \frac{p(\mathcal{D}|\theta) \cdot p(\theta)}{p(\mathcal{D})} \end{equation} $$

各項の意味は以下のとおりです。

記号 名前 意味
$p(\theta)$ 事前分布 データを見る前のパラメータに対する信念
$p(\mathcal{D} \mid \theta)$ 尤度関数 パラメータ $\theta$ のもとでデータが観測される確率
$p(\theta \mid \mathcal{D})$ 事後分布 データを見た後のパラメータに対する信念
$p(\mathcal{D})$ 周辺尤度 正規化定数(エビデンス)

よく使われる比例関係の表現として、

$$ \begin{equation} \underbrace{p(\theta|\mathcal{D})}_{\text{事後分布}} \propto \underbrace{p(\mathcal{D}|\theta)}_{\text{尤度}} \times \underbrace{p(\theta)}_{\text{事前分布}} \end{equation} $$

と書くこともあります。分母の $p(\mathcal{D})$ はパラメータ $\theta$ に依存しない定数のため、事後分布の形状を知るうえでは尤度と事前分布の積だけを考えれば十分です。

周辺尤度

(1) 式の分母 $p(\mathcal{D})$ は次のように計算されます。

$$ \begin{equation} p(\mathcal{D}) = \int p(\mathcal{D}|\theta) \cdot p(\theta) \, d\theta \end{equation} $$

この積分が解析的に計算できるかどうかが、ベイズ推定の計算の難しさを左右します。

具体例:コイントスのベイズ推定

問題設定

表が出る確率 $\mu$ が未知のコインを考えます。$N$ 回投げて表が $m$ 回出たとき、$\mu$ をベイズ推定しましょう。

尤度関数

コイン投げの結果はベルヌーイ分布に従うので、尤度関数は、

$$ \begin{equation} p(\mathcal{D}|\mu) = \mu^m (1-\mu)^{N-m} \end{equation} $$

事前分布

パラメータ $\mu \in [0, 1]$ の事前分布として、ベータ分布を選びます。

$$ \begin{equation} p(\mu) = \text{Beta}(\mu|a, b) = \frac{\Gamma(a+b)}{\Gamma(a)\Gamma(b)} \mu^{a-1}(1-\mu)^{b-1} \end{equation} $$

$a = b = 1$ とすると一様分布になり、「事前に何も知らない」状態を表現できます。

事後分布の導出

$$ \begin{align} p(\mu|\mathcal{D}) &\propto p(\mathcal{D}|\mu) \cdot p(\mu) \\ &= \mu^m (1-\mu)^{N-m} \cdot \mu^{a-1}(1-\mu)^{b-1} \\ &= \mu^{m+a-1}(1-\mu)^{N-m+b-1} \end{align} $$

これはベータ分布 $\text{Beta}(\mu|m+a, N-m+b)$ のカーネルに一致するので、

$$ \begin{equation} p(\mu|\mathcal{D}) = \text{Beta}(\mu|m+a, N-m+b) \end{equation} $$

点推定

事後分布から点推定値を得る方法はいくつかあります。

MAP推定(Maximum A Posteriori): 事後分布を最大にする値

$$ \hat{\mu}_{\text{MAP}} = \frac{m + a – 1}{N + a + b – 2} $$

事後平均(EAP推定): 事後分布の期待値

$$ \hat{\mu}_{\text{EAP}} = \frac{m + a}{N + a + b} $$

$a = b = 1$(一様事前分布)の場合、MAP推定は最尤推定 $\hat{\mu}_{\text{MLE}} = m/N$ に一致します。

Python での実装

コイントスのベイズ推定を Python で実装し、データが増えるにつれて事後分布がどう変化するかを可視化しましょう。

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import beta

# 事前分布のハイパーパラメータ
a_prior, b_prior = 1, 1  # 一様分布(無情報事前分布)

# コイン投げのデータ生成(真の確率 0.6)
np.random.seed(42)
true_mu = 0.6
N_total = 100
data = np.random.binomial(1, true_mu, size=N_total)

mu = np.linspace(0, 1, 500)

fig, axes = plt.subplots(2, 3, figsize=(14, 8))
axes = axes.flatten()

observations = [0, 1, 3, 10, 30, 100]

for idx, n in enumerate(observations):
    ax = axes[idx]
    obs = data[:n]
    m = obs.sum() if n > 0 else 0

    a_post = a_prior + m
    b_post = b_prior + (n - m)

    pdf = beta.pdf(mu, a_post, b_post)
    ax.plot(mu, pdf, 'b-', linewidth=2, label=f'Beta({a_post}, {b_post})')
    ax.fill_between(mu, pdf, alpha=0.15, color='blue')
    ax.axvline(x=true_mu, color='r', linestyle='--', alpha=0.7, label=f'True mu={true_mu}')

    if n > 0:
        mle = m / n
        ax.axvline(x=mle, color='g', linestyle=':', alpha=0.7, label=f'MLE={mle:.2f}')

    ax.set_title(f'N={n}, heads={int(m)}', fontsize=12)
    ax.set_xlabel('mu', fontsize=10)
    ax.set_ylabel('p(mu|D)', fontsize=10)
    ax.legend(fontsize=8)
    ax.grid(True, alpha=0.3)

plt.suptitle('Bayesian Inference: Coin Toss Example', fontsize=14)
plt.tight_layout()
plt.show()

このグラフでは、データが0件の時は一様分布(何も知らない状態)から始まり、データが増えるにつれて事後分布のピークが真の確率 $\mu = 0.6$ 付近に鋭くなっていく様子が確認できます。

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import beta

# 事前分布の影響を比較
np.random.seed(42)
true_mu = 0.6
data = np.random.binomial(1, true_mu, size=10)
m = data.sum()
N = len(data)

# 3種類の事前分布
priors = [
    (1, 1, "Uniform Beta(1,1)"),
    (2, 5, "Biased Beta(2,5)"),
    (10, 10, "Concentrated Beta(10,10)")
]

mu = np.linspace(0, 1, 500)
fig, axes = plt.subplots(1, 3, figsize=(15, 5))

for idx, (a, b_param, name) in enumerate(priors):
    ax = axes[idx]
    a_post = a + m
    b_post = b_param + (N - m)

    # 事前分布
    prior_pdf = beta.pdf(mu, a, b_param)
    ax.plot(mu, prior_pdf, 'g--', linewidth=1.5, label=f'Prior: {name}')

    # 事後分布
    post_pdf = beta.pdf(mu, a_post, b_post)
    ax.plot(mu, post_pdf, 'b-', linewidth=2, label=f'Posterior: Beta({a_post},{b_post})')

    ax.fill_between(mu, post_pdf, alpha=0.15, color='blue')
    ax.axvline(x=true_mu, color='r', linestyle='--', alpha=0.7, label=f'True mu={true_mu}')
    ax.set_title(name, fontsize=12)
    ax.set_xlabel('mu', fontsize=10)
    ax.legend(fontsize=8)
    ax.grid(True, alpha=0.3)

plt.suptitle(f'Effect of Prior Distribution (N={N}, heads={m})', fontsize=14)
plt.tight_layout()
plt.show()

このコードでは、異なる事前分布(一様分布、偏った事前分布、集中した事前分布)がデータ数が少ないときに事後分布に与える影響を比較しています。データが少ないほど事前分布の影響が大きく、データが増えるほど尤度の影響が支配的になります。

最尤推定との違い

観点 最尤推定 ベイズ推定
推定対象 点推定値 $\hat{\theta}$ 分布 $p(\theta \mid \mathcal{D})$
事前知識 使わない 事前分布として組み込む
不確かさ 点推定のみ 分布の幅で不確かさを表現
データが少ない場合 過学習しやすい 事前分布による正則化効果

ベイズ推定の大きな利点は、推定結果が点ではなく分布として得られるため、パラメータの不確かさを自然に表現できることです。

まとめ

本記事では、ベイズ推定の基本について解説しました。

  • ベイズ推定は「事前分布 × 尤度 → 事後分布」という枠組みで、データを使って信念を更新する手法
  • コイントスの例題では、ベータ分布(事前分布)× ベルヌーイ尤度 → ベータ分布(事後分布)と解析的に計算できる
  • データが増えるにつれて事後分布が真のパラメータに収束し、事前分布の影響が薄れていく
  • ベイズ推定は不確かさを分布として表現できるため、データが少ない場合でも安定した推定ができる

次のステップとして、以下の記事も参考にしてください。