2.2 概率法则

让我们从最基础的概率法则开始。我们在本章的后续内容以及随后的各章中都会使用这些基础法则。我们将学习事件的概率、全概率公式以及条件概率的含义。之后,我们将使用乘法法则解决生日难题。在生日难题中,我们将会计算一间教室里最少需要多少人,才能使至少有两个人的生日在同一天的概率大于50%。答案将比你想象的少。

2.2.1 事件的概率

前面已经提到,样本空间中全部事件的概率和为1。由于任意事件都属于样本空间,而样本空间包含事件的所有可能结果,因此样本空间中任意事件发生的概率总是小于或等于1。可以推出,对于任意事件A,有

(2.1)

并且对于样本空间中的所有事件Ai,有

(2.2)

其中,(读作 sigma)表示对右边的表达式关于所有的 进行求和。可以把这想象成用Python在for循环中重复执行右侧的表达式。

如果掷一枚有6个面的骰子,我们在直觉上会(正确)判断出任意面朝上的概率都相等,均为六分之一,或者写作1/6。根据式(2.1),P(1)(即掷出1的概率)应该在0和1之间。由于01/61,因此满足条件。再根据式(2.2),样本空间中所有事件的概率和应该为1。由于P(1) = P(2) = P(3) = P(4) = P(5) = P(6) = 1/6并且1/6 + 1/6 + 1/6 + 1/6 + 1/6 + 1/6 = 1,因此也满足条件。

如果事件A发生的概率为P(A),那么事件A不发生的概率为

(2.3)

其中,读作“非A”,表示A的补。有时候,你会看到用PA)表示,这里的“¬”是逻辑符号里的“非”。

可以从式(2.1)和式(2.2)推出式(2.3),因为每个事件发生的概率都小于1,而任意发生的事件来自样本空间的概率恒为1,所以任意不是A的事件发生的概率,一定等于1减去事件A发生的概率。

举个例子,掷一枚骰子,结果在区间[1, 6]的概率为1,但结果为4的概率是1/6。因此,结果不是4的概率就等于其他所有可能结果的概率之和,即

也就是说,结果有83%的概率不是4。

如果我们掷两次骰子,然后把结果相加呢?此时样本空间的取值范围是2到12的整数区间。然而,此时并非所有求和结果的概率都相等,而这也是双骰子游戏的关键所在。要想计算各个求和结果的概率,我们就要列举它们各自出现的所有可能。然后把各自可能事件的总数除以全部事件的总数,得到各自的出现概率。表2-1展示了如何列举所有的可能结果。

表2-1 两个骰子的各种可能组合对应的求和结果

在表2-1中,掷两次骰子的结果一共构成36种可能组合。可以看到,两次加在一起为7的概率最大,因为它对应6种组合。2和12的可能性最小,它们各自只对应1种组合。由于7对应6种组合,因此结果为7的概率为6/36 ≈ 0.1667。我们在第3章讨论概率分布和贝叶斯定理时还会用到表2-1。表2-1阐述了如下一般性法则:如果可以列举整个样本空间,那就可以计算任意事件的概率。

我们再看一个例子,如果这次同时掷三枚硬币,那么结果为零次正面、一次正面、两次正面和三次正面的概率分别是多少?我们可以通过列举法来计算,如表2-2所示。

表2-2 掷三枚硬币的情况

根据表2-2,我们可以计算出得到一次正面和两次正面的概率都是37.5%。不妨用代码来检验一下:

import numpy as np
N = 1000000
M = 3
heads = np.zeros(M+1)
for i in range(N):
    flips = np.random.randint(0,2,M)
    h, _ = np.bincount(flips, minlength=2)
    heads[h] += 1
prob = heads / N
print("Probabilities: %s" % np.array2string(prob))

以上代码模拟了1 000 000次(N)掷三枚硬币(M)的实验。零次、一次、两次或三次正面朝上的次数被保存在变量heads中。每次实验都挑选3个位于区间[0, 1](flips)的整数,然后统计正面(0)的次数。我们不用管反面的情况,只用np.bincount统计正面的次数并累加到变量heads中。接下来进行下一次实验,以此循环迭代。

当全部模拟实验完成后,用heads除以总实验次数,得到概率(prob)。最后,输出各个事件的概率值。对于零次正面、一次正面、两次正面和三次正面的概率,用一行代码就可以输出:

Probabilities: [0.125236, 0.3751, 0.37505, 0.124614]

这与上面推导的概率结果大体相同,因而我们大致可以相信自己的结果是正确的。

2.2.2 加法法则

