ベイズの定理とは?直感的理解から数学的導出、Python実装まで徹底解説

あなたが健康診断を受けたとしましょう。ある病気の検査で「陽性」と判定されました。その検査は感度99%、つまり本当に病気の人を99%の確率で正しく陽性と判定できる優秀な検査です。では、あなたが本当にその病気にかかっている確率はどれくらいでしょうか?

「99%の感度だから、ほぼ間違いなく病気だ」と考えたくなりますが、実はそうではありません。もしその病気が10,000人に1人しかかからない希少疾患だとしたら、検査で陽性と出ても本当に病気である確率はわずか約2%以下です。この驚くべきギャップを正しく理解し、計算するための道具がベイズの定理(Bayes’ theorem)です。

ベイズの定理は、「新しい証拠(データ)を観測したとき、もともと持っていた信念(確率)をどのように更新すべきか」を教えてくれる数学的なルールです。18世紀の牧師トーマス・ベイズにちなんで名付けられたこの定理は、現代のあらゆる分野で活用されています。

  • 医療診断: 検査結果が陽性だったとき、本当に病気である確率を正しく計算する
  • 迷惑メールフィルタ: メールの文面から迷惑メールである確率を推定する(ナイーブベイズ分類器)
  • 機械学習: ベイズ推定、ベイズ最適化、ガウス過程など、データからモデルを構築する基盤技術
  • 自動運転: センサーデータを統合して周囲の環境を推定するセンサーフュージョン

本記事の内容

  • 条件付き確率の復習と乗法定理
  • ベイズの定理の直感的な理解 — 「信念の更新ルール」としての解釈
  • ベイズの定理の数学的な導出
  • 事前確率・尤度・事後確率の役割
  • 具体例: 医療検査問題、迷惑メールフィルタ
  • Pythonでの数値計算と可視化
  • 連続版ベイズの定理とベイズ統計学への接続

前提知識

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

条件付き確率の復習

ベイズの定理は条件付き確率の性質から直接導かれるため、まずは条件付き確率をしっかり復習しておきましょう。

条件付き確率の定義

条件付き確率とは、「ある事象が起きたと分かった上で、別の事象が起きる確率」のことです。日常的な場面で考えてみましょう。

たとえば、天気予報で「午前中に曇った日は、午後に雨が降りやすい」という経験則があるとします。これは「午前に曇り」という条件のもとでの「午後に雨」の確率が、無条件の「午後に雨」の確率よりも高いことを意味しています。

数学的には、事象 $B$ が起きたという条件のもとで事象 $A$ が起きる確率を

$$ P(A|B) = \frac{P(A \cap B)}{P(B)} $$

と定義します。ここで $P(B) > 0$ を仮定しています。$P(A \cap B)$ は $A$ と $B$ が同時に起きる確率です。

この定義式は「$B$ が起きた世界に限定したとき、そのうち $A$ も起きている割合」と読めます。全体の標本空間を $B$ に絞り込んでいるのです。

乗法定理

条件付き確率の定義式を変形すると、同時確率を条件付き確率で表す乗法定理が得られます。

$$ P(A \cap B) = P(A|B) \cdot P(B) $$

同様に、条件を入れ替えた形も成り立ちます。

$$ P(A \cap B) = P(B|A) \cdot P(A) $$

左辺はどちらも同じ $P(A \cap B)$ なので、右辺同士を等号で結ぶことができます。この関係こそが、ベイズの定理を導く鍵です。

全確率の定理

もう一つ重要な道具として、全確率の定理を確認します。事象 $A_1, A_2, \ldots, A_n$ が互いに排反で、かつその和集合が全体の標本空間 $\Omega$ に等しいとき(つまり $\{A_1, \ldots, A_n\}$ が $\Omega$ の分割であるとき)、任意の事象 $B$ に対して

$$ P(B) = \sum_{k=1}^{n} P(B|A_k) P(A_k) $$

が成り立ちます。これは「$B$ が起きる確率は、考えうる全ての原因 $A_k$ を通じた経路の確率を合計したもの」という意味です。

たとえば、工場に3つの製造ラインがあり、それぞれ全体の40%、35%、25%の製品を作っているとします。各ラインの不良品率がそれぞれ1%、2%、3%のとき、ランダムに取り出した製品が不良品である確率は

$$ P(\text{不良品}) = 0.01 \times 0.40 + 0.02 \times 0.35 + 0.03 \times 0.25 = 0.004 + 0.007 + 0.0075 = 0.0185 $$

と計算できます。全確率の定理は、ベイズの定理の分母を計算する際に不可欠です。

