本文首先介绍了Logistic模型的原理,然后尝试用Logistic曲线拟合疫情,虽然疫情已经接近尾声,模型的预测意义并不大,但仍然可以通过回溯过去发现有趣的现象。

目录

1. Logistic模型

  • 1.1 马尔萨斯人口模型
  • 1.2 Logistic增长模型

2. 用Logistic模型拟合疫情

  • 2.1 湖北省
  • 2.2 湖北省外

3. Python实现

参考文献

1. Logistic模型

逻辑斯蒂方程(Logistic function)由比利时数学家兼生物学家皮埃尔·弗朗索瓦·韦吕勒(Pierre Francois Verhulst)在研究人口增长模型时提出,是对马尔萨斯人口模型(Malthus, 1798)的改进。下图可以直观看出两者的区别,下面将对两种模型作详细介绍。

1.1 马尔萨斯人口模型

马尔萨斯人口模型假定人口增长率

保持不变

其中

表示人口数,是时间
的函数。

求解微分方程可以得到人口随时间变化的函数,

其中

表示第0期人口。

不难发现,人口呈现指数增长,即J型曲线。然而现实中受到自然资源约束以及疾病等因素影响,人口增长率不可能一直保持不变。

1.2 Logistic增长模型

皮埃尔在马尔萨斯人口模型的基础上进行了改进,将人口增长率设为

,其中
可以理解为环境最大允许的最大人口数量。此时,当人口
越接近于
时,增长率越低,即人口增长率随人口数量的增加而线性减少。

求解微分方程可以得到人口随时间变化的函数,

其中

表示第0期人口。

如下左图,该曲线描述的人口增长呈现S型,增长速率随时间先增后减,在

处增长最快。注意到,增长速率(
)表示人口当期变化的绝对数值,而增长率(
)表示人口变化量与当期人口的比值。

相比于马尔萨斯人口模型,Logistic增长模型更加符合实际,该模型常常被应用于描述种群、传染病增长以及商品销售量预测等领域。

2. 用Logistic模型拟合疫情

考虑到湖北省内与湖北省外存在异质性,下面将用Logistic模型分别对湖北省与湖北省外的累计确诊人数进行拟合。首先需要获取累计确诊人数,数据来源为WindQuant提供的Wind数据接口,更多数据下载方法见

PurePlayer:获取COVID-19疫情历史数据的n种方法​zhuanlan.zhihu.com

然后使用Scipy.optimezi库的curve_fit函数对Logistic曲线进行非线性最小二乘拟合。待定参数包括

三个,根据最小化MSE准则,采用网格调参的方式寻找最优参数:对最大容量
以步长1遍历(10000, 80000)区间,对增长率
以步长0.01遍历(0, 1)区间。

2.1 湖北省

湖北省疫情拟合结果:最大容量

为67667,增长率
为0.24。

疫情的拐点发生在2月8日前后,这也是疫情增长最快一段时期,在这段时间内,由于疫情的快速增长和医疗资源的相对匮乏,官方公布的确诊人数失真严重。从拟合结果来看,当前疫情已经到达尾声。

2.2 湖北省外

省外疫情拟合结果:最大容量

为12857,增长率
为0.26。疫情的拐点发生在2月3日前后,当前疫情也已经到达尾声。

3. Python实现

下面直接给出Python代码,注意第17行需要将userid修改为自己的WindQuant用户ID,当然也可以对代码略作修改后读取本地数据或者其他数据源。微信搜索公众号PurePlay,后台回复Logistic,即可获取完整的数据、代码以及结果文件。

