感染症伝播の時間変化のグラフ化をChatGPTに頼んでみた。潜伏期間・人口移動まで追加要素もOK

やっぱりChatGPTはすごい

伝染性感染症伝播の数式モデルを教えて下さい

伝染性疾患の伝播に関する基本的な数式モデルには、SIRモデル(感受性、感染、回復)があります。SIRモデルは、感染症が広がるプロセスを3つのカテゴリに分けます:感受性(S)、感染(I)、および回復(R)。

SIRモデルでは、以下の3つの基本的な微分方程式で表されます:

dS/dt = -βSI dI/dt = βSI - γI dR/dt = γI

ここで、βは感染率(感染源の人口密度、感染症の伝播率、接触率)、γは回復率(感染者の回復率または死亡率)を表します。

このモデルは、感受性者の数(S)、感染者の数(I)および回復者の数(R)を時間の関数として表します。感染症の伝播が終息するには、感染者数が減少し、感受性者数が増加する必要があります。


上記微分方程式をpythonでグラフ化してもらえませんか

SIRモデルの微分方程式をPythonで解いてグラフにプロットするには、まずNumPyおよびMatplotlibライブラリをインストールする必要があります。以下のようにコードを書くことができます。


import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint

# SIRモデルの微分方程式
def deriv(y, t, N, beta, gamma):
    S, I, R = y
    dSdt = -beta * S * I / N
    dIdt = beta * S * I / N - gamma * I
    dRdt = gamma * I
    return dSdt, dIdt, dRdt

# 初期値
N = 1000
I0, R0 = 1, 0
S0 = N - I0 - R0

# パラメーター
beta = 0.2
gamma = 1./10 

# グラフ化する時間範囲
t = np.linspace(0, 160, 160)

# 微分方程式を解く
y0 = S0, I0, R0
ret = odeint(deriv, y0, t, args=(N, beta, gamma))
S, I, R = ret.T

# グラフにプロットする
fig = plt.figure(facecolor='w')
ax = fig.add_subplot(111, facecolor='#dddddd', axisbelow=True)
ax.plot(t, S/1000, 'b', alpha=0.5, lw=2, label='Susceptible')
ax.plot(t, I/1000, 'r', alpha=0.5, lw=2, label='Infected')
ax.plot(t, R/1000, 'g', alpha=0.5, lw=2, label='Recovered with immunity')
ax.set_xlabel('Time /days')
ax.set_ylabel('Number (1000s)')
ax.set_ylim(0,1.2)
ax.yaxis.set_tick_params(length=0)
ax.xaxis.set_tick_params(length=0)
ax.grid(b=True, which='major', c='w', lw=2, ls='-')
legend = ax.legend()
legend.get_frame().set_alpha(0.5)
for spine in ('top', 'right', 'bottom', 'left'):
    ax.spines[spine].set_visible(False)
plt.show()

このコードでは、最初にSIRモデルの微分方程式をderiv関数として定義します。odeint関数を使用して微分方程式を解き、グラフにプロットします。グラフのx軸には時間、y軸には人口(単位は千人)が表示されます。感受性者は青色、感染者は赤色、回復者は緑色で表示されます。

上記コードを実行すると、SIRモデルの感染症伝播の時間変化を表すグラフが表示されます。


python出力
# パラメーター
beta = 0.3
gamma = 0.9/10

としてみた


Python



潜伏期間のある感染症も伝播モデルの数式化お願いできますか?

潜伏期間のある感染症に対する基本的な伝播モデルは、SEIRモデル(感受性、潜伏、感染、回復)です。SIRモデルに比べて複雑なモデルになりますが、感染症の伝播をより正確にモデル化することができます。

SEIRモデルでは、人口を感受性(S)、潜伏期間中(E)、感染期間中(I)および回復(R)の4つのカテゴリに分けます。感染者は、潜伏期間を経て感染期間に移行します。

以下は、SEIRモデルの基本的な微分方程式です。

dS/dt = -βSI dE/dt = βSI - αE dI/dt = αE - γI dR/dt = γI

ここで、βは感染率、αは潜伏期間中の感染率、γは回復率を表します。

このモデルでは、感受性者(S)、潜伏者(E)、感染者(I)、回復者(R)の数を時間の関数として表します。感染者数が増加するにつれ、潜伏者数も増加し、回復者数が増加すると感染者数が減少します。

