ヘロログ
統計学

ベイズの定理

ベイズの定理は、新しい情報(証拠)が得られたときに、ある事象の確率をどのように更新すべきかを教えてくれる定理である。18世紀のイギリスの数学者トーマス・ベイズにちなんで名付けられた。

この定理は現代の様々な分野で活用されている。迷惑メールフィルタは、メールに含まれる単語からスパムである確率を計算する。医療診断では、検査結果から実際に病気である確率を求める。機械学習の分野でも、ベイズ推定やナイーブベイズ分類器など、ベイズの定理を基盤とした手法が広く使われている。

条件付き確率

ベイズの定理を理解するには、まず条件付き確率を押さえておく必要がある。

条件付き確率とは、ある事象が起きたという条件のもとで、別の事象が起きる確率のことである。事象 A が起きたという条件のもとで事象 B が起きる確率を P(B|A) と書き、次のように定義する。

条件付き確率の定義
P(B|A) = \frac{P(A \cap B)}{P(A)}

ただし P(A) > 0 とする。

この定義は、ベン図で考えると理解しやすい。事象 A が起きたという条件下では、標本空間が A に限定される。その中で B も起きている部分、つまり A \cap B の割合が条件付き確率となる。

Ω A B A∩B
図1: ベン図による条件付き確率の理解。P(B|A)A の中で A \cap B が占める割合

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

P(A \cap B) = P(A) \times P(B|A)

これは「AB が両方起きる確率」を、「まず A が起きる確率」と「A が起きた条件のもとで B が起きる確率」の積として計算できることを意味する。

ベイズの定理の導出

AB は対称なので、乗法定理は次のようにも書ける。

P(A \cap B) = P(B) \times P(A|B)

2つの式の左辺が等しいので、右辺も等しい。

P(A) \times P(B|A) = P(B) \times P(A|B)

この式を P(A|B) について解くと、ベイズの定理が得られる。

ベイズの定理
P(A|B) = \frac{P(B|A) \, P(A)}{P(B)}

ここで、分母の P(B) は全確率の公式を使って展開できる。AA^cA の余事象)は互いに排反で、その和が全事象 \Omega となるので、

P(B) = P(B|A) \, P(A) + P(B|A^c) \, P(A^c)

これを代入すると、より実用的な形になる。

ベイズの定理(展開形)
P(A|B) = \frac{P(B|A) \, P(A)}{P(B|A) \, P(A) + P(B|A^c) \, P(A^c)}

ベイズの定理では、各確率に特別な名前がついている。

用語 記号 意味
事前確率 P(A) 証拠 B を観測する前の A の確率
事後確率 P(A|B) 証拠 B を観測した後の A の確率
尤度 P(B|A) A のもとで B が観測される確率

ベイズの定理は「原因 → 結果」の確率から「結果 → 原因」の確率を求める道具と考えることができる。たとえば、病気(原因)から症状(結果)が出る確率がわかっているとき、症状(結果)から病気(原因)である確率を計算できる。

簡単な計算例

まず、手計算で追える簡単な例でベイズの定理の使い方を確認しよう。

箱と玉の問題

2つの箱がある。箱Aには赤玉3個と白玉2個、箱Bには赤玉1個と白玉4個が入っている。箱Aを選ぶ確率は \frac{1}{3}、箱Bを選ぶ確率は \frac{2}{3} である。箱を1つ選び、その中から玉を1つ取り出したところ赤玉であった。このとき、箱Aを選んでいた確率を求めよ。

箱A P(箱A) = 1/3 箱B P(箱B) = 2/3
図2: 箱と玉の問題の設定

【解答】

求めたいのは P(\text{箱A}|\text{赤}) である。ベイズの定理を適用する。

まず、各条件付き確率を整理する。

  • P(\text{赤}|\text{箱A}) = \frac{3}{5}(箱Aから赤玉を引く確率)
  • P(\text{赤}|\text{箱B}) = \frac{1}{5}(箱Bから赤玉を引く確率)

全確率の公式より、赤玉を引く確率は