import numpy as np
import pandas as pd
import datetime as dt
import time
import requests
import json
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
mpl.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
from scipy.optimize import curve_fit
from sklearn.metrics import mean_squared_errordef load_data():# 下载原始数据,数据来源为WindQuant提供的Wind数据接口# "Nation","Hubei","Outside",分别表示全国、省内和省外的累计确诊人数userid = "94ac606a-c220-46af-abf3" # 此处仅为无效id,需要改为自己的WindQuant用户IDindicators = "S6274770,S6275447,S6291523"factors_name = ["Nation","Hubei","Outside"]startdate = "2020-01-16"enddate = dt.datetime.strftime(dt.date.today() + dt.timedelta(-1),"%Y-%m-%d")# 数据的结束日期设置为昨天url = '''https://www.windquant.com/qntcloud/data/edb?userid={}&indicators={}&startdate={}&enddate={}'''.format(userid,indicators,startdate,enddate)response = requests.get(url)data = json.loads(response.content.decode("utf-8"))try:time_list = data["times"]value_list = data["data"]for i in range(len(time_list)):time_list[i] = time.strftime("%Y-%m-%d", time.localtime(time_list[i]/1000))result = pd.DataFrame(columns=factors_name, index = time_list)for i in range(len(factors_name)):result[factors_name[i]] = value_list[i]print(result)result.to_csv(r"DataLogisticData.csv")return resultexcept Exception as e:print("服务异常")def data_abstract(result,area):# result:下载的原始数据# area:“Hubei”或“Outside”,分别返回省内和省外的累计确诊人数y_data = result[area]# 删除缺失值并转换为float型y_data[y_data == 'NaN'] = np.NANy_data = y_data.dropna()y_data = y_data.astype(float)global first_date # 后续数据可视化需要first_date = dt.datetime.strptime(y_data.index[0],'%Y-%m-%d')# 返回与数据集等长的从0开始的时间序列作为logistic函数的自变量x_data = np.asarray(range(0,len(y_data)))  return x_data, y_datahyperparameters_r = None
hyperparameters_K = None
def logistic_increase_function(t,P0):# logistic生长函数:t:time   P0:initial_value    K:capacity  r:increase_rate# 后面将对r和K进行网格优化r = hyperparameters_rK = hyperparameters_Kexp_value = np.exp(r * (t))return (K * exp_value * P0) / (K + (exp_value - 1) * P0)def fitting(logistic_increase_function, x_data, y_data):# 传入要拟合的logistic函数以及数据集# 返回拟合结果popt = Nonemse = float("inf")i = 0# 网格搜索来优化r和K参数r = Nonek = Nonek_range = np.arange(10000, 80000, 1000)r_range = np.arange(0, 1, 0.01)for k_ in k_range:global hyperparameters_Khyperparameters_K = k_for r_ in r_range:global hyperparameters_rhyperparameters_r = r_# 用非线性最小二乘法拟合popt_, pcov_ = curve_fit(logistic_increase_function, x_data, y_data, maxfev = 4000)# 采用均方误准则选择最优参数mse_ = mean_squared_error(y_data, logistic_increase_function(x_data, *popt_))if mse_ <= mse:mse = mse_popt = popt_r = r_k = k_i = i+1print('r当前进度:{0}{1}%'.format('▉'*int(i*10/len(k_range)/len(r_range)),int(i*100/len(k_range)/len(r_range))), end='')print('拟合完成')hyperparameters_K = khyperparameters_r = rpopt, pcov = curve_fit(logistic_increase_function, x_data, y_data)print("K:capacity  P0:initial_value   r:increase_rate")print(hyperparameters_K, popt, hyperparameters_r)return hyperparameters_K, hyperparameters_r, poptdef predict(logistic_increase_function, popt):# 根据最优参数进行预测future = np.linspace(0, 60, 60)future = np.array(future)future_predict = logistic_increase_function(future, popt)diff = np.diff(future_predict)diff = np.insert(diff, 0, np.nan)return future, future_predict, diffdef visualize(area, future, future_predict, x_data, y_data, diff):# 绘图x_show_data_all = [(first_date + (dt.timedelta(days=i))).strftime("%m-%d") for i in future]x_show_data = x_show_data_all[:len(x_data)]plt.figure(figsize=(12, 6), dpi=300)plt.scatter(x_show_data, y_data, s=35, marker='.', c = "dimgray", label="确诊人数")plt.plot(x_show_data_all, future_predict, 'r', linewidth=1.5, label='预测曲线')plt.plot(x_show_data_all, diff, "r", c='darkorange',linewidth=1.5, label='一阶差分')plt.tick_params(labelsize=10)plt.xticks(x_show_data_all)plt.grid()  # 显示网格plt.legend()  # 指定legend的位置右下角ax = plt.gca()for label in ax.xaxis.get_ticklabels():label.set_rotation(45)if area == "Hubei":plt.ylabel('湖北省累计确诊人数')plt.savefig(r"DataHubei.png",dpi=300)else:plt.ylabel('湖北省外累计确诊人数')plt.savefig(r"DataOutside.png",dpi=300)plt.show()if __name__ == '__main__':# 载入数据result = load_data()for area in ["Outside", "Hubei"]:# 从原始数据中提取对应数据x_data, y_data = data_abstract(result, area)# 拟合并通过网格调参寻找最优参数K, r, popt = fitting(logistic_increase_function, x_data, y_data)# 模型预测future, future_predict, diff= predict(logistic_increase_function, popt)# 绘制图像visualize(area, future, future_predict, x_data, y_data, diff)

参考文献

[1] Verhulst, P. E., Corresp. Math. Phys., 10, 113, 1838.

[2] 马尔萨斯.人口原理[M].北京:商务印书馆,1992.6.

[2] 宋波, 玄玉仁, 卢凤勇, et al. 浅评逻辑斯蒂方程[J]. 生态学杂志, 1986(03):59-64.

[3] 徐荣辉. 逻辑斯蒂方程及其应用[J]. 山西财经大学学报,2010,32(S2):311-312.

相关文章

PurePlayer:获取COVID-19疫情历史数据的n种方法​zhuanlan.zhihu.com

PurePlayer:假如把COVID-19疫情作为股票因子…​zhuanlan.zhihu.com

