生物医学网络科学Biomedical Network Science
Example09 / 14

超级传播——负二项后代分布、早期灭绝与“20/80”

所属专题
网络上的传播与免疫
下载
Notebook · .py

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

Output输出图

超级传播——负二项后代分布、早期灭绝与“20/80”:输出图 1

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 秒;可以修改参数后重新运行。

超级传播——负二项后代分布、早期灭绝与“20/80”