用MATLAB构建SEIR模型:从理论到疫情预测实战指南
传染病动力学模型一直是公共卫生领域的重要工具,而SEIR模型作为其中的经典框架,能够帮助我们理解疾病传播的内在规律。本文将带你从零开始,用MATLAB实现一个完整的SEIR模型,不仅能理解其数学原理,还能亲手运行代码观察疫情发展曲线。
1. SEIR模型基础与数学原理
SEIR模型将人群划分为四个基本类别:易感者(Susceptible)、潜伏者(Exposed)、感染者(Infectious)和康复者(Recovered)。这种划分反映了传染病传播的关键阶段,每个群体的数量随时间变化,构成了一个动态系统。
核心微分方程组描述了各群体间的转化关系:
dS/dt = -βSI/N dE/dt = βSI/N - σE dI/dt = σE - γI dR/dt = γI其中:
- β:有效接触率(感染率)
- σ:潜伏期倒数(1/平均潜伏期)
- γ:康复率(1/平均感染期)
- N:总人口数(S+E+I+R)
提示:在实际应用中,我们通常使用离散化的迭代方程而非连续微分方程,这更便于计算机实现。
参数设定参考值(可根据实际情况调整):
| 参数 | 物理意义 | 典型值范围 | 单位 |
|---|---|---|---|
| β | 感染率 | 0.3-0.6 | 1/天 |
| σ | 潜伏期倒数 | 0.1-0.2 | 1/天 |
| γ | 康复率 | 0.05-0.1 | 1/天 |
| N | 总人口 | 根据场景设定 | 人 |
2. MATLAB实现基础SEIR模型
让我们从最基础的SEIR模型开始实现。以下代码展示了如何在MATLAB中构建并求解这个系统:
% 基础SEIR模型实现 function [t, S, E, I, R] = basic_SEIR() % 参数设置 N = 1e6; % 总人口 beta = 0.5; % 感染率 sigma = 0.2; % 潜伏期倒数 gamma = 0.1; % 康复率 % 初始条件 E0 = 10; % 初始潜伏者 I0 = 0; % 初始感染者 R0 = 0; % 初始康复者 S0 = N - E0 - I0 - R0; % 初始易感者 % 时间范围(天) tspan = [0 200]; y0 = [S0; E0; I0; R0]; % 定义微分方程 seir_ode = @(t,y) [ -beta*y(1)*y(3)/N; % dS/dt beta*y(1)*y(3)/N - sigma*y(2); % dE/dt sigma*y(2) - gamma*y(3); % dI/dt gamma*y(3) % dR/dt ]; % 求解ODE [t, y] = ode45(seir_ode, tspan, y0); % 提取结果 S = y(:,1); E = y(:,2); I = y(:,3); R = y(:,4); % 可视化 plot(t, S, 'b', t, E, 'y', t, I, 'r', t, R, 'g'); legend('易感者','潜伏者','感染者','康复者'); xlabel('时间(天)'); ylabel('人数'); title('基础SEIR模型模拟结果'); end运行这段代码,你将看到典型的传染病传播曲线:易感者逐渐减少,感染人数先上升后下降,最终趋于稳定。
3. 模型进阶:添加现实因素
基础SEIR模型虽然简洁,但现实中的疫情传播往往更为复杂。我们可以通过以下扩展使模型更贴近实际情况:
3.1 添加死亡人群(D)
在实际疫情中,我们需要考虑病患死亡的情况。修改后的模型称为SEIRD:
% 在参数部分添加: mu = 0.02; % 死亡率 % 修改微分方程部分: seird_ode = @(t,y) [ -beta*y(1)*y(3)/N; beta*y(1)*y(3)/N - sigma*y(2); sigma*y(2) - gamma*y(3) - mu*y(3); gamma*y(3); mu*y(3) % 死亡人数 ];3.2 考虑潜伏期传染性
某些疾病在潜伏期就具有传染性,我们需要调整模型:
% 添加新参数 beta_e = 0.3; % 潜伏者传染率 % 修改微分方程: dS/dt = -βSI/N - β_eSE/N dE/dt = βSI/N + β_eSE/N - σE3.3 引入防控措施效应
社会防控措施会改变疾病传播参数,我们可以模拟不同阶段的防控强度:
% 在第30天加强防控 if t >= 30 beta = 0.2; % 防控后降低的感染率 end4. 参数估计与模型验证
构建模型后,关键步骤是确定合适的参数值并进行验证:
参数估计方法:
- 从文献获取同类疾病的典型值
- 使用疫情早期数据进行曲线拟合
- 采用最大似然估计等统计方法
MATLAB拟合示例:
% 假设我们有实际数据actual_I actual_I = [...]'; % 实际感染人数数据 % 定义误差函数 error_func = @(params) sum((SEIR_model(params) - actual_I).^2); % 初始参数猜测 initial_params = [0.5, 0.2, 0.1]; % 使用fminsearch进行优化 best_params = fminsearch(error_func, initial_params);模型验证指标:
- 均方根误差(RMSE)
- 决定系数(R²)
- 预测区间覆盖率
5. 结果分析与可视化进阶
优秀的可视化能帮助我们更好地理解模型结果:
5.1 多场景对比
% 运行不同防控强度的模拟 [t1, ~, I1] = SEIR_model('beta', 0.6); [t2, ~, I2] = SEIR_model('beta', 0.3); plot(t1, I1, 'r', t2, I2, 'b--'); legend('无防控','有防控'); title('不同防控强度下的感染曲线');5.2 动态再生数R₀计算
基本再生数R₀是评估疫情严重程度的关键指标:
R0 = beta/gamma; % 基础再生数 % 随时间变化的有效再生数 Rt = beta*S./(gamma*N);5.3 三维参数敏感性分析
% 分析β、σ、γ对峰值感染人数的影响 [beta_grid,gamma_grid] = meshgrid(0.1:0.05:0.6, 0.05:0.02:0.15); peak_I = arrayfun(@(b,g) max(SEIR_model('beta',b,'gamma',g)), beta_grid, gamma_grid); surf(beta_grid, gamma_grid, peak_I); xlabel('感染率β'); ylabel('康复率γ'); zlabel('感染峰值');6. 实际应用中的注意事项
在将SEIR模型应用于实际问题时,有几个关键点需要考虑:
- 数据质量:确保输入数据的准确性和一致性,包括人口基数、初期感染人数等
- 参数不确定性:通过敏感性分析了解哪些参数对结果影响最大
- 模型局限性:SEIR模型假设均匀混合人群,忽略了空间异质性等复杂因素
- 伦理考量:模型预测结果可能影响公共决策,需谨慎解读和传达
注意:任何数学模型都是对现实的简化,预测结果应结合专业判断和实际情况综合考量。
7. 扩展模型方向
对于想要进一步探索的研究者,可以考虑以下扩展方向:
- 空间SEIR模型:加入地理信息,模拟疾病在不同区域间的传播
- 年龄结构模型:考虑不同年龄组的接触模式和易感性差异
- 随机SEIR模型:引入随机因素,更好地反映现实中的不确定性
- 网络SEIR模型:基于复杂网络理论,模拟非均匀接触模式
% 网络SEIR模型的简化示例 % 假设我们有一个接触网络adj_matrix function dydt = network_SEIR(t, y, adj_matrix, N, beta, sigma, gamma) S = y(1:N); E = y(N+1:2*N); I = y(2*N+1:3*N); infection_force = adj_matrix * I; dSdt = -beta * S .* infection_force; dEdt = beta * S .* infection_force - sigma * E; dIdt = sigma * E - gamma * I; dRdt = gamma * I; dydt = [dSdt; dEdt; dIdt; dRdt]; end在实际项目中,我发现最耗时的部分往往是数据的收集和清洗,而非模型构建本身。建议在开始建模前,先花足够时间确保数据质量,这能大幅减少后期的调试工作。