Im vorherigen Artikel habe ich ein Programm veröffentlicht, das das Verhalten des neuen Koronavirus mit dem SEIR-Modell vorhersagt. Dieses Mal haben wir das Programm zu einer GUI gemacht, damit wir den Inhalt teilen können.
`Vorheriger Artikel: Ich habe versucht, das Verhalten des neuen Koronavirus mit dem SEIR-Modell vorherzusagen. `` Link: https://qiita.com/kotai2003/items/ed28fb723a335a873061

Derzeit wurden viele Forschungsarbeiten veröffentlicht, um die SEIR-Parameter aus den Fällen des neuen Coronavirus abzuschätzen. Dieses Mal werde ich das SEIR-Modell mit den Parameterschätzungen berechnen, die in dem am 16. Februar veröffentlichten Artikel veröffentlicht wurden. (Referenz 2)
| Parameter | Festlandchina (ohne Provinz Hubei) | Provinz Hubei (außer Wuhan) | Wuhan |
|---|---|---|---|
| Bevölkerung N.(million) | 1340 | 45 | 14 |
| Infektionsrate[beta] | 1.0 | 1.0 | 1.0 |
| Latency period (days) | 2 | 2 | 2 |
| infectious_period (days) | 6.6 | 7.2 | 7.4 |
| E_0 | 696 | 592 | 318 |
| I_0 | 652 | 515 | 389 |
Zum Beispiel [Social Distance Strategy](https://ja.wikipedia.org/wiki/%E7%A4%BE%E4%BC%9A%E8%B7%9D%E9%9B%A2%E6%88%A6 Mit% E7% 95% A5) kann durch Simulation bestätigt werden, wie der Peak infizierter Personen schwankt, wenn die Infektionsrate von 0,5 auf 0,4 sinkt.
### Fall 2: Infektionsrate 0,4
Der Höhepunkt der Infektionen ist gesunken und das Timing hat sich nach rechts verschoben.
Mit einer solchen Berechnung ist es möglich, die Wirkung des "Zwecks von Gegenmaßnahmen (Grundkonzept)" zu bestätigen, der am 23. Februar vom Hauptquartier der Regierung für die Kontrolle des Corona-Virus-Infektionskrankheiten angekündigt wurde.
main_routine.py
import tkinter as tk
from tkinter import ttk
from tkinter import Menu
from tkinter import messagebox
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from calcSEIR import SEIR_EQ
class Application(tk.Frame):
def __init__(self,master):
super().__init__(master)
self.pack()
self.master.geometry("1000x600")
self.master.title("SEIR Epidemic Model Simulator")
self.create_widgets()
def create_widgets(self):
#Canvas Frame
self.canvas_frame = tk.Frame(self)
self.canvas_frame.configure(width=600, height=480)
self.canvas_frame.grid(row=0, column=0)
self.canvas_frame.grid(padx = 20, pady=20)
#Label Frame for Input Parameters
self.frame_param = tk.LabelFrame( self )
self.frame_param.configure( text=' Input Paramaters ' )
self.frame_param.grid( row=0, column=1 )
self.frame_param.grid( padx=20, pady=20 )
#1. Population
#Label_population
self.label_popu = tk.Label( self.frame_param)
self.label_popu.configure(text ='Population (Million)')
self.label_popu.grid(row =0, column = 0)
#Scale population
self.var_popu = tk.DoubleVar() #scale variable
self.scale_popu = tk.Scale( self.frame_param)
self.scale_popu.configure(orient="horizontal")
self.scale_popu.configure(from_=1, to= 1350)
self.scale_popu.configure(variable=self.var_popu)
self.scale_popu.grid(row=0, column=1)
#2. Infection Rate
# Label_Infection_Rate
self.label_IR = tk.Label( self.frame_param )
self.label_IR.configure( text='Infection Rate' )
self.label_IR.grid( row=1, column=0 )
# Scale Infection_Rate
self.var_IR = tk.DoubleVar() # scale variable
self.scale_IR = tk.Scale( self.frame_param )
self.scale_IR.configure( orient="horizontal" )
self.scale_IR.configure( from_=0.1, to=2 , resolution=0.1)
self.scale_IR.configure( variable=self.var_IR )
self.scale_IR.grid( row=1, column=1 )
#3. Latency Period
# Label_
self.label_LP = tk.Label( self.frame_param )
self.label_LP.configure( text='Latency Period (days)' )
self.label_LP.grid( row=2, column=0 )
# Scale
self.var_LP = tk.IntVar() # scale variable
self.scale_LP = tk.Scale( self.frame_param )
self.scale_LP.configure( orient="horizontal" )
self.scale_LP.configure( from_=1, to=14 , resolution=0.1)
self.scale_LP.configure( variable=self.var_LP )
self.scale_LP.grid( row=2, column=1 )
# 3.5 Infection Period
# Label_
self.label_IP = tk.Label( self.frame_param )
self.label_IP.configure( text='Infections Period (days)' )
self.label_IP.grid( row=3, column=0 )
# Scale
self.var_IP = tk.IntVar() # scale variable
self.scale_IP = tk.Scale( self.frame_param )
self.scale_IP.configure( orient="horizontal" )
self.scale_IP.configure( from_=1, to=14, resolution=0.1 )
self.scale_IP.configure( variable=self.var_IP )
self.scale_IP.grid( row=3, column=1 )
#4 E_0
self.label_E0 = tk.Label( self.frame_param )
self.label_E0.configure( text='E(t=0)' )
self.label_E0.grid( row=4, column=0 )
#Entry
self.Entry_E0 = tk.Entry(self.frame_param)
self.Entry_E0.grid(row=4, column=1)
self.Entry_E0.insert(tk.END,"696")
#5 I_0
self.label_I0 = tk.Label( self.frame_param )
self.label_I0.configure( text='I(t=0)' )
self.label_I0.grid( row=5, column=0 )
# Entry
self.Entry_I0 = tk.Entry( self.frame_param )
self.Entry_I0.grid( row=5, column=1 )
self.Entry_I0.insert( tk.END, "652" )
#6 R_0
self.label_R0 = tk.Label( self.frame_param )
self.label_R0.configure( text='E(t=0)' )
self.label_R0.grid( row=6, column=0 )
# Entry
self.Entry_R0 = tk.Entry( self.frame_param )
self.Entry_R0.grid( row=6, column=1 )
self.Entry_R0.insert( tk.END, "0" )
#7 Time
self.label_time = tk.Label(self.frame_param)
self.label_time.configure( text = 'Time [days]')
self.label_time.grid(row=7, column=0)
self.var_time = tk.IntVar() # scale variable
self.scale_time = tk.Scale( self.frame_param )
self.scale_time.configure( orient="horizontal" )
self.scale_time.configure( from_=10, to=500, resolution=1 )
self.scale_time.configure( variable=self.var_time )
self.scale_time.grid( row=7, column=1 )
#Basic Reproduction Number
# Label Frame result
self.frame_basicR0 = tk.LabelFrame( self )
self.frame_basicR0.configure( text=' Basic Reproduction Number ' )
self.frame_basicR0.grid( row=2, column=1 )
self.frame_basicR0.grid( padx=20, pady=20 )
self.label_basicR0 = tk.Label(self.frame_basicR0)
self.label_basicR0.grid(row = 0, column=0)
self.label_basicR0.configure(text = ' R0 is ')
self.msg_basicR0 = tk.Message(self.frame_basicR0)
self.msg_basicR0.grid(row=0, column=1)
self.msg_basicR0.configure(text ='')
# Button
##Label Frame for Buttons
# Label Frame for Input Parameters
self.frame_button = tk.LabelFrame( self )
self.frame_button.configure( text=' Operation ' )
self.frame_button.grid( row=2, column=0 )
self.frame_param.grid( padx=20, pady=20 )
#button
# Plot (Rungekutta. Plot..Canvas..)
self.button_plot = tk.Button( self.frame_button )
self.button_plot.configure( text='Calculate & Plot' )
self.button_plot.grid( column=0, row=1 )
self.button_plot.configure( command=self.plotCalc )
self.button_plot.configure(width = 20, height=2)
# Quit Button
self.button_quit = tk.Button( self.frame_button )
self.button_quit.config( text='Quit' )
self.button_quit.grid( column=2, row=1 )
self.button_quit.configure( command=self.quit_app )
self.button_quit.configure( width = 15, height=2 )
## Event Call Back
def plotCalc(self):
# parameters
self.t_max = self.var_time.get() # days
self.dt = 0.01
# initial_state
self.N_pop = 1e6*self.var_popu.get()
self.E_0 = int(self.Entry_E0.get())
self.I_0 = int(self.Entry_I0.get())
self.R_0 = int(self.Entry_R0.get())
self.S_0 = self.N_pop - (self.E_0 + self.I_0 + self.R_0)
self.ini_state = [self.S_0, self.E_0, self.I_0, self.R_0] # [S[0],E,[0], I[0], R[0]]
#Infektionsrate
self.beta_const = self.var_IR.get() #Infektionsrate
#Infektionsrate nach Exposition
self.epsilon_const = 1 / self.var_LP.get()
#Wiederherstellungsrate und Isolationsrate
self.gamma_const = 1 / self.var_IP.get()
#Basic Reproduction number in SEIR model
self.basicR0 = self.beta_const/self.gamma_const +self.beta_const/self.epsilon_const
self.msg_basicR0.configure( text=str(self.basicR0) )
#https://www.fields.utoronto.ca/programs/scientific/10-11/drugresistance/emergence/fred1.pdf
# numerical integration
self.times = np.arange( 0, self.t_max, self.dt )
self.args = (self.beta_const, self.epsilon_const, self.gamma_const, self.N_pop)
# Numerical Solution using scipy.integrate
# Solver SEIR model
self.result = odeint(SEIR_EQ, self.ini_state, self.times, self.args )
## Plotting
# Generate Figure instance
self.fig = plt.Figure()
#Generate Axe instance
#ax1
self.ax1 = self.fig.add_subplot(111)
self.ax1.plot(self.times, self.result)
self.ax1.set_title('SEIR Epidemic model')
self.ax1.set_xlabel('time [days]')
self.ax1.set_ylabel('population [persons]')
self.ax1.legend(['Susceptible', 'Exposed', 'Infectious', 'Removed'])
self.ax1.grid()
#Link to Axe instance to Canvas
#Then show Canvas onto canvas_Frame
self.canvas = FigureCanvasTkAgg( self.fig, self.canvas_frame )
self.canvas.draw()
self.canvas.get_tk_widget().grid(column=0, row=0)
def quit_app(self):
self.Msgbox = tk.messagebox.askquestion( "Exit Applictaion", "Are you sure?", icon="warning" )
if self.Msgbox == "yes":
self.master.destroy()
else:
tk.messagebox.showinfo( "Return", "you will now return to application screen" )
def main():
root = tk.Tk()
app = Application(master=root)#Inherit
app.mainloop()
if __name__ == "__main__":
main()
calcSEIR.py
# Define differential equation of SEIR model
'''
dS/dt = -beta * S * I / N
dE/dt = beta* S * I / N - epsilon * E
dI/dt = epsilon * E - gamma * I
dR/dt = gamma * I
[v[0], v[1], v[2], v[3]]=[S, E, I, R]
dv[0]/dt = -beta * v[0] * v[2] / N
dv[1]/dt = beta * v[0] * v[2] / N - epsilon * v[1]
dv[2]/dt = epsilon * v[1] - gamma * v[2]
dv[3]/dt = gamma * v[2]
'''
def SEIR_EQ(v, t, beta, epsilon, gamma, N ):
return [-beta * v[0] * v[2] / N ,beta * v[0] * v[2] / N - epsilon * v[1],
epsilon * v[1] - gamma * v[2],gamma * v[2]]
Recommended Posts