条件付き確率の基本を確認したところで、いよいよベイズの定理の導出に進みましょう。

ベイズの定理の直感的理解

信念の更新ルール

ベイズの定理を直感的に理解するために、探偵の推理を想像してみましょう。

ある事件で、容疑者がAさん、Bさん、Cさんの3人いるとします。事件の状況から、探偵は最初「Aさんの確率が50%、Bさんが30%、Cさんが20%」と見積もりました。これが事前確率です。

次に、新しい証拠(事件現場の近くにBさんの車が止まっていた目撃証言)が見つかりました。この証拠のもとで、探偵は確率を更新します。「Bさんの可能性が上がり、Aさん・Cさんの可能性は相対的に下がる」と判断するでしょう。更新後の確率が事後確率です。

この「事前の信念 + 新しい証拠 → 事後の信念」という更新プロセスを数学的に定式化したものがベイズの定理です。

3つの構成要素

ベイズの定理は次の3つの要素から成り立っています。

事前確率(prior probability) $P(A)$: データを見る前に、仮説 $A$ がどの程度もっともらしいかを表す確率です。探偵の例では「捜査前の各容疑者の怪しさ」に相当します。事前確率には過去の経験や既存の知識が反映されます。

尤度(likelihood) $P(B|A)$: 仮説 $A$ が正しいとしたとき、観測された証拠 $B$ がどれくらいの確率で生じるかを表します。探偵の例では「もしBさんが犯人なら、事件現場の近くにBさんの車が止まっている確率」に相当します。尤度は「仮説のもとでのデータの生成確率」です。

事後確率(posterior probability) $P(A|B)$: 証拠 $B$ を観測した後に、仮説 $A$ がどれくらい正しいかを表す確率です。探偵の例では「新しい証拠を踏まえた上での各容疑者の怪しさ」です。

この3つを結ぶ公式がベイズの定理であり、比例関係として書くと

$$ \text{事後確率} \propto \text{尤度} \times \text{事前確率} $$

となります。つまり、事後確率は「データが仮説をどれくらい支持するか(尤度)」と「もともとの信念(事前確率)」の積に比例するのです。

直感的なイメージをつかんだところで、これを数式として厳密に導出しましょう。

ベイズの定理の数学的導出

条件付き確率からの導出

先ほど復習した乗法定理を使います。同時確率 $P(A \cap B)$ を2通りに表現できました。

$$ P(A \cap B) = P(A|B) \cdot P(B) $$

$$ P(A \cap B) = P(B|A) \cdot P(A) $$

左辺が同じなので、右辺同士を等号で結びます。

$$ P(A|B) \cdot P(B) = P(B|A) \cdot P(A) $$

両辺を $P(B)$ で割ると($P(B) > 0$ を仮定)

$$ \begin{equation} P(A|B) = \frac{P(B|A) \cdot P(A)}{P(B)} \end{equation} $$

これがベイズの定理です。条件付き確率の定義から、わずか数ステップで導かれることがわかります。数式自体は極めてシンプルですが、その解釈は奥深いものがあります。

各項の意味と役割

ベイズの定理の各項を改めて整理しましょう。

記号 名前 役割
$P(A \mid B)$ 事後確率 証拠 $B$ を見た後の仮説 $A$ の確率(知りたい量)
$P(B \mid A)$ 尤度 仮説 $A$ のもとで証拠 $B$ が観測される確率
$P(A)$ 事前確率 証拠を見る前の仮説 $A$ の確率
$P(B)$ 周辺尤度(エビデンス) 証拠 $B$ が観測される全体的な確率(正規化定数)

なぜこの形になるのかを直感的に考えてみましょう。事後確率 $P(A|B)$ は次のように読めます。

  • 分子の $P(B|A) \cdot P(A)$: 仮説 $A$ が正しくて、かつ証拠 $B$ が観測される確率($A$ 経由で $B$ が起きるルートの確率)
  • 分母の $P(B)$: 全ての仮説を通じて $B$ が起きる確率(全ルートの確率の合計)

したがって、ベイズの定理は「$B$ が起きた全ルートのうち、$A$ 経由のルートが占める割合」を計算していると解釈できます。

全確率の定理を用いた形

分母の $P(B)$ は、仮説の集合 $\{A_1, A_2, \ldots, A_n\}$ が標本空間の排反な分割をなすとき、全確率の定理により

$$ P(B) = \sum_{k=1}^{n} P(B|A_k) P(A_k) $$

と展開できます。これを代入すると、ベイズの定理は次のようになります。

$$ \begin{equation} P(A_i|B) = \frac{P(B|A_i) P(A_i)}{\sum_{k=1}^{n} P(B|A_k) P(A_k)} \end{equation} $$

