中国疫情发展趋势预测
笔者使用的增长模型预测中国疫情发展趋势,使用了3种增长模型进行了预测,这里只贴出利用逻辑斯蒂增长模型的代码。
logistic增长的曲线也称为s型曲线。下图左图为曲线数量,右图为增长速率。
逻辑斯蒂增长模型,又叫阻滞增长模型,
逻辑斯蒂曲线通常分为5个时期:
- 开始期,由于种群个体数很少,密度增长缓慢,又称潜伏期。
- 加速期,随个体数增加,密度增长加快。
- 转折期,当个体数达到饱和密度一半(K/2),密度增长最快。
- 减速期,个体数超过密度一半(K/2)后,增长变慢。
- 饱和期,种群个体数达到K值而饱和。
根据历史经验,2003年非典患者预测,部分学者利用逻辑斯蒂增长模型进行预测,并且准确率很高,所以我们也尝试利用逻辑斯蒂增长模型进行新型冠状病毒患者数量,逻辑斯蒂增长模型具体为:$y=\frac{k}{1+\mathrm{e}^{-a(x-b)}}$
其中k表示新型冠状病毒患者的上限值;a反映了增长速度;b表示拐点,即从b点开始上升速度变慢,在b点时上升速度达到最高。
好了逻辑斯蒂增长模型的基本知识就介绍这么多,现在让我们开始来点干货。
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
import warnings
# from scipy.optimize import curve_fit # 非线性最小二乘法拟合
from scipy.optimize import leastsq
warnings.filterwarnings('ignore')
plt.style.use("seaborn")
plt.rc('font', family='SimHei', size=13) # 显示中文
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
# 先读取数据
China_data = pd.read_csv(r"./total.csv", encoding='gbk')
China_data
然后我们先来绘制中国疫情累计确诊患者数量走势图,我们主要的任务是预测,所有就不贴出交互的图,贴个简单的走势图即可
plt.plot(China_data['累计确诊'], label='确诊')
plt.plot(China_data['现存疑似'], label='现存疑似')
plt.plot(China_data['累计死亡'], label='死亡')
plt.plot(China_data['累计治愈'], label='治愈')
plt.legend(loc="best")
plt.xlabel("时间")
plt.title("2019-nCoV疫情曲线")
根据之前预测非典患者数量的经验,我们也考虑使用增长模型来预测
# 逻辑斯蒂增长模型
def logistic_increase_function(p, t):
K, a, b = p
exp_value = np.exp(-a * (t - b))
return K / (1 + exp_value)
# 定义预测误差函数
def err_f(p, t, y):
return logistic_increase_function(p, t) - y
# 参数初始值
logistic_p0 = [80000, 0.8, 20] # 初始值只要不是太离谱,最终都会收敛
# 我们选择的数据
t = np.array([i + 1 for i in range(56)])
China_y = China_data['累计确诊'].values
# 利用最小二乘法求解参数
logistic_params = leastsq(err_f, logistic_p0, args=(t, China_y))
China_p = logistic_params[0]
# 利用我们定义的逻辑斯蒂增长函数预测
China_predict_data = logistic_increase_function(China_p, t)
China_predict_data
# 预测的误差
China_e = China_y - China_predict_data
China_e
# 绘制误差的散点图
plt.scatter(China_y, China_e)
对于误差大的样本点,可以删除,然后重新拟合参数,这里我们就不删除了
# 绘图
plt.scatter(t, China_y, label="实际确诊患者数量")
plt.plot(t, China_predict_data, label='预测患者数量曲线')
plt.xlabel('time')
plt.ylabel('患者数量')
plt.legend(loc='best')
# 预测中国疫情未来走势
future_t = [i + 1 for i in range(0, 100)]
China_future_fit = logistic_increase_function(China_p, future_t)
China_future_fit
# 绘图
plt.scatter(t, China_y, label="实际确诊患者数量")
plt.plot(future_t, China_future_fit, label="预测未来患者数量")
plt.xlabel('time')
plt.ylabel('患者数量')
plt.legend(loc='best')
模型预测的结果是中国新冠肺炎最终的患者数量是80717人左右,拐点出现在第30天,即2月7日左右,疫情将在第80天,即3月29日左右结束。
感兴趣的朋友,可以利用这个模型预测韩国、日本、意大利、伊朗等国家的疫情发展趋势,另外笔者还利用Gompertz增长模型也进行了预测,这里就不贴出来了,感兴趣的朋友,可以自己实现一下。
这里仅贴出Gompertz模型的函数
# Gompertz增长模型
def func(p, t):
k, a, b = p
return k * a**(b**t)