ただし、このモデルは、感染症の伝播を正確にモデル化するための多くの要素を考慮していないため、実際の感染症の伝播を正確に再現するには、より複雑なモデルが必要になる場合があります。

上記微分方程式をpythonでグラフ化してもらえませんか

SEIRモデルをPythonでグラフ化するためには、NumPyおよびMatplotlibライブラリが必要です。また、微分方程式を解くためにScipyのodeint関数を使用します。

以下は、SEIRモデルを解くPythonコードの例です。

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt

# SEIRモデルの微分方程式
def deriv(y, t, N, beta, gamma, alpha):
    S, E, I, R = y
    dSdt = -beta * S * I / N
    dEdt = beta * S * I / N - alpha * E
    dIdt = alpha * E - gamma * I
    dRdt = gamma * I
    return dSdt, dEdt, dIdt, dRdt

# 初期値
N = 10000
I0, R0 = 1, 0
E0 = 0
S0 = N - I0 - R0 - E0

# パラメーター
beta = 1.2
gamma = 0.2
alpha = 1./5 

# グラフ化する時間範囲
t = np.linspace(0, 160, 160)

# 微分方程式を解く
y0 = S0, E0, I0, R0
ret = odeint(deriv, y0, t, args=(N, beta, gamma, alpha))
S, E, I, R = ret.T

# グラフにプロットする
fig = plt.figure(facecolor='w')
ax = fig.add_subplot(111, facecolor='#dddddd', axisbelow=True)
ax.plot(t, S/1000, 'b', alpha=0.5, lw=2, label='Susceptible')
ax.plot(t, E/1000, 'y', alpha=0.5, lw=2, label='Exposed')
ax.plot(t, I/1000, 'r', alpha=0.5, lw=2, label='Infected')
ax.plot(t, R/1000, 'g', alpha=0.5, lw=2, label='Recovered with immunity')
ax.set_xlabel('Time /days')
ax.set_ylabel('Number (1000s)')
ax.set_ylim(0,12)
ax.yaxis.set_tick_params(length=0)
ax.xaxis.set_tick_params(length=0)
ax.grid(b=True, which='major', c='w', lw=2, ls='-')
legend = ax.legend()
legend.get_frame().set_alpha(0.5)
for spine in ('top', 'right', 'bottom', 'left'):
    ax.spines[spine].set_visible(False)
plt.show()

上記コードでは、微分方程式を解くために、deriv関数を定義してodeint関数を使用して微分方程式を解きます。解から各カテゴリの数をプロットするために、SEIRの値を取得します。感受性者は青色、潜伏者は黄色、感染者は赤色、回復者は緑色で表示されます。上記コードを実行すると、SEIRモデルの感染症伝播の時間変化を表すグラフが表示されます。横軸は時間(単位は日)、縦軸には人口(単位は千人)が表示されます。各カテゴリのプロットを見ることにより、感染の初期段階では感染者数が急激に増加し、その後潜伏者数が増加し、感染者数が減少し、回復者数が増加することがわかります。

ただし、このモデルには、感染症の伝播を正確にモデル化するために必要な多くの要素を考慮していないため、実際の感染症の伝播を正確に再現するには、より複雑なモデルが必要になる場合があります。また、実際の感染症の伝播には、環境要因や人々の行動などの複雑な要因が影響しているため、SEIRモデルで再現することは困難である場合があります。


上記に人の移動を加味したモデルできますか?

はい、人の移動を加味したSEIRモデルも存在します。これは、感染症の伝播をより現実的にモデル化するために使用されます。

人の移動を考慮に入れたSEIRモデルでは、感染者が移動することによって、感染症の伝播が発生することが考慮されます。このモデルでは、地域間の移動を想定して、人口が複数の地域に分割されます。各地域には、感受性者、潜伏者、感染者、回復者の4つのカテゴリがあります。

以下は、人の移動を考慮に入れたSEIRモデルの微分方程式の例です。

dS/dt = -beta * S * I / N + m * (Sj - S)
dE/dt = beta * S * I / N - alpha * E + m * (Ej - E)
dI/dt = alpha * E - gamma * I + m * (Ij - I)
dR/dt = gamma * I + m * (Rj - R)

ここで、S、E、I、Rはそれぞれ感受性、潜伏、感染、回復カテゴリの人口を表します。Nは全人口、mは移動率を表し、Sj、Ej、Ij、Rjは他の地域からの感染者の流入を表します。このモデルでは、各カテゴリの人口が時間とともにどのように変化するかを表す微分方程式が与えられています。