\begin{aligned} P(\text{赤}) &= P(\text{赤}|\text{箱A}) \, P(\text{箱A}) + P(\text{赤}|\text{箱B}) \, P(\text{箱B}) \\[5pt] &= \frac{3}{5} \times \frac{1}{3} + \frac{1}{5} \times \frac{2}{3} \\[5pt] &= \frac{1}{5} + \frac{2}{15} = \frac{3}{15} + \frac{2}{15} = \frac{5}{15} = \frac{1}{3} \end{aligned}

ベイズの定理より

\begin{aligned} P(\text{箱A}|\text{赤}) &= \frac{P(\text{赤}|\text{箱A}) \, P(\text{箱A})}{P(\text{赤})} \\[5pt] &= \frac{\frac{3}{5} \times \frac{1}{3}}{\frac{1}{3}} = \frac{\frac{1}{5}}{\frac{1}{3}} = \frac{1}{5} \times \frac{3}{1} = \frac{3}{5} \end{aligned}

よって、赤玉が出たとき箱Aを選んでいた確率は \frac{3}{5} である。

ポイント

事前確率では P(\text{箱A}) = \frac{1}{3} だったが、「赤玉が出た」という情報を得ることで、事後確率は P(\text{箱A}|\text{赤}) = \frac{3}{5} に更新された。赤玉が多い箱Aから取り出した可能性が高まったわけである。

具体例:製品検査

ある工場で製造される製品の不良品率は2%である。検査装置は、不良品を96%の確率で「不良」と判定するが、良品でも5%の確率で誤って「不良」と判定してしまう。検査で「不良」と判定された製品が、実際に不良品である確率を求めよ。

【解答】

事象を次のように定義する。

  • D: 製品が不良品である
  • +: 検査で「不良」と判定される

問題文から、次の確率がわかる。

  • P(D) = 0.02(不良品率、事前確率)
  • P(+|D) = 0.96(感度:不良品を正しく検出する確率)
  • P(+|D^c) = 0.05(偽陽性率:良品を誤って不良と判定する確率)

求めたいのは P(D|+)(陽性的中率)である。

まず、検査で「不良」と判定される確率 P(+) を計算する。

\begin{aligned} P(+) &= P(+|D) \, P(D) + P(+|D^c) \, P(D^c) \\[5pt] &= 0.96 \times 0.02 + 0.05 \times 0.98 \\[5pt] &= 0.0192 + 0.049 = 0.0682 \end{aligned}

ベイズの定理より

\begin{aligned} P(D|+) &= \frac{P(+|D) \, P(D)}{P(+)} \\[5pt] &= \frac{0.96 \times 0.02}{0.0682} = \frac{0.0192}{0.0682} \\[5pt] &= \frac{96}{341} \approx 0.282 \end{aligned}

検査で「不良」と判定されても、実際に不良品である確率は約28%にすぎない。

注意:ベースレートの無視

感度96%という高い検出率にもかかわらず、陽性的中率が28%と低いのは、そもそもの不良品率(ベースレート)が2%と低いためである。良品が98%を占めているため、5%の偽陽性でも絶対数としては多くの誤判定が生じる。このように、ベースレートを無視して条件付き確率だけで判断すると、誤った結論を導くことがある。

1000個の製品を検査した場合 全製品 1000個 不良品 20個 良品 980個 陽性 19個 陰性 1個 陽性(偽) 49個 陰性 931個 陽性判定: 19 + 49 = 68個 うち実際の不良品: 19個 → 陽性的中率 = 19/68 ≈ 28%
図3: 1000個の製品を検査した場合の内訳

練習問題

問1. ある地域では、1日の天気が雨である確率は30%である。雨の日に傘を持っている人の割合は90%、晴れの日に傘を持っている人の割合は20%である。街で傘を持っている人を見かけたとき、その日が雨である確率を求めよ。

事象を次のように定義する。

  • R: 雨が降っている
  • U: 傘を持っている

問題文より

  • P(R) = 0.3
  • P(U|R) = 0.9
  • P(U|R^c) = 0.2

