跳转至

3.7   贝叶斯定理

有一天傍晚,小率准备出门跑步。他看了眼窗外,地面有点湿,风也不小,就随口问均哥:

“如果我今天跑步了,你能不能反过来猜一猜,今天更可能是什么天气?”

均哥没有马上回答。他从抽屉里拿出一张记录表,上面记着过去 100 天的天气,以及小率当天有没有跑步。

“这就是贝叶斯定理要解决的问题。”均哥说,“我们平时常常是从原因推结果:下雨时跑步的概率是多少?但很多时候,我们看到的是结果,想反推原因:已经知道你跑步了,今天是下雨天的概率是多少?”

贝叶斯定理被放在本章最后,是因为它不是一个孤立的新公式,而是把前面几节的内容合在一起:先有概率,再有联合概率,再有条件概率和全概率,最后才轮到“看到结果以后反推来源”。

这一节,我们不从公式开始。我们先把 100 天画成格子,像数积木一样数清楚:

  • 某件事本身发生了多少次?
  • 两件事同时发生了多少次?
  • 在某个条件下,另一件事发生了多少次?
  • 如果一个结果可能来自多种原因,所有来源加起来是多少?
  • 已经看到结果以后,某一个原因占所有来源的多大比例?

数清楚这些格子以后,贝叶斯公式就不是突然冒出来的“神秘公式”,而是一个很自然的比例。


3.7.1   概率:某件事发生的可能性

先只看天气,不看跑步。

过去 100 天里,小率和均哥记录到:

天气 天数 概率
下雨 20 天 \(20/100=0.20\)
刮风 30 天 \(30/100=0.30\)
晴天 50 天 \(50/100=0.50\)
合计 100 天 \(1.00\)

这里的概率(Probability),可以先理解成一句很朴素的话:

在很多次类似的日子里,这件事大约会出现多大比例。

如果 100 天里有 20 天下雨,我们就说:

\[ P(\text{下雨})=\frac{20}{100}=0.20 \]

读作“下雨的概率是 0.20”,也就是大约 20%。

图 3.7.1 用 100 天天气格子理解概率

图 3.7.1   概率就是先确定总范围,再看目标事件在这个范围里占多少格。
也就是说,概率不是在说“明天一定怎样”,而是在说“放到很多天里看,大约有多少天会这样”。
对。概率最重要的第一步,是先说清楚分母是谁。这里的分母就是过去 100 天。

这一点看似简单,却是后面所有公式的地基。只要分母换了,问题就换了。


3.7.2   联合概率:两件事同时发生

现在加入第二件事:小率有没有跑步。

均哥把 100 天的记录又整理了一遍:

天气 该天气天数 其中跑步天数 联合概率
下雨 20 天 4 天 \(4/100=0.04\)
刮风 30 天 27 天 \(27/100=0.27\)
晴天 50 天 30 天 \(30/100=0.30\)
合计 100 天 61 天 \(61/100=0.61\)

“下雨并且跑步”是两件事同时发生:

\[ P(\text{下雨且跑步})=\frac{4}{100}=0.04 \]

这种“两件事同时发生”的概率,叫 联合概率(Joint Probability)

图 3.7.2 用天气和跑步记录理解联合概率

图 3.7.2   联合概率看的仍然是全部 100 天,只是目标格子变成了“两件事同时满足”的格子。

注意,联合概率的分母仍然是 100 天。它问的是:

在全部 100 天里,有多少天既属于某种天气,又发生了跑步?

所以:

\[ P(\text{刮风且跑步})=\frac{27}{100}=0.27 \]
\[ P(\text{晴天且跑步})=\frac{30}{100}=0.30 \]

这些数字以后会派上大用场。因为贝叶斯定理本质上就是在比较不同“来源路径”的联合概率。


3.7.3   条件概率:先缩小范围,再看比例

小率看着表格,发现一个有趣的现象:

“下雨天有 20 天,其中我跑了 4 天;刮风天有 30 天,其中我跑了 27 天。这个差别好大。”

均哥点点头:“这时你问的已经不是联合概率,而是条件概率。”

条件概率(Conditional Probability)问的是:

已经知道某个条件成立,在这个更小的范围里,另一件事发生的概率是多少?

例如“下雨时跑步的概率”:

\[ P(\text{跑步}\mid\text{下雨}) = \frac{\text{下雨且跑步的天数}}{\text{下雨天数}} = \frac{4}{20} =0.20 \]

这里竖线右边的“下雨”,就是条件。它告诉我们:现在分母不再是全部 100 天,而是先缩小到 20 个下雨天。

同样地:

条件 计算 条件概率
下雨时跑步 \(4/20\) \(0.20\)
刮风时跑步 \(27/30\) \(0.90\)
晴天时跑步 \(30/50\) \(0.60\)

图 3.7.3 用缩小范围理解条件概率

图 3.7.3   条件概率先按条件选出一块区域,再在这块区域里数目标事件。

把这个关系写成一般形式,就是:

