ベイズの定理は、新しい情報(証拠)が得られたときに、ある事象の確率をどのように更新すべきかを教えてくれる定理である。18世紀のイギリスの数学者トーマス・ベイズにちなんで名付けられた。
この定理は現代の様々な分野で活用されている。迷惑メールフィルタは、メールに含まれる単語からスパムである確率を計算する。医療診断では、検査結果から実際に病気である確率を求める。機械学習の分野でも、ベイズ推定やナイーブベイズ分類器など、ベイズの定理を基盤とした手法が広く使われている。
条件付き確率
ベイズの定理を理解するには、まず条件付き確率を押さえておく必要がある。
条件付き確率とは、ある事象が起きたという条件のもとで、別の事象が起きる確率のことである。事象 A が起きたという条件のもとで事象 B が起きる確率を P(B|A) と書き、次のように定義する。
ただし P(A) > 0 とする。
この定義は、ベン図で考えると理解しやすい。事象 A が起きたという条件下では、標本空間が A に限定される。その中で B も起きている部分、つまり A \cap B の割合が条件付き確率となる。
条件付き確率の定義式を変形すると、次の乗法定理が得られる。
これは「A と B が両方起きる確率」を、「まず A が起きる確率」と「A が起きた条件のもとで B が起きる確率」の積として計算できることを意味する。
ベイズの定理の導出
A と B は対称なので、乗法定理は次のようにも書ける。
2つの式の左辺が等しいので、右辺も等しい。
この式を P(A|B) について解くと、ベイズの定理が得られる。
ここで、分母の P(B) は全確率の公式を使って展開できる。A と A^c(A の余事象)は互いに排反で、その和が全事象 \Omega となるので、
これを代入すると、より実用的な形になる。
ベイズの定理では、各確率に特別な名前がついている。
| 用語 | 記号 | 意味 |
|---|---|---|
| 事前確率 | 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を選んでいた確率を求めよ。
【解答】
求めたいのは P(\text{箱A}|\text{赤}) である。ベイズの定理を適用する。
まず、各条件付き確率を整理する。
- P(\text{赤}|\text{箱A}) = \frac{3}{5}(箱Aから赤玉を引く確率)
- P(\text{赤}|\text{箱B}) = \frac{1}{5}(箱Bから赤玉を引く確率)
全確率の公式より、赤玉を引く確率は
ベイズの定理より
よって、赤玉が出たとき箱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(+) を計算する。
ベイズの定理より
検査で「不良」と判定されても、実際に不良品である確率は約28%にすぎない。
感度96%という高い検出率にもかかわらず、陽性的中率が28%と低いのは、そもそもの不良品率(ベースレート)が2%と低いためである。良品が98%を占めているため、5%の偽陽性でも絶対数としては多くの誤判定が生じる。このように、ベースレートを無視して条件付き確率だけで判断すると、誤った結論を導くことがある。
練習問題
事象を次のように定義する。
- R: 雨が降っている
- U: 傘を持っている
問題文より
- P(R) = 0.3
- P(U|R) = 0.9
- P(U|R^c) = 0.2
傘を持っている確率は
ベイズの定理より
よって、傘を持っている人を見かけたとき雨である確率は約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でベイズの定理を計算する関数を実装してみよう。
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}%)")
連続的にベイズ更新を行う例も見てみよう。検査を複数回行った場合、前回の事後確率が次回の事前確率となる。
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}%")