├── images
└── 1.png
├── .idea
├── .gitignore
├── vcs.xml
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
└── COVID-19-SEIR-LSTM.iml
├── NCP_cum_pred.png
├── SEIR_basic.png
├── real_data.xlsx
├── NCP_new_predict.png
├── NCP_active_predict.png
├── SEIR_20200123_Intervention.png
├── SEIR_20200202_Intervention.png
├── README.md
├── NCP_cum_pred.py
├── SEIR_basic.py
├── NCP_active_predict.py
├── NCP_new_predict.py
├── SEIR_20200202_Intervention.py
└── SEIR_20200123_Intervention.py
/images/1.png:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | /modules.xml
5 |
--------------------------------------------------------------------------------
/NCP_cum_pred.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndyYue1893/COVID-19-SEIR-LSTM/HEAD/NCP_cum_pred.png
--------------------------------------------------------------------------------
/SEIR_basic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndyYue1893/COVID-19-SEIR-LSTM/HEAD/SEIR_basic.png
--------------------------------------------------------------------------------
/real_data.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndyYue1893/COVID-19-SEIR-LSTM/HEAD/real_data.xlsx
--------------------------------------------------------------------------------
/NCP_new_predict.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndyYue1893/COVID-19-SEIR-LSTM/HEAD/NCP_new_predict.png
--------------------------------------------------------------------------------
/NCP_active_predict.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndyYue1893/COVID-19-SEIR-LSTM/HEAD/NCP_active_predict.png
--------------------------------------------------------------------------------
/SEIR_20200123_Intervention.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndyYue1893/COVID-19-SEIR-LSTM/HEAD/SEIR_20200123_Intervention.png
--------------------------------------------------------------------------------
/SEIR_20200202_Intervention.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndyYue1893/COVID-19-SEIR-LSTM/HEAD/SEIR_20200202_Intervention.png
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/COVID-19-SEIR-LSTM.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # COVID-19-SEIR-LSTM
2 | 本项目实现2019新型冠状病毒肺炎(COVID-19)预测,采用经典传染病动力学模型SEIR,通过控制接触率来改变干预程度,体现防控的意义。
3 |
4 | 另外,采用LSTM神经网络实现一定程度的预测,输入前三天的数据,预测第四天的数据。下一步要增加干预值作为输入,优化输入输出的序列长度,更好地实现预测。
5 |
6 | SEIR and LSTM prediction of the epidemics trend of COVID-19.
7 |
8 | 先上图
9 | 
10 | 
11 | 
12 |
--------------------------------------------------------------------------------
/NCP_cum_pred.py:
--------------------------------------------------------------------------------
1 | import torch
2 | from torch import nn
3 | import numpy as np
4 | import matplotlib.pyplot as plt
5 |
6 | # 数据预处理
7 | import pandas as pd
8 | df = pd.read_excel('real_data.xlsx')
9 | value = df['全国累计确诊'].values[10:67]
10 | print(len(value))
11 | x = []
12 | y = []
13 | seq = 3
14 | for i in range(len(value)-seq-1):
15 | x.append(value[i:i+seq])
16 | y.append(value[i+seq])
17 | #print(x, '\n', y)
18 |
19 | train_x = (torch.tensor(x[0:40]).float()/100000.).reshape(-1, seq, 1)
20 | train_y = (torch.tensor(y[0:40]).float()/100000.).reshape(-1, 1)
21 | test_x = (torch.tensor(x[40:57]).float()/100000.).reshape(-1, seq, 1)
22 | test_y = (torch.tensor(y[40:57]).float()/100000.).reshape(-1, 1)
23 | print(test_y)
24 | # 模型训练
25 | class LSTM(nn.Module):
26 | def __init__(self):
27 | super(LSTM, self).__init__()
28 | self.lstm = nn.LSTM(input_size=1, hidden_size=16, num_layers=1, batch_first=True)
29 | self.linear = nn.Linear(16 * seq, 1)
30 | def forward(self, x):
31 | x, (h, c) = self.lstm(x)
32 | x = x.reshape(-1, 16 * seq)
33 | x = self.linear(x)
34 | return x
35 |
36 | # 模型训练
37 | model = LSTM()
38 | optimzer = torch.optim.Adam(model.parameters(), lr=0.005)
39 | loss_func = nn.MSELoss()
40 | model.train()
41 |
42 | for epoch in range(400):
43 | output = model(train_x)
44 | loss = loss_func(output, train_y)
45 | optimzer.zero_grad()
46 | loss.backward()
47 | optimzer.step()
48 | if epoch % 20 == 0:
49 | tess_loss = loss_func(model(test_x), test_y)
50 | print("epoch:{}, train_loss:{}, test_loss:{}".format(epoch, loss, tess_loss))
51 |
52 | # 模型预测、画图
53 | model.eval()
54 | prediction = list((model(train_x).data.reshape(-1))*100000) + list((model(test_x).data.reshape(-1))*100000)
55 | plt.plot(value[3:], label='True Value')
56 | plt.plot(prediction[:41], label='LSTM fit')
57 | plt.plot(np.arange(40, 53, 1), prediction[40:], label='LSTM pred')
58 | print(len(value[3:]))
59 | print(len(prediction[40:]))
60 | plt.legend(loc='best')
61 | plt.title('Cumulative infections prediction(mainland China)')
62 | plt.xlabel('Day')
63 | plt.ylabel('Cumulative Cases')
64 | plt.show()
65 |
--------------------------------------------------------------------------------
/SEIR_basic.py:
--------------------------------------------------------------------------------
1 | # SEIR传染病模型仿真
2 | "View more, visit my github repository: https://github.com/AndyYue1893/Novel-Coronavirus-Pneumonia-SEIR-LSTM"
3 | '没有解析解,ode求解数值解'
4 | '重点是动力学模型的准确性(SEIR还是SEIRS、SIQR、SIQS模型,以及媒体宣传和随机因素的影响),难点是beta,gamma,sigma/Te的取值'
5 | '模型忽略迁入率和迁出率,死亡率,参数设置参考钟院士等文章http://dx.doi.org/10.21037/jtd.2020.02.64'
6 | ######################################
7 | # N: 区域内总人口 #
8 | # S: 易感者 #
9 | # E: 潜伏者 #
10 | # I: 感染者 #
11 | # R: 康复者 #
12 | # r: 每天接触的人数 #
13 | # r2: 潜伏者每天接触的人数 #
14 | # beta1: 感染者传染给易感者的概率, I——>S #
15 | # beta2: 潜伏者感染易感者的概率, E——>S #
16 | # sigma: 潜伏者转化为感染者的概率, E——>I #
17 | # gama: 康复概率, I——>R #
18 | # T: 传播时间 #
19 | #######################################
20 |
21 | import numpy as np
22 | import matplotlib.pyplot as plt
23 | import scipy.integrate as spi
24 | N = 100000 # 湖北省为6000 0000
25 | E_0 = 0
26 | I_0 = 1
27 | R_0 = 0
28 | S_0 = N - E_0 - I_0 - R_0
29 | beta1 = 0.78735 # 真实数据拟合得出
30 | beta2 = 0.15747
31 | # r2 * beta2 = 2
32 | sigma = 0.1 # 1/14, 潜伏期的倒数
33 | gamma = 0.1 # 1/7, 感染期的倒数
34 | r = 1 # 政府干预措施决定
35 | T = 150
36 |
37 | #ode求解
38 | INI = [S_0, E_0, I_0, R_0]
39 | def SEIR(inivalue, _):
40 | X = inivalue
41 | Y = np.zeros(4)
42 | # S数量
43 | Y[0] = - (r * beta1 * X[0] * X[2]) / N - (r * beta2 * X[0] * X[1]) / N
44 | # E数量
45 | Y[1] = (r * beta1 * X[0] * X[2]) / N + (r * beta2 * X[0] * X[1]) / N - sigma * X[1]
46 | # I数量
47 | Y[2] = sigma * X[1] - gamma * X[2]
48 | # R数量
49 | Y[3] = gamma * X[2]
50 | return Y
51 |
52 | T_range = np.arange(0, T+1)
53 | Res = spi.odeint(SEIR, INI, T_range)
54 | S_t = Res[:, 0]
55 | E_t = Res[:, 1]
56 | I_t = Res[:, 2]
57 | R_t = Res[:, 3]
58 |
59 | plt.plot(S_t, color='blue', label='Susceptibles')#, marker='.')
60 | plt.plot(E_t, color='grey', label='Exposed')
61 | plt.plot(I_t, color='red', label='Infected')
62 | plt.plot(R_t, color='green', label='Removed')
63 | plt.xlabel('Day')
64 | plt.ylabel('Number')
65 | plt.title('SEIR Model')
66 | plt.legend()
67 | plt.show()
--------------------------------------------------------------------------------
/NCP_active_predict.py:
--------------------------------------------------------------------------------
1 | import torch
2 | from torch import nn
3 | import numpy as np
4 | import matplotlib.pyplot as plt
5 |
6 | # 数据预处理
7 | import pandas as pd
8 | df = pd.read_excel('real_data.xlsx') # 这个会直接默认读取到这个Excel的第一个表单
9 | value = df['湖北现有确诊'].values[0:67]
10 | #value = df['全国累计确诊'].values[10:50]
11 | print(len(value))
12 | x = []
13 | y = []
14 | seq = 3
15 | for i in range(len(value)-seq):
16 | x.append(value[i:i+seq])
17 | y.append(value[i+seq])
18 | #print(x, '\n', y)
19 | print(len(x)) # 67
20 |
21 | train_x = (torch.tensor(x[:50]).float()/100000.).reshape(-1, seq, 1)
22 | train_y = (torch.tensor(y[:50]).float()/100000.).reshape(-1, 1)
23 | test_x = (torch.tensor(x[50:]).float()/100000.).reshape(-1, seq, 1)
24 | test_y = (torch.tensor(y[50:]).float()/100000.).reshape(-1, 1)
25 | print(len(train_x))
26 | print(len(test_x))
27 |
28 | # 模型训练
29 | class LSTM(nn.Module):
30 | def __init__(self):
31 | super(LSTM, self).__init__()
32 | self.lstm = nn.LSTM(input_size=1, hidden_size=16, num_layers=1, batch_first=True)
33 | self.linear = nn.Linear(16 * seq, 1)
34 | def forward(self, x):
35 | x, (h, c) = self.lstm(x)
36 | x = x.reshape(-1, 16 * seq)
37 | x = self.linear(x)
38 | return x
39 |
40 | # 模型训练
41 | model = LSTM()
42 | optimzer = torch.optim.Adam(model.parameters(), lr=0.005)
43 | loss_func = nn.MSELoss()
44 | model.train()
45 |
46 | for epoch in range(400):
47 | output = model(train_x)
48 | loss = loss_func(output, train_y)
49 | optimzer.zero_grad()
50 | loss.backward()
51 | optimzer.step()
52 | if epoch % 20 == 0:
53 | tess_loss = loss_func(model(test_x), test_y)
54 | print("epoch:{}, train_loss:{}, test_loss:{}".format(epoch, loss, tess_loss))
55 |
56 | # 模型预测、画图
57 | model.eval()
58 | prediction = list((model(train_x).data.reshape(-1))*100000) + list((model(test_x).data.reshape(-1))*100000)
59 | plt.plot(value[3:], label='True Value')
60 | plt.plot(prediction[:51], label='LSTM fit')
61 | plt.plot(np.arange(50, 64, 1), prediction[50:64], label='LSTM pred')
62 | print(len(value[3:]))
63 | print(len(prediction))
64 | plt.legend(loc='best')
65 | plt.title('Active infections prediction(Hubei province)')
66 | plt.xlabel('Day')
67 | plt.ylabel('Active Cases')
68 | plt.show()
69 |
--------------------------------------------------------------------------------
/NCP_new_predict.py:
--------------------------------------------------------------------------------
1 | # 基于AI数据模型的疫情预测
2 | '考虑到传染病动力学建模的复杂性和参数确定的复杂度,采用LSTM神经网络对湖北省新增病例数预测,并对比体现防控的意义'
3 |
4 | import torch
5 | from torch import nn
6 | import numpy as np
7 | import matplotlib.pyplot as plt
8 | '''
9 | # 数据预处理
10 | with open("data.txt", "r", encoding="utf-8") as f:
11 | data = f.read()
12 | print([data])
13 | data = [row.split(',') for row in data.split("\n")]
14 | value = [int(each[1]) for each in data]
15 | print(data, '\n', value)
16 | # 异常点处理
17 | '''
18 | import pandas as pd
19 | df = pd.read_excel('real_data.xlsx')#这个会直接默认读取到这个Excel的第一个表单
20 | value = df['湖北新增确诊'].values[0:67]
21 | #value = df['全国累计确诊'].values[10:50]
22 | print(len(value))
23 |
24 |
25 | x = []
26 | y = []
27 | seq = 3
28 | for i in range(len(value)-seq-1):
29 | x.append(value[i:i+seq])
30 | y.append(value[i+seq])
31 | #print(x, '\n', y)
32 |
33 | train_x = (torch.tensor(x[:50]).float()/1000.).reshape(-1, seq, 1)
34 | train_y = (torch.tensor(y[:50]).float()/1000.).reshape(-1, 1)
35 | test_x = (torch.tensor(x[50:]).float()/1000.).reshape(-1, seq, 1)
36 | test_y = (torch.tensor(y[50:]).float()/1000.).reshape(-1, 1)
37 | #print(train_x, '\n', train_y)
38 | # 模型训练
39 | class LSTM(nn.Module):
40 | def __init__(self):
41 | super(LSTM, self).__init__()
42 | self.lstm = nn.LSTM(input_size=1, hidden_size=16, num_layers=1, batch_first=True)
43 | self.linear = nn.Linear(16 * seq, 1)
44 | def forward(self, x):
45 | x, (h, c) = self.lstm(x)
46 | x = x.reshape(-1, 16 * seq)
47 | x = self.linear(x)
48 | return x
49 |
50 | # 模型训练
51 | model = LSTM()
52 | optimzer = torch.optim.Adam(model.parameters(), lr=0.005)
53 | loss_func = nn.MSELoss()
54 | model.train()
55 | l = []
56 | for epoch in range(600):
57 | output = model(train_x)
58 | loss = loss_func(output, train_y)
59 | l.append(loss)
60 | optimzer.zero_grad()
61 | loss.backward()
62 | optimzer.step()
63 | if epoch % 20 == 0:
64 | tess_loss = loss_func(model(test_x), test_y)
65 | print("epoch:{}, train_loss:{}, test_loss:{}".format(epoch, loss, tess_loss))
66 |
67 | # 模型预测、画图
68 | model.eval()
69 | prediction = list((model(train_x).data.reshape(-1))*1000) + list((model(test_x).data.reshape(-1))*1000)
70 | print(len(value[3:]), len(prediction), len(np.arange(50, 64, 1)), len(prediction[50:64]))
71 | #print('train_x', train_x*1000, '\n', 'train_y', train_y*1000, '\n', 'test_x', test_x*1000, '\n', 'test_y', len(test_y), test_y*1000)
72 | plt.figure(1)
73 | plt.plot(value[3:], label='True Value')
74 | plt.plot(prediction[:51], label='LSTM fit')
75 | plt.plot(np.arange(50, 63, 1), prediction[50:64], label='LSTM pred')
76 | plt.legend(loc='best')
77 | plt.title('New daily infections prediction(Hubei province)')
78 | plt.xlabel('Day')
79 | plt.ylabel('New Confirmed Cases')
80 | #plt.figure(2)
81 | #plt.plot(l)
82 | plt.show()
--------------------------------------------------------------------------------
/SEIR_20200202_Intervention.py:
--------------------------------------------------------------------------------
1 | # SEIR传染病模型仿真
2 | "View more, visit my github repository: https://github.com/AndyYue1893/Novel-Coronavirus-Pneumonia-SEIR-LSTM"
3 | '没有解析解,ode求解数值解'
4 | '重点是动力学模型的准确性(SEIR还是SEIRS、SIQR、SIQS模型,以及媒体宣传和随机因素的影响),难点是beta,gamma,sigma/Te的取值'
5 | '模型忽略迁入率和迁出率,潜伏者传染率beta2,参数设置参考钟院士等文章http://dx.doi.org/10.21037/jtd.2020.02.64'
6 | ######################################
7 | # N: 区域内总人口 #
8 | # S: 易感者 #
9 | # E: 潜伏者 #
10 | # I: 感染者 #
11 | # R: 康复者 #
12 | # r: 每天接触的人数 #
13 | # r2: 潜伏者每天接触的人数 #
14 | # beta1: 感染者传染给易感者的概率, I——>S #
15 | # beta2: 潜伏者感染易感者的概率, E——>S #
16 | # sigma: 潜伏者转化为感染者的概率, E——>I #
17 | # gama: 康复概率, I——>R #
18 | # T: 传播时间 #
19 | #######################################
20 |
21 | import numpy as np
22 | import matplotlib.pyplot as plt
23 | import scipy.integrate as spi
24 |
25 | # 阶段一,11.24 - 1.23 1.11
26 | N = 60000000 # 湖北省为6000万,武汉900万
27 | E_0 = 0
28 | I_0 = 1
29 | R_0 = 0
30 | S_0 = N - E_0 - I_0 - R_0
31 | b1 = 0.02 # 真实数据拟合得出
32 | b2 = 0.021/3#0.007
33 | # r2 * beta2 = 2
34 | sigma = 1/14 # 1/14, 潜伏期的倒数
35 | gamma = 1/7 # 1/7, 感染期的倒数
36 | r = 18 # 政府干预措施决定
37 | T = 84
38 |
39 | #ode求解
40 | INI = [S_0, E_0, I_0, R_0]
41 | def SEIR(inivalue, _):
42 | X = inivalue
43 | Y = np.zeros(4)
44 | # S数量
45 | Y[0] = - (r * b1 * X[0] * X[2]) / N - (r * b2 * X[0] * X[1]) / N
46 | # E数量
47 | Y[1] = (r * b1 * X[0] * X[2]) / N + (r * b2 * X[0] * X[1]) / N - sigma * X[1]
48 | # I数量
49 | Y[2] = sigma * X[1] - gamma * X[2]
50 | # R数量
51 | Y[3] = gamma * X[2]
52 | return Y
53 |
54 | T_range = np.arange(0, T+1)
55 | Res = spi.odeint(SEIR, INI, T_range)
56 | S_t = Res[:, 0]
57 | E_t = Res[:, 1]
58 | I_t = Res[:, 2]
59 | R_t = Res[:, 3]
60 | #print(I_t[60], type(I_t)) # 549
61 | #print(E_t[57])
62 |
63 |
64 | # 阶段二,1.23后
65 | S_2 = S_t[T]
66 | E_2 = E_t[T]
67 | I_2 = I_t[T]
68 | R_2 = R_t[T]
69 |
70 | beta1 = 0.02#0.15747 # 真实数据拟合得出
71 | beta2 = 0.021/3#0.78735
72 | # r2 * beta2 = 2
73 | sigma2 = 1/4 # 1/14, 潜伏期的倒数
74 | #gamma = 1/6.736 # 1/7, 感染期的倒数
75 | r2 = 0.1 # 政府干预措施决定
76 | T2 = 150-T
77 |
78 | #ode求解
79 | INI = [S_2, E_2, I_2, R_2]
80 | def SEIR(inivalue, _):
81 | X = inivalue
82 | Y = np.zeros(4)
83 | # S数量
84 | Y[0] = - (r2 * beta1 * X[0] * X[2]) / N - (r2 * beta2 * X[0] * X[1]) / N
85 | # E数量
86 | Y[1] = (r2 * beta1 * X[0] * X[2]) / N + (r2 * beta2 * X[0] * X[1]) / N - sigma2 * X[1]
87 | # I数量
88 | Y[2] = sigma2 * X[1] - gamma * X[2]
89 | # R数量
90 | Y[3] = gamma * X[2]
91 | return Y
92 |
93 | T_range = np.arange(0, T2+1)
94 | Res = spi.odeint(SEIR, INI, T_range)
95 | S_t2 = Res[:, 0]
96 | E_t2 = Res[:, 1]
97 | I_t2 = Res[:, 2]
98 | R_t2 = Res[:, 3]
99 |
100 | plt.figure(figsize=(10, 6))
101 | #显示日期
102 | import pandas as pd
103 | xs = pd.date_range(start='20191124', periods=T+1, freq='1D')#生成2020-02-11类型的日期数组()
104 | #print(xs)
105 | xs2 = pd.date_range(start='20200216', periods=T2+1, freq='1D')
106 |
107 | #plt.plot(S_t, color='blue', label='Susceptibles')#, marker='.')
108 | plt.plot(xs, E_t, color='grey', label='Exposed', marker='.')
109 | plt.plot(xs2, E_t2, color='grey', label='Exposed Prediction')
110 | plt.plot(xs, I_t, color='red', label='Infected', marker='.')
111 | plt.plot(xs2, I_t2, color='red', label='Infected Prediction')
112 | plt.plot(xs, I_t + R_t, color='green', label='Infected + Removed', marker='.')
113 | plt.plot(xs2, I_t2 + R_t2, color='green', label='Cumulative Infections Prediction')
114 | #plt.plot(np.arange(0, T+1, 1), I_t + R_t, color='green', label='Removed')
115 | #plt.plot(np.arange(T, T+T2+1, 1), I_t2 + R_t2, color='green', label='Infected2')
116 | #plt.xlabel('Date')
117 | plt.ylabel('Number')
118 | plt.title('SEIR Prediction(Hubei province, 10 days later intervention)')
119 | plt.legend()
120 |
121 | xs3 = pd.date_range(start='20200202', periods=1, freq='1D')
122 | #plt.plot(xs3, np.arange(1000, 2000, 1000))
123 | plt.annotate(r'$2.2-Intervention$', xy=(xs3, 200), xycoords='data', xytext=(-44, -60), textcoords='offset points',
124 | fontsize=10, arrowprops=dict(arrowstyle='->', connectionstyle='arc3, rad=0'))
125 | #print(I_t2)
126 | xs4 = pd.date_range(start='20200220', periods=1, freq='1D')
127 | plt.annotate(r'$2.20-Peak$', xy=(xs4, 103911), xycoords='data', xytext=(-25, -130), textcoords='offset points',
128 | fontsize=10, arrowprops=dict(arrowstyle='->', connectionstyle='arc3, rad=0'))
129 | #print(R_t2)
130 | xs5 = pd.date_range(start='20200420', periods=1, freq='1D')
131 | plt.annotate(r'4.20-Epidemic-Scale:261963', xy=(xs5, 261963), xycoords='data', xytext=(-70, -60), textcoords='offset points',
132 | fontsize=10, arrowprops=dict(arrowstyle='->', connectionstyle='arc3, rad=0'))
133 | #plt.text(30, 10, r'$This\ is\ the\ some\ text.\ \mu_j\ \sigma_i\ \alpha_t$')
134 | plt.show()
--------------------------------------------------------------------------------
/SEIR_20200123_Intervention.py:
--------------------------------------------------------------------------------
1 | # SEIR传染病模型仿真
2 | "View more, visit my github repository: https://github.com/AndyYue1893/Novel-Coronavirus-Pneumonia-SEIR-LSTM"
3 | '没有解析解,ode求解数值解'
4 | '重点是动力学模型的准确性(SEIR还是SEIRS、SIQR、SIQS模型,以及媒体宣传和随机因素的影响),难点是beta,gamma,sigma/Te的取值'
5 | '模型忽略迁入率和迁出率,死亡率,参数设置参考钟院士等文章http://dx.doi.org/10.21037/jtd.2020.02.64'
6 | ######################################
7 | # N: 区域内总人口 #
8 | # S: 易感者 #
9 | # E: 潜伏者 #
10 | # I: 感染者 #
11 | # R: 康复者 #
12 | # r: 每天接触的人数 #
13 | # r2: 潜伏者每天接触的人数 #
14 | # beta1: 感染者传染给易感者的概率, I——>S #
15 | # beta2: 潜伏者感染易感者的概率, E——>S #
16 | # sigma: 潜伏者转化为感染者的概率, E——>I #
17 | # gama: 康复概率, I——>R #
18 | # T: 传播时间 #
19 | #######################################
20 |
21 | import numpy as np
22 | import matplotlib.pyplot as plt
23 | import scipy.integrate as spi
24 | import pytest # test git commit, 20240427
25 |
26 | # 阶段一,11.24 - 1.23 1.11
27 | N = 60000000 # 湖北省为6000万,武汉900万
28 | E_0 = 0
29 | I_0 = 1
30 | R_0 = 0
31 | S_0 = N - E_0 - I_0 - R_0
32 | beta1 = 0.02 # 真实数据拟合得出
33 | beta2 = 0.021/3 #0.007
34 | # r2 * beta2 = 2
35 | sigma = 1/14 # 1/14, 潜伏期的倒数
36 | gamma = 1/7 # 1/7, 感染期的倒数
37 | r = 18 # 政府干预措施决定
38 | T = 74
39 |
40 | #ode求解
41 | INI = [S_0, E_0, I_0, R_0]
42 | def SEIR(inivalue, _):
43 | X = inivalue
44 | Y = np.zeros(4)
45 | # S数量
46 | Y[0] = - (r * beta1 * X[0] * X[2]) / N - (r * beta2 * X[0] * X[1]) / N
47 | # E数量
48 | Y[1] = (r * beta1 * X[0] * X[2]) / N + (r * beta2 * X[0] * X[1]) / N - sigma * X[1]
49 | # I数量
50 | Y[2] = sigma * X[1] - gamma * X[2]
51 | # R数量
52 | Y[3] = gamma * X[2]
53 | return Y
54 |
55 | T_range = np.arange(0, T+1)
56 | Res = spi.odeint(SEIR, INI, T_range)
57 | S_t = Res[:, 0]
58 | E_t = Res[:, 1]
59 | I_t = Res[:, 2]
60 | R_t = Res[:, 3]
61 |
62 |
63 | # 阶段二,1.23后
64 | S_2 = S_t[T]
65 | E_2 = E_t[T]
66 | I_2 = I_t[T]
67 | R_2 = R_t[T]
68 |
69 | beta1 = 0.02#0.15747 # 真实数据拟合得出
70 | beta2 = 0.021/3 # 0.78735
71 | # r2 * beta2 = 2
72 | sigma2 = 1/4 # 1/14, 潜伏期的倒数
73 | #gamma = 1/6.736 # 1/7, 感染期的倒数
74 | r2 = 0.1 # 政府干预措施决定
75 | T2 = 150-T
76 |
77 | #ode求解
78 | INI = [S_2, E_2, I_2, R_2]
79 | def SEIR(inivalue, _):
80 | X = inivalue
81 | Y = np.zeros(4)
82 | # S数量
83 | Y[0] = - (r2 * beta1 * X[0] * X[2]) / N - (r2 * beta2 * X[0] * X[1]) / N
84 | # E数量
85 | Y[1] = (r2 * beta1 * X[0] * X[2]) / N + (r2 * beta2 * X[0] * X[1]) / N - sigma2 * X[1]
86 | # I数量
87 | Y[2] = sigma2 * X[1] - gamma * X[2]
88 | # R数量
89 | Y[3] = gamma * X[2]
90 | return Y
91 |
92 | T_range = np.arange(0, T2+1)
93 | Res = spi.odeint(SEIR, INI, T_range)
94 | S_t2 = Res[:, 0]
95 | E_t2 = Res[:, 1]
96 | I_t2 = Res[:, 2]
97 | R_t2 = Res[:, 3]
98 |
99 | #显示日期
100 | plt.figure(figsize=(10, 6))
101 | import pandas as pd
102 | xs = pd.date_range(start='20191124', periods=T+1, freq='1D') # 生成2020-02-11类型的日期数组()
103 | #print(xs)
104 | xs2 = pd.date_range(start='20200206', periods=T2+1, freq='1D')
105 |
106 | #plt.plot(S_t, color='blue', label='Susceptibles')#, marker='.')
107 | plt.plot(xs, E_t, color='grey', label='Exposed', marker='.')
108 | plt.plot(xs2, E_t2, color='grey', label='Exposed Prediction')
109 | plt.plot(xs, I_t, color='red', label='Infected', marker='.')
110 | plt.plot(xs2, I_t2, color='red', label='Infected Prediction')
111 | plt.plot(xs, I_t + R_t, color='green', label='Infected + Removed', marker='.')
112 | plt.plot(xs2, I_t2 + R_t2, color='green', label='Cumulative Infections Prediction')
113 | #plt.plot(np.arange(0, T+1, 1), I_t + R_t, color='green', label='Removed')
114 | #plt.plot(np.arange(T, T+T2+1, 1), I_t2 + R_t2, color='green', label='Infected2')
115 | #plt.xlabel('Date')
116 | plt.ylabel('Number')
117 | plt.title('SEIR Prediction(Hubei Province, 1.23 Intervention)')
118 | plt.legend()
119 |
120 | xs3 = pd.date_range(start='20200123', periods=1, freq='1D')
121 | #plt.plot(xs3, np.arange(1000, 2000, 1000))
122 | plt.annotate(r'$1.23-Intervention$', xy=(xs3, -3000), xycoords='data', xytext=(-47, -30), textcoords='offset points',
123 | fontsize=10, arrowprops=dict(arrowstyle='->', connectionstyle='arc3, rad=0'))
124 |
125 | xs4 = pd.date_range(start='20200210', periods=1, freq='1D')
126 | plt.annotate(r'$2.10-Peak$', xy=(xs4, 24700), xycoords='data', xytext=(-25, -130), textcoords='offset points',
127 | fontsize=10, arrowprops=dict(arrowstyle='->', connectionstyle='arc3, rad=0'))
128 |
129 | xs5 = pd.date_range(start='20200401', periods=1, freq='1D')
130 | plt.annotate(r'$4.1-Epidemic-Scale:62188$', xy=(xs5, 62188), xycoords='data', xytext=(-75, -60), textcoords='offset points',
131 | fontsize=10, arrowprops=dict(arrowstyle='->', connectionstyle='arc3, rad=0'))
132 |
133 | xs6 = pd.date_range(start='20200123', periods=1, freq='1D')
134 | plt.annotate(r'$1.23-Exposed:5257$', xy=(xs6, 5257), xycoords='data', xytext=(-180, -3), textcoords='offset points',
135 | fontsize=10, arrowprops=dict(arrowstyle='->', connectionstyle='arc3, rad=0'))
136 |
137 | xs7 = pd.date_range(start='20191124', periods=1, freq='1D')
138 | plt.annotate(r'$2019.11.24-0-Case$', xy=(xs7, -3000), xycoords='data', xytext=(-56, -30), textcoords='offset points',
139 | fontsize=10, arrowprops=dict(arrowstyle='->', connectionstyle='arc3, rad=0'))
140 |
141 | xs8 = pd.date_range(start='20200206', periods=1, freq='1D')
142 | plt.annotate(r'$14days-Delay$', xy=(xs8, 41000), xycoords='data', xytext=(-130, -3), textcoords='offset points',
143 | fontsize=10, arrowprops=dict(arrowstyle='<->', connectionstyle='arc3, rad=0'))
144 | #plt.text(30, 10, r'$This\ is\ the\ some\ text.\ \mu_j\ \sigma_i\ \alpha_t$')
145 | plt.show()
146 |
147 |
148 | # 写数据到excel
149 | import xlsxwriter
150 | workbook = xlsxwriter.Workbook('result_data.xlsx') #创建一个Excel文件
151 | worksheet = workbook.add_worksheet()
152 | for i in range(1, 151):
153 | #print(i)
154 | num = str(i)
155 | row = 'A' + num
156 | if i < 75:
157 | data = [S_t[i], E_t[i], I_t[i], R_t[i], I_t[i]+R_t[i]]
158 | else:
159 | data = [S_t2[i - 75], E_t2[i - 75], I_t2[i - 75], R_t2[i - 75], I_t2[i-75]+R_t2[i-75]]
160 | worksheet.write_row(row, data)
161 | i += 1
162 |
163 | workbook.close()
164 |
--------------------------------------------------------------------------------