跳到内容

第 10 卷 / 第 8 章 / 第 1 课

8.1 概率空间与条件概率:先写模型,再更新判断 ​

监控系统报告“异常命中率 99%”时,这个数字可能指召回率、精确率,也可能只是历史样本准确率。概率计算之前,必须先说明随机试验、事件和条件信息。

概率空间 ​

概率空间写作:

text
(Ω, 𝔽, P)
  • Ω:全部可能结果的样本空间;
  • 𝔽:允许讨论的事件集合;
  • P:为事件赋概率的函数。

有限样本空间中常把所有子集都当事件。一般概率空间需要事件族包含 Ω,并对补集和可数并封闭,以避免给任意病态子集都强行赋概率。

概率满足 Kolmogorov 公理:

text
P(A)≥0
P(Ω)=1
若可数个 A_i 两两互斥,P(⋃A_i)=ΣP(A_i)

由此推出:

text
P(Aᶜ)=1-P(A)
P(A∪B)=P(A)+P(B)-P(A∩B)

“有利结果/全部结果”需要等可能 ​

公平六面骰:

text
P(偶数)=3/6=1/2

这个计数公式依赖六个点数等可能。若骰子有偏,事件概率应是各结果概率之和,不能只数元素个数。

软件流量也通常不均匀:10 种请求类型不代表每类概率 1/10。用测试用例数量代替生产分布,会得到错误的期望故障率。

条件概率 ​

已知事件 B 发生,且 P(B)>0:

text
P(A|B)=P(A∩B)/P(B)

它把样本空间限制到 B,再看其中有多少也属于 A。

乘法公式:

text
P(A∩B)=P(A|B)P(B)

多个事件的链式法则:

text
P(A₁∩...∩A_n)
=P(A₁)P(A₂|A₁)...P(A_n|A₁∩...∩A_{n-1})

不放回抽样的后续概率会随前面结果改变,正适合链式计算。

使用上面写成条件概率的链式形式时,各条件前缀必须有正概率。若某个前缀概率为零,联合事件也为零,但后续的条件概率商可能没有定义。

全概率公式 ​

若 B₁,...,B_k 两两互斥、并集为 Ω,且概率非零:

text
P(A)=Σ_i P(A|B_i)P(B_i)

例如请求来自 Web、Mobile、Batch 三类入口,总超时率是各入口超时率按流量占比加权,而不是三个百分比的简单平均。

Bayes 定理 ​

text
P(B_i|A)
=P(A|B_i)P(B_i)
 / Σ_j P(A|B_j)P(B_j)

在全概率划分的条件下,还要求观察事件 P(A)>0。Bayes 定理交换的是条件方向,本身不证明事件之间的因果关系。下面用一组假设的监控参数:

text
故障基础率 P(D)=0.001
告警召回率 P(+|D)=0.99
假阳性率 P(+|¬D)=0.02

发出告警后确有故障的概率:

text
P(D|+)
=0.99·0.001 /
 (0.99·0.001 + 0.02·0.999)
≈0.0472

约 4.7%。这表示该模型下的告警精确率,而非总体准确率。按 100000 个同分布窗口的期望数量理解,会有 99 个真告警与 1998 个误告警;99/(99+1998) 正是上述比例。下面的 Python 3 示例以分数核对数值:

python
from fractions import Fraction

base = Fraction(1, 1000)
recall = Fraction(99, 100)
false_positive = Fraction(2, 100)
true_alert = recall * base
false_alert = false_positive * (1 - base)
posterior = true_alert / (true_alert + false_alert)
print(f"{float(posterior):.4%}")  # 4.7210%

独立与互斥完全不同 ​

事件 A,B 独立:

text
P(A∩B)=P(A)P(B)

若 P(B)>0,等价于 P(A|B)=P(A)。

互斥则是:

text
A∩B=∅

两个概率都为正的互斥事件不独立,因为知道 A 发生会让 B 概率变成 0。

两两独立不自动推出相互独立。三个事件可能任意两者独立,三者联合却有约束。

例如独立公平位 X,Y 与 Z=X XOR Y:任意一对同时为 1 的概率都是 1/4,各位为 1 的边际概率都是 1/2,但三者同时为 1 不可能。直接枚举四个等可能结果:

python
from itertools import product
from fractions import Fraction

outcomes = [(x, y, x ^ y) for x, y in product((0, 1), repeat=2)]
def probability(predicate):
    return Fraction(sum(predicate(row) for row in outcomes), len(outcomes))

for i, j in [(0, 1), (0, 2), (1, 2)]:
    assert probability(lambda row: row[i] == row[j] == 1) == Fraction(1, 4)
print(probability(lambda row: row == (1, 1, 1)))  # 0, rather than 1/8.

条件独立 ​

若 P(C)>0,在给定 C 后:

text
P(A∩B|C)=P(A|C)P(B|C)

共享原因会造成边际相关,却可能在分层后消失。例如设机房断电概率为 0.01,断电时两个服务必定都失败;不断电时,两者独立以 0.01 概率失败。每个服务的边际故障率为 0.01+0.99×0.01=0.0199,联合故障率为 0.01+0.99×0.01²=0.010099,远大于边际概率乘积 0.00039601。这里的条件独立来自明确假设,不能仅因“控制了一个变量”就自动认定。

朴素 Bayes 分类器假设特征在类别条件下独立,这常是近似建模选择,不是数据自然保证。

概率树检查依赖 ​

袋中 3 红 2 蓝,不放回取两次。第二次红的概率:

text
P(R₂)=P(R₂|R₁)P(R₁)+P(R₂|B₁)P(B₁)
=2/4·3/5 + 3/4·2/5
=3/5

对称性也能直接说明任一位置是红球的边际概率均为 3/5。条件分支展示了两次抽取不独立。

模型假设要可审查 ​

计算故障概率前应写明:

  • 时间窗口;
  • 请求是独立抽样还是突发相关;
  • 数据来自哪个人群或流量层;
  • 缺失和重试如何处理;
  • 观察事件是否改变系统;
  • 概率是主观先验、历史频率还是模型预测。

同一个公式不会修复样本偏差和错误因果假设。

完成检查 ​

  1. 用概率树计算不放回取两球同色的概率;
  2. 构造两个互斥但不独立的事件;
  3. 构造三个两两独立但不相互独立的事件;
  4. 为告警系统写出基础率、召回率、假阳性率和阳性预测值;
  5. 用全概率公式聚合三个流量入口的超时率。

参考资料 ​

Built with VitePress | Software Systems Atlas