我们从定义开始:若事件AB不能同时发生,即一次最多只能发生其中一个事件,则称事件AB互斥。例如,抛硬币的结果要么是正面,要么是反面,而不可能同时是正面和反面。互斥意味着若事件A发生,则事件B就被排除发生的可能,反之亦然。此外,如果两个事件发生的概率完全不相关,也就是说,无论事件B是否发生,事件A发生的概率都不受影响,则称事件AB相互独立。

加法法则关注的是关于两个或两个以上互斥事件中任意一个事件发生的概率。例如,掷一枚标准的骰子,结果为4或5的概率是多少?我们知道掷出4和5的概率都是1/6,而由于这两个事件互斥,我们在直觉上会认为掷出4或5的概率是两者概率之和,因为4和5作为事件的结果都属于样本空间,并且要么两者中有一方发生,要么两者都不发生。于是,我们可以得出

(2.4)

这里的 Υ 是指“或”或“并”。对于一个标准的骰子,掷出4或5的概率是1/6 + 1/6 = 1/3,大约33%。       

掷两次硬币的结果的样本空间是{HHHTTHTT},所以结果为两次正面或两次反面的概率是

关于加法法则还有更多内容,在进一步了解之前,我们先介绍一下乘法法则。

2.2.3 乘法法则

相比加法法则回答事件A发生或事件B发生的概率,乘法法则回答的是事件A发生且事件B也发生的概率:

(2.5)

这里的∩表示“且”或“交”。

如果事件AB互斥,则可以很快得出P(AB) = 0,因为如果事件A以概率P(A)发生,那么事件B发生的概率P(B) = 0,因而两者的乘积为0。同样,如果事件B发生,那么P(A) = 0。

当然,并非所有事件都互斥。例如,假定世界上有80%的人眼睛是棕色,并且其中有50%是女性。那么,如果随机挑选一人,她是女性并且眼睛是棕色的概率是多少?让我们使用乘法法则来计算:

P(女性, 棕色眼睛) = P (女性) × P(棕色眼睛) = 0.5 × 0.8 = 0.4

结果是:有40%的概率随机选到棕色眼睛的女性。

深入思考一下就会发现,乘法法则是很有道理的。在当前的假设下,无论女性的占比(即概率)如何,棕色眼睛在女性中的占比都不会改变,是否选中女性对于是否选中棕色眼睛没有任何影响。

乘法法则并不局限于两个事件。考虑以下情况:根据保险公司的数据,我们知道一名美国人在任意一年中有1 / 1 222 000或大约0.000082%的概率遭到雷击,那么一名拥有棕色眼睛的美国女性,在一年中遭到雷击的概率是多少?

还是用乘法法则:

P(女性, 棕色眼睛, 遭到雷击) = P(女性) × P(棕色眼睛) × P(遭到雷击)

≈0.5×0.8×0.00000082

≈0.00000033=0.000033%

美国总人口数约为331 000 000,按照0.000033%的比例预测,一年中会有109位棕色眼睛的女性遭到雷击。根据美国国家气象局的数据,一年中大约有270人遭到雷击。再根据上面的计算结果,这里面应该有40%的棕色眼睛女性,也就是270 × 0.4 = 108人。我们的计算结果还是很可靠的。

2.2.4 加法法则的修正版

前面说过,关于加法法则还有更多的内容,我们来看看缺失了哪一块。式(2.4)适用于互斥事件AB。那么,如果事件之间并不互斥呢?这种情况需要对公式进行修改:

(2.6)

我们来看一个例子。

假如一位考古学家发现一个小宝藏,里面有20枚古硬币。他注意到其中12枚是罗马币,8枚是希腊币。他还注意到罗马币中有6枚银币,希腊币中有3枚银币,余下的都是青铜币。那么从这个宝藏里随机选中一枚罗马币或银币的概率是多少?

如果认为挑中银币和挑中罗马币是两个互斥事件,那么我们很可能会认为

P(银币or罗马币) = P(银币) + P(罗马币)

(这是错误的!)

两者之和为21/20 = 1.05,由于概率值不可能大于1,因此一定哪里有问题。

问题就在于宝藏里有一些罗马银币,它们被计数了两次—— 一次在P(银币)中,另一次在P(罗马币)中。因此,在最终的求和结果中应该减去重复计数的次数。由于一共有6枚罗马银币,因此随机选中罗马银币的概率是P(罗马and银币) = 6/20。减去这个值,我们可以得到随机选中一枚罗马币或银币的概率是75%。

P(银币or罗马币) = P(银币) + P(罗马币) − P(罗马and银币)

与加法法则类似,乘法法则中也有一些细节需要考虑,我们很快就会讨论这些内容。下面我们先试着用乘法法则解决2.2.5小节中的生日难题。

2.2.5 生日难题

