离散概率
概率论是研究随机现象规律性的数学分支。离散概率专注于有限或可数无限样本空间中的概率问题,是算法分析、机器学习、密码学、网络协议等领域的基础工具。理解概率思维,能帮助我们处理不确定性、做出合理决策。
概率的基本概念
随机试验与样本空间
随机试验是具有以下特点的试验:
- 可以在相同条件下重复进行
- 所有可能的结果事先已知
- 每次试验的结果事先不能确定
样本空间(Sample Space)是随机试验所有可能结果组成的集合,记作 或 。样本空间中的每个元素称为样本点或基本事件。
例子:
- 抛一枚硬币:(正面、反面)
- 掷一枚骰子:
- 抛两枚硬币:
- 从一副牌中抽一张:
import random
# 模拟掷骰子
def roll_die():
return random.randint(1, 6)
# 模拟抛两枚硬币
def flip_two_coins():
outcomes = ['HH', 'HT', 'TH', 'TT']
return random.choice(outcomes)
事件
**事件(Event)**是样本空间的子集。事件发生当且仅当试验结果属于该事件。
基本事件:只包含一个样本点的事件。
复合事件:包含多个样本点的事件。
特殊事件:
- 必然事件:,一定发生的事件
- 不可能事件:,不可能发生的事件
事件的运算:
设 和 是两个事件:
- 并事件 : 或 发生
- 交事件 : 和 同时发生
- 差事件 : 发生但 不发生
- 对立事件 或 : 不发生
互斥事件:如果 ,则称 和 互斥(或互不相容)。
# 骰子样本空间
omega = {1, 2, 3, 4, 5, 6}
# 定义事件
A = {2, 4, 6} # 偶数
B = {1, 2, 3} # 小于等于3
# 事件运算
print(f"A ∪ B = {A | B}") # {1, 2, 3, 4, 6}
print(f"A ∩ B = {A & B}") # {2}
print(f"A - B = {A - B}") # {4, 6}
print(f"A 的对立事件 = {omega - A}") # {1, 3, 5}
概率的定义
古典概型:当样本空间有限且每个基本事件等可能发生时,事件 的概率定义为:
例子:掷骰子得到偶数的概率:
概率的公理化定义(柯尔莫哥洛夫公理):
设 是样本空间, 是事件域( 的某些子集构成的 -代数)。概率 是定义在 上的实值函数,满足:
- 非负性:对于任意事件 ,
- 规范性:
- 可列可加性:对于互不相容的事件序列 ,有:
概率的基本性质
从公理可以推导出以下性质:
-
-
有限可加性:若 两两互斥,则:
-
对立事件公式:
-
单调性:若 ,则
-
有界性:
-
加法公式:
-
容斥原理推广:
例子:一副52张牌中,抽到红桃或A的概率是多少?
设 为"抽到红桃", 为"抽到A"。
(13张红桃)
(4张A)
(红桃A只有一张)
# 验证
from fractions import Fraction
P_A = Fraction(13, 52)
P_B = Fraction(4, 52)
P_AB = Fraction(1, 52)
P_union = P_A + P_B - P_AB
print(P_union) # 4/13
条件概率
条件概率的定义
设 和 是两个事件,且 。在事件 发生的条件下,事件 发生的条件概率定义为:
直观理解:条件概率将样本空间"缩小"到事件 发生的情况,重新计算 在这个新样本空间中的概率。
例子:掷两枚骰子,已知点数之和为8,求其中一枚出现3点的概率。
样本空间:,共36个等可能结果。
事件 (和为8):,共5个结果。
事件 (至少一枚为3):,共11个结果。
:,共2个结果。
# 计算条件概率
def conditional_prob(event_A, event_B, sample_space):
"""计算 P(A|B)"""
intersection = event_A & event_B
if len(event_B) == 0:
return None
return len(intersection) / len(event_B)
# 骰子例子
omega = {(i, j) for i in range(1, 7) for j in range(1, 7)}
B = {(i, j) for i, j in omega if i + j == 8}
A = {(i, j) for i, j in omega if i == 3 or j == 3}
print(f"P(A|B) = {conditional_prob(A, B, omega)}") # 0.4 = 2/5
乘法公式
由条件概率的定义,可以得到乘法公式:
推广形式:
例子:不放回地从一副52张牌中依次抽取3张,求三张都是A的概率。
from fractions import Fraction
prob = Fraction(4, 52) * Fraction(3, 51) * Fraction(2, 50)
print(prob) # 1/5525
独立性
独立性的定义
两个事件 和 称为独立的,如果:
等价地(当 ):
直观理解:事件 的发生不影响事件 发生的概率。
注意:"独立"与"互斥"是不同的概念:
- 独立:
- 互斥:
如果 且 ,则独立和互斥不能同时成立(除非概率为0)。
多个事件的独立性
三个事件 称为相互独立,当且仅当以下四个条件同时成立:
注意:两两独立不等于相互独立。可能存在三个事件两两独立,但不是相互独立的情况。
例子:抛两枚均匀硬币,定义事件:
- :第一枚正面
- :第二枚正面
- :两枚结果相同
验证独立性:
✓
✓
✓
所以这三个事件两两独立,但不是相互独立。
# 验证独立性
def check_independence(event_A, event_B, sample_space):
"""检查两个事件是否独立"""
P_A = len(event_A) / len(sample_space)
P_B = len(event_B) / len(sample_space)
P_AB = len(event_A & event_B) / len(sample_space)
return abs(P_AB - P_A * P_B) < 1e-10
# 抛两枚硬币
omega = {'HH', 'HT', 'TH', 'TT'}
A = {'HH', 'HT'} # 第一枚正面
B = {'HH', 'TH'} # 第二枚正面
C = {'HH', 'TT'} # 两枚相同
print(f"A 和 B 独立: {check_independence(A, B, omega)}") # True
print(f"A 和 C 独立: {check_independence(A, C, omega)}") # True
print(f"B 和 C 独立: {check_independence(B, C, omega)}") # True
全概率公式与贝叶斯定理
全概率公式
设 是样本空间的一个划分(即两两互斥且并集为 ),且 。对于任意事件 :
理解:事件 可以分解为在各种条件下发生的概率之和。
例子:某工厂有甲、乙、丙三台机器生产零件,产量分别为25%、35%、40%,次品率分别为5%、4%、3%。从中随机抽取一件,求抽到次品的概率。
设 分别为"由甲、乙、丙生产", 为"次品"。
# 全概率公式计算
def total_probability(prior_probs, conditional_probs):
"""计算 P(A)
prior_probs: P(B_i)
conditional_probs: P(A|B_i)
"""
return sum(p * c for p, c in zip(prior_probs, conditional_probs))
# 机器生产例子
prior = [0.25, 0.35, 0.40] # P(B_i)
conditional = [0.05, 0.04, 0.03] # P(A|B_i)
print(f"P(A) = {total_probability(prior, conditional):.4f}") # 0.0385
贝叶斯定理
贝叶斯定理描述了如何根据新的证据更新概率估计。它是机器学习和统计推断的核心工具。
术语:
- :先验概率(Prior),在观察到证据 之前对 的概率估计
- :似然(Likelihood),在 为真时观察到 的概率
- :后验概率(Posterior),观察到证据 后对 的更新概率
例子:接上例,已知抽到一件次品,求它是由甲机器生产的概率。
def bayes_theorem(prior, likelihood, evidence):
"""计算后验概率 P(B_i|A)
prior: P(B_i)
likelihood: P(A|B_i)
evidence: P(A)
"""
return [p * l / evidence for p, l in zip(prior, likelihood)]
# 计算后验概率
prior = [0.25, 0.35, 0.40]
likelihood = [0.05, 0.04, 0.03]
evidence = total_probability(prior, likelihood)
posterior = bayes_theorem(prior, likelihood, evidence)
print(f"P(甲|次品) = {posterior[0]:.4f}") # 0.3247
print(f"P(乙|次品) = {posterior[1]:.4f}") # 0.3636
print(f"P(丙|次品) = {posterior[2]:.4f}") # 0.3117
贝叶斯定理的应用
医疗诊断:
某种疾病在人群中的患病率为0.1%(先验)。一种检测方法的准确率为:患者检测呈阳性的概率为99%,健康人检测呈阳性的概率为5%(假阳性率)。如果某人检测结果为阳性,他实际患病的概率是多少?
设 为患病, 为检测阳性。
结论:即使检测呈阳性,实际患病的概率也只有约2%!这说明了为什么罕见疾病的筛查需要谨慎解读结果。
# 医疗诊断计算
P_D = 0.001 # 患病率
P_pos_given_D = 0.99 # 敏感性
P_pos_given_not_D = 0.05 # 假阳性率
# 全概率公式
P_pos = P_D * P_pos_given_D + (1 - P_D) * P_pos_given_not_D
# 贝叶斯定理
P_D_given_pos = P_D * P_pos_given_D / P_pos
print(f"P(患病|阳性) = {P_D_given_pos:.4f}") # 0.0194
离散随机变量
随机变量的定义
随机变量是从样本空间到实数的函数。对于每个样本点 ,随机变量 给出一个实数值 。
离散随机变量是取值为有限个或可数无限个的随机变量。
例子:
- 掷骰子, 为出现的点数:
- 抛硬币, 为正面出现的次数:
- 100次试验中成功的次数:
import random
def die_roll():
"""随机变量:掷骰子的点数"""
return random.randint(1, 6)
def coin_flips(n):
"""随机变量:n次抛硬币中正面次数"""
return sum(random.choice([0, 1]) for _ in range(n))
概率质量函数(PMF)
离散随机变量 的概率质量函数(Probability Mass Function)定义为:
PMF 满足:
- 对所有
例子:掷两枚骰子, 为点数之和。
的取值范围:
| 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
def two_dice_sum_pmf():
"""计算两枚骰子和的PMF"""
pmf = {}
for i in range(1, 7):
for j in range(1, 7):
s = i + j
pmf[s] = pmf.get(s, 0) + 1
for s in pmf:
pmf[s] /= 36
return pmf
pmf = two_dice_sum_pmf()
for x, p in sorted(pmf.items()):
print(f"P(X={x}) = {p:.4f}")
累积分布函数(CDF)
随机变量 的累积分布函数(Cumulative Distribution Function)定义为:
CDF 的性质:
- 是非减函数
- 是右连续的
def cdf_from_pmf(pmf):
"""从PMF计算CDF"""
cdf = {}
cumulative = 0
for x in sorted(pmf.keys()):
cumulative += pmf[x]
cdf[x] = cumulative
return cdf
cdf = cdf_from_pmf(two_dice_sum_pmf())
print(f"P(X ≤ 7) = {cdf[7]:.4f}") # 0.5833
期望与方差
期望
离散随机变量 的期望(Expected Value)或均值定义为:
期望表示随机变量的"平均值"或"中心位置"。
期望的性质:
- 线性性:
- 常数期望:( 是常数)
- 非负性:如果 ,则
随机变量函数的期望:
例子:掷骰子的期望值。
def expected_value(pmf):
"""计算期望"""
return sum(x * p for x, p in pmf.items())
# 掷骰子
die_pmf = {i: 1/6 for i in range(1, 7)}
print(f"E[X] = {expected_value(die_pmf)}") # 3.5
# 两枚骰子和
print(f"E[两骰子和] = {expected_value(two_dice_sum_pmf())}") # 7.0
方差
方差衡量随机变量与其期望的偏离程度:
标准差是方差的平方根:
方差的性质:
- ( 是常数)
- 如果 和 独立,则
例子:掷骰子的方差。
def variance(pmf):
"""计算方差"""
mean = expected_value(pmf)
return sum((x - mean)**2 * p for x, p in pmf.items())
def variance_formula(pmf):
"""用公式 Var(X) = E[X²] - E[X]² 计算"""
mean = expected_value(pmf)
e_x_squared = sum(x**2 * p for x, p in pmf.items())
return e_x_squared - mean**2
# 掷骰子
die_pmf = {i: 1/6 for i in range(1, 7)}
print(f"Var(X) = {variance(die_pmf):.4f}") # 2.9167
print(f"σ = {variance(die_pmf)**0.5:.4f}") # 1.7078
常见离散分布
伯努利分布
伯努利分布描述一次试验的结果(成功/失败)。
import random
def bernoulli(p):
"""伯努利分布抽样"""
return 1 if random.random() < p else 0
# 模拟
results = [bernoulli(0.3) for _ in range(10000)]
print(f"均值 ≈ {sum(results)/len(results)}") # 约等于 0.3
二项分布
二项分布描述 次独立伯努利试验中成功的次数。
例子:抛10枚硬币,正面次数的分布。
from math import comb
def binomial_pmf(n, p, k):
"""二项分布 PMF"""
return comb(n, k) * p**k * (1-p)**(n-k)
# 抛10枚硬币,恰好3枚正面的概率
print(f"P(X=3) = {binomial_pmf(10, 0.5, 3):.4f}") # 0.1172
# 计算完整的PMF
def binomial_distribution(n, p):
"""二项分布的完整PMF"""
return {k: binomial_pmf(n, p, k) for k in range(n+1)}
pmf = binomial_distribution(10, 0.5)
print(f"E[X] = {expected_value(pmf)}") # 5.0
print(f"Var(X) = {variance(pmf):.4f}") # 2.5
几何分布
几何分布描述首次成功所需的试验次数。
例子:射击命中率0.3,首次命中所需要的射击次数。
def geometric_pmf(p, k):
"""几何分布 PMF"""
return (1-p)**(k-1) * p
# 首次命中需要3次射击的概率
print(f"P(X=3) = {geometric_pmf(0.3, 3):.4f}") # 0.147
# 期望:平均需要 1/0.3 ≈ 3.33 次
print(f"E[X] = {1/0.3:.2f}") # 3.33
泊松分布
泊松分布描述单位时间/空间内稀有事件发生的次数。
例子:某网站平均每小时收到5个请求,求一小时内收到3个请求的概率。
import math
def poisson_pmf(lam, k):
"""泊松分布 PMF"""
return lam**k * math.exp(-lam) / math.factorial(k)
# P(X=3)
print(f"P(X=3) = {poisson_pmf(5, 3):.4f}") # 0.1404
# P(X ≤ 3)
cumulative = sum(poisson_pmf(5, k) for k in range(4))
print(f"P(X ≤ 3) = {cumulative:.4f}") # 0.2650
泊松分布与二项分布的关系:
当 很大、 很小,且 保持适中时,。
这是一个重要的近似,用于简化计算。例如,一个国家有1亿人口,每个人患某罕见病的概率为 ,则患病人数近似服从 。
大数定律与中心极限定理
大数定律
弱大数定律:设 是独立同分布的随机变量,期望为 。则样本均值依概率收敛于期望:
理解:随着样本量增加,样本均值趋近于总体期望。这是统计推断的基础。
import random
def law_of_large_numbers_demo():
"""大数定律演示"""
results = []
cumulative = 0
for n in range(1, 10001):
cumulative += random.randint(1, 6) # 掷骰子
results.append(cumulative / n)
return results
# 模拟
results = law_of_large_numbers_demo()
print(f"10次平均: {results[9]:.4f}") # 波动较大
print(f"100次平均: {results[99]:.4f}") # 接近3.5
print(f"10000次平均: {results[-1]:.4f}") # 非常接近3.5
中心极限定理
中心极限定理(CLT):设 是独立同分布的随机变量,期望为 ,方差为 。则:
即样本均值的标准化形式依分布收敛于标准正态分布。
理解:无论原始分布是什么,大样本的均值近似服从正态分布。这解释了为什么正态分布在统计中如此重要。
import random
import math
def central_limit_theorem_demo(sample_size, num_samples):
"""中心极限定理演示"""
sample_means = []
for _ in range(num_samples):
# 从任意分布(如均匀分布)抽样
sample = [random.random() for _ in range(sample_size)]
sample_means.append(sum(sample) / len(sample))
return sample_means
# 模拟
means = central_limit_theorem_demo(30, 1000)
mean_of_means = sum(means) / len(means)
std_of_means = math.sqrt(sum((m - mean_of_means)**2 for m in means) / len(means))
print(f"样本均值的均值: {mean_of_means:.4f}") # 接近 0.5(均匀分布的期望)
print(f"样本均值的标准差: {std_of_means:.4f}") # 接近 sqrt(1/12/30) ≈ 0.053
小结
本章介绍了离散概率的基础知识:
- 基本概念:样本空间、事件、概率的定义与性质
- 条件概率:定义、乘法公式
- 独立性:两个事件的独立、多个事件的独立
- 全概率公式与贝叶斯定理:概率更新、后验概率计算
- 离散随机变量:PMF、CDF
- 期望与方差:定义、性质、计算
- 常见分布:伯努利、二项、几何、泊松分布
- 极限定理:大数定律、中心极限定理
概率论为处理不确定性提供了数学框架。从算法的平均复杂度分析到机器学习的统计推断,从密码学的安全性证明到网络协议的可靠性分析,概率思维无处不在。
练习
-
一副扑克牌52张,随机抽取5张,求恰好有2张A的概率。
-
证明:如果 和 独立,则 和 也独立。
-
某疾病患病率为0.5%,检测方法的敏感性为95%(患者阳性概率),特异性为90%(健康人阴性概率)。如果检测结果为阳性,实际患病的概率是多少?
-
设 ,证明 和 。
-
某客服中心平均每分钟接到3个电话。用泊松分布计算一分钟内接到超过5个电话的概率。
-
解释为什么大数定律保证了"赌场总是赢家"。