- name
- seir-modeling
- description
- 当用户需要用仓室模型做传染病传播情景推演、选择 SIR/SEIR/SEIRS 模型结构、 理解 β/σ/γ/R0 参数含义、做参数敏感性分析、估计峰值时间与峰值感染数、 解读或评审一篇仓室模型结果时使用。同义场景:SEIR 模型、SIR 模型、 仓室模型、传播动力学建模、基本再生数 R0、有效再生数、传染期/潜伏期 参数化、疫情趋势情景模拟、干预效果推演、"帮我跑一个 SEIR 看看峰值"。
- argument-hint
- [model=sir|seir beta sigma gamma population i0 days]
- metadata
- {"domains":["epidemiology","public-health"],"last_reviewed":"2026-08-18"}
# seir-modeling:仓室模型情景推演规程
## 目的
用确定性仓室模型(SIR/SEIR)做**情景推演**:在给定参数假设下,回答
"若传播机制如此、参数取这些值,曲线大致长什么样、峰值何时多高"。
本技能规定模型选择的决策树、参数意义与来源标注、敏感性分析做法,
以及最重要的**解读纪律**——模型输出是条件推演,不是预测水晶球。
解读纪律(内化后再动手):
1. 每个数字都连着假设:报告结果时必须同段给出参数取值、取值来源与
区间;光秃秃的峰值数字不得写入产物。
2. 模型是简化:均匀混合、无年龄结构、无空间、参数恒定。现实偏离
这些假设时,输出只作定性参考。
3. 参数未知时跑**区间**而非单点:用多组参数给出情景范围,杜绝
"挑一个看起来合理的数跑一次就当结论"。
## 前置检查
1. 明确推演问题:要回答"峰值多高""何时达峰"还是"某参数变化对曲线
形态的影响"?问题决定模型与输出重点。
2. 确认病种关键生物学参数(潜伏期、传染期)有文献或方案来源;拿不到
时标 `[模型知识—待核实]` 并在报告中说明这是假设值而非实测值。
3. 确认人群规模与初始感染数的设定依据(真实场景规模 or 示意性规模)。
4. 脚本就绪:`skills/seir-modeling/scripts/seir.py`(纯 stdlib)。
## 1 · 模型选择决策树
```
是否需要显式表达"已感染但尚未有传染性"的潜伏期?
├─ 不需要(潜伏期很短或只关心粗略形态)→ SIR
└─ 需要(潜伏期不可忽视)→ SEIR
└─ 康复后免疫是否随时间消失?
├─ 不消失(本脚本范围)→ SEIR
└─ 消失(需 R → S 回流)→ SEIRS(本脚本不实现,见"不做什么")
```
补充判断:
- 只关心**单波封闭人群**(如一次集体单位暴发后的续发),SIR/SEIR 够用;
- 需要出生死亡、年龄结构、空间或随机效应,超出本脚本范围,转
计算类 skill 或专业建模环境;
- 不确定选哪个:两个都跑,比较形态差异,把差异写进报告(这本身
就是敏感性分析)。
## 2 · 参数意义与标定
| 参数 | 含义 | 与可观测量的关系 |
| --- | --- | --- |
| β(beta) | 传播率:单位时间有效接触 × 单次接触传播概率 | 不直接可观测,常由 R0 反推 |
| σ(sigma) | 潜伏期转化率 | ≈ 1/平均潜伏期 [模型知识—待核实:指数分布假设下成立] |
| γ(gamma) | 恢复率 | ≈ 1/平均传染期 [模型知识—待核实:同上] |
| R0 | 基本再生数 | SIR 及本脚本 SEIR 形式下 R0 = β/γ [模型知识—待核实] |
标定规程:
1. 先定 γ 与 σ(来自潜伏期/传染期的文献或方案值,带来源标签);
2. 再由目标 R0 反推 β = R0·γ,R0 的取值来源同样标注;
3. 初始值:i0(初始感染者)、e0(初始潜伏者,默认 0)、population;
4. 每个参数在报告中给"取值 + 来源标签 + 不确定区间"三件套,缺一
不写结果。
## 3 · 运行脚本
```bash
# JSON 输出(含参数回显、R0、峰值、逐日序列)
python scripts/seir.py --model seir --beta 0.5 --sigma 0.2 --gamma 0.1 \
--population 1000000 --i0 10 --days 160 --format json
# CSV 输出(序列到 stdout,峰值摘要到 stderr)
python scripts/seir.py --model sir --beta 0.3 --gamma 0.1 \
--population 100000 --i0 5 --days 120 --format csv > sir.csv
```
脚本行为说明:
- 积分器为手写 RK4,步长 `--dt`(默认 0.1 天),逐日快照输出;
- 输入校验:参数必须为正,i0+e0 ≤ population,SEIR 必须给 σ;
- 输出中的 `r0` 由 β/γ 计算回显,供核对参数录入是否有误。
## 4 · 敏感性分析
至少做两组对比,全部落盘并登记 provenance:
1. **参数区间扫描**:对每个不确定参数取其区间端点(如 R0 的文献
上下限),组合出低/中/高三档情景各跑一次;
2. **结构敏感性**:SIR 与 SEIR 各跑一次,比较峰值时间与高度差异。
报告形式:情景表(每行一个情景:参数取值、峰值时间、峰值感染数、
最终规模),不给"最优拟合"单一结论。需要系统拟合观测数据(最小
二乘/MCMC)时转计算类 skill,本技能不拟合。
## 5 · 结果解读纪律
写入报告时逐条自查:
1. 每个数字旁边是否有参数三件套(取值/来源/区间)?
2. 措辞是否为"在……假设下,推演显示……",而非"预测将……"?
3. 是否说明了模型简化(均匀混合、参数恒定、封闭人群)及偏离方向?
4. 峰值是否同时给出**区间**(多档情景的峰值的范围)?
5. 若把推演与真实监测曲线并置,是否明确标注"模型未拟合该数据"
或拟合方法?
6. 任何对外(含媒体、决策部门)使用推演结果,是否已按 guardrail
第 8 条取得确认,并附完整假设说明?
## 输出模板
```markdown
## 仓室模型情景推演(<日期>)
### 模型与假设
- 结构:SEIR;均匀混合、封闭人群、参数恒定(简化假设)
- 参数:β=<值>(由 R0=<值>×γ 反推,R0 来源 <标签>);
σ=<值>(≈1/潜伏期 <值> 天,<来源标签>);γ=<值>(≈1/传染期,<来源标签>)
- 初始:N=<population>,I₀=<i0>,E₀=<e0>
### 情景结果
| 情景 | R0 | 峰日 | 峰值感染数 | 备注 |
| --- | --- | --- | --- | --- |
| 低 | … | … | … | [实验数据:seir.py 输出] |
### 解读
- 在以上假设下,推演显示 <峰值区间与达峰时间区间>;这些是条件推演,
不构成疫情预测。
- 敏感性:<哪个参数最影响结果>;结构对比:<SIR vs SEIR 差异>。
### 局限
- <逐条列出简化假设与数据缺口>
```
## 本技能不做什么
- **不做参数拟合**:不用观测数据估计参数(最小二乘/极大似然/MCMC
交给计算类 skill 或专业环境);本技能只做前向推演。
- **不做 SEIRS/SEIRV/年龄结构/随机模型**:脚本只实现 SIR 与 SEIR;
需要更复杂结构时说明理由并转专业工具。
- **不做实时预测与对外发布**:推演结果对外使用属 guardrail 第 8 条
危险操作,必须先确认;任何"疫情预测"措辞在产物中禁用。
- **不编造病种参数**:潜伏期/传染期/R0 的具体数值必须有来源;
模型印象值标 `[模型知识—待核实]` 且只用于演示性情景。
- **不做政策建议**:干预参数(如β下降多少对应何种措施)的映射超出
本技能证据范围,不替用户把情景翻译成决策。
## 收尾与下一步
1. 汇总:跑了几个情景、峰值与达峰时间的区间、最敏感的参数。
2. 指向产物(JSON/CSV 序列、情景报告)并登记 provenance。
3. 建议下一步:
- 需要拟合真实数据或更复杂模型 → python-analysis 等计算类 skill;
- 结果写入报告 → `epi-writing`(附参数三件套与情景表);
- 参数来源需补文献 → literature-search。
在 GitHub 查看