ある大学の統計学のテストで、A組(40人)の合格率は80%、B組(60人)の合格率は60%でした。では、全体(100人)の合格率はいくらでしょうか?
単純に $(80 + 60) / 2 = 70\%$ と計算するのは誤りです。2つのクラスの人数が異なるため、各クラスの合格率を人数で重み付けして平均する必要があります。
$$ \text{全体の合格率} = \frac{40}{100} \times 0.80 + \frac{60}{100} \times 0.60 = 0.32 + 0.36 = 0.68 $$
この「場合に分けて確率を計算し、重み付きで合計する」という考え方を一般化したものが全確率の定理(law of total probability)です。
全確率の定理は単純ですが極めて重要です。複雑な事象の確率を直接計算するのが難しい場合に、事象を適切な場合に分けて各場合の条件付き確率から全体の確率を求めることができます。以下のような場面で不可欠です。
- ベイズの定理の分母: ベイズの定理 $P(A|B) = P(B|A)P(A)/P(B)$ の分母 $P(B)$ の計算に使用
- マルコフ連鎖: 状態遷移確率から定常分布を計算する
- 信頼性工学: 複数のコンポーネントを持つシステムの故障確率の計算
- 保険数理: 異なるリスクグループの加重平均で全体のリスクを算出
本記事の内容
- 全確率の定理の直感的な理解と数学的定式化
- 定理の証明
- ベイズの定理との関係
- 具体例による計算(品質管理、通信システム)
- 連続版(全確率の定理の密度関数版)
- Pythonでの可視化と数値実験
前提知識
この記事を読む前に、以下の記事を読んでおくと理解が深まります。
全確率の定理とは — 「場合分けの原理」
日常的な直感
全確率の定理の考え方は、実は私たちが日常的に使っています。
たとえば、「明日、通勤に遅刻する確率」を知りたいとします。天気を「晴れ」「雨」「雪」の3つに場合分けすると
- 晴れの場合は遅刻しにくい(遅刻確率5%)
- 雨の場合は遅刻しやすい(遅刻確率20%)
- 雪の場合は非常に遅刻しやすい(遅刻確率60%)
天気予報が「晴れ70%、雨25%、雪5%」だとすると、明日遅刻する全体の確率は
$$ 0.70 \times 0.05 + 0.25 \times 0.20 + 0.05 \times 0.60 = 0.035 + 0.05 + 0.03 = 0.115 $$
つまり、11.5%です。
この計算こそが全確率の定理の本質です。直接求めにくい確率(遅刻する確率)を、条件(天気の種類)で場合分けし、各条件のもとでの確率と条件自体の確率の積を足し合わせているのです。
標本空間の分割
全確率の定理を理解するための鍵は、標本空間の分割(partition)です。
事象 $B_1, B_2, \ldots, B_n$ が標本空間 $\Omega$ の分割をなすとは、以下の2条件が成り立つことです。
- 排反性: $B_i \cap B_j = \emptyset$($i \neq j$)— 場合が重ならない
- 網羅性: $B_1 \cup B_2 \cup \cdots \cup B_n = \Omega$ — 場合が全てをカバーする
上の例では、$B_1 = \{\text{晴れ}\}$、$B_2 = \{\text{雨}\}$、$B_3 = \{\text{雪}\}$ が標本空間の分割になっています。必ず3つのうちどれか1つが起き、2つ以上が同時に起きることはありません。
この分割の考え方を使って、全確率の定理を数式で定式化しましょう。
全確率の定理の数学的定式化と証明
定理の主張
$B_1, B_2, \ldots, B_n$ が標本空間 $\Omega$ の分割であり、全ての $i$ に対して $P(B_i) > 0$ であるとき、任意の事象 $A$ に対して
$$ \begin{equation} P(A) = \sum_{i=1}^{n} P(A | B_i) \cdot P(B_i) \end{equation} $$
が成り立ちます。
直感的に言えば、$A$ の確率は、各場合 $B_i$ での$A$の条件付き確率を、$B_i$ の確率で重み付けして合計したものです。
証明
この定理は非常にシンプルに証明できます。
$\{B_1, \ldots, B_n\}$ が $\Omega$ の分割なので、任意の事象 $A$ は
$$ A = A \cap \Omega = A \cap (B_1 \cup B_2 \cup \cdots \cup B_n) = (A \cap B_1) \cup (A \cap B_2) \cup \cdots \cup (A \cap B_n) $$
$B_i$ が排反なので $A \cap B_i$ も排反です。したがって、確率の加法性から
$$ P(A) = \sum_{i=1}^{n} P(A \cap B_i) $$
乗法定理 $P(A \cap B_i) = P(A | B_i) P(B_i)$ を代入すると
$$ P(A) = \sum_{i=1}^{n} P(A | B_i) \cdot P(B_i) $$
証明は完了です。
幾何学的な解釈
全確率の定理はベン図で見ると特に明快です。事象 $A$ を $B_1, B_2, \ldots, B_n$ で「スライス」して、各スライスの面積を合計したものが $A$ 全体の面積に等しいということです。
$B_i$ が標本空間を重なりなくカバーしているので、$A$ もまた $A \cap B_1, A \cap B_2, \ldots, A \cap B_n$ に重なりなく分割されます。各 $P(A \cap B_i)$ を足せば $P(A)$ になるのは自然なことです。
全確率の定理がベイズの定理とどう関係するかを見てみましょう。
ベイズの定理との関係
全確率の定理はベイズの定理の「分母」
ベイズの定理は
$$ P(B_i | A) = \frac{P(A | B_i) P(B_i)}{P(A)} $$
です。この分母 $P(A)$ を全確率の定理で展開すると
$$ \begin{equation} P(B_i | A) = \frac{P(A | B_i) P(B_i)}{\sum_{k=1}^{n} P(A | B_k) P(B_k)} \end{equation} $$
つまり、全確率の定理とベイズの定理は表裏一体の関係にあります。
- 全確率の定理: 原因から結果への確率($P(A|B_i)$ と $P(B_i)$)が与えられたとき、結果全体の確率 $P(A)$ を求める
- ベイズの定理: 結果 $A$ が観測されたとき、どの原因 $B_i$ が最もありそうかを逆算する
全確率の定理は「合成」(synthesis)、ベイズの定理は「分析」(analysis)と対比できます。
事前確率と事後確率の変換
全確率の定理をベイズの定理と組み合わせると、事前確率($P(B_i)$)から事後確率($P(B_i|A)$)への変換が完成します。
事前の段階では、各原因 $B_i$ の確率は $P(B_1), P(B_2), \ldots, P(B_n)$ です。
証拠 $A$ を観測した後、各原因の確率は $P(B_1|A), P(B_2|A), \ldots, P(B_n|A)$ に更新されます。
全ての事後確率の合計が1になることは、ベイズの定理の分母が全確率の定理で計算されていることから保証されます。
$$ \sum_{i=1}^{n} P(B_i | A) = \sum_{i=1}^{n} \frac{P(A|B_i) P(B_i)}{P(A)} = \frac{P(A)}{P(A)} = 1 $$
具体的な計算例を見ていきましょう。
具体例1: 品質管理での欠陥率計算
問題設定
ある製品は3つの工場で生産されています。
| 工場 | 生産比率 | 不良品率 |
|---|---|---|
| 工場A | 50% | 2% |
| 工場B | 30% | 3% |
| 工場C | 20% | 5% |
ランダムに1つ製品を選んだとき、それが不良品である確率を求めます。さらに、不良品だった場合にどの工場で作られた可能性が高いかも計算します。
全確率の定理による計算
$D =$ 「不良品」、$A, B, C$ = 各工場で生産されたとすると
$$ P(D) = P(D|A)P(A) + P(D|B)P(B) + P(D|C)P(C) $$
各値を代入すると
$$ P(D) = 0.02 \times 0.50 + 0.03 \times 0.30 + 0.05 \times 0.20 $$
各項を計算します。
$$ P(D) = 0.010 + 0.009 + 0.010 = 0.029 $$
全体の不良品率は2.9%です。
ベイズの定理による逆推定
不良品がどの工場から来た確率が高いかは、ベイズの定理で求まります。
$$ P(A|D) = \frac{P(D|A)P(A)}{P(D)} = \frac{0.02 \times 0.50}{0.029} = \frac{0.010}{0.029} \approx 0.345 $$
$$ P(B|D) = \frac{P(D|B)P(B)}{P(D)} = \frac{0.03 \times 0.30}{0.029} = \frac{0.009}{0.029} \approx 0.310 $$
$$ P(C|D) = \frac{P(D|C)P(C)}{P(D)} = \frac{0.05 \times 0.20}{0.029} = \frac{0.010}{0.029} \approx 0.345 $$
興味深い結果です。工場Aは不良品率が最も低い(2%)のに、不良品の出所としては最も確率が高い(34.5%)。これは工場Aの生産量が多い(50%)ためです。一方、工場Cは不良品率が最も高い(5%)ですが、生産量が少ない(20%)ため、不良品の出所としての確率は工場Aと同程度です。
確率の合計が $0.345 + 0.310 + 0.345 = 1.000$ となることも確認できます。
具体例2: 通信システムのビットエラー率
問題設定
デジタル通信で、送信ビットの0と1の割合が $P(0) = 0.6$、$P(1) = 0.4$ であるとします。チャネルの特性は
- 0を送信して正しく0が受信される確率: $P(R=0|S=0) = 0.95$
- 1を送信して正しく1が受信される確率: $P(R=1|S=1) = 0.90$
受信側で0を受信する確率 $P(R=0)$ と、0を受信したとき送信が0であった確率 $P(S=0|R=0)$ を求めます。
計算
全確率の定理から
$$ P(R=0) = P(R=0|S=0)P(S=0) + P(R=0|S=1)P(S=1) $$
$P(R=0|S=1) = 1 – P(R=1|S=1) = 1 – 0.90 = 0.10$ なので
$$ P(R=0) = 0.95 \times 0.60 + 0.10 \times 0.40 = 0.570 + 0.040 = 0.610 $$
ベイズの定理で事後確率を求めると
$$ P(S=0|R=0) = \frac{P(R=0|S=0)P(S=0)}{P(R=0)} = \frac{0.95 \times 0.60}{0.610} = \frac{0.570}{0.610} \approx 0.934 $$
0を受信したとき、送信が実際に0であった確率は約93.4%です。
次に、全確率の定理を連続確率変数に拡張しましょう。
連続版の全確率の定理
密度関数版
離散確率変数 $Y$ がとる値の集合が $\{y_1, y_2, \ldots\}$ のとき、連続確率変数 $X$ の密度関数 $f_X(x)$ は
$$ f_X(x) = \sum_j f_{X|Y}(x | y_j) P(Y = y_j) $$
$Y$ も連続の場合は、和が積分に置き換わります。
$$ \begin{equation} f_X(x) = \int_{-\infty}^{\infty} f_{X|Y}(x | y) f_Y(y) \, dy \end{equation} $$
これは周辺密度を同時密度から計算する操作であり、「$Y$ を積分消去する」($Y$ を周辺化する)とも表現されます。
具体例: 正規混合分布
全確率の定理の連続版の典型的な応用が混合分布(mixture distribution)です。
クラスター $Z$ が $K$ 個あり、$P(Z = k) = \pi_k$ で、各クラスター内のデータが $f_k(x)$ に従うとき
$$ f(x) = \sum_{k=1}^{K} \pi_k f_k(x) $$
たとえば混合正規分布は
$$ f(x) = \sum_{k=1}^{K} \pi_k \, \mathcal{N}(x | \mu_k, \sigma_k^2) $$
です。これは全確率の定理そのものであり、全体の密度関数を各クラスターの密度と混合比率から構成しています。
それでは、Pythonを使ってこれらの概念を可視化しましょう。
Pythonでの実装と可視化
全確率の定理の可視化
品質管理の例を使って、全確率の定理の「場合分け」を視覚的に表現します。
import numpy as np
import matplotlib.pyplot as plt
# 工場のデータ
factories = ['Factory A', 'Factory B', 'Factory C']
production_share = [0.50, 0.30, 0.20]
defect_rate = [0.02, 0.03, 0.05]
colors = ['steelblue', 'coral', 'green']
# 全確率の定理による不良品率
contributions = [p * d for p, d in zip(production_share, defect_rate)]
total_defect = sum(contributions)
# ベイズの定理による事後確率
posterior = [c / total_defect for c in contributions]
fig, axes = plt.subplots(1, 3, figsize=(16, 5))
# (a) 全確率の定理の分解
ax = axes[0]
bottom = 0
for i, (factory, contrib) in enumerate(zip(factories, contributions)):
bar = ax.bar('P(Defect)', contrib, bottom=bottom, color=colors[i],
alpha=0.8, label=f'{factory}: {contrib:.3f}',
edgecolor='gray')
ax.text(0, bottom + contrib/2, f'{factory}\n{contrib:.3f}',
ha='center', va='center', fontsize=10, fontweight='bold')
bottom += contrib
ax.axhline(total_defect, color='black', linestyle='--', linewidth=1.5)
ax.text(0.35, total_defect + 0.001, f'Total = {total_defect:.3f}',
fontsize=12, fontweight='bold')
ax.set_ylabel('Probability', fontsize=12)
ax.set_title('Law of Total Probability\n'
r'$P(D) = \sum_i P(D|B_i)P(B_i)$', fontsize=13)
ax.legend(fontsize=9, loc='upper right')
ax.set_ylim(0, 0.04)
ax.grid(True, alpha=0.3, axis='y')
# (b) 事前確率 vs 事後確率
ax = axes[1]
x_pos = np.arange(3)
width = 0.35
bars1 = ax.bar(x_pos - width/2, production_share, width, color='lightblue',
alpha=0.8, edgecolor='gray', label='Prior P(Factory)')
bars2 = ax.bar(x_pos + width/2, posterior, width, color='salmon',
alpha=0.8, edgecolor='gray', label='Posterior P(Factory|Defect)')
ax.set_xticks(x_pos)
ax.set_xticklabels(factories, fontsize=10)
ax.set_ylabel('Probability', fontsize=12)
ax.set_title("Prior vs Posterior\n(Bayes' Theorem)", fontsize=13)
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3, axis='y')
for bar in bars1:
ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.01,
f'{bar.get_height():.2f}', ha='center', fontsize=10)
for bar in bars2:
ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.01,
f'{bar.get_height():.3f}', ha='center', fontsize=10)
# (c) 不良品率と生産比率のトレードオフ
ax = axes[2]
# 不良品率を変化させたときの全体不良品率への寄与
defect_range = np.linspace(0.001, 0.10, 100)
for i, factory in enumerate(factories):
contribution_curve = production_share[i] * defect_range
ax.plot(defect_range * 100, contribution_curve * 100, linewidth=2,
color=colors[i], label=f'{factory} (share={production_share[i]:.0%})')
ax.set_xlabel('Defect Rate (%)', fontsize=12)
ax.set_ylabel('Contribution to Total Defect Rate (%)', fontsize=12)
ax.set_title('Contribution = Defect Rate × Production Share', fontsize=13)
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3)
# 実際の値をマーク
for i in range(3):
ax.plot(defect_rate[i]*100, contributions[i]*100, 'o',
color=colors[i], markersize=10, markeredgecolor='black',
markeredgewidth=1.5)
plt.tight_layout()
plt.savefig('total_probability_theorem.png', dpi=150, bbox_inches='tight')
plt.show()
このグラフから、全確率の定理の構造が直感的に読み取れます。
-
左図(全確率の定理の分解): 全体の不良品率2.9%が、3つの工場の寄与の合計として分解されています。工場Aと工場Cの寄与がともに1.0%で同等であるのは、工場Aは不良品率が低いが生産量が多く、工場Cは不良品率が高いが生産量が少ないためです。
-
中央図(事前 vs 事後): 工場の生産比率(事前確率、青)と不良品だった場合の工場の確率(事後確率、赤)を比較しています。工場Bの事後確率が事前確率より高くなり、工場Aの事後確率は事前確率より低くなっています。ベイズの定理による確率の更新が見て取れます。
-
右図(寄与曲線): 各工場の不良品率に対する全体への寄与を示しています。生産比率が大きいほど傾きが急で、同じ不良品率の改善でも全体への影響が大きいことがわかります。品質改善の優先順位を決める際に有用な視点です。
通信チャネルの全確率
通信システムの例を可視化します。
import numpy as np
import matplotlib.pyplot as plt
# チャネルパラメータ
p_send_0 = 0.6
p_send_1 = 0.4
p_correct_0 = 0.95 # P(R=0|S=0)
p_correct_1 = 0.90 # P(R=1|S=1)
# 遷移確率
p_r0_s0 = p_correct_0 # 0→0
p_r1_s0 = 1 - p_correct_0 # 0→1
p_r0_s1 = 1 - p_correct_1 # 1→0
p_r1_s1 = p_correct_1 # 1→1
fig, axes = plt.subplots(1, 3, figsize=(16, 5))
# (a) チャネル遷移図
ax = axes[0]
# 送信側
ax.text(0.1, 0.75, 'S=0', fontsize=16, ha='center', va='center',
bbox=dict(boxstyle='round,pad=0.4', facecolor='lightblue'))
ax.text(0.1, 0.25, 'S=1', fontsize=16, ha='center', va='center',
bbox=dict(boxstyle='round,pad=0.4', facecolor='lightsalmon'))
# 受信側
ax.text(0.9, 0.75, 'R=0', fontsize=16, ha='center', va='center',
bbox=dict(boxstyle='round,pad=0.4', facecolor='lightblue'))
ax.text(0.9, 0.25, 'R=1', fontsize=16, ha='center', va='center',
bbox=dict(boxstyle='round,pad=0.4', facecolor='lightsalmon'))
# 遷移の矢印
ax.annotate('', xy=(0.78, 0.75), xytext=(0.22, 0.75),
arrowprops=dict(arrowstyle='->', color='blue', lw=2))
ax.text(0.5, 0.80, f'{p_r0_s0:.2f}', fontsize=13, ha='center',
color='blue', fontweight='bold')
ax.annotate('', xy=(0.78, 0.25), xytext=(0.22, 0.75),
arrowprops=dict(arrowstyle='->', color='red', lw=1.5, ls='--'))
ax.text(0.35, 0.45, f'{p_r1_s0:.2f}', fontsize=12, ha='center',
color='red')
ax.annotate('', xy=(0.78, 0.75), xytext=(0.22, 0.25),
arrowprops=dict(arrowstyle='->', color='red', lw=1.5, ls='--'))
ax.text(0.65, 0.55, f'{p_r0_s1:.2f}', fontsize=12, ha='center',
color='red')
ax.annotate('', xy=(0.78, 0.25), xytext=(0.22, 0.25),
arrowprops=dict(arrowstyle='->', color='blue', lw=2))
ax.text(0.5, 0.20, f'{p_r1_s1:.2f}', fontsize=13, ha='center',
color='blue', fontweight='bold')
# 事前確率
ax.text(0.1, 0.95, f'P={p_send_0:.1f}', fontsize=11, ha='center')
ax.text(0.1, 0.05, f'P={p_send_1:.1f}', fontsize=11, ha='center')
ax.set_xlim(-0.05, 1.05)
ax.set_ylim(-0.05, 1.05)
ax.set_title('Binary Symmetric Channel', fontsize=13)
ax.axis('off')
# (b) 全確率の定理による受信確率
ax = axes[1]
# P(R=0)の分解
p_r0 = p_r0_s0 * p_send_0 + p_r0_s1 * p_send_1
p_r1 = p_r1_s0 * p_send_0 + p_r1_s1 * p_send_1
contributions_r0 = [p_r0_s0 * p_send_0, p_r0_s1 * p_send_1]
contributions_r1 = [p_r1_s0 * p_send_0, p_r1_s1 * p_send_1]
x_labels = ['P(R=0)', 'P(R=1)']
x_pos = [0, 1]
# スタック棒グラフ
bottom_0 = 0
colors_ch = ['steelblue', 'salmon']
labels_ch = ['from S=0', 'from S=1']
for i, (c0, c1) in enumerate(zip(contributions_r0, contributions_r1)):
ax.bar(0, contributions_r0[i], bottom=sum(contributions_r0[:i]),
color=colors_ch[i], alpha=0.8, edgecolor='gray',
label=labels_ch[i] if True else '')
ax.bar(1, contributions_r1[i], bottom=sum(contributions_r1[:i]),
color=colors_ch[i], alpha=0.8, edgecolor='gray')
ax.text(0, p_r0 + 0.02, f'{p_r0:.3f}', ha='center', fontsize=12,
fontweight='bold')
ax.text(1, p_r1 + 0.02, f'{p_r1:.3f}', ha='center', fontsize=12,
fontweight='bold')
ax.set_xticks([0, 1])
ax.set_xticklabels(x_labels, fontsize=12)
ax.set_ylabel('Probability', fontsize=12)
ax.set_title('Law of Total Probability\nfor Received Bits', fontsize=13)
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3, axis='y')
ax.set_ylim(0, 0.75)
# (c) ベイズの定理による復号
ax = axes[2]
# P(S=0|R=0) と P(S=1|R=0)
p_s0_r0 = (p_r0_s0 * p_send_0) / p_r0
p_s1_r0 = (p_r0_s1 * p_send_1) / p_r0
p_s0_r1 = (p_r1_s0 * p_send_0) / p_r1
p_s1_r1 = (p_r1_s1 * p_send_1) / p_r1
# 棒グラフ
x_pos2 = np.arange(2)
width = 0.35
ax.bar(x_pos2 - width/2, [p_s0_r0, p_s0_r1], width, color='steelblue',
alpha=0.8, label='P(S=0|R)', edgecolor='gray')
ax.bar(x_pos2 + width/2, [p_s1_r0, p_s1_r1], width, color='salmon',
alpha=0.8, label='P(S=1|R)', edgecolor='gray')
ax.set_xticks(x_pos2)
ax.set_xticklabels(['Received 0', 'Received 1'], fontsize=12)
ax.set_ylabel('Posterior Probability', fontsize=12)
ax.set_title("Bayes' Decoding\nP(Sent | Received)", fontsize=13)
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3, axis='y')
# 値のアノテーション
for i, (v0, v1) in enumerate(zip([p_s0_r0, p_s0_r1], [p_s1_r0, p_s1_r1])):
ax.text(i - width/2, v0 + 0.02, f'{v0:.3f}', ha='center', fontsize=10)
ax.text(i + width/2, v1 + 0.02, f'{v1:.3f}', ha='center', fontsize=10)
plt.tight_layout()
plt.savefig('total_probability_channel.png', dpi=150, bbox_inches='tight')
plt.show()
この通信チャネルの可視化から、全確率の定理とベイズ復号の仕組みが読み取れます。
-
左図(チャネルモデル): 送信ビット(S=0, S=1)から受信ビット(R=0, R=1)への遷移確率が示されています。青い矢印が正しい伝送、赤い破線がエラーです。0の正答率(0.95)が1の正答率(0.90)より高い非対称チャネルです。
-
中央図(全確率の定理): $P(R=0) = 0.610$ と $P(R=1) = 0.390$ の内訳が示されています。$P(R=0)$ の大部分は「S=0が正しく受信された」(青い部分)ですが、一部「S=1がエラーで0になった」(赤い部分)寄与もあります。
-
右図(ベイズ復号): 受信結果からの事後確率です。R=0を受信した場合、S=0であった確率は93.4%と高く、正しく復号できます。R=1を受信した場合、S=1であった確率は92.3%です。このベイズ復号は最適な復号方式(MAP復号)の基盤です。
混合分布と全確率の定理
連続版の全確率の定理の応用として、混合正規分布を可視化します。
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
# 混合正規分布のパラメータ
weights = [0.4, 0.35, 0.25]
means = [-2, 1, 4]
stds = [0.8, 1.2, 0.6]
x = np.linspace(-6, 8, 500)
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# (a) 混合分布の分解
ax = axes[0]
mixture = np.zeros_like(x)
colors_mix = ['steelblue', 'coral', 'green']
for i, (w, mu, sigma) in enumerate(zip(weights, means, stds)):
component = w * stats.norm.pdf(x, mu, sigma)
mixture += component
ax.fill_between(x, component, alpha=0.3, color=colors_mix[i],
label=rf'$\pi_{i+1}\mathcal{{N}}(\mu_{i+1}={mu}, \sigma_{i+1}={sigma})$')
ax.plot(x, component, color=colors_mix[i], linewidth=1.5)
ax.plot(x, mixture, 'k-', linewidth=2.5, label='Mixture $f(x)$')
ax.set_xlabel('x', fontsize=12)
ax.set_ylabel('Density', fontsize=12)
ax.set_title('Mixture of Gaussians\n'
r'$f(x) = \sum_k \pi_k \mathcal{N}(x|\mu_k, \sigma_k^2)$',
fontsize=13)
ax.legend(fontsize=9)
ax.grid(True, alpha=0.3)
# (b) 各コンポーネントの責任(事後確率)
ax = axes[1]
for i, (w, mu, sigma) in enumerate(zip(weights, means, stds)):
component = w * stats.norm.pdf(x, mu, sigma)
responsibility = component / np.maximum(mixture, 1e-10)
ax.plot(x, responsibility, linewidth=2, color=colors_mix[i],
label=rf'$P(Z={i+1}|x)$')
ax.set_xlabel('x', fontsize=12)
ax.set_ylabel('Posterior P(Component | x)', fontsize=12)
ax.set_title("Component Responsibility\n(Bayes' Theorem)", fontsize=13)
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3)
ax.set_ylim(-0.05, 1.05)
plt.tight_layout()
plt.savefig('mixture_total_probability.png', dpi=150, bbox_inches='tight')
plt.show()
この混合分布の可視化から、全確率の定理の連続版がどのように機能するかが読み取れます。
-
左図(混合分布の分解): 黒い太線が全体の密度関数 $f(x)$ であり、色付きの領域が各コンポーネントの重み付き密度 $\pi_k \mathcal{N}(x|\mu_k, \sigma_k^2)$ です。全確率の定理の式 $f(x) = \sum_k \pi_k f_k(x)$ そのものが可視化されています。各コンポーネントの「積み上げ」が全体の密度を構成しています。
-
右図(コンポーネントの責任): ベイズの定理を適用して、データ点 $x$ が各コンポーネントから生成された事後確率(責任、responsibility)を示しています。$x = -2$ 付近ではコンポーネント1の責任がほぼ1であり、$x = 1$ 付近ではコンポーネント2が支配的です。各コンポーネントの間の領域では責任が混合します。この責任の計算がEMアルゴリズムのE-ステップの本質です。
全確率の定理の一般化
可算無限の分割
分割が可算無限個の場合にも、全確率の定理は成り立ちます。
$$ P(A) = \sum_{i=1}^{\infty} P(A | B_i) P(B_i) $$
ただし、右辺の級数が収束することが必要です。$\sum_{i=1}^{\infty} P(B_i) = 1$ なので、$P(A|B_i) \leq 1$ から級数の収束は保証されます。
期待値の分解公式(全期待値の定理)
全確率の定理の「期待値版」として、全期待値の定理(law of total expectation)があります。
$$ \begin{equation} E[X] = E[E[X|Y]] = \sum_y E[X|Y=y] P(Y=y) \end{equation} $$
連続版は
$$ E[X] = \int_{-\infty}^{\infty} E[X|Y=y] f_Y(y) \, dy $$
同様に、全分散の定理(law of total variance)も成り立ちます。
$$ \text{Var}(X) = E[\text{Var}(X|Y)] + \text{Var}(E[X|Y]) $$
全分散は「各条件内での分散の平均」+「条件ごとの平均のばらつき」に分解されます。
まとめ
本記事では、全確率の定理の直感的な理解から数学的な導出、ベイズの定理との関係、具体例まで解説しました。
- 全確率の定理 $P(A) = \sum_i P(A|B_i) P(B_i)$ は、複雑な事象の確率を「場合分け」して計算する基本原理である
- ベイズの定理の分母として不可欠であり、全確率の定理なしにはベイズの定理の分母を計算できない
- 品質管理や通信システムなど、複数の原因が混在する問題で、全体の確率を各原因の寄与に分解できる
- 連続版では和が積分に置き換わり、混合分布は全確率の定理の直接的な応用である
- 全期待値の定理と全分散の定理は、全確率の定理の期待値・分散版であり、階層モデルの分析に必要不可欠
次のステップとして、以下の記事も参考にしてください。