この形は、複数の仮説の中から証拠 $B$ に基づいて最も確からしい仮説を選ぶ問題で特に便利です。分母は全仮説にわたるエビデンスの合計であり、分子の各仮説への寄与を正規化する役割を果たします。

比例関係としての表現

複数の仮説を比較するとき、分母 $P(B)$ は全ての仮説に共通する定数です。そのため

$$ P(A_i|B) \propto P(B|A_i) \cdot P(A_i) $$

と書くことができます。「事後確率は、尤度と事前確率の積に比例する」というこの簡潔な関係は、ベイズ統計学で最も頻繁に使われる表現です。

数式の導出ができたところで、具体的な数値を使った例題を通じて、ベイズの定理がどのように働くかを体感しましょう。

具体例1: 医療検査問題

問題設定

冒頭で触れた医療検査の問題を、正確な数値で解いてみます。

  • 有病率(事前確率): $P(\text{病気}) = 0.001$(0.1%、つまり1,000人に1人が罹患)
  • 感度(真陽性率): $P(\text{陽性}|\text{病気}) = 0.99$(99%)
  • 特異度(真陰性率): $P(\text{陰性}|\text{健康}) = 0.95$(95%)

求めたいのは「検査で陽性と判定されたとき、本当に病気である確率」、すなわち $P(\text{病気}|\text{陽性})$ です。

ステップ1: 偽陽性率の計算

特異度が95%なので、健康な人が誤って陽性と判定される確率(偽陽性率)は

$$ P(\text{陽性}|\text{健康}) = 1 – P(\text{陰性}|\text{健康}) = 1 – 0.95 = 0.05 $$

です。つまり、健康な人の5%が誤って陽性と判定されてしまいます。

ステップ2: 全確率の定理でエビデンスを計算

全確率の定理を使って、陽性と判定される全体的な確率 $P(\text{陽性})$ を計算します。

$$ P(\text{陽性}) = P(\text{陽性}|\text{病気}) \cdot P(\text{病気}) + P(\text{陽性}|\text{健康}) \cdot P(\text{健康}) $$

ここで $P(\text{健康}) = 1 – P(\text{病気}) = 0.999$ です。数値を代入すると

$$ P(\text{陽性}) = 0.99 \times 0.001 + 0.05 \times 0.999 = 0.00099 + 0.04995 = 0.05094 $$

ステップ3: ベイズの定理を適用

$$ P(\text{病気}|\text{陽性}) = \frac{P(\text{陽性}|\text{病気}) \cdot P(\text{病気})}{P(\text{陽性})} = \frac{0.99 \times 0.001}{0.05094} \approx 0.0194 $$

つまり、検査で陽性と判定されても、本当に病気である確率はわずか約1.94%です。

なぜこんなに低いのか — 基準率の無視

この結果は「基準率の無視」(base rate neglect)と呼ばれる認知バイアスを浮き彫りにします。直感的に理解するために、100,000人に検査を行った場合を考えましょう。

  • 病気の人: 100,000 × 0.001 = 100人
  • うち陽性と判定される人(真陽性): 100 × 0.99 = 99人
  • 健康な人: 100,000 × 0.999 = 99,900人
  • うち陽性と判定される人(偽陽性): 99,900 × 0.05 = 4,995人
  • 陽性と判定された人の合計: 99 + 4,995 = 5,094人
  • そのうち本当に病気の人: 99 / 5,094 ≈ 1.94%

偽陽性の数が真陽性の約50倍にもなっています。有病率が低い場合、母集団のほとんどが健康な人であるため、少しの偽陽性率でも大量の偽陽性を生んでしまうのです。

ベイズの定理は、検査の精度だけでなく、事前確率(有病率)が結論に決定的な影響を与えることを教えてくれます。

医療の場面を見たところで、次はベイズの定理が情報技術でどう使われているかを見てみましょう。

具体例2: 迷惑メールフィルタ

問題設定

受信したメールに「当選」という単語が含まれていたとき、そのメールが迷惑メール(スパム)である確率を求めます。

過去のデータから以下がわかっているとします。

  • 全メールのうちスパムの割合: $P(\text{スパム}) = 0.3$
  • スパムに「当選」が含まれる確率: $P(\text{当選}|\text{スパム}) = 0.8$
  • 正常なメールに「当選」が含まれる確率: $P(\text{当選}|\text{正常}) = 0.01$

ベイズの定理の適用

全確率の定理で分母を計算します。