傘を持っている確率は

P(U) = 0.9 \times 0.3 + 0.2 \times 0.7 = 0.27 + 0.14 = 0.41

ベイズの定理より

P(R|U) = \frac{0.9 \times 0.3}{0.41} = \frac{0.27}{0.41} = \frac{27}{41} \approx 0.659

よって、傘を持っている人を見かけたとき雨である確率は約66%である。

まとめ

項目 内容
ベイズの定理 P(A|B) = \frac{P(B|A) \, P(A)}{P(B)}
事前確率 証拠を観測する前の確率 P(A)
事後確率 証拠を観測した後の確率 P(A|B)
尤度 仮説のもとで証拠が観測される確率 P(B|A)
全確率の公式 P(B) = P(B|A)P(A) + P(B|A^c)P(A^c)
用途 「結果」から「原因」の確率を求める

Pythonで実装する

Pythonでベイズの定理を計算する関数を実装してみよう。

bayes_theorem.py
def bayes_theorem(p_a, p_b_given_a, p_b_given_not_a):
    """
    ベイズの定理を用いて事後確率を計算する
    
    Parameters
    ----------
    p_a : float
        事前確率 P(A)
    p_b_given_a : float
        尤度 P(B|A)
    p_b_given_not_a : float
        P(B|A^c)
    
    Returns
    -------
    float
        事後確率 P(A|B)
    """
    # 全確率の公式で P(B) を計算
    p_b = p_b_given_a * p_a + p_b_given_not_a * (1 - p_a)
    
    # ベイズの定理
    p_a_given_b = (p_b_given_a * p_a) / p_b
    
    return p_a_given_b


# 製品検査の例
p_defect = 0.02          # 不良品率(事前確率)
sensitivity = 0.96       # 感度
false_positive = 0.05    # 偽陽性率

result = bayes_theorem(p_defect, sensitivity, false_positive)
print(f"検査陽性時の不良品確率: {result:.4f} ({result*100:.1f}%)")
検査陽性時の不良品確率: 0.2815 (28.2%)

連続的にベイズ更新を行う例も見てみよう。検査を複数回行った場合、前回の事後確率が次回の事前確率となる。

bayes_update.py
def bayes_update(prior, likelihood_pos, likelihood_neg, evidence):
    """
    ベイズ更新を行う
    
    Parameters
    ----------
    prior : float
        事前確率
    likelihood_pos : float
        仮説が真のときに証拠が観測される確率
    likelihood_neg : float
        仮説が偽のときに証拠が観測される確率
    evidence : bool
        観測された証拠(True: 陽性, False: 陰性)
    
    Returns
    -------
    float
        事後確率
    """
    if evidence:
        p_e_given_h = likelihood_pos
        p_e_given_not_h = likelihood_neg
    else:
        p_e_given_h = 1 - likelihood_pos
        p_e_given_not_h = 1 - likelihood_neg
    
    p_e = p_e_given_h * prior + p_e_given_not_h * (1 - prior)
    posterior = (p_e_given_h * prior) / p_e
    
    return posterior


# 医療検査の例(2段階検査)
prior = 0.005            # 罹患率 0.5%
sens1, fp1 = 0.95, 0.03  # 検査1: 感度95%, 偽陽性率3%
sens2, fp2 = 0.90, 0.08  # 検査2: 感度90%, 偽陽性率8%

print("=== 医療検査のベイズ更新 ===")
print(f"事前確率(罹患率): {prior*100:.1f}%")

# 検査1が陽性
posterior1 = bayes_update(prior, sens1, fp1, evidence=True)
print(f"検査1陽性後: {posterior1*100:.2f}%")

# 検査2も陽性(検査1陽性後の確率を事前確率として使う)
posterior2 = bayes_update(posterior1, sens2, fp2, evidence=True)
print(f"検査2陽性後: {posterior2*100:.1f}%")
=== 医療検査のベイズ更新 === 事前確率(罹患率): 0.5% 検査1陽性後: 13.73% 検査2陽性後: 64.2%