PurePlayer:AHP | 层次分析法原理及Python实现​zhuanlan.zhihu.com

以上是本篇的全部内容,欢迎关注我的知乎|简书|CSDN|微信公众号PurePlay, 会不定期分享研究与学习干货。

python实现排队论模型_Logistic模型拟合COVID-19疫情以及Python实现相关推荐

  1. 用python对人口模型数据拟合_万字案例 | 用Python建立客户流失预测模型(含源数据+代码)...

    1.采集数据 本数据集来自DF ,数据源地址: https://www.datafountain.cn/dataSets/35/details# 本数据集描述了电信用户是否流失以及其相关信息,共包含7 ...

  2. python线性加权模型_局部加权之线性回归(1) - Python实现

    1 #局部加权线性回归 2 #交叉验证计算泛化误差最小点 3 4 5 importnumpy6 from matplotlib importpyplot as plt7 8 9 #待拟合不含噪声之目标 ...

  3. python实现var模型_copula函数及其Var计算的Python实现

    Copula函数思想 Copula函数能够把随机变量之间的相关关系与变量的边际分布分开进行研究,这种思想方法在多元统计分析中非常重要.直观来看,可以将任意维的联合分布H(x1,...,xn)=P(X1 ...

  4. 【Python】django模型models的外键关联使用

    [Python]django模型models的外键关联使用 Python 2.7.10,django 1.8.6 外键关联:http://www.bubuko.com/infodetail-61830 ...

  5. android studio调用python_Android Studio调用python运行thensorflow模型--CLE方案实现

    Android Studio调用python运行thensorflow模型--CLE方案实现 Android Studio调用python运行thensorflow模型--CLE方案实现 我使用的是虚 ...

  6. 经济数据预测 | Python实现ARIMA模型股票趋势预测

    经济数据预测 | Python实现ARIMA模型股票趋势预测 目录 经济数据预测 | Python实现ARIMA模型股票趋势预测 基本介绍 数据描述 程序设计 参考资料 基本介绍 随着人们生活水平的提 ...

  7. python拟合离散数据_Logit模型拟合实战案例(Python)——离散选择模型之六

    前言:本文详细介绍如何在Python中拟合Logit模型,包括数据准备.哑变量的处理.参数拟合结果解读等内容. 本文为系列离散选择模型(Discrete Choice Model, DCM)系列文章的 ...

  8. stata中心化处理_带有stata第2部分自定义配色方案的covid 19可视化

    stata中心化处理 This guide will cover an important, yet, under-explored part of Stata: the use of custom ...

  9. Python信贷风控模型:Adaboost,XGBoost,SGD, SVC,随机森林, KNN预测信贷违约支付

    全文链接:http://tecdat.cn/?p=26184 在此数据集中,我们必须预测信贷的违约支付,并找出哪些变量是违约支付的最强预测因子?以及不同人口统计学变量的类别,拖欠还款的概率如何变化?( ...

最新文章

  1. excel函数大全_让你的EXCEL工作效率翻倍的函数大全
  2. python实现字符串切割
  3. HDU 1253-大逃亡(裸-DBFS)
  4. Apache HttpClient库的日志级别设置原理
  5. 网络交换机3大常见故障问题
  6. 20145335郝昊《网络攻防》Exp4 Adobe阅读器漏洞攻击
  7. 只有低价才是中国智能硬件的出路吗?
  8. C语言链表详解(通俗易懂,超详细)
  9. u检验中的查u界值表_u检验、t检验、F检验、X2检验
  10. DaZeng:雪碧图(精灵图)的使用
  11. 惠普电脑u盘重装系统步骤_惠普电脑如何重装系统?惠普电脑用U盘重装win10系统教程...
  12. HBuilder X 无法启动微信开发者工具问题解决方法
  13. Word给公式插入编号和引用
  14. 什么时候,董明珠能成功卖给记者一部格力手机?
  15. 【c++篇】STL常见容器Stackqueue
  16. fairyGUI的学习记录2
  17. 数据仓库中的数据粒度
  18. 数据分析之《我不是药神》
  19. [MachineLearning] 机器学习速成笔记 - Bilibili
  20. Python全栈开发【基础二】

热门文章

  1. java能字典_适用于Java的任何字典定义API?
  2. linux配置iscsi无账号密码,linux配置ISCSI服务器的方法
  3. 自组四旋翼2015.9
  4. SPH(光滑粒子流体动力学)流体模拟实现七:屏幕空间流体渲染(SSF)
  5. iso安装器_U盘安装优麒麟20.04系统,Ubuntu通用
  6. 如何把测试库的统计信息导入到生产库
  7. 洛谷P3803 【模板】多项式乘法(FFT)
  8. 在Linux中实现多网卡绑定
  9. [C# 基础知识系列]专题十五:全面解析扩展方法
  10. samba文件共享服务详解