做技术的应该都遇到过这种场景:服务器每分钟收到多少请求?接口一天报错几次?网站一小时来多少访客?
这些问题的共同点是:在一段固定时间里,某个事件发生了多少次。
这类数据有个特点:单次看是随机的,但拉长周期会有一个稳定的平均值。
这种场景下,泊松分布就是最合适的建模工具。
今天咱们不扯虚的,直接把这个东西讲清楚,然后拿几个常见的场景跑一遍代码。
泊松分布到底是个啥?
说白了,泊松分布就是用来描述在固定时间或空间内,某件事发生次数的概率分布。
它有几个前提条件,你得先确认你的场景满不满足:
- 事件是独立的------这次来电话不影响下一次来电话。
- 平均发生率是恒定的------比如平均每分钟 3 个电话,不会突然变成 30 个。
- 不会同时发生两件事------两个电话不能在同一毫秒进来。
如果满足这三条,你就可以用泊松分布来算概率。
它的公式长这样:
P(X=k)=k!λke−λ
- (k):你想知道的事件次数,比如"恰好 5 次"。
- (λ):平均发生次数,比如"平均每分钟 3 次"。
- (e):欧拉数,约等于 2.718。
这个分布的均值和方差都是 λ。也就是说,如果平均每分钟来 3 个电话,那数据的波动程度也是 3。
先跑个代码,手动算一把
不用急着调库,咱们先自己写个函数算算,感受一下。
python
import math
def poisson_probability(k, lambd):
return (lambd ** k) * math.exp(-lambd) / math.factorial(k)
# 假设平均每分钟来 2 个事件,我想知道恰好来 3 个的概率
k = 3
lambd = 2
prob = poisson_probability(k, lambd)
print(f"恰好发生 {k} 次的概率: {prob:.4f}")
# 输出: 恰好发生 3 次的概率: 0.1804
这就是泊松公式的直接实现。
这个函数丢到任何 Python 环境里都能跑。
用 SciPy 省点事
实际工作中没人会手写阶乘,直接用 scipy.stats.poisson 就行。
它给你提供了 PMF(概率质量函数)和 CDF(累积分布函数)。
python
from scipy.stats import poisson
lambd = 4
k_values = list(range(10)) # 0 到 9 次
pmf_values = [poisson.pmf(k, lambd) for k in k_values]
cdf_values = [poisson.cdf(k, lambd) for k in k_values]
print("PMF:", pmf_values)
print("CDF:", cdf_values)
PMF 就是"恰好发生 k 次的概率",CDF 就是"发生次数小于等于 k 的概率"。
这两个东西在你做容量规划的时候特别有用。
场景一:网站流量预测
假设你负责一个网站,历史数据告诉你平均每分钟有 10 个访客。
你想模拟一下一天的情况,看看访客数大概怎么分布。
python
from scipy.stats import poisson
import matplotlib.pyplot as plt
# 模拟 1000 分钟的访客数,平均每分钟 10 人
data = poisson.rvs(mu=10, size=1000)
plt.hist(data, bins=15, density=True, alpha=0.7, color='skyblue')
plt.title("模拟网站流量 (λ = 10)")
plt.xlabel("每分钟访客数")
plt.ylabel("频率")
plt.show()
跑完你会看到一个近似正态的分布,中心在 10 附近。

这个图能帮你回答:"如果我要保证 95% 的情况下服务器不崩,我得准备多少并发?"
场景二:客服中心来电
客服中心平均每分钟接到 3 个电话。
老板问你:"恰好接到 5 个电话的概率有多大?"
你直接算:
python
from scipy.stats import poisson
prob_5_calls = poisson.pmf(5, 3)
print(f"恰好接到 5 个电话的概率: {prob_5_calls:.4f}")
# 输出: 恰好接到 5 个电话的概率: 0.1008
大概 10%。
那如果老板问"不超过 5 个电话的概率"呢?
用 CDF:
python
prob_leq_5 = poisson.cdf(5, 3)
print(f"不超过 5 个电话的概率: {prob_leq_5:.4f}")
# 输出: 不超过 5 个电话的概率: 0.9161
这种计算在排班的时候特别实用。
你知道平均来电数,就能估算需要多少个客服坐席。
场景三:系统故障(稀有事件)
有些事件很稀有,比如服务器每天平均只崩 0.5 次。
你想看看一年里故障次数的分布。
python
from scipy.stats import poisson
import matplotlib.pyplot as plt
# 模拟 365 天的故障次数,平均每天 0.5 次
failures = poisson.rvs(mu=0.5, size=365)
plt.hist(failures, bins=range(5), density=True, color='salmon', alpha=0.7)
plt.title("模拟每日系统故障 (λ = 0.5)")
plt.xlabel("故障次数")
plt.ylabel("频率")
plt.show()
你会发现大部分天数是 0 次或 1 次,偶尔有 2 次。

这种分布对于制定容灾策略很有帮助------你知道极端情况大概是什么样。
啥时候别用泊松分布?
泊松分布不是万能的。
如果平均发生率不恒定(比如白天电话多、晚上电话少),或者事件之间有依赖关系(比如一次故障引发另一次故障),那泊松分布就不准了。
另外,当试验次数 n 很大,成功概率 p 很小时,二项分布可以近似成泊松分布,此时 λ=n⋅p。
这个在 A/B 测试里偶尔会用到。
总结
泊松分布就是用来算"固定时间内事件发生次数"的概率工具。
你只要记住:
- 平均发生率 λ 是核心参数。
- 用
scipy.stats.poisson可以快速算PMF和CDF。 - 网站流量、客服来电、系统故障这些场景都能直接套。
- 用之前先确认事件独立、发生率恒定、不同时发生。
下次再遇到"平均每天发生 X 次"的问题,别拍脑袋,直接上泊松分布跑一下,心里就有数了。