$$ P(\text{当選}) = P(\text{当選}|\text{スパム}) \cdot P(\text{スパム}) + P(\text{当選}|\text{正常}) \cdot P(\text{正常}) $$

数値を代入すると

$$ P(\text{当選}) = 0.8 \times 0.3 + 0.01 \times 0.7 = 0.24 + 0.007 = 0.247 $$

ベイズの定理により

$$ P(\text{スパム}|\text{当選}) = \frac{0.8 \times 0.3}{0.247} = \frac{0.24}{0.247} \approx 0.972 $$

「当選」という単語を含むメールは、約97.2%の確率でスパムと判定されます。

逐次更新: 証拠を積み重ねる

ベイズの定理の強力な特徴の一つは、証拠を逐次的に取り込めることです。最初の証拠で得られた事後確率を、次の証拠に対する事前確率として使えます。

たとえば、「当選」に続いて「今すぐ」という単語も見つかったとします。$P(\text{今すぐ}|\text{スパム}) = 0.6$、$P(\text{今すぐ}|\text{正常}) = 0.05$ として、先ほどの事後確率 0.972 を新しい事前確率として使います。

$$ P(\text{スパム}|\text{当選}, \text{今すぐ}) = \frac{0.6 \times 0.972}{0.6 \times 0.972 + 0.05 \times 0.028} = \frac{0.5832}{0.5832 + 0.0014} \approx 0.998 $$

証拠が2つになっただけで、スパムの確率は99.8%まで上昇しました。このように、ベイズの定理は新しい証拠が加わるたびに信念を更新していく仕組みを提供しています。これがナイーブベイズ分類器の基本原理です。

数値計算で理解を深めたところで、Python で可視化を行い、ベイズの定理のさまざまな性質をグラフで確認しましょう。

Python で医療検査問題を可視化する

ここでは、事前確率(有病率)が事後確率にどのような影響を与えるかを、Python を使って可視化します。

import numpy as np
import matplotlib.pyplot as plt

# 医療検査のパラメータ
sensitivity = 0.99   # 感度 P(陽性|病気)
specificity = 0.95   # 特異度 P(陰性|健康)
fpr = 1 - specificity  # 偽陽性率

# 有病率(事前確率)を変化させる
prevalence = np.linspace(0.0001, 0.5, 1000)

# ベイズの定理で事後確率を計算
p_positive = sensitivity * prevalence + fpr * (1 - prevalence)
posterior = (sensitivity * prevalence) / p_positive

fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# (a) 事後確率 vs 有病率
ax = axes[0]
ax.plot(prevalence * 100, posterior * 100, 'b-', linewidth=2.5)
ax.axhline(50, color='gray', linestyle='--', alpha=0.5, label='50% line')
ax.axvline(0.1, color='red', linestyle=':', linewidth=1.5, alpha=0.7,
           label='Prevalence = 0.1%')

# 有病率 0.1% のときの事後確率をプロット
idx = np.argmin(np.abs(prevalence - 0.001))
ax.plot(0.1, posterior[idx] * 100, 'ro', markersize=10)
ax.annotate(f'{posterior[idx]*100:.1f}%',
            xy=(0.1, posterior[idx]*100),
            xytext=(5, 15), fontsize=12, fontweight='bold',
            arrowprops=dict(arrowstyle='->', color='red'))
ax.set_xlabel('Prevalence (%)', fontsize=12)
ax.set_ylabel('P(Disease | Positive) (%)', fontsize=12)
ax.set_title('Posterior Probability vs Prevalence\n'
             f'(Sensitivity={sensitivity}, Specificity={specificity})',
             fontsize=13)
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3)
ax.set_xlim(0, 50)
ax.set_ylim(0, 100)

# (b) 100,000人での人数内訳
ax = axes[1]
n_total = 100000
prev_val = 0.001
n_disease = int(n_total * prev_val)
n_healthy = n_total - n_disease

tp = int(n_disease * sensitivity)    # 真陽性
fn = n_disease - tp                   # 偽陰性
fp = int(n_healthy * fpr)             # 偽陽性
tn = n_healthy - fp                   # 真陰性

categories = ['True\nPositive', 'False\nPositive',
              'False\nNegative', 'True\nNegative']
counts = [tp, fp, fn, tn]
colors = ['green', 'red', 'orange', 'steelblue']

bars = ax.bar(categories, counts, color=colors, alpha=0.8, edgecolor='gray')
for bar, count in zip(bars, counts):
    ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 500,
            f'{count:,}', ha='center', fontsize=11, fontweight='bold')
ax.set_ylabel('Number of People', fontsize=12)
ax.set_title(f'Screening {n_total:,} People\n(Prevalence = {prev_val*100}%)',
             fontsize=13)