问:一个房间里平均需要有多少人,才能使他们中有两个人的生日在同一天的概率大于50%?这个问题被称为生日难题。让我们看看能否用概率的乘法法则来解决这个问题。

假定不考虑闰年,那么一年有365天。从直观上讲,随意挑选的两人在同一天出生的概率,等于365天里任意一天被选中的概率。由于样本空间是365天,而每一天被选中的可能性相同,因此有

又因为挑选的两人要么生日相同,要么生日不同,所以得出

也就是说,一年的365天里,只有一天可用于匹配,剩下的364天都不可以。

0.3%的概率非常低,这意味着从1000对人里随意挑选一对,问他们是否同一天出生,平均只有三对人选给出肯定回答。也就是说,可能性并不高。

我们继续思考,为了计算方便,我们可以从另一个角度思考这个问题。考虑至少需要多少人,才能使他们中没有两个人的生日在同一天的概率小于50%。

由于我们已经算出,任意两人不在同一天出生的概率是;因此,如果我们随机挑选两对人,那么这两对人选都不在同一天出生的概率是

P(两对人选的生日都不同) = P(第一对人选的生日不同) × P(第二对人选的生日不同)

≈ 0.9945 = 99.45%   

这里用到了乘法法则。类似地,假如房间里有3个人——(AB),那就有3种配对方式,即(AB)、(AC)和(BC)。可以算出:

同理,对于n对人选的生日都不同的情况:

(2.7)

所以,我们的任务就是找到最小的n,使得所有人选的生日全都不同的概率小于50%,而n是房间内人数m的函数。为什么是小于50%呢?因为如果找到了最小的n,使得所有n对人选都不在同一天出生的概率小于50%,那就意味着至少有一对人选在同一天出生的概率大于50%。

从3个人里随意挑选两人看是否同一天出生,一共有3种配对方式。如果从4个人里挑,一共有6种挑法。也就是说,配对方式的数量会随着人数的增加而增加。有没有办法直接根据总人数m计算出有多少种配对方式n呢?如果可以,我们就能根据找到的最小n计算出对应的m,使得式(2.7)的概率值小于50%。

m个不同的对象里任意挑选两个对象,一共有多少种不同的挑选方法呢?换言之,从m个事物中同时挑选两个进行组合,一共有多少种组合方式呢?根据组合公式,对于从m个事物中同时挑选k个进行组合,总共的组合方式为

有时这称为“从m中选k”,在生日难题中,k = 2。让我们先计算出需要的对数n,再根据组合公式,看看当k = 2时,m需要是多少才能得出n种组合。

可以用如下简单的Python循环来计算n

for n in range(300):
    if ((364/365)**n < 0.5):
        print(n)
        break

结果算出来n = 253。所以,我们平均需要253对人选才能使至少有一对人选在同一天出生的概率大于50%。最后一步就是计算使得从中任意挑选两人的组合数为253的总人数m。利用粗暴的试错法,可以得到

所以,平均需要m = 23人才能使至少有两人同一天出生的概率大于50%。

这个计算过程真实可靠吗?代码可以告诉我们答案。首先,让我们通过代码来模拟随机挑选过程,并证明任意两人同一天出生的概率是否为0.3%:

match = 0
for i in range(100000):
    a = np.random.randint(0,364)
    b = np.random.randint(0,364)
    if (a == b):
        match += 1
print("Probability of a random match = %0.6f" % (match/100000,))

上述代码模拟了100 000轮随机配对过程,其中,位于区间[0, 364]的随机整数代表一个人的出生日期。如果两个人的生日相同,则对match加1。整个模拟过程结束后,输出概率值。这段代码的输出结果证明了我们计算出的0.3%的概率是可信的:

Probability of a random match = 0.003100

那么关于使至少两个人同一天出生的概率大于50%的最少人数的计算是否正确呢?这里需要使用两层循环。第一层循环遍历房间里的总人数m,第二层循环在m个人中进行n次配对模拟。代码如下:

for m in range(2,31):
    matches = 0
    for n in range(100000):
        match = 0
        b = np.random.randint(0,364,m)
        for i in range(m):
            for j in range(m):
                if (i != j) and (b[i] == b[j]):
                    match += 1
        if (match != 0):
            matches += 1
    print("%2d %0.6f" % (m, matches/100000))

m从2取到30。对于每m个人,进行100 000次模拟。每次模拟时,将我们从房间里挑选的人的生日保存在变量b中,然后通过两两比较来判断是否有人在同一天出生。如果有,就对match加1。只要match至少为1,就增加matches并进行下一次模拟。最终,在对所有的总人数都完成模拟后,输出至少有一对匹配的概率值。

