传染病的数学模型是数学建模中的典型问题,常见的传染病模型有 SI、SIR、SIRS、SEIR 模型。html
SIS 模型型将人群分为 S 类和 I 类,考虑患病者能够治愈而变成易感者,但不考虑免疫期。python
本文详细给出了 SIS 模型的建模、例程、运行结果和模型分析,让小白都能懂。算法
『Python小白的数学建模课 @ Youcans』 带你从数模小白成为国赛达人。编程
Python小白的数学建模课-09.微分方程模型
Python小白的数学建模课-B2.新冠疫情 SI模型
Python小白的数学建模课-B3.新冠疫情 SIS模型
Python小白的数学建模课-B4.新冠疫情 SIR模型
Python小白的数学建模课-B5.新冠疫情 SEIR模型
Python小白的数学建模课-B6.改进 SEIR疫情模型数组
传染病动力学是对传染病进行定量研究的重要方法。它依据种群繁衍迁移的特性、传染病在种群内产生及传播的机制、医疗与防控条件等外部因素,创建能够描述传染病动力学行为的数学模型,经过对模型进行定性、定量分析和数值计算,模拟传染病的传播过程,预测传染病的发展趋势,研究防控策略的做用。函数
SI 模型把人群分为易感者(S类)和患病者(I类)两类,易感者(S类)与患病者(I类)有效接触即被感染,变为患病者,无潜伏期、无治愈状况、无免疫力。工具
SI 模型适用于只有易感者和患病者两类人群,且没法治愈的疾病。spa
按照 SI 模型,最终全部人都会被传染而变成病人,这是由于模型中没有考虑病人能够治愈。所以只能是健康人患病,而患病者不能恢复健康(甚至也不会死亡,而是不断传播疫情),因此终将所有被传染。code
SIS 模型将人群分为 S 类和 I 类,考虑患病者(I 类)能够治愈而变成易感者(S 类),但不考虑免疫期,所以患病者(I 类)治愈变成易感者之后还能够被感染而变成患病者。orm
SIS 模型适用于只有易感者和患病者两类人群,能够治愈,但会反复发做的疾病,例如脑炎、细菌性痢疾等治愈后也不具备免疫力的传染病。
SIS 模型假设:
须要说明的是,不考虑生死或人口流动,一般是因为考虑一个封闭环境并且假定疫情随时间的变化比生死、迁移随时间的变化显著得多, 所以后者能够忽略不计。
SIS 模型的微分方程:
由
得:
由日治愈率 \(\mu\) 可知平均治愈天数为 \(1/\mu\),也称平均传染期。定义 \(\sigma = \lambda / \mu\),其含义是每一个病人在传染期内所传染的平均人数,称为传染期接触数。例如,平均传染期 \(1/\mu = 5\),日接触率 \(\lambda = 2\)(天天传染 2人),则传染期接触数 \(\sigma = 10\)。
SIS 模型的解析解为:
注意:网上有些博文中解析解的公式误写成 \(exp((\lambda-\mu)t)\) ,漏掉了一个负号。
SIS 模型是常微分方程初值问题,可使用 Scipy 工具包的 scipy.integrate.odeint() 函数求数值解。
scipy.integrate.odeint(func, y0, t, args=())
**scipy.integrate.odeint() **是求解微分方程的具体方法,经过数值积分来求解常微分方程组。
odeint() 的主要参数:
odeint() 的返回值:
odeint() 的编程步骤:
# 1. SIS 模型,常微分方程,解析解与数值解的比较 from scipy.integrate import odeint # 导入 scipy.integrate 模块 import numpy as np # 导入 numpy包 import matplotlib.pyplot as plt # 导入 matplotlib包 def dy_dt(y, t, lamda, mu): # SIS 模型,导数函数 dy_dt = lamda*y*(1-y) - mu*y # di/dt = lamda*i*(1-i)-mu*i return dy_dt # 设置模型参数 number = 1e5 # 总人数 lamda = 1.2 # 日接触率, 患病者天天有效接触的易感者的平均人数 sigma = 2.5 # 传染期接触数 mu = lamda/sigma # 日治愈率, 天天被治愈的患病者人数占患病者总数的比例 fsig = 1-1/sigma y0 = i0 = 1e-5 # 患病者比例的初值 tEnd = 50 # 预测日期长度 t = np.arange(0.0,tEnd,1) # (start,stop,step) print("lamda={}\tmu={}\tsigma={}\t(1-1/sig)={}".format(lamda,mu,sigma,fsig)) # 解析解 if lamda == mu: yAnaly = 1.0/(lamda*t +1.0/i0) else: yAnaly= 1.0/((lamda/(lamda-mu)) + ((1/i0)-(lamda/(lamda-mu))) * np.exp(-(lamda-mu)*t)) # odeint 数值解,求解微分方程初值问题 ySI = odeint(dy_dt, y0, t, args=(lamda,0)) # SI 模型 ySIS = odeint(dy_dt, y0, t, args=(lamda,mu)) # SIS 模型 # 绘图 plt.plot(t, yAnaly, '-ob', label='analytic') plt.plot(t, ySIS, ':.r', label='ySIS') plt.plot(t, ySI, '-g', label='ySI') plt.title("Comparison between analytic and numerical solutions") plt.axhline(y=fsig,ls="--",c='c') # 添加水平直线 plt.legend(loc='best') # youcans plt.axis([0, 50, -0.1, 1.1]) plt.show()
本图为例程 2.2 的运行结果,图中对解析解(蓝色)与使用 odeint() 获得的数值解(红色)进行比较。在该例中,没法观察到解析解与数值解的差别,代表数值解的偏差很小。
本图也比较了对相同日接触率和患病者初值下 SI模型与 SIS模型进行了比较。SI 模型更早进入爆发期,最终收敛到 100%;SIS 模型下进入爆发期较晚,患病者的比例最终收敛到某个常数(与模型参数有关)。
考察 SI 模型与 SIS模型的关系,显然 SI 模型是 SIS 模型在 \(\mu = 0\) 时的特殊状况。
对于 SIS 模型,须要考虑日接触率 \(\lambda\) 与日治愈率 \(\mu\) 的关系、患病者比例的初值 \(i_0\) 的影响,总人数 N 没有影响。
直观地考虑,若是天天治愈的人数高于感染的人数,则疫情逐渐好转,不然疫情逐渐严重。所以日接触率 \(\lambda\) 与日治愈率 \(\mu\) 的关系很是关键,这就是传染期接触数 \(\sigma = \lambda / \mu\) 的意义。
当 \(\sigma<1\) 时,传染期接触数小于 1,日接触率小于日治愈率,患病率单调降低,最终清零,与患病率初值无关。 \(\sigma\) 越小,疫情清零速度越快; \(\sigma\) 越接近于 1,疫情清零越慢,但最终仍将清零。
分析其实际意义,传染期接触数小于 1,代表在传染期内通过接触而使易感者变成患病者的数量,小于在传染期内治愈的患病者的数量,所以患病者数量、比例都会逐渐下降,因此最终能够清零,称为无病平衡点。
当 \(\sigma=1\) 时,不论患病率初值如何,患病率也是单调降低,最终趋近于 0。虽然在数学上患病率只能趋近于 0 而不等于 0,但考虑到总人数 N 是有限的,而患病者和易感者人数须要取整,所以 \(\sigma=1\) 时最终也会清零。
当 \(\sigma>1\) 时,传染期接触数大于 1,日接触率大于日治愈率,患病率的升降有两种状况:
这代表,当 \(\sigma>1\) 时疫情终将稳定但不会清零,而是长期保持必定的患病率,称为地方病平衡点。
当 \(\sigma=1\) 时,不论患病率初值如何,患病率都单调降低并最终趋于 0。
患病率的一阶导数 \(di/dt\) 的变化曲线,代表不论传染期接触数和初值如何,患病率的变化率都将收敛到 0,所以疫情终将稳定。当 \(\sigma<1\) 时, \(di/dt\) 始终是负值,单调上升趋近于 0; 当 \(\sigma>1\) 时, \(di/dt\) 始终是正值,先上升达到峰值后再逐渐减少趋近于 0。
本图为患病率 \(i(t)\) 与一阶导数 \(di/dt\) 在不一样传染期接触数下的关系曲线(相空间图)。当 \(\sigma\leq 1\) 时,曲线收敛到原点 \((0,0)\),即存在无病平衡点; 当 \(\sigma>1\) 时,曲线收敛到 \((1-1/\sigma,0)\),即存在地方病平衡点。
# 4. SIS 模型,模型参数对 di/dt的影响 from scipy.integrate import odeint # 导入 scipy.integrate 模块 import numpy as np # 导入 numpy包 import matplotlib.pyplot as plt # 导入 matplotlib包 def dy_dt(y, t, lamda, mu): # SIS 模型,导数函数 dy_dt = lamda*y*(1-y) - mu*y # di/dt = lamda*i*(1-i)-mu*i return dy_dt # 设置模型参数 number = 1e5 # 总人数 lamda = 1.2 # 日接触率, 患病者天天有效接触的易感者的平均人数 # sigma = np.array((0.1, 0.5, 0.8, 0.95, 1.0)) # 传染期接触数 sigma = np.array((0.5, 0.8, 1.0, 1.5, 2.0, 3.0)) # 传染期接触数 y0 = i0 = 0.05 # 患病者比例的初值 tEnd = 100 # 预测日期长度 t = np.arange(0.0,tEnd,0.1) # (start,stop,step) for p in sigma: ySIS = odeint(dy_dt, y0, t, args=(lamda,lamda/p)) # SIS 模型 yDeriv = lamda*ySIS*(1-ySIS) - ySIS*lamda/p # plt.plot(t, yDeriv, '-', label=r"$\sigma$ = {}".format(p)) plt.plot(ySIS, yDeriv, '-', label=r"$\sigma$ = {}".format(p)) #label='di/dt~i' print("lamda={}\tmu={}\tsigma={}\t(1-1/sig)={}".format(lamda,lamda/p,p,(1-1/p))) # 绘图 plt.axhline(y=0,ls="--",c='c') # 添加水平直线 plt.title("i(t)~di/dt in SIS model") # youcans-xupt plt.legend(loc='best') plt.show()
SIS 模型代表:
须要指出的是,本文讨论的 SIS模型是把考察地区视为一个疫情均匀分布的总体进行研究。实际上,在考察区域的疫情分布必然是不均衡的,可能在局部区域发生疫情爆发致使该区域患病人数激增,是否会影响 SIS 模型的演化过程和稳定性呢?相关研究代表,扩散速度的不一样可能致使种群空间分布的差别,在低风险区域将达到无病平衡点,在高风险区域仍将达到地方病平衡点。
【本节完】
版权声明:
欢迎关注 『Python小白的数学建模课 @ Youcans』 原创做品
原创做品,转载必须标注原文连接:(https://www.cnblogs.com/youcans/p/14968504.html)。
Copyright 2021 Youcans, XUPT
Crated:2021-06-09
欢迎关注 『Python小白的数学建模课 @ Youcans』,每周更新数模笔记
Python小白的数学建模课-01.新手必读
Python小白的数学建模课-02.数据导入
Python小白的数学建模课-03.线性规划
Python小白的数学建模课-04.整数规划
Python小白的数学建模课-05.0-1规划
Python小白的数学建模课-06.固定费用问题
Python小白的数学建模课-07.选址问题
Python小白的数学建模课-09.微分方程模型
Python小白的数学建模课-B2.新冠疫情 SI模型
Python小白的数学建模课-B3.新冠疫情 SIS模型
Python数模笔记-PuLP库
Python数模笔记-StatsModels统计回归
Python数模笔记-Sklearn
Python数模笔记-NetworkX
Python数模笔记-模拟退火算法