ax.grid(True, alpha=0.3, axis='y')

plt.tight_layout()
plt.savefig('bayes_theorem_medical.png', dpi=150, bbox_inches='tight')
plt.show()

このグラフから2つの重要な知見が得られます。

  1. 左図(事後確率と有病率の関係): 有病率が極めて低い領域(0.1%付近)では、感度99%・特異度95%という高精度な検査であっても、事後確率はわずか約2%です。有病率が上昇するにつれて事後確率は急速に増加し、有病率が約5%を超えると事後確率が50%を超えます。この非線形な曲線は、事前確率がいかに結論を左右するかを如実に示しています。

  2. 右図(100,000人のスクリーニング結果): 偽陽性(赤)が約5,000人であるのに対し、真陽性(緑)はわずか99人です。陽性と判定された人のほとんどが実は健康であり、これが事後確率を押し下げる直接的な原因です。低有病率のスクリーニングでは、偽陽性の数が真陽性を圧倒してしまうのです。

Python でベイズ更新の逐次的な動きを可視化する

次に、コイン投げを題材に、データが増えるにつれて事後分布がどう変化するかを見てみましょう。事前分布としてベータ分布 $\text{Beta}(1, 1)$(一様分布)を使い、表が出る確率 $\theta$ を逐次推定します。

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

# コイン投げのシミュレーション
np.random.seed(42)
true_theta = 0.7   # 真のコインの偏り
n_flips = 100
flips = np.random.binomial(1, true_theta, n_flips)

# 描画する観測ステップ
steps = [0, 1, 3, 5, 10, 20, 50, 100]
theta_grid = np.linspace(0, 1, 500)

fig, axes = plt.subplots(2, 4, figsize=(16, 8))
axes = axes.flatten()

for idx, n in enumerate(steps):
    ax = axes[idx]
    if n == 0:
        a_post, b_post = 1, 1
        title = 'Prior (n=0)'
    else:
        k = int(np.sum(flips[:n]))
        a_post = 1 + k
        b_post = 1 + (n - k)
        title = f'n={n}, heads={k}'

    posterior_pdf = stats.beta.pdf(theta_grid, a_post, b_post)
    ax.plot(theta_grid, posterior_pdf, 'b-', linewidth=2)
    ax.fill_between(theta_grid, posterior_pdf, alpha=0.15, color='blue')
    ax.axvline(true_theta, color='red', linestyle='--', linewidth=1.5,
               alpha=0.7, label=f'True $\\theta$={true_theta}')

    post_mean = a_post / (a_post + b_post)
    ax.axvline(post_mean, color='green', linestyle=':', linewidth=1.5,
               alpha=0.7, label=f'Mean={post_mean:.3f}')

    ax.set_title(title, fontsize=11)
    ax.set_xlim(0, 1)
    ax.set_xlabel(r'$\theta$', fontsize=10)
    if idx % 4 == 0:
        ax.set_ylabel('Density', fontsize=10)
    ax.legend(fontsize=7, loc='upper left')
    ax.grid(True, alpha=0.3)

plt.suptitle('Sequential Bayesian Update: Coin Flip\n'
             r'Prior: Beta(1,1), Likelihood: Binomial($\theta$)',
             fontsize=14, y=1.02)
plt.tight_layout()
plt.savefig('bayes_sequential_update.png', dpi=150, bbox_inches='tight')
plt.show()

この逐次更新の可視化から、ベイズ推論の本質的な性質が読み取れます。

  1. 事前分布から事後分布への変化: $n=0$ では一様分布であり、「$\theta$ の値について何も情報がない」状態です。データが1件入るだけでも分布の形が変わり始め、$n=100$ では真の値 $\theta = 0.7$ の周辺に鋭いピークを持つ分布になります。

  2. 事後平均の収束: 緑の点線で示した事後平均は、データが少ない段階ではばらつきますが、データが増えるにつれて真の値 $0.7$ に安定して近づいていきます。これはベイズ推定の一致性(consistency)の表れです。

  3. 不確実性の定量化: 分布の幅はデータに対する確信度を表しています。$n=5$ では広い(不確実性が大きい)のに対し、$n=100$ では狭い(確信度が高い)。ベイズ推論は、推定値だけでなく「どれくらい自信があるか」も同時に教えてくれるのです。

Python で事前分布の影響を可視化する

事前分布の選び方が推定結果にどう影響するかを比較してみましょう。同じデータに対して、異なる事前分布を使うとどうなるかを見ます。

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

# 観測データ: 20回中14回表
n_obs = 20
k_obs = 14
theta_grid = np.linspace(0, 1, 500)