\[ P(B\mid A)=\frac{P(A\cap B)}{P(A)} \]

反过来,把两边同时乘以 \(P(A)\),就得到联合概率公式:

\[ P(A\cap B)=P(A)P(B\mid A) \]

回到天气表,这句话非常好理解:

天气 \(P(\text{天气})\) \(P(\text{跑步}\mid\text{天气})\) 相乘得到联合概率
下雨 \(0.20\) \(0.20\) \(0.20\times0.20=0.04\)
刮风 \(0.30\) \(0.90\) \(0.30\times0.90=0.27\)
晴天 \(0.50\) \(0.60\) \(0.50\times0.60=0.30\)

也就是说,前面那张“联合概率表”并不是孤立的。它可以由两部分拼出来:

某种天气本身出现的概率 × 在这种天气下跑步的概率。

在天气例子里:

  • \(A\) 可以表示“下雨”。
  • \(B\) 可以表示“跑步”。
  • \(P(B\mid A)\) 就是“下雨时跑步的概率”。
我有点分不清:$P(\text{下雨且跑步})$ 和 $P(\text{跑步}\mid\text{下雨})$ 到底差在哪里?
看分母。前者在全部 100 天里数“下雨且跑步”;后者先只看 20 个下雨天,再数其中跑步的比例。

这句话要牢牢记住:联合概率看全部范围,条件概率看条件范围。


3.7.4   全概率公式:把所有来源加起来

现在换一个问题:

不管天气是什么,小率总体上跑步的概率是多少?

这个问题当然可以直接从表里数:

\[ P(\text{跑步})=\frac{61}{100}=0.61 \]

但均哥希望小率换一种看法。

“跑步这件事,可以从三种天气来源里来。”均哥说,“下雨天可能跑步,刮风天可能跑步,晴天也可能跑步。我们把每条来源路径的贡献算出来,再加起来。”

第一条路径:下雨,然后跑步。

\[ P(\text{下雨})P(\text{跑步}\mid\text{下雨}) =0.20\times0.20 =0.04 \]

第二条路径:刮风,然后跑步。

\[ P(\text{刮风})P(\text{跑步}\mid\text{刮风}) =0.30\times0.90 =0.27 \]

第三条路径:晴天,然后跑步。

\[ P(\text{晴天})P(\text{跑步}\mid\text{晴天}) =0.50\times0.60 =0.30 \]

把所有能产生“跑步”的来源加起来:

\[ P(\text{跑步}) =0.04+0.27+0.30 =0.61 \]

这就是 全概率公式(Law of Total Probability) 的直觉:如果一个结果可以由几个互不重叠的来源产生,就把每个来源的贡献加起来。

图 3.7.4 用天气来源理解全概率公式

图 3.7.4   全概率公式不是凭空算总数,而是把所有可能来源的贡献逐条相加。

更一般地,如果 \(A_1,A_2,\ldots,A_k\) 是几类互不重叠、合起来覆盖全部情况的来源,那么:

\[ P(B)=P(A_1)P(B\mid A_1)+P(A_2)P(B\mid A_2)+\cdots+P(A_k)P(B\mid A_k) \]

在天气例子里,\(B\) 是“跑步”,三个来源分别是“下雨”“刮风”“晴天”。

为什么要学全概率公式

因为贝叶斯公式的分母,往往就是一个全概率公式。你想反推某个来源,就必须先知道“所有能产生这个结果的来源”一共有多大。

你可能会问:既然联合概率表里已经有 \(0.04,0.27,0.30\),为什么不直接把它们加起来?

在这张 100 天记录表里,当然可以直接加:

\[ P(\text{跑步}) =P(\text{下雨且跑步})+P(\text{刮风且跑步})+P(\text{晴天且跑步}) =0.04+0.27+0.30 =0.61 \]

但现实题目里,我们常常拿不到现成的联合概率。更常见的是拿到两类信息:

  • 每种来源本身有多常见,例如下雨、刮风、晴天各占多少。
  • 在每种来源之下,结果出现的概率是多少,例如各类天气下小率跑步的比例。

这时,全概率公式就把“来源概率”和“条件概率”拼成了“结果总概率”。它的价值不只是算这道题,而是提供一种分而治之的思路。


3.7.5   贝叶斯公式:看到结果后反推来源

现在终于回到小率最开始的问题:

已经知道小率今天跑步了,今天是下雨天的概率是多少?

这个问题的方向和刚才不一样。

刚才我们算的是:

\[ P(\text{跑步}\mid\text{下雨}) \]

也就是“如果下雨,小率跑步的概率是多少”。

现在要算的是:

\[ P(\text{下雨}\mid\text{跑步}) \]

也就是“如果小率跑步了,今天是下雨的概率是多少”。

这两个式子只是顺序换了一下,但含义完全不同。

最直观的数法是:过去 100 天里,小率一共跑步 61 天,其中下雨且跑步 4 天。所以:

