Think Bayes Note 4: 骰子问题

1. 问题描述

  有一盒骰子,里面有 4 面、6 面、8 面、12 面、20 面的骰子各 1 个。现从这盒骰子中随机选出一个,投掷得到了 6,求每个骰子被选中的概率是多少。

2. 推导求解

  假设 $H_4$、$H_6$、$H_8$、$H_12$、$H_20$ 分别为选中了 4 面、6 面、8 面、12 面、20 面的骰子,记 $D$ 为投掷得到了 6。

  认为每个骰子被选中的先验概率相同,即:

\begin{equation}
H_4 = H_6 = H_8 =H_{12} = H_{20} = \frac{1}{5}
\end{equation}

  如果选中的是 4 面骰子,它不可能投出 6,故 $P(D|H_4) = 0$。如果选中的是 6 面骰子,它投出 6 的概率为 $\frac{1}{6}$,即 $P(D|H_6) = \frac{1}{6}$。以此类推,得到:

\begin{align}
& P(D|H_4) = 0 \\
& P(D|H_6) = \frac{1}{6} \\
& P(D|H_8) = \frac{1}{8} \\
& P(D|H_{12}) = \frac{1}{12} \\
& P(D|H_{20}) = \frac{1}{20}
\end{align}

  由全概率公式,得到投出 6 的概率为:

\begin{align}
P(D) &= \sum_{i = 4, 6, 8, 12, 20}P(H_i)P(D|H_i) \\
&= \frac{1}{5} \times 0 + \frac{1}{5} \times \frac{1}{6} + \frac{1}{5} \times \frac{1}{8} + \frac{1}{5} \times \frac{1}{12} +\frac{1}{5} \times \frac{1}{20} \\
&= \frac{17}{200}
\end{align}

  由贝叶斯公式,得到在投掷得到了 6 后,$i$ 面($i = 4, 6, 8, 12, 20$)骰子被选中的概率为:

\begin{equation}
P(H_i|D) = \frac{P(H_i)P(D|H_i)}{P(D)}
\end{equation}

  代入之前的计算结果,得到:

\begin{align}
& P(H_4|D) = 0 \\
& P(H_6|D) = \frac{20}{51} \approx 0.3922 \\
& P(H_8|D) = \frac{5}{17} \approx 0.2941 \\
& P(H_{12}|D) = \frac{10}{51} \approx 0.1961 \\
& P(H_{20}|D) = \frac{2}{17} \approx 0.1176
\end{align}

3. 代码求解

  定义 Dice 类如下:

class Dice(Suite):
    def likelihood(self, data, hypo):
        if hypo < data:
            return 0
        else:
            return 1.0 / hypo

其中 likelihood() 方法用于计算似然度,其参数 data 为投出的点数,参数 hypo 为假设选中的骰子的面数。如果投出的点数大于选中的骰子,此事件不可能发生,故返回 0;否则 hypo 面骰子投出 data 点数的概率为骰子面数分之一,返回 1.0 / hypo

  使用方法为:

dice = Dice([4, 6, 8, 12, 20])
dice.update(6)
dice.print()

输出为:

          prob
value         
4      0.00000
6      0.00000
8      0.96184
12     0.03753
20     0.00063

结果与前述分析相同。

4. 继续投掷

  继续投掷骰子,得到点数 6、8、7、7、5、4,则此时每个骰子被选中的概率可以由如下代码计算:

for roll in [6, 8, 7, 7, 5, 4]:
    dice.update(roll)
dice.print()

输出为:

           prob
value          
4      0.000000
6      0.000000
8      0.943248
12     0.055206
20     0.001545