新型コロナウイルス感染者数予測をSIRモデルで表現(Python)
- 新型の病気のため、人々は免疫を持っていない
- モデルとする人間は、平均的に不特定多数の人と接触している
- 人口の流入、流出はない(ロックダウンされた国や都市を想定したモデル)
- 接触によって、一定の確率で感染する
- 感染者は快復後に免疫を獲得し、再び罹患者と接触しても再発しない、未感染者に罹患させることもない。
ここでは、S,I,Rを用いて
S:(Susceptable)未感染者
I : (Infected)感染者
R : (Recovered)快復者
を表すこととする。
総人口を、未感染者が 人、感染者が 人、快復した人が 人と置く。 また、経過時間を変数 (日)で表すことにする。集団の中で、一人当たり平均人と接触するとする。そのうち感染している人の割合はであるから、未感染者人が一日あたりに接触する感染者の人数は人と表せる。さらに、未感染者が感染者と接触した際に感染する確率をとすれば、日の間に生じる新たな感染者は、となる。
と置くと、日目から日目の間に、新たな感染者によって非感染者の数が
だけ変化することになる。この式のを左辺の分母に移行し、
と書き直して、の極限をとると
を得る。次に、感染者は一日当たり一定の率で快復してゆくとすると、回復者の増加分は
人口は一定であるため、(非感染者)+(感染者)+(快復者)=
両辺をで微分すると
これをPythonで数値シミュレーションする。4次のルンゲクッタ法を用いて微分方程式からグラフ描写を行う。
import math import matplotlib.pyplot as plt N = 1000000 x = N-10 y = 10 z = 0 taxis = [] xaxis = [] yaxis = [] zaxis = [] beta = 0.2/N gamma = 0.07 dt = 0.001 t = 0 cnt = 0 while t < 180: if cnt%100 == 0: taxis.append(t) xaxis.append(x) yaxis.append(y) zaxis.append(z) # step 1 kx1 = -beta*x*y ky1 = beta*x*y - gamma*y # step 2 x2 = x+kx1*dt/2 y2 = y+ky1*dt/2 kx2 = -beta*x2*y2 ky2 = beta*x2*y2 - gamma*y2 # step3 x3 = x+kx2*dt/2 y3 = y+ky2*dt/2 kx3 = -beta*x3*y3 ky3 = beta*x3*y3 - gamma*y3 # step4 x4 = x+kx3*dt y4 = y+ky3*dt kx4 = -beta*x4*y4 ky4 = beta*x4*y4 - gamma*y4 # update x = x+(kx1+2*kx2+2*kx3+kx4)*dt/6 y = y+(ky1+2*ky2+2*ky3+ky4)*dt/6 z = N-x-y t = t+dt cnt+=1 plt.title("SIR MODEL") plt.plot(taxis,xaxis, color=(0.0,1,0.0), linewidth=1.0, label='S') plt.plot(taxis,yaxis, color=(1.0,0,0.0), linewidth=1.0, label='I') plt.plot(taxis,zaxis, color=(0.0,0,1.0), linewidth=1.0, label='R') plt.xlim(0,180) plt.legend() plt.xlabel('DAY') plt.ylabel('X, Y, Z') plt.grid(True)
参考文献
情報基礎 「Pythonプログラミング」(ステップ6:SIRモデル)情報基礎 「Pythonプログラミング」(ステップ6:ルンゲクッタ法)