# 3種類の事前分布
priors = [
    ('Beta(1,1) - Uniform', 1, 1, 'blue'),
    ('Beta(5,5) - Centered', 5, 5, 'red'),
    ('Beta(2,8) - Biased low', 2, 8, 'green'),
]

fig, axes = plt.subplots(1, 3, figsize=(16, 5))

for idx, (name, a_prior, b_prior, color) in enumerate(priors):
    ax = axes[idx]

    # 事前分布
    prior = stats.beta.pdf(theta_grid, a_prior, b_prior)
    # 尤度(正規化のため最大値で割る)
    likelihood = stats.binom.pmf(k_obs, n_obs, theta_grid)
    likelihood_scaled = likelihood / np.max(likelihood) * np.max(prior) * 0.5
    # 事後分布
    a_post = a_prior + k_obs
    b_post = b_prior + (n_obs - k_obs)
    posterior = stats.beta.pdf(theta_grid, a_post, b_post)

    ax.plot(theta_grid, prior, '--', color=color, linewidth=2,
            alpha=0.6, label=f'Prior: {name}')
    ax.plot(theta_grid, likelihood_scaled, 'k-', linewidth=1.5,
            alpha=0.5, label='Likelihood (scaled)')
    ax.plot(theta_grid, posterior, '-', color=color, linewidth=2.5,
            label=f'Posterior: Beta({a_post},{b_post})')
    ax.fill_between(theta_grid, posterior, alpha=0.1, color=color)

    # MLE と事後平均
    mle = k_obs / n_obs
    post_mean = a_post / (a_post + b_post)
    ax.axvline(mle, color='black', linestyle=':', linewidth=1.5,
               label=f'MLE={mle:.3f}')
    ax.axvline(post_mean, color=color, linestyle=':',
               linewidth=1.5, label=f'Post.mean={post_mean:.3f}')

    ax.set_xlabel(r'$\theta$', fontsize=12)
    ax.set_ylabel('Density', fontsize=12)
    ax.set_title(f'Prior: {name}\n(n={n_obs}, k={k_obs})', fontsize=11)
    ax.legend(fontsize=7, loc='upper left')
    ax.grid(True, alpha=0.3)
    ax.set_xlim(0, 1)

plt.suptitle('Effect of Prior Distribution on Posterior',
             fontsize=14, y=1.02)
plt.tight_layout()
plt.savefig('bayes_prior_effect.png', dpi=150, bbox_inches='tight')
plt.show()

この比較から、事前分布の影響に関する重要な知見が得られます。

  1. 一様事前分布(左): 事前分布が何の情報も持たないため、事後分布は尤度関数と同じ形になります。事後平均 $0.682$ はMLE $0.700$ に近い値です。事前情報がないとき、ベイズ推定は最尤推定とほぼ同じ結論を導きます。

  2. 対称的な事前分布(中央): $\text{Beta}(5, 5)$ は「$\theta$ は0.5付近だろう」という弱い事前信念を表します。事後分布は尤度のピーク(0.7付近)と事前分布のピーク(0.5)の間に引っ張られ、事後平均は $0.633$ とMLE より小さくなります。これが事前分布による縮小効果(shrinkage)です。

  3. 偏った事前分布(右): $\text{Beta}(2, 8)$ は「$\theta$ は小さい値だろう」という強い信念を表します。データが14/20=70%の表を示しているにもかかわらず、事後分布は事前分布にかなり引っ張られています。しかし、データ量が増えれば事前分布の影響は薄まっていきます。

このように、事前分布の選択はベイズ推定の結果に直接影響しますが、データ量が十分に多ければその影響は小さくなるというのが一般的な性質です。

ここまで離散的な確率と簡単な具体例で議論してきましたが、実際の統計学やデータ分析ではパラメータが連続値をとる場合が多くあります。次に、連続版のベイズの定理を見ていきましょう。

連続版ベイズの定理

離散から連続への拡張

これまでの議論では、$P(A)$ や $P(B|A)$ は離散的な確率でした。しかし、「コインの表が出る確率 $\theta$」のように、パラメータが連続値をとる場合には確率密度関数(pdf)を使います。

連続版ベイズの定理は、パラメータ $\theta$ とデータ $x$ に対して

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

と書けます。離散版との対応を整理しましょう。

離散版 連続版 意味
$P(A)$ $p(\theta)$ 事前分布
$P(B \mid A)$ $p(x \mid \theta)$ 尤度関数
$P(A \mid B)$ $p(\theta \mid x)$ 事後分布
$\sum_k P(B \mid A_k) P(A_k)$ $\int p(x \mid \theta) p(\theta) d\theta$ 周辺尤度

