3. 常见概率分布及其计算

概率分布是随机模拟的“零件库”。做随机模拟时,我们很少从零构造随机性,而是先判断某个随机变量服从哪种分布,再用对应的参数生成样本、计算概率或求分位数。本节围绕五个最常用的分布展开:离散型的二项分布与泊松分布,连续型的均匀分布、指数分布与正态分布。重点不是背公式,而是搞清楚每个分布的参数含义、适用场景,以及如何用 Python 的 scipy.stats 完成“已知取值求概率”和“已知概率求取值”这两类计算。

离散分布:计次型随机变量

二项分布描述 n 次独立重复试验中“成功”的次数,记作 X ~ B(n, p)。它有两个参数:试验次数 n 和单次成功概率 p。典型场景是抛硬币、产品抽检合格数、点击广告后的转化人数。其概率质量函数为 P(X=k) = C(n,k) p^k (1-p)^(n-k)。在 Python 中,binom.pmf(k, n, p) 给出恰好 k 次的概率,binom.cdf(k, n, p) 给出不超过 k 次的累积概率。

泊松分布描述单位时间或单位空间内稀有事件发生的次数,记作 X ~ Poisson(λ),只有一个参数 λ(平均发生次数)。它可看作 n 很大、p 很小时二项分布的极限,常用于呼叫中心来电数、网站每分钟访问量、放射性衰变计数。其概率质量函数为 P(X=k) = e^(-λ) λ^k / k!。对应函数是 poisson.pmf(k, mu) 与 poisson.cdf(k, mu)。

需要注意离散分布的一个重要细节:cdf(k) 计算的是 P(X ≤ k),包含 k 本身。若要求 P(X ≥ 3),应写成 1 - cdf(2) 而不是 1 - cdf(3),这是初学者最容易出错的地方。

连续分布:区间型随机变量

均匀分布 U(a, b) 表示区间 [a, b] 内任意等长子区间被取到的概率相同,是最基础的“无偏好”随机源,也是随机数生成器的底层模型。uniform.cdf(x, a, b) 给出 P(X ≤ x),当 x 落在区间内时结果就是 (x-a)/(b-a)。

指数分布 Exp(λ) 描述泊松过程中相邻两次事件的时间间隔,参数 λ 是事件发生率。它的一个重要性质是无记忆性:已经等待了多久,不影响还需等待多久的分布。常用于设备寿命、服务等待时间建模。其累积分布函数为 F(x) = 1 - e^(-λx)(x ≥ 0)。

正态分布 N(μ, σ²) 由均值 μ 和标准差 σ 决定,是中心极限定理的归宿,大量独立随机因素叠加后的结果近似正态。它的概率计算通常不直接积分,而是借助标准正态或 norm.cdf 完成。例如 P(a < X < b) = norm.cdf(b, mu, sigma) - norm.cdf(a, mu, sigma)。

五类常见分布:参数、形态与 Python 计算入口 离散分布(计次) 二项分布 B(n, p) 参数:n 试验次数,p 单次成功概率 场景:n 次独立试验中的成功次数 P(X=k)=C(n,k)p^k(1-p)^(n-k) binom.pmf(k,n,p) / binom.cdf(k,n,p) 泊松分布 Poisson(λ) 参数:λ 单位时间平均发生次数 场景:稀有事件计数(来电、访问量) P(X=k)=e^(-λ)λ^k/k! poisson.pmf(k,mu) / poisson.cdf(k,mu) 连续分布(区间) 均匀分布 U(a, b) 参数:区间端点 a、b;区间内等可能 uniform.cdf(x,a,b) / uniform.ppf(q,a,b) 指数分布 Exp(λ) 参数:λ 事件发生率;无记忆性 expon.cdf(x,scale=1/λ) / expon.ppf(q,scale=1/λ) 正态分布 N(μ, σ²) 参数:均值 μ、标准差 σ;钟形对称 norm.cdf(x,mu,sigma) / norm.ppf(q,mu,sigma) 两类核心计算方向 已知取值 x → 求概率:用 cdf / pmf  |  已知概率 q → 求分位数:用 ppf(离散分布用 ppf 需注意取整)

用 Python 完成概率与分位数计算

下面用一组明确标注为示例的参数,演示两类计算。假设某产品抽检中单件合格率为 0.9,抽 20 件,求恰好 18 件合格的概率,以及合格件数不超过 17 件的概率:

from scipy import stats

# 二项分布示例:n=20, p=0.9
p18 = stats.binom.pmf(18, 20, 0.9)      # 恰好 18 件合格
p_le17 = stats.binom.cdf(17, 20, 0.9)   # 不超过 17 件合格
p_ge18 = 1 - stats.binom.cdf(17, 20, 0.9)  # 至少 18 件

# 泊松分布示例:λ=4,求一天来电不超过 2 次的概率
p_pois = stats.poisson.cdf(2, mu=4)

# 正态分布示例:μ=100, σ=15,求 P(90 < X < 110)
p_norm = stats.norm.cdf(110, 100, 15) - stats.norm.cdf(90, 100, 15)

# 分位数:正态分布 95% 分位点
q95 = stats.norm.ppf(0.95, 100, 15)

运行上述代码(示例参数,结果以实际执行为准)会得到:p18 约为 0.0319,p_le17 约为 0.3231,p_ge18 约为 0.6769;泊松累积概率约为 0.2381;正态区间概率约为 0.4950;95% 分位点约为 124.67。这些数值说明:虽然单件合格率高达 0.9,但 20 件中恰好 18 件合格的概率并不高,因为“恰好”这一条件很窄;而“至少 18 件”则宽松得多。

分位数计算是反向操作:给定累积概率 q,求对应的取值 x,使 P(X ≤ x) = q。连续分布直接用 ppf 即可。离散分布的 ppf 返回的是满足累积概率首次达到 q 的最小整数,因此结果天然是整数,但含义是“阶梯式”的,解读时要结合 cdf 验证。例如 stats.binom.ppf(0.5, 20, 0.9) 返回 18,意味着合格件数不超过 18 的概率首次超过 0.5。

判断该用哪个分布,可以问三个问题:结果是计数还是连续量?计数的话,试验次数是否固定(固定用二项,不固定用泊松)?连续量的话,是否有明确的上下界(有界用均匀)、是否描述等待时间(用指数)、是否由大量独立因素叠加(用正态)?
使用 scipy.stats 时注意参数命名差异:指数分布的 scale 是 1/λ 而非 λ 本身,正态分布的 scale 是标准差 σ 而非方差 σ²。参数传错不会报错,但结果会系统性偏离,务必用已知简单情形(如标准正态 norm.cdf(0) 应等于 0.5)做一次自检。

掌握这五个分布后,随机模拟的基本流程就清晰了:先依据业务机理选定分布并估计参数,再用 rvs 生成样本、用 cdf/pmf 算概率、用 ppf 定阈值,最后把计算结果与模拟结果相互印证。这套“分布选择—参数设定—正向求概率—反向求分位”的闭环,是后续蒙特卡洛模拟与统计推断的直接基础。