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