形式的には離散版と同じですが、分母の周辺尤度が積分になるのが重要な違いです。

$$ p(x) = \int p(x | \theta) \cdot p(\theta) \, d\theta $$

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

比例関係

$p(x)$ は $\theta$ に依存しない定数なので、事後分布の「形」を知るだけなら

$$ p(\theta | x) \propto p(x | \theta) \cdot p(\theta) $$

で十分です。ベイズ統計学では、この比例関係を利用して事後分布の形を特定し、後から正規化定数を求める(あるいはMCMCなどでサンプリングする)というアプローチが一般的です。

共役事前分布

事前分布と尤度関数の組み合わせによっては、事後分布が事前分布と同じ分布族に属することがあります。この性質を共役性(conjugacy)と呼び、計算が解析的に行えるため非常に便利です。

代表的な共役ペアを表にまとめます。

尤度 事前分布(共役) 事後分布
ベルヌーイ / 二項分布 ベータ分布 $\text{Beta}(\alpha, \beta)$ $\text{Beta}(\alpha + k, \beta + n – k)$
ポアソン分布 ガンマ分布 $\text{Gamma}(\alpha, \beta)$ $\text{Gamma}(\alpha + \sum x_i, \beta + n)$
正規分布(既知分散) 正規分布 $N(\mu_0, \sigma_0^2)$ 正規分布
多項分布 ディリクレ分布 ディリクレ分布

共役事前分布を使えば、事後分布のパラメータを更新するだけで済むため、逐次的なベイズ更新が効率的に行えます。

ベイズ統計学への接続

連続版ベイズの定理は、ベイズ統計学全体の基盤です。ベイズ統計学では、未知のパラメータ $\theta$ を確率変数として扱い、データの観測によって事前分布 $p(\theta)$ を事後分布 $p(\theta|x)$ へと更新します。

事後分布から得られる情報は豊富です。

  • 点推定: 事後平均 $E[\theta|x]$、事後最頻値(MAP推定)$\arg\max_\theta p(\theta|x)$
  • 区間推定: 95%信用区間(事後分布の中央95%が含まれる区間)
  • 予測分布: 新しいデータ $x_{\text{new}}$ の確率 $p(x_{\text{new}}|x) = \int p(x_{\text{new}}|\theta) p(\theta|x) d\theta$

最尤推定が「点」しか返さないのに対し、ベイズ推定は「分布」を返すため、推定の不確実性を完全に記述できるのが大きな利点です。

ここまでの理論を踏まえ、最後にもう一つの Python 実装として、感度と特異度の組み合わせが事後確率にどう影響するかを等高線図で可視化しましょう。

Python で感度・特異度と事後確率の関係を可視化する

検査の感度と特異度をさまざまに変えたとき、事後確率がどう変わるかを等高線図で調べます。有病率を複数設定して比較します。

import numpy as np
import matplotlib.pyplot as plt

# 感度と特異度の範囲
sensitivity_range = np.linspace(0.5, 1.0, 200)
specificity_range = np.linspace(0.5, 1.0, 200)
sens_grid, spec_grid = np.meshgrid(sensitivity_range, specificity_range)

# 4つの有病率で比較
prevalences = [0.001, 0.01, 0.05, 0.1]

fig, axes = plt.subplots(2, 2, figsize=(12, 10))
axes = axes.flatten()

for idx, prev in enumerate(prevalences):
    ax = axes[idx]
    fpr_grid = 1 - spec_grid
    p_pos = sens_grid * prev + fpr_grid * (1 - prev)
    post = (sens_grid * prev) / p_pos

    contour = ax.contourf(sens_grid * 100, spec_grid * 100,
                          post * 100, levels=20, cmap='RdYlGn')
    plt.colorbar(contour, ax=ax, label='P(Disease|Positive) %')
    ax.contour(sens_grid * 100, spec_grid * 100,
               post * 100, levels=[50], colors='black',
               linewidths=2, linestyles='--')
    ax.set_xlabel('Sensitivity (%)', fontsize=11)
    ax.set_ylabel('Specificity (%)', fontsize=11)
    ax.set_title(f'Prevalence = {prev*100:.1f}%', fontsize=12)

plt.suptitle('Posterior Probability as Function of\n'
             'Sensitivity and Specificity',
             fontsize=14, y=1.02)
plt.tight_layout()
plt.savefig('bayes_sensitivity_specificity.png', dpi=150, bbox_inches='tight')
plt.show()