\[ P(\text{下雨}\mid\text{跑步}) = \frac{\text{下雨且跑步的天数}}{\text{所有跑步天数}} = \frac{4}{61} \approx0.066 \]

也就是说,已知小率跑步了,这一天是下雨天的概率大约是 6.6%。

图 3.7.5 用天气来源理解贝叶斯公式

图 3.7.5   贝叶斯公式的分子是目标来源的贡献,分母是所有来源的贡献总和。

用刚才的“来源路径”语言重写一遍:

  • 分子:下雨这条路径对“跑步”的贡献。
  • 分母:所有天气路径对“跑步”的贡献。

因此:

\[ P(\text{下雨}\mid\text{跑步}) = \frac{P(\text{下雨})P(\text{跑步}\mid\text{下雨})} {P(\text{跑步})} \]

把全概率公式代入分母:

\[ P(\text{下雨}\mid\text{跑步}) = \frac{P(\text{下雨})P(\text{跑步}\mid\text{下雨})} {P(\text{下雨})P(\text{跑步}\mid\text{下雨}) +P(\text{刮风})P(\text{跑步}\mid\text{刮风}) +P(\text{晴天})P(\text{跑步}\mid\text{晴天})} \]

代入数字:

\[ P(\text{下雨}\mid\text{跑步}) = \frac{0.20\times0.20} {0.20\times0.20+0.30\times0.90+0.50\times0.60} = \frac{0.04}{0.61} = \frac{4}{61} \approx0.066 \]

这就是贝叶斯定理(Bayes' Theorem)。

更一般地:

\[ P(A_i\mid B)= \frac{P(A_i)P(B\mid A_i)} {\sum_j P(A_j)P(B\mid A_j)} \]

它说的是:

已经看到结果 \(B\) 以后,某个来源 \(A_i\) 的概率,等于“这个来源产生结果的贡献”除以“所有来源产生结果的总贡献”。

原来贝叶斯不是在凭感觉猜原因,而是在问:目标来源在所有可能来源里占多少。
对。看到结果以后,我们不是只盯着一个来源,而是把所有能产生这个结果的来源都放到桌面上比较。

3.7.6   用 Python 复现这张天气表

下面用 Python 把整张表算一遍。代码只做一件事:把天气天数、跑步天数、概率、联合概率、条件概率和贝叶斯反推结果放在同一张表里。

import pandas as pd

data = pd.DataFrame({
    "天气": ["下雨", "刮风", "晴天"],
    "天气天数": [20, 30, 50],
    "跑步天数": [4, 27, 30],
})

total_days = data["天气天数"].sum()
total_running_days = data["跑步天数"].sum()

data["P(天气)"] = data["天气天数"] / total_days
data["P(天气且跑步)"] = data["跑步天数"] / total_days
data["P(跑步|天气)"] = data["跑步天数"] / data["天气天数"]
data["对跑步的贡献"] = data["P(天气)"] * data["P(跑步|天气)"]
data["P(天气|跑步)"] = data["对跑步的贡献"] / (total_running_days / total_days)

print(data)
print()
print("P(跑步) =", total_running_days / total_days)
print("P(下雨|跑步) =", data.loc[data["天气"] == "下雨", "P(天气|跑步)"].iloc[0])

运行后你会看到:

  • \(P(\text{跑步})=0.61\)
  • \(P(\text{下雨}\mid\text{跑步})\approx0.066\)
  • \(P(\text{刮风}\mid\text{跑步})=27/61\approx0.443\)
  • \(P(\text{晴天}\mid\text{跑步})=30/61\approx0.492\)

这也解释了一个直觉:小率最常在晴天和刮风天跑步,所以“已知他跑步了”以后,我们更应该把概率分给晴天和刮风,而不是下雨。


3.7.7   小结:贝叶斯定理到底在做什么

这一节从一张 100 天天气表出发,依次走过了五个台阶:

台阶 问题 核心分母
概率 某件事发生了多少次? 全部 100 天
联合概率 两件事同时发生了多少次? 全部 100 天
条件概率 在某个条件下,另一件事发生多少次? 条件对应的那部分天数
全概率公式 一个结果可以来自哪些来源? 所有来源的贡献总和
贝叶斯公式 看到结果后,某个来源占多大比例? 所有能产生该结果的来源

贝叶斯定理最值得记住的不是公式长什么样,而是这句话:

看到一个结果以后,不要只盯着一个原因;要把所有可能产生这个结果的来源列出来,再看目标来源在其中占多少。

在天气例子里,结果是“跑步”,来源是“下雨、刮风、晴天”。

在现实生活里,结果可能是一条推荐内容被点击、一封邮件被判定为垃圾邮件、一个模型把图片识别成某类,或者一次天气预报被证实。贝叶斯定理提醒我们:看见结果之后,判断原因时必须同时考虑两件事:

  • 这个原因本来有多常见。
  • 这个原因产生当前结果的可能性有多大。

这就是从“正着推”走向“反着想”的第一把钥匙。