1 什么是概率
概率是一个介于 000 和 111 之间的数(包含 000 和 111),用于衡量事件发生的可能性:
- 当概率为 000 时,代表这个事件绝对不可能发生;
- 当概率为 111 时,代表这个事件必然会发生;
- 当概率在 000 到 111 之间时,数值越大,事件发生的可能性就越大。
1.1 样本空间和事件
1.1.1 样本空间
样本空间(Sample Space):指一个随机试验中,所有可能出现的结果的集合,通常用符 Ω\OmegaΩ(大写希腊字母欧米伽)表示。
1.1.2 事件
事件(Event),指样本空间的一个子集,通常用大写字母A、B、C等表示。事件可以是单个 结果,也可以是 多个结果 的组合。
1.2 随机变量
随机变量(Random Variable)是一个函数,这个函数将样本空间中的每一个结果,对应到一个实数。简单来说,就是给随机试验的每个可能结果贴一个 数字标签,把非数值结果转化为 数值 结果,让我们可以用数学方法分析概率。
1.3 具体事例
假设某抽奖活动,总共有 100010001000 张奖券,其中一等奖 101010 张、二等奖 505050 张、三等奖 100100100 张,其余为无奖券。
- 样本空间(Ω\OmegaΩ)
对应抽奖的所有可能结果,即 100010001000 张奖券的集合,每张奖券都是一个独立的结果,因此 样本空间 Ω\OmegaΩ 的总结果数 = 100010001000,且每张奖券被抽中的可能性相等。
- 事件
对应我们关心的抽奖结果,例如我们关注以下两个事件:
(1) 事件 A:"抽中一等奖",是 样本空间 的一个子集,包含的结果数 = 101010;
(2) 事件 B:"抽中获奖奖券",同样是 样本空间 的子集,包含的结果数=10+50+100=160包含的结果数 = 10+50+100 = 160包含的结果数=10+50+100=160,即 一等奖、二等奖、三等奖奖券的总和。
- 随机变量
我们定义 随机变量 X,用于量化抽奖结果,方便后续概率计算,赋值如下:
X = 抽中奖券的奖项等级,无奖记为 000,三等奖记为 111,二等奖记为 222,一等奖记为 333。
此时,随机变量 X 的可能取值为 000、111、222、333,分别对应抽奖的四种结果,将 抽中某类奖券 的非数值描述,转化为了可计算的数值,这就是 随机变量 的核心作用。
2 概率的法则
2.1 事件的概率
样本空间 中全部 事件 的概率和为 111。由于任意 事件 都属于 样本空间,而 样本空间 包含 事件 的所有可能结果,因此样本空间中任意 事件 发生的 概率 总是小于或等于1。对于任意 事件 A:
0≤P(A)≤10 \le P(A) \le 10≤P(A)≤1
对于 样本空间 中的所有 事件 AiA_{i}Ai:
ΣiP(Ai)=1\Sigma_{i} P(A_{i}) = 1ΣiP(Ai)=1
例如,掷一枚有6个面的骰子,任意面朝上的概率都相等,均为 16\frac{1}{6}61。样本空间 中所有 事件 的概率和应该为 111。
P(1)=P(2)=P(3)=P(4)=P(5)=P(6)=16P(1)+P(2)+P(3)+P(4)+P(5)+P(6)=16+16+16+16+16+16=1 \begin{aligned} & P(1) = P(2) = P(3) = P(4) = P(5) = P(6) = \frac{1}{6} \\ &\begin{aligned} P(1) + P(2) + P(3) + P(4) + P(5) + P(6) &= \frac{1}{6} + \frac{1}{6}+ \frac{1}{6}+ \frac{1}{6}+ \frac{1}{6}+ \frac{1}{6} \\ &=1 \end{aligned} \end{aligned} P(1)=P(2)=P(3)=P(4)=P(5)=P(6)=61P(1)+P(2)+P(3)+P(4)+P(5)+P(6)=61+61+61+61+61+61=1
如果事件 AAA 发生的概率为 P(A)P(A)P(A),那么事件 AAA 不发生的概率为
P(Aˉ)=1−P(A) P(\bar{A}) = 1 - P(A) P(Aˉ)=1−P(A)
其中,Aˉ\bar{A}Aˉ 读作 非A,表示 AAA 的补。
举个例子,掷一枚骰子,结果在区间 [1,6][1,6][1,6] 的概率为 111,但结果为 444 的概率是 16\frac{1}{6}61。因此,结果不是 444 的概率就等于其他所有可能结果的概率之和:
P(4ˉ)=1−P(4)=1−16=56≈0.8333⋯ \begin{aligned} P(\bar{4}) &= 1 - P(4) \\ &= 1 - \frac{1}{6} \\ &= \frac{5}{6} \\ &\approx 0.8333 \cdots \end{aligned} P(4ˉ)=1−P(4)=1−61=65≈0.8333⋯
如果掷两次骰子,那么 样本空间 的取值范围是 222 到 121212 的整数区间。要想计算各个求和结果的概率,我们就要列举它们各自出现的所有可能。然后把各自可能事件的总数除以全部事件的总数,得到各自的出现概率。下表展示了如何列举所有的可能结果。
| 求和结果 | 组合 | 组合的数量 | 概率(近似值) |
|---|---|---|---|
| 222 | 1+11 + 11+1 | 111 | 0.02780.02780.0278 |
| 333 | 1+2,2+11+2, 2+11+2,2+1 | 222 | 0.05560.05560.0556 |
| 444 | 1+3,3+1,2+21+3,3+1,2+21+3,3+1,2+2 | 333 | 0.08330.08330.0833 |
| 555 | 1+4,2+3,3+2,4+11+4,2+3,3+2,4+11+4,2+3,3+2,4+1 | 444 | 0.1111 |
| 666 | 1+5,2+4,3+3,4+2,5+11+5,2+4,3+3,4+2,5+11+5,2+4,3+3,4+2,5+1 | 555 | 0.1389 |
| 777 | 1+6,2+5,3+4,4+3,5+2,6+11+6,2+5,3+4,4+3,5+2,6+11+6,2+5,3+4,4+3,5+2,6+1 | 666 | 0.1667 |
| 888 | 2+6,3+5,4+4,5+3,6+22+6,3+5,4+4,5+3,6+22+6,3+5,4+4,5+3,6+2 | 555 | 0.1389 |
| 999 | 3+6,4+5,5+4,6+33+6,4+5,5+4,6+33+6,4+5,5+4,6+3 | 444 | 0.1111 |
| 101010 | 4+6,5+5,6+44+6,5+5,6+44+6,5+5,6+4 | 333 | 0.0833 |
| 111111 | 5+6,6+55+6,6+55+6,6+5 | 222 | 0.0556 |
| 121212 | 6+66+66+6 | 111 | 0.0278 |
| 合计 | 36 | 1.0000 |
掷两次骰子的结果一共构成 363636 种可能组合。两次加在一起为 777 的概率最大,共666种组合。
222 和 121212 的概率最小,各自只对应1种组合。
由于 777 对应 666 种组合,因此结果为7的概率为 636≈0.1667\frac{6}{36} \approx 0.1667366≈0.1667。
再看一个例子,同时掷三枚硬币,那么结果为 零次正面、一次正面、两次正面 和 三次正面 的 概率 分别是多少?我们可以通过列举法来计算,如下表。
| 正面的硬币数 | 组合(T表示反面,H表示正面) | 组合的数量 | 概率 |
|---|---|---|---|
| 000 | TTT | 111 | 0.1250.1250.125 |
| 111 | HTT,THT,TTH | 333 | 0.3750.3750.375 |
| 222 | HHT,HTH,THH | 333 | 0.3750.3750.375 |
| 333 | HHH | 111 | 0.1250.1250.125 |
| 合计 | 8 | 1.0001.0001.000 |
下面通过 python 代码证明上面的概率是否正确:
python
import numpy as np
# 进行 1000000 轮实验
N = 1000000
# 每轮扔 3 个硬币
M = 3
# 生成包含 4 个元素的数组
# 元素的初始值为 0
# 用于记录上表中,每种结果的次数
heads = np.zeros(M+1)
# 进行 1000000 轮实验
for i in range(N):
# 模拟每次实验,扔 3 枚硬币
# 随机生成 3 个元素的数组,每个元素为 0(反面) 或 1(正面)
flips = np.random.randint(0, 2, M)
# 统计 0 出现多少次、1 出现多少次
# 这里用 h 接收 1 出现的次数,0 出现的次数不管
# minlength=2 强制输出长度一定是 2,避免数据只有 0 或只有 1 时报错
_, h = np.bincount(flips, minlength = 2)
# 对应的结果次数 + 1
heads[h] += 1
# 计算每个结果的概率
prob = heads / N
# 打印每个结果的概率
print(f'Probabilities: {np.array2string(prob)}')
以上代码模拟了 100000010000001000000 次(NNN)掷三枚硬币(MMM)的实验:
(1) 零次、一次、两次 或 三次 正面朝上的次数被保存在变量 heads 中;
(2) 每次实验都挑选 333 个位于区间 [0,1][0,1][0,1] (flips)的整数,然后统计正面(111)的次数;
(3) 用 np.bincount 统计正面的次数并累加到变量 heads中。接下来进行下一次实验,以此循环迭代。
(4) 当全部模拟实验完成后,用 heads除以总实验次数,得到概率(prob), 输出:
markdown
Probabilities: [0.125115 0.375361 0.374271 0.125253]
2.2 事件互斥的加法法则
概率加法法则(Addition Rule of Probability),是用来计算两个事件中至少有一个发生的概率的核心公式,需要理解以下两个概念:
- 互斥事件(Mutually Exclusive Events)
两个事件不可能同时发生,它们的交集为 空集 (A∩B)=∅(A \cap B)=\emptyset(A∩B)=∅。
比如:掷骰子时,掷出 1 点 和 掷出 2 点 就是 互斥事件。
- 相容事件(Non-Mutually Exclusive Events)
两个事件可以同时发生,它们的交集不为 空集 (A∩B)≠∅(A \cap B) \neq \emptyset(A∩B)=∅
比如:掷骰子时,掷出偶数点 和 掷出点数大于 3 就是相容事件。
2.2.1 互斥事件的加法法则具体事例
若 事件A 和 B 不能同时发生,即一次最多只能发生其中一个事件,则称事件A和B 互斥。
比如:掷骰子时,掷出 1 点 和 掷出 2 点 就是 互斥事件,它们的 交集 为 空集 (A∩B)=∅(A \cap B)=\emptyset(A∩B)=∅。
如果 A事件 为掷出 1 点,B事件 为 掷出 2 点,则 A 发生 或 B 发生 的 概率,等于两个事件各自 概率的和:
P(A)∪P(B)=P(A)+P(B)P(A) \cup P(B) = P(A) + P(B)P(A)∪P(B)=P(A)+P(B)
又例如掷两次硬币的 结果 的 样本空间 是 HH,HT,TH,TT{HH,HT,TH,TT}HH,HT,TH,TT(TTT 表示反面,HHH 表示正面),所以结果为两次正面或两次反面的概率是:
P(HHorTT)=P(HH)+P(TT)=14+14=12 \begin{aligned} P(\text{HH} \quad or \quad TT) &= P(HH) + P(TT) \\ &= \frac{1}{4} + \frac{1}{4} \\ &= \frac{1}{2} \end{aligned} P(HHorTT)=P(HH)+P(TT)=41+41=21
2.3 乘法法则
相比 加法法则 回答 事件A 发生或 事件B 发生的 概率,乘法法则 回答的是 事件A 发生且 事件B 也发生的 概率:
P(AandB)=P(A∩B)=P(A)P(B)P(A \quad and \quad B)=P(A \cap B)=P(A)P(B)P(AandB)=P(A∩B)=P(A)P(B)
2.3.1 事件互斥时的乘法法则
如果 事件A 和 B互斥,则可以很快得出 P(A∩B)=0P(A \cap B)=0P(A∩B)=0,因为如果 事件A 以概率 P(A)P(A)P(A) 发生,那么 事件B 发生的概率 P(B)=0P(B)=0P(B)=0,因而两者的乘积为 000。同样,如果 事件B 发生,那么 P(A)=0P(A)=0P(A)=0。
2.3.2 事件不互斥时的乘法法则
假定世界上有 80%80\%80% 的人眼睛是棕色,并且其中有 50%50\%50% 是女性。那么,如果随机挑选一人,她是 女性 并且眼睛是 棕色 的 概率 是:
P(女性,棕色眼睛)=P(女性)×P(棕色眼睛)=0.5×0.8=0.4 \begin{aligned} P(女性,棕色眼睛) &= P(女性) \times P(棕色眼睛) \\ &= 0.5 \times 0.8 \\ &= 0.4 \end{aligned} P(女性,棕色眼睛)=P(女性)×P(棕色眼睛)=0.5×0.8=0.4
结果是,有 40%40\%40% 的概率随机选到 棕色眼睛 的 女性。
乘法法则并不局限于两个事件。例如,根据保险公司的数据,在美国在任意一年中有 11222000\frac{1}{1222000}12220001 即大约 0.0000820.000082%0.000082 的 概率 遭到雷击,那么一名拥有 棕色 眼睛的美国 女性,在一年中遭到雷击的概率是:
P(女性,棕色眼睛,遭到雷击)=P(女性)×P(棕色眼睛)×P(遭到雷击)=0.5×0.8×0.00000082≈0.00000033=0.000033% \begin{aligned} P(女性,棕色眼睛,遭到雷击) &= P(女性) \times P(棕色眼睛) \times P(遭到雷击)\\ &= 0.5 \times 0.8 \times 0.00000082 \\ &\approx 0.00000033 \\ &=0.000033\% \end{aligned} P(女性,棕色眼睛,遭到雷击)=P(女性)×P(棕色眼睛)×P(遭到雷击)=0.5×0.8×0.00000082≈0.00000033=0.000033%
2.4 事件不互斥的加法法则
如果 事件A 和 事件B 不互斥,直接相加会重复计算 两个事件同时发生 的部分,因此需要减去 交集 的 概率:
P(A∪B)=P(A)+P(B)−P(A∩B)P(A \cup B) = P(A) + P(B) - P(A \cap B)P(A∪B)=P(A)+P(B)−P(A∩B)
因为,P(A)P(A)P(A) 包含了 只发生 A 和 A、B 同时发生,P(B)P(B)P(B) 包含了 只发生 B 和 A、B 同时发生,相加后 交集 部分被算了两次,所以要减去一次 P(A∩B)P(A \cap B)P(A∩B)。
例如,扔两个骰子,求 点数和为 7 或 第一个骰子掷出 6 的 概率:
(1) 事件 AAA:点数和为 777,从表格可知组合有 666 种,P(A)=636=16≈0.1667P(A)=\frac{6}{36}=\frac{1}{6} \approx 0.1667P(A)=366=61≈0.1667;
(2) 事件 BBB:第一个骰子掷出 666,组合有 (6,1),(6,2)...(6,6) 共 666 种,P(B)=636=16≈0.1667P(B)=\frac{6}{36}=\frac{1}{6} \approx 0.1667P(B)=366=61≈0.1667;
(3) 事件 A∩BA \cap BA∩B:点数和为 7 且 第一个骰子为 6,只有 (6,1) 这 111 种组合,P(A∩B)=136≈0.0278P(A∩B)=\frac{1}{36} \approx 0.0278P(A∩B)=361≈0.0278;
(4) 代入公式计算:
P(A∪B)=636+636−136=1136≈0.3056 \begin{aligned} P(A \cup B) &= \frac{6}{36} + \frac{6}{36} - \frac{1}{36} \\ &= \frac{11}{36} \\ &\approx 0.3056 \end{aligned} P(A∪B)=366+366−361=3611≈0.3056
2.5 生日难题
生日难题,全称生日悖论 / 生日问题(Birthday Problem),是概率论里最经典、最反直觉的古典概率计算问题。
2.5.1 生日难题的意义
它解决这样一个难题:
一个房间里平均需要有多少人,才能使他们中有两个人的生日在同一天的 概率 大于 50%50\%50%?
2.5.2 使用概率乘法解决生日难题
在不考虑闰年情况下,随意挑选的两人在同一天出生的 概率,等于 365365365 天里任意一天被选中的 概率。由于 样本空间 是365365365 天,而每一天被选中的可能性相同,因此有:
P(两人生日相同)=1365≈0.00274P(两人生日不同)=1−1365=364365≈0.9973 \begin{aligned} &P(两人生日相同) = \frac{1}{365} \approx 0.00274\\\\ &P(两人生日不同) = 1 - \frac{1}{365} = \frac{364}{365} \approx 0.9973 \end{aligned} P(两人生日相同)=3651≈0.00274P(两人生日不同)=1−3651=365364≈0.9973
如果,随即抽两对人,那么这两对人都 不在同一天 生日的 概率 是:
P(两对人生日均不同)=P(第一对人生日不同)×P(第二对人生日不同)=364365×364365≈0.9945=99.45% \begin{aligned} P(两对人生日均不同) &=P(第一对人生日不同) \times P(第二对人生日不同) \\ &=\frac{364}{365} \times \frac{364}{365} \\ &\approx 0.9945 \\ &=99.45 \% \end{aligned} P(两对人生日均不同)=P(第一对人生日不同)×P(第二对人生日不同)=365364×365364≈0.9945=99.45%
类似地,随即抽 3 对人,这三对人都 不在同一天 生日的 概率 是:
P(三对人生日均不同)=P(第一对人生日不同)×P(第二对人生日不同)×P(第三对人生日不同)=364365×364365×364365 \begin{aligned} P(三对人生日均不同) &=P(第一对人生日不同) \times P(第二对人生日不同) \times P(第三对人生日不同) \\ &=\frac{364}{365} \times \frac{364}{365} \times \frac{364}{365} \end{aligned} P(三对人生日均不同)=P(第一对人生日不同)×P(第二对人生日不同)×P(第三对人生日不同)=365364×365364×365364
同理,对于 nnn 对人选的生日都不同的情况:
P(n对人生日均不同)=(364365)n P(n对人生日均不同)=\begin{pmatrix}\frac{364}{365} \end{pmatrix}^{n} P(n对人生日均不同)=(365364)n
因此,现在解决问题,就要找到最小的 nnn,使得所有人选的生日全都不同的概率小于 50%50\%50%,而 nnn 是房间内人数 mmm 的函数。
对于从 mmm 个人中同时挑选 kkk 个进行 组合,总共的 组合 数为:
C(m,k)=(mk)=m!k!(m−k)! C(m,k) = \begin{pmatrix}m\\k\end{pmatrix}=\frac{m!}{k!(m-k)!} C(m,k)=(mk)=k!(m−k)!m!
在生日难题中,每次抽 222 个人作为一对人,k=2k=2k=2。因此,计算步骤:
(1) 先计算出需要的对数 nnn
(2) 再根据 组合公式,看看当 k=2k=2k=2 时,mmm 需要是多少才能得出 nnn 种 组合。
可以用如下简单的Python循环来计算n:
python
# 循环300次
for n in range(300):
# 当 n 对人生日都不相同的概率小于0.5时,输出n
# 此时 n 就是使 生日都不相同的概率小于0.5 的对数
if ((364 / 365)**n < 0.5):
print(n)
break
最终结果为 n=253n = 253n=253。即,需要 253253253 对人选才能使至少有一对人选在同一天出生的概率大于50%50\%50%。
此时,上面的组合式中,k=2k = 2k=2,结果为 253253253 即:
C(m,2)=(m2)=m!2!(m−2)!=253 \begin{aligned} C(m,2) &= \begin{pmatrix}m\\2\end{pmatrix} \\ &=\frac{m!}{2!(m-2)!} \\ &=253 \end{aligned} C(m,2)=(m2)=2!(m−2)!m!=253
现在,就是要求 m:
m!2!(m−2)!=m(m−1)(m−2)!2(m−2)!=m(m−1)2=m2−m2=253 \begin{aligned} \frac{m!}{2!(m-2)!} &=\frac{m(m-1)(m-2)!}{2(m-2)!} \\ &=\frac{m(m-1)}{2} \\ &=\frac{m^2 - m}{2} \\ &=253 \end{aligned} 2!(m−2)!m!=2(m−2)!m(m−1)(m−2)!=2m(m−1)=2m2−m=253
所以,现在变成了解方程 m2−m−506=0m^2 - m - 506 = 0m2−m−506=0,求 mmm:
m2−m−506=(m−23)(m+22)=0 m^2 - m - 506 = (m - 23)(m + 22) = 0 m2−m−506=(m−23)(m+22)=0
解得 m=23m = 23m=23 或 m=−22m = -22m=−22,舍掉 负数。
所以,平均需要 m=23m=23m=23人才能使至少有两人同一天出生的概率大于 50%50\%50%。
2.5.3 程序验证
证明任意两人同一天出生的概率是否为0.3%
python
import numpy as np
# 记录同一天生日的次数
match = 0
# 模拟 1000000 次 实验
# 实验内容,抽一对人,并且看是否为同一天生日
for i in range(1000000):
# 第一个人的生日日期,从 0-364 中随即取一整数
a = np.random.randint(0, 364)
# 第一个人的生日日期,从 0-364 中随即取一整数
b = np.random.randint(0, 364)
# 如果是同一天生日,则 match 变量加一
if (a == b):
match += 1
print(f"一对人,同一天生日的概率为 {match / 1000000}")
运行结果,约为 0.3%0.3\%0.3%。
生日难题的结果是否正确
python
# 导入numpy库,用于生成随机数和数值计算
import numpy as np
# 验证生日问题:m个人中至少两人生日相同的概率
# 人数 m 从 2 取到 30,依次计算不同人数下的概率
for m in range(2,31):
# 记录当前人数m下,10万次实验中【出现生日相同】的总次数
matches = 0
# 对每 m 个人进行 100000 次独立模拟实验
for n in range(100000):
# 单次实验中,生日重复的计数(只要有重复就>0)
match = 0
# 随机生成m个人的生日:0~364代表一年365天
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 # 发现生日重复,计数+1
# 如果本次实验出现了生日重复(match≠0)
if (match != 0):
matches += 1 # 总成功次数+1
# 输出:人数m + 出现生日相同的频率(概率),保留6位小数
print("%2d %0.6f" % (m, matches/100000))
输出结果如下:

从运行结果看:
232323 人时,概率约 50%50\%50%
303030 人时,概率超过 70%70\%70%
跟上面的计算结果是一致的。