この等高線図から、検査設計における重要な知見が得られます。

  1. 有病率が低いとき(左上、0.1%): 感度と特異度がともに非常に高くても、事後確率はなかなか高くなりません。特に特異度が99%以上でないと事後確率は10%にも達しません。低有病率のスクリーニングでは特異度が圧倒的に重要です。

  2. 有病率が中程度のとき(右下、10%): 感度と特異度がともに80%程度でも事後確率が50%を超える領域が広がります。有病率が高い集団(例: 症状のある患者集団)に対しては、検査の性能要件が緩和されます。

  3. 等高線の傾き: すべてのパネルで、等高線は特異度の方向(縦軸)により密に並んでいます。これは、特異度を少し改善するだけで事後確率が大きく変わることを意味しています。検査の開発において、偽陽性率の低減がいかに重要かがわかります。

オッズ形式のベイズの定理

オッズとベイズファクター

ベイズの定理には、オッズ(odds)を使った見通しの良い形もあります。ここで紹介するオッズ形式は、計算と解釈の両面で便利です。

事象 $A$ のオッズとは、$A$ が起きる確率と起きない確率の比です。

$$ O(A) = \frac{P(A)}{P(\bar{A})} = \frac{P(A)}{1 – P(A)} $$

たとえば、確率が $2/3$ のとき、オッズは $2:1$(「2対1で起きる」)となります。

ベイズの定理を仮説 $A$ とその否定 $\bar{A}$ について書き、辺々割ると

$$ \frac{P(A|B)}{P(\bar{A}|B)} = \frac{P(B|A)}{P(B|\bar{A})} \cdot \frac{P(A)}{P(\bar{A})} $$

この式を言葉で表すと

$$ \text{事後オッズ} = \text{ベイズファクター} \times \text{事前オッズ} $$

ここでベイズファクター $\text{BF} = P(B|A) / P(B|\bar{A})$ は、証拠 $B$ が仮説 $A$ をどれだけ支持するかを表す指標です。

オッズ形式の利点

オッズ形式には2つの利点があります。

  1. 乗法的な更新: 独立な証拠 $B_1, B_2, \ldots$ に対して、ベイズファクターを掛けるだけで事後オッズが求まります。

$$ \text{事後オッズ} = \text{BF}_1 \times \text{BF}_2 \times \cdots \times \text{BF}_n \times \text{事前オッズ} $$

  1. 直感的な解釈: $\text{BF} > 1$ なら証拠は仮説を支持し、$\text{BF} < 1$ なら反証です。$\text{BF} = 10$ なら「証拠は仮説を10倍支持している」と読めます。

医療検査の例をオッズで解く

先ほどの医療検査問題をオッズ形式で解き直してみましょう。

事前オッズ: $P(\text{病気}) / P(\text{健康}) = 0.001 / 0.999 \approx 1/999$

ベイズファクター: $P(\text{陽性}|\text{病気}) / P(\text{陽性}|\text{健康}) = 0.99 / 0.05 = 19.8$

$$ \text{事後オッズ} = 19.8 \times \frac{1}{999} \approx \frac{1}{50.5} $$

事後確率に変換すると $P(\text{病気}|\text{陽性}) = 1 / (1 + 50.5) \approx 0.0194$、先ほどの計算と一致します。

オッズ形式で見ると、「検査陽性というベイズファクター約20の証拠」をもってしても、「事前オッズ 1/999 という極めて低い出発点」を覆すには力不足であるという構造が直感的に理解できます。

まとめ

本記事では、ベイズの定理について条件付き確率の復習から始めて、直感的な理解、数学的導出、具体例、Python による可視化まで解説しました。

  • ベイズの定理の本質: 「事前の信念 + 新しい証拠 → 事後の信念」という信念の更新ルールであり、$P(A|B) = P(B|A) P(A) / P(B)$ という形をとる
  • 事前確率の重要性: 医療検査の例が示すように、検査の精度がどんなに高くても、事前確率(有病率)が低ければ陽性の予測値は低くなる(基準率の無視に注意)
  • 逐次更新: ベイズの定理は証拠を逐次的に取り込め、事後確率を新しい事前確率として再利用できる
  • オッズ形式: 事後オッズ = ベイズファクター × 事前オッズ という形は、証拠の「力」を直感的に評価できる
  • 連続版ベイズの定理: $p(\theta|x) \propto p(x|\theta) p(\theta)$ はベイズ統計学の基盤であり、パラメータの不確実性を分布として表現する
  • 事前分布の影響: 事前分布の選択は推定結果に影響するが、データ量が増えればその影響は薄まる

ベイズの定理はベイズ統計学全体の出発点です。次のステップとして、以下の記事も参考にしてください。