执行代码并将结果画图显示出来,可以得到图2-1,其中的虚线代表50%。第一个超过50%的点对应的人数是23,这与我们的计算结果完全一致。

图2-1 同一天出生的概率与房间里人数的函数关系

2.2.6 条件概率

假如我们有一袋弹珠,其中8个是红色的,剩下的2个是蓝色的。我们知道,如果随机挑选,则有2/10(即20%)的概率挑中蓝色球。假如我们先挑中了一个蓝色球,然后放回袋子,摇一摇,再挑一个弹珠,那么我们再次挑中蓝色球的概率是多少?因为袋子里仍然有10个弹球且其中的2个是蓝色的,所以概率依然是20%。

如果事件A的发生(挑中一个蓝色球后放回袋子)不影响事件B发生的概率,则称这两个事件相互独立。例如,我们第一次挑中的弹珠的颜色并不影响第二次挑中蓝色球的概率。抛硬币的实验也是类似的。

现在考虑另一个场景。我们依旧从袋子里挑选弹珠,袋子里也依然是8个红色球和2个蓝色球。但这一次,我们先挑中了一个红色球,因为很喜欢这种颜色,所以我们将这个弹珠留下放到了一边。那么接下来,我们再次挑中一个红色球的概率是多少?这次情况变了。现在一共只有9个弹珠,其中有7个红色球,所以我们再次挑中红色球的概率是7/9,约78%。而最初这一概率是8/10,即80%。事件A(第一次挑中红色球)的发生,影响了事件B(第二次挑中红色球)发生的概率,所以这两个事件不再相互独立,即事件B的概率被事件A改变了。我们用P(B|A)来表示在给定事件A发生的条件下事件B发生的概率。这是一个条件概率,它以事件A的发生为条件。

有了条件概率,我们就可以对乘法法则进行更新。式(2.5)是乘法公式在独立情况(比如棕色眼睛女性的例子)下的表达式。而在非独立情况下,乘法公式为

(2.8)

这说明两个事件同时发生的概率,等于其中一个事件以另一个事件发生为条件发生的概率,乘以另一个事件发生的概率。

回到挑弹珠的例子,我们算出,在挑中一个红色球并且留下的情况下,再次挑中一个红色球的概率是7/9,约78%,这就是P(B | A)。对于P(A),即最初挑中红色球的概率,我们知道是80%。因此,第一次挑中红色球并留下(即事件A)且第二次又挑中红色球(即事件B)的概率大约是62%,即

如果两个事件互斥,那么P(B | A) = P(A | B) = 0。如果事件AB相互独立,那么P(A | B) = P(A)且P(B | A) = P(B),因为条件事件是否发生对随后的事件没有影响。

最后需要注意P(B | A) ≠ P(A | B),混淆这两个条件概率是人们经常犯的一个严重错误。在第3章,我们将在有关贝叶斯定理的内容中阐述这两个条件概率的正确关系。等到之后讨论概率的链式法则时,还会涉及条件概率的内容。

2.2.7 全概率公式

如果样本空间可以划分为不相交的区域BiB1B2等),使得整个样本空间可以被Bi的集合完全覆盖,并且各个Bi之间没有重叠区域,则可以计算某个事件在所有区域上的概率和:

这里的P(A | Bi)是事件A在区域Bi上的概率;P(Bi)是事件B在区域Bi上的概率,也就是区域Bi占样本空间的比例。在这种描述中,P(A)是事件A关于所有区域Bi的全概率。下面让我们通过例子来看看如何运用全概率公式。

假设有三个小镇Kish、Kesh和Kuara,它们各自的人口数为2000、1000和3000。此外,每个小镇上有蓝色眼睛的人占比分别是12%、3%和21%。我们想知道从这三个小镇随机挑选的一个人有蓝色眼睛的概率。不同小镇的蓝色眼睛人口比例不同,而不同小镇的人口数也不同,或许就是小镇的人口数造成了某些影响。但不管怎么说,为了计算P(蓝色眼睛),就要用到全概率公式:

这里的P(蓝色眼睛 | Kish)是一个人住在Kish且拥有蓝色眼睛的概率,而P(Kish)是一个人住在Kish的概率,其他概率的含义类似。

以上就是计算全概率需要的所有变量。其中,从每个小镇挑中蓝色眼睛的人的概率是给定的,而一个人住在各个小镇的概率等于各小镇人口占三个小镇总人口的比例:

由此

这意味着,如果从这三个小镇随机挑选一位居民,将有15%的概率挑中蓝色眼睛的人。注意选中各个小镇的概率加起来等于1(P(Kish) + P(Kesh) + P(Kuara) = 1)。这是对样本空间进行完全划分的必要条件,所有的居民都必须被划分到这三个小镇之一。