几何分布:从“等一个结果”开始
你有没有过这样的经历?
- 在游戏里抽卡,抽了多少次才终于出货?
- 站在路边等公交车,第几辆来的才是你要坐的那一路?
- 给客户打电话,打到第几个才终于接通?
- 刷短视频时,刷了多少条才刷到自己想看的内容?
这些场景背后,都藏着一个共同的概率模型——几何分布(Geometric Distribution)。
几何分布描述的是:在一次次独立的重复试验中,首次成功所需要的试验次数。
它的核心问题就是--“等到第一次成功,需要等多久?”
今天这篇文章,就用最通俗的方式带你搞懂几何分布,然后用 Python 把它用起来。
几何分布到底是什么?
一个最简单的例子
想象你正在玩一个抛硬币猜正反的游戏。你不断抛硬币,直到第一次出现正面就算赢。
- 第 1 次就抛到正面 → 成功(次数 = 1)
- 第 1 次反面、第 2 次正面 → 成功(次数 = 2)
- 前 2 次反面、第 3 次正面 → 成功(次数 = 3)
- ……一直下去
这里的“首次出现正面所需的抛掷次数”X,就服从几何分布。
几何分布有三个核心特征:
- 每次试验只有两种结果:成功或失败
- 每次试验成功的概率 p 是固定的
- 你一直重复试验,直到第一次成功就停下来
概率怎么算?
如果每次试验成功的概率是 p,那么第 k 次试验才首次成功的概率是:
$ P(X = k) = (1 - p)^{(k-1)} × p $
怎么理解这个公式?
前 k-1 次全部失败,概率是$ (1-p)^{(k-1)} $;第 k 次终于成功了,概率是 p。
两者相乘,就是“前 k-1 次都失败、第 k 次成功”的概率。
两个重要性质
① 期望(平均需要多少次)
如果每次成功的概率是 p,那么平均需要 1/p 次才能首次成功。
比如抛硬币(p=0.5),平均抛 2 次就能首次出现正面。抽卡概率如果是 1%(p=0.01),平均需要抽 100 次才能出货——这就是所谓的“保底期望”。
② 无记忆性(最反直觉的性质)
这是几何分布最神奇的地方:你已经失败了多少次,不会改变下一次成功的概率。
举个例子:你已经连续抛了 10 次都是反面,那么下一次抛到正面的概率仍然是 50%——跟第一次抛的时候一模一样。
前面 10 次失败“不占额度”,也不增加下一次成功的概率。
这个性质在现实生活中其实不太“自然”——很多人会认为“都输了这么多次了,下次该赢了吧”,但几何分布告诉我们:不会。每一次都是全新的开始。
用 Python 计算几何分布
准备工作
首先安装并导入必要的库:
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import geom
scipy.stats.geom 是 Python 中处理几何分布的核心工具。
概率质量函数(PMF)——算“恰好第 k 次成功”的概率
假设某款游戏的抽卡出 SSR 概率是 5%(p=0.05),你想知道恰好第 3 抽才出 SSR 的概率是多少?
p = 0.05
k = 3
# 恰好第 k 次才首次成功
prob = geom.pmf(k, p)
print(f"P(第 {k} 次才首次成功) = {prob:.4%}")
输出:
P(第 3 次才首次成功) = 4.5125%
验证一下公式:前 2 次失败$ (0.95)^2 $× 第 3 次成功(0.05)= 0.045125,完全吻合。
如果你想看前 20 次每次“恰好首次成功”的概率分布:
x = np.arange(1, 21)
pmf_values = geom.pmf(x, p)
plt.figure(figsize=(10, 5))
plt.vlines(x, 0, pmf_values, colors='b', lw=2, alpha=0.7)
plt.scatter(x, pmf_values, color='red', s=30)
plt.xlabel('首次成功的试验次数 (k)')
plt.ylabel('概率')
plt.title(f'几何分布 PMF (p={p})')
plt.show()
你会看到:次数越靠后,概率越小——因为要“连续失败很多次”本身就越难发生。
累积分布函数(CDF)——“前 k 次内成功的概率”
更常见的问题是:“抽 10 次之内能出 SSR 的概率是多少?”
这时候用 CDF(累积分布函数):
p = 0.05
k = 10
# 10 次以内(含第 10 次)首次成功的概率
prob_within_10 = geom.cdf(k, p)
print(f"P(前 {k} 次内首次成功) = {prob_within_10:.4%}")
输出:
P(前 10 次内首次成功) = 40.1263%
也就是说,只有 40% 的玩家能在 10 抽以内出货,剩下 60% 的人要等 10 抽以后。
生存函数(SF)——“超过 k 次还没成功的概率”
反过来问:“抽了 10 次还没出 SSR 的概率是多少?”
# 超过 10 次还没成功
prob_over_10 = geom.sf(k, p) # 等价于 1 - geom.cdf(k, p)
print(f"P(超过 {k} 次还没成功) = {prob_over_10:.4%}")
输出:
P(超过 10 次还没成功) = 59.8737%
这不就是“非酋”的概率吗?将近 60% 的人抽 10 次都出不了货——是不是突然觉得合理多了?
期望值——平均需要多少次?
mean = geom.mean(p)
print(f"平均需要 {mean:.1f} 次才能首次成功")
输出:
平均需要 20.0 次才能首次成功
5% 的概率,平均 20 次出货——期望值 = 1/p。
随机模拟——生成一批“首次成功次数”
用 geom.rvs() 可以模拟大量玩家的“首次成功所需次数”:
# 模拟 10000 名玩家,每人抽到 SSR 就停
samples = geom.rvs(p, size=10000)
print(f"模拟平均值: {np.mean(samples):.2f}")
print(f"模拟方差: {np.var(samples):.2f}")
# 绘制直方图
plt.figure(figsize=(10, 5))
plt.hist(samples, bins=range(1, 60), edgecolor='black', alpha=0.7)
plt.xlabel('首次成功所需次数')
plt.ylabel('人数')
plt.title(f'10000 名玩家首次抽到 SSR 的次数分布 (p={p})')
plt.show()
输出(每次运行略有不同):
模拟平均值: 19.98
模拟方差: 379.45
你会发现大部分玩家集中在 1-20 次之间,但也有少数“非酋”超过 50 次甚至 100 次才出货——这就是几何分布的“长尾”特征。
生活中的几何分布
场景一:游戏抽卡(上面已经算过了)
出卡概率 5%,抽到出为止。你可以用几何分布回答:
- 第 3 抽就出的概率是多少?(PMF)
- 10 抽以内出的概率是多少?(CDF)
- 平均要抽多少次?(期望)
场景二:等公交车
假设某路公交车平均每 10 分钟一班,但具体到达时间随机。你可以把“每一分钟”看作一次试验,车来的概率是 1/10 = 0.1。
那么:
- 恰好第 8 分钟车来的概率是多少?→
geom.pmf(8, 0.1) - 15 分钟以内能等到车的概率是多少?→
geom.cdf(15, 0.1) - 平均要等多久?→ 1/0.1 = 10 分钟
场景三:电话销售
你是一名电话销售,每次通话的成交概率是 8%(p=0.08)。
- 打到第 5 个电话才成交的概率?→
geom.pmf(5, 0.08) - 打 20 个电话以内能成交的概率?→
geom.cdf(20, 0.08) - 平均要打多少个电话才能成一单?→ 1/0.08 = 12.5 个
场景四:投飞镖
你向靶心投飞镖,每次命中靶心的概率是 17%。
- 第 6 次投掷才首次命中的概率?→
geom.pmf(6, 0.17) - 5 次以内命中的概率?→
geom.cdf(5, 0.17)
完整代码
把上面所有的代码整理在一起,方便你直接运行:
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import geom
# ============ 基础参数 ============
p = 0.05 # 单次成功概率
# ============ PMF:恰好第 k 次成功 ============
k = 3
print(f"P(第 {k} 次才首次成功) = {geom.pmf(k, p):.4%}")
# ============ CDF:k 次以内成功 ============
k = 10
print(f"P(前 {k} 次内首次成功) = {geom.cdf(k, p):.4%}")
# ============ SF:超过 k 次还没成功 ============
print(f"P(超过 {k} 次还没成功) = {geom.sf(k, p):.4%}")
# ============ 期望和方差 ============
print(f"期望(平均次数)= {geom.mean(p):.1f}")
print(f"方差 = {geom.var(p):.2f}")
# ============ 可视化 PMF ============
x = np.arange(1, 21)
pmf_values = geom.pmf(x, p)
plt.figure(figsize=(10, 5))
plt.vlines(x, 0, pmf_values, colors='b', lw=2, alpha=0.7)
plt.scatter(x, pmf_values, color='red', s=30)
plt.xlabel('首次成功的试验次数 (k)')
plt.ylabel('概率')
plt.title(f'几何分布 PMF (p={p})')
plt.show()
# ============ 随机模拟 ============
samples = geom.rvs(p, size=10000)
print(f"模拟平均值: {np.mean(samples):.2f}")
print(f"模拟方差: {np.var(samples):.2f}")
plt.figure(figsize=(10, 5))
plt.hist(samples, bins=range(1, 60), edgecolor='black', alpha=0.7)
plt.xlabel('首次成功所需次数')
plt.ylabel('人数')
plt.title(f'10000 次模拟的首次成功次数分布 (p={p})')
plt.show()
总结
| 你想知道的问题 | 用什么函数 | 代码示例 |
|---|---|---|
| 恰好第 k 次才首次成功 | geom.pmf(k, p) |
geom.pmf(3, 0.05) |
| k 次以内(含)首次成功 | geom.cdf(k, p) |
geom.cdf(10, 0.05) |
| 超过 k 次还没成功 | geom.sf(k, p) |
geom.sf(10, 0.05) |
| 平均需要多少次 | geom.mean(p) |
geom.mean(0.05) |
| 模拟一批“首次成功次数” | geom.rvs(p, size=n) |
geom.rvs(0.05, size=1000) |
几何分布的核心就三句话:
- 它回答的是:“等到第一次成功,需要等多久?”
- 概率公式:$ P(X=k) = (1-p)^{(k-1)} × p $
- 平均等待时间:1/p 次
下次当你在游戏里抽卡、在路边等车、或者刷短视频等一个“想看的内容”时,不妨想一想——你现在经历的,可能正是一个几何分布的现实样本。
而有了 Python 和 scipy.stats.geom,你可以把这种“等待”变成精确的计算,让自己对生活中的不确定性多一分掌控感。

浙公网安备 33010602011771号