このモデルでは、人口の移動を表す項が微分方程式に追加されます。感染者は他の地域からの感染者の流入によって増加する可能性があるため、移動率は感染症の伝播にとって非常に重要な要因となります。

このように、人の移動を考慮に入れたSEIRモデルを使用することで、感染症の伝播をより現実的にモデル化することができます。

pythonでの提示お願いします。

人の移動を考慮に入れたSEIRモデルをPythonで実装するには、微分方程式を解くためのScipyのodeint関数を使用することができます。以下は、Pythonで実装した例です


import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt

# モデルパラメータ
N = 10000  # 人口総数
beta = 1.2  # 感染率
gamma = 0.2  # 回復率
alpha = 1./5  # 潜伏期間中の感染率
m = 0.1  # 移動率

# 初期値
I0, E0, R0 = 1, 0, 0
S0 = N - I0 - E0 - R0

# 初期値を配列にまとめる
y0 = [S0, E0, I0, R0]

# 人口を複数の地域に分割する
n_regions = 2
populations = np.array([N/n_regions, N/n_regions])

# 移動量を計算する
def calc_move(y, t, N, m, populations):
    S, E, I, R = y
    move_S = m * (populations - S)
    move_E = m * (populations - E)
    move_I = m * (populations - I)
    move_R = m * (populations - R)
    return [move_S[0], move_E[0], move_I[0], move_R[0], move_S[1], move_E[1], move_I[1], move_R[1]]

# SEIRモデルの微分方程式
def deriv(y, t, N, beta, gamma, alpha, m, populations):
    S, E, I, R = y
    dSdt = -beta * S * I / N + calc_move(y, t, N, m, populations)[0] - calc_move(y, t, N, m, populations)[4]
    dEdt = beta * S * I / N - alpha * E + calc_move(y, t, N, m, populations)[1] - calc_move(y, t, N, m, populations)[5]
    dIdt = alpha * E - gamma * I + calc_move(y, t, N, m, populations)[2] - calc_move(y, t, N, m, populations)[6]
    dRdt = gamma * I + calc_move(y, t, N, m, populations)[3] - calc_move(y, t, N, m, populations)[7]
    return dSdt, dEdt, dIdt, dRdt

# グラフ化する時間範囲
t = np.linspace(0, 160, 160)

# 微分方程式を解く
ret = odeint(deriv, y0, t, args=(N, beta, gamma, alpha, m, populations))
S, E, I, R = ret.T

# グラフにプロットする
fig = plt.figure(facecolor='w')
ax = fig.add_subplot(111, facecolor='#dddddd', axisbelow=True)
ax.plot(t, S/n_regions/1000,        'b', alpha=0.5, lw=2, label='Susceptible')
ax.plot(t, E/n_regions/1000, 'y', alpha=0.5, lw=2, label='Exposed')
ax.plot(t, I/n_regions/1000, 'r', alpha=0.5, lw=2, label='Infected')
ax.plot(t, R/n_regions/1000, 'g', alpha=0.5, lw=2, label='Recovered with immunity')
ax.set_xlabel('Time /days')
ax.set_ylabel('Number (1000s)')
ax.set_ylim(0,12)
ax.yaxis.set_tick_params(length=0)
ax.xaxis.set_tick_params(length=0)
ax.grid(b=True, which='major', c='w', lw=2, ls='-')
legend = ax.legend()
legend.get_frame().set_alpha(0.5)
for spine in ('top', 'right', 'bottom', 'left'):
    ax.spines[spine].set_visible(False)
plt.show()

上記コードでは、人の移動を加味したSEIRモデルを実装しています。具体的には、人口を2つの地域に分割して、各地域に感受性、潜伏、感染、回復の4つのカテゴリが存在すると仮定しています。また、移動率をmとして、各地域の人口に対する感染者の流入を計算するための関数を定義しています。

微分方程式の解き方は先程のSEIRモデルの例と同様に、Scipyのodeint関数を使用しています。また、グラフのプロット方法も同様です。

このコードを実行することで、人の移動を考慮に入れたSEIRモデルの感染症伝播の時間変化を表すグラフが表示されます。2つの地域ごとに、各カテゴリの人口が時間とともにどのように変化するかを確認できます。感染者の増加による移動によって、感染症の伝播がどのように変化するかを観察することができます。


でも正しいかどうか・・・

この記事が気に入ったらサポートをしてみませんか?