![e93645571af7c3131b11345c5e7a464c.png](https://i-blog.csdnimg.cn/blog_migrate/16ec139a151095aad4973f958b98b148.jpeg)
本文只讲述如何使用Python将模型中的微分方程进行可视化,具体各个模型的理论细节,请移步其他专业传染病动力学文章。
SI模型
SI模型只适合研究具有高传染风险又不能被治愈的病(比如HIV)已经患病的人就不能再被传染了 。人群分为两类 :易感者(S-susceptiable)和感染者(I-infective)
SI-Model
#SI-Model
import scipy.integrate as spi
import numpy as np
import plotly as py
import plotly.graph_objects as go
pyplt = py.offline.plot
fig = go.Figure()
# N为人群总数
N = 10000
# β为传染率系数
beta = 0.25
# gamma为恢复率系数
gamma = 0
# I_0为感染者的初始人数
I_0 = 1
# S_0为易感者的初始人数
S_0 = N - I_0
# T为传播时间
T = 150
# INI为初始状态下的数组
INI = (S_0,I_0)
def funcSI(inivalue,_):
Y = np.zeros(2)
X = inivalue
# 易感个体变化
Y[0] = - (beta * X[0] * X[1]) / N + gamma * X[1]
# 感染个体变化
Y[1] = (beta * X[0] * X[1]) / N - gamma * X[1]
return Y
T_range = np.arange(0,T + 1)
RES = spi.odeint(funcSI,INI,T_range)
fig.add_trace(go.Scatter(
y = RES[:,0],
mode = 'lines', # 线性图
name = '感染者'
))
fig.add_trace(go.Scatter(
y = RES[:,1],
mode = 'lines', # 线性图
name = '易感者'
))
fig.update_layout(
yaxis={'title':'人数'},
xaxis={'title':'天数'},
title={'text':'SI-Model','xref':'paper','x':0.5,},
hovermode="x",
#height=600,
template="plotly_white",
)
fig.show()
![4dacb86b1f2a32a086a6cba5bd887fce.png](https://i-blog.csdnimg.cn/blog_migrate/7cc9a5c0dd7762e82a5f29d422cf4a1f.jpeg)
SIS模型
SIS模型适合研究具有传染性和反复性的流行病,和SI模型做比较,区别就是计算感染者的增加数时要 减去被治愈的人数
SIS-Model
#SIS-Model
import scipy.integrate as spi
import numpy as np
import plotly.graph_objects as go
pyplt = py.offline.plot
fig = go.Figure()
# N为人群总数
N = 10000
# β为传染率系数
beta = 0.25
# gamma为恢复率系数
gamma = 0.05
# I_0为感染者的初始人数
I_0 = 1
# S_0为易感者的初始人数
S_0 = N - I_0
# T为传播时间
T = 150
# INI为初始状态下的数组
INI = (S_0,I_0)
def funcSIS(inivalue,_):
Y = np.zeros(2)
X = inivalue
# 易感个体变化
Y[0] = - (beta * X[0]) / N * X[1] + gamma * X[1]
# 感染个体变化
Y[1] = (beta * X[0] * X[1]) / N - gamma * X[1]
return Y
T_range = np.arange(0,T + 1)
RES = spi.odeint(funcSIS,INI,T_range)
fig.add_trace(go.Scatter(
y = RES[:,0],
mode = 'lines', # 线性图
name = '感染者'
))
fig.add_trace(go.Scatter(
y = RES[:,1],
mode = 'lines', # 线性图
name = '易感者'
))
fig.update_layout(
yaxis={'title':'人数'},
xaxis={'title':'天数'},
title={'text':'SIS-Model','xref':'paper','x':0.5,},
hovermode="x",
#height=600,
template="plotly_white",
)
fig.show()
![a5d569a69f66dbcc0321b1415e2cd615.png](https://i-blog.csdnimg.cn/blog_migrate/792595fca53c5c94fb1b29c470210702.jpeg)
SIR模型
SIR模型适合研究没有潜伏期的急性传染病,治疗后能够痊愈并具有抗病性。模型加入移出者(Removed),即被治愈的病人不会再被传染。
SIR-Model
#SIR-Model
import scipy.integrate as spi
import numpy as np
import plotly.graph_objects as go
pyplt = py.offline.plot
fig = go.Figure()
# N为人群总数
N = 10000
# β为传染率系数
beta = 0.25
# gamma为恢复率系数
gamma = 0.05
# I_0为感染者的初始人数
I_0 = 1
# R_0为治愈者的初始人数
R_0 = 0
# S_0为易感者的初始人数
S_0 = N - I_0 - R_0
# T为传播时间
T = 150
# INI为初始状态下的数组
INI = (S_0,I_0,R_0)
def funcSIR(inivalue,_):
Y = np.zeros(3)
X = inivalue
# 易感个体变化
Y[0] = - (beta * X[0] * X[1]) / N
# 感染个体变化
Y[1] = (beta * X[0] * X[1]) / N - gamma * X[1]
# 治愈个体变化
Y[2] = gamma * X[1]
return Y
T_range = np.arange(0,T + 1)
RES = spi.odeint(funcSIR,INI,T_range)
fig.add_trace(go.Scatter(
y = RES[:,0],
mode = 'lines', # 线性图
name = '感染者'
))
fig.add_trace(go.Scatter(
y = RES[:,1],
mode = 'lines', # 线性图
name = '易感者'
))
fig.add_trace(go.Scatter(
y = RES[:,2],
mode = 'lines', # 线性图
name = '治愈者'
))
fig.update_layout(
yaxis={'title':'人数'},
xaxis={'title':'天数'},
title={'text':'SIR-Model','xref':'paper','x':0.5,},
hovermode="x",
#height=600,
template="plotly_white",
)
fig.show()
![ef35be34e5e687ee60cda8839ba5e6ee.png](https://i-blog.csdnimg.cn/blog_migrate/9b7367dfa46e4bb75c562ce63474c2ac.jpeg)
SIRS模型
现实情况却是部分传染病并不会痊愈后拥有终身抗体,即被治愈的病人 仍会再被传染。SIRS模型相对SIR模型加入抗体时间
SIRS-Model
#SIRS-Model
import scipy.integrate as spi
import numpy as np
import plotly.graph_objects as go
pyplt = py.offline.plot
fig = go.Figure()
# N为人群总数
N = 10000
# β为传染率系数
beta = 0.25
# gamma为恢复率系数
gamma = 0.05
# Ts为抗体持续时间
Ts = 15
# I_0为感染者的初始人数
I_0 = 1
# R_0为治愈者的初始人数
R_0 = 0
# S_0为易感者的初始人数
S_0 = N - I_0 - R_0
# T为传播时间
T = 150
# INI为初始状态下的数组
INI = (S_0,I_0,R_0)
def funcSIRS(inivalue,_):
Y = np.zeros(3)
X = inivalue
# 易感个体变化
Y[0] = - (beta * X[0] * X[1]) / N + X[2] / Ts
# 感染个体变化
Y[1] = (beta * X[0] * X[1]) / N - gamma * X[1]
# 治愈个体变化
Y[2] = gamma * X[1] - X[2] / Ts
return Y
T_range = np.arange(0,T + 1)
RES = spi.odeint(funcSIRS,INI,T_range)
fig.add_trace(go.Scatter(
y = RES[:,0],
mode = 'lines', # 线性图
name = '感染者'
))
fig.add_trace(go.Scatter(
y = RES[:,1],
mode = 'lines', # 线性图
name = '易感者'
))
fig.add_trace(go.Scatter(
y = RES[:,2],
mode = 'lines', # 线性图
name = '治愈者'
))
fig.update_layout(
yaxis={'title':'人数'},
xaxis={'title':'天数'},
title={'text':'SIRS-Model','xref':'paper','x':0.5,},
hovermode="x",
#height=600,
template="plotly_white",
)
fig.show()
![91a6282ef0beb03b0865fd02a5f36774.png](https://i-blog.csdnimg.cn/blog_migrate/fb792dd6e8bf476ec33729160d8a023f.jpeg)
SEIR模型
SIR模型忽略了太多因素了导致和实际情况有较大出入,比如潜伏期,药物,出生死亡等等。接来下可以把 潜伏期考虑进去,新增一个人群,叫 潜伏者E(exposed)
SEIR-Model
#SEIR-Model
import scipy.integrate as spi
import numpy as np
import plotly.graph_objects as go
pyplt = py.offline.plot
fig = go.Figure()
# N为人群总数
N = 10000
# β为传染率系数
beta = 0.5
# gamma为恢复率系数
gamma = 0.1
# Te为疾病潜伏期
Te = 14
# I_0为感染者的初始人数
I_0 = 1
# E_0为潜伏者的初始人数
E_0 = 0
# R_0为治愈者的初始人数
R_0 = 0
# S_0为易感者的初始人数
S_0 = N - I_0 - E_0 - R_0
# T为传播时间
T = 150
# INI为初始状态下的数组
INI = (S_0,E_0,I_0,R_0)
def funcSEIR(inivalue,_):
Y = np.zeros(4)
X = inivalue
# 易感个体变化
Y[0] = - (beta * X[0] * X[2]) / N
# 潜伏个体变化
Y[1] = (beta * X[0] * X[2]) / N - X[1] / Te
# 感染个体变化
Y[2] = X[1] / Te - gamma * X[2]
# 治愈个体变化
Y[3] = gamma * X[2]
return Y
T_range = np.arange(0,T + 1)
RES = spi.odeint(funcSEIR,INI,T_range)
fig.add_trace(go.Scatter(
y = RES[:,0],
mode = 'lines', # 线性图
name = '易感者'
))
fig.add_trace(go.Scatter(
y = RES[:,1],
mode = 'lines', # 线性图
name = '潜伏者',
line=dict(color="yellow")
))
fig.add_trace(go.Scatter(
y = RES[:,2],
mode = 'lines', # 线性图
name = '感染者',
line=dict(color="red")
))
fig.add_trace(go.Scatter(
y = RES[:,3],
mode = 'lines', # 线性图
name = '治愈者',
line=dict(color="green")
))
fig.update_layout(
yaxis={'title':'人数'},
xaxis={'title':'天数'},
title={'text':'SERI-Model','xref':'paper','x':0.5,},
hovermode="x",
#height=600,
template="plotly_white",
)
fig.show()
![13c682dbb26277249d1b689a69658ebb.png](https://i-blog.csdnimg.cn/blog_migrate/dc27172dc24ae8780c85e3df5a0378be.jpeg)
SEIRS模型
SEIRS模型即对SEIR模型 添加抗体存在时长
SEIRS-Model
#SEIRS-Model
import scipy.integrate as spi
import numpy as np
import plotly.graph_objects as go
pyplt = py.offline.plot
fig = go.Figure()
# N为人群总数
N = 10000
# β为传染率系数
beta = 0.5
# gamma为恢复率系数
gamma = 0.1
# Ts为抗体持续时间
Ts = 15
# Te为疾病潜伏期
Te = 14
# I_0为感染者的初始人数
I_0 = 1
# E_0为潜伏者的初始人数
E_0 = 0
# R_0为治愈者的初始人数
R_0 = 0
# S_0为易感者的初始人数
S_0 = N - I_0 - E_0 - R_0
# T为传播时间
T = 150
# INI为初始状态下的数组
INI = (S_0,E_0,I_0,R_0)
def funcSEIRS(inivalue,_):
Y = np.zeros(4)
X = inivalue
# 易感个体变化
Y[0] = - (beta * X[0] * X[2]) / N + X[3] / Ts
# 潜伏个体变化
Y[1] = (beta * X[0] * X[2]) / N - X[1] / Te
# 感染个体变化
Y[2] = X[1] / Te - gamma * X[2]
# 治愈个体变化
Y[3] = gamma * X[2] - X[3] / Ts
return Y
T_range = np.arange(0,T + 1)
RES = spi.odeint(funcSEIRS,INI,T_range)
fig.add_trace(go.Scatter(
y = RES[:,0],
mode = 'lines', # 线性图
name = '易感者'
))
fig.add_trace(go.Scatter(
y = RES[:,1],
mode = 'lines', # 线性图
name = '潜伏者',
line=dict(color="orange")
))
fig.add_trace(go.Scatter(
y = RES[:,2],
mode = 'lines', # 线性图
name = '感染者',
line=dict(color="red")
))
fig.add_trace(go.Scatter(
y = RES[:,3],
mode = 'lines', # 线性图
name = '治愈者',
line=dict(color="green")
))
fig.update_layout(
yaxis={'title':'人数'},
xaxis={'title':'天数'},
title={'text':'SERIS-Model','xref':'paper','x':0.5,},
hovermode="x",
#height=600,
template="plotly_white",
)
fig.show()
![143fb5dffcd3748974dc1a58b99bfa8b.png](https://i-blog.csdnimg.cn/blog_migrate/2ee2c5dd7f5babd63f8632f8e5175bb6.jpeg)
病毒其实不可怕,你宅我宅它就挂
病毒其实不可怕,戴好口罩它也挂
参考:
关于传染病的数学模型有哪些?www.zhihu.com![363fc313654168a2e1d3d5eef1b461d1.png](https://i-blog.csdnimg.cn/blog_migrate/91083ea829310226d329922706f45db2.jpeg)
![fd1db1c8609d9317a05c6b69d5d04c2a.png](https://i-blog.csdnimg.cn/blog_migrate/56bef7cde128509d06a44f0e6d3e4b68.jpeg)