Example09 / 14
超级传播——负二项后代分布、早期灭绝与“20/80”
用分支过程模拟疾病早期:每个感染者的继发病例数 ~ 负二项(R0, k),离散度 k 越小个体差异越大。 计算 (1) 疫情自行灭绝的概率(解 q = g(q),g 为负二项生成函数); (2) 造成 80% 传播的感染者比例。 解读:R0 相同时,k 越小越容易早期灭绝,但一旦暴发更“爆炸”;少数感染者贡献大部分传播, 这与 Lloyd-Smith 等 2005 的结论一致,也说明针对个体的干预比全员均匀干预更有效。
Output输出图

Output文字输出
k = 0.1 灭绝概率 = 0.861 零继发病例比例 = 0.722 造成 80% 传播的感染者比例 = 0.092 k = 0.5 灭绝概率 = 0.558 零继发病例比例 = 0.408 造成 80% 传播的感染者比例 = 0.277 k = 1.0 灭绝概率 = 0.400 零继发病例比例 = 0.285 造成 80% 传播的感染者比例 = 0.364 k = 10.0 灭绝概率 = 0.144 零继发病例比例 = 0.108 造成 80% 传播的感染者比例 = 0.535
Code代码
# 用分支过程模拟疾病早期:每个感染者的继发病例数 ~ 负二项(R0, k),离散度 k 越小个体差异越大。
# 计算 (1) 疫情自行灭绝的概率(解 q = g(q),g 为负二项生成函数);
# (2) 造成 80% 传播的感染者比例。
# 解读:R0 相同时,k 越小越容易早期灭绝,但一旦暴发更“爆炸”;少数感染者贡献大部分传播,
# 这与 Lloyd-Smith 等 2005 的结论一致,也说明针对个体的干预比全员均匀干预更有效。
import numpy as np
import matplotlib.pyplot as plt
R0 = 2.5
rng = np.random.default_rng(0)
fig, ax = plt.subplots(figsize=(6.4, 4.2))
for kdisp, ls in zip([0.1, 0.5, 1.0, 10.0], ["-", "--", "-.", ":"]):
g = lambda s: (1 + R0 / kdisp * (1 - s)) ** (-kdisp) # 负二项生成函数
q = 0.0
for _ in range(5000):
q = g(q)
p = kdisp / (kdisp + R0)
off = rng.negative_binomial(kdisp, p, size=200000)
srt = np.sort(off)[::-1]
frac = np.searchsorted(np.cumsum(srt), 0.8 * srt.sum()) / len(srt)
print("k = %5.1f 灭绝概率 = %.3f 零继发病例比例 = %.3f 造成 80%% 传播的感染者比例 = %.3f"
% (kdisp, q, (off == 0).mean(), frac))
cum = np.cumsum(srt) / srt.sum()
idx = np.linspace(0, len(srt) - 1, 400).astype(int)
ax.plot(idx / len(srt), cum[idx], ls=ls, lw=2, label="k = %g (extinction %.2f)" % (kdisp, q))
ax.axhline(0.8, c="0.7", lw=0.8)
ax.set_xlabel("fraction of cases (most infectious first)"); ax.set_ylabel("fraction of transmission")
ax.legend(); ax.set_title("Small k: few cases cause most transmission (R0 = 2.5)")
plt.tight_layout(); plt.show()Run在浏览器中运行
首次加载 Python 环境约需 20–40 秒;可以修改参数后重新运行。