预测疫情新增确诊数,我是这么做的

简介: 预测疫情新增确诊数,我是这么做的

平常我的工作和机器学习相关,我看到数据的第一反应就是构建模型来预测,于是我今天花了几个小时做了下这个工作。


下面是两周的全国层面的疫情数据,我们能不能,基于这 14 条数据,预测一下明天的新增确诊人数呢?做到技术与时事的结合。

6.jpg

其中各个字段名称含义如下:


  • new:每天新增确诊人数,昨天新增为 2829

  • all:当前总共确诊人数

  • watch:当前医学观察人数

先说结论吧:


预测明天公布的新增确诊人数为 2997 人,有浮动哈,具体浮动多少我也不敢说,怕脸疼


分析


说说我是怎么分析的吧,所有确诊人数和新增确诊人数我们看一个就行了,这里我选的是每日新增确诊人数,来看看每日新增确诊人数的折线图(目的是观察相等时间间隔下数据的趋势)

7.jpg

可以看到一个随时间稳步攀升的趋势,这是我们期望预测的指标,也就是我们的因变量。

接下来看看因变量,也就是我们的当前医学观察人数:

8.jpg

再给这两个变量画个图:

plt.figure()
plt.plot(df["watch"], df["new"])
plt.show()

9.jpg

可以去掉 27 号的数据:

clean_df = df.drop(df.index[7])
plt.figure()
plt.plot(clean_df["watch"], clean_df["new"])
plt.show()
# 绘图并计算相关程度 高达0.9935173395339865
clean_df.watch.corr(clean_df.new)

10.jpg

这里我们知道的是当天的医学观察数和当天的新增确诊数有较强的线性关系,现在有一个问题是我们并不能通过当天的医学观察数来预测当天新增确诊数,因为医学观察数要到预测的那天才知道。


我是这样解决:


  • 观察今日的医学观察数和明日的新增确诊数有什么关系,这样我们只要知道今日的医学观察数就可以进行预测

  • 先构建当日的医学观察数和当日的新增确诊数模型,再构建一个模型基于历史的医学观察数预测后面一天的医学观察数,这样就得到了最新的医学观察数,同样可以根据此时的医学观察数预测对应的新增确诊数

先看第一个方案,数据重新排列一下,如下:

11.jpg

绘制当前数据的图像:

plt.figure()
plt.plot(new_df["watch"], new_df["new"])
plt.show()

12.jpg

目测线性关系没有很强,算一下看看:

# 0.9840477846537675 还可以 没上面的好
new_df.watch.corr(new_df.new)
# 对数据进行对数化
log_df = np.log(new_df)
# 0.9931578091568266
log_df.watch.corr(log_df.new)

不错,可以看到这个方案可行,此方案实现就可以直接预测出今日医学观察数对应的明日新增确诊数。


再看第二个方案,我们已经有了当日医学观察数和当日新增确诊数的模型,现在缺的是当日医学观察数,我们可以根据时间序列的ARIMA模型来根据历史数据预测当日医学观察数。

from statsmodels.tsa.stattools import adfuller as ADF
# 并不平稳 p值太大,不平稳
ADF(df["watch"])
# 对数化 平稳了
log_watch_df = np.log(clean_watch_df)
ADF(np.log(df["watch"])), ADF(log_watch_df)

就这样,我们确定了预测方案:


  • 第一个方案:输入今日医学观察数,得出明日新增确诊数

  • 第二个方案:通过时间序列模型预测命题医学观察数,再输入明日医学观察数,输出新增确诊数

开干吧!开始构建模型。


模型


首先构建两个线性回归模型:


  • 输入今日医学观察数,预测明日新增确诊数

  • 输入明日医学观察数,输出明日新增确诊数
from sklearn.linear_model import LinearRegression
# 第一个线性回归模型
X_train = clean_df["watch"].values.reshape(-1,1)
y_train = clean_df["new"].to_list()
lin_reg01 = LinearRegression()
lin_reg01.fit(X_train, y_train)
# 第二个线性回归模型 new_df指的是上述重新排列后的数据集
X_log_train = np.log(new_df["watch"].values.reshape(-1,1))
y_log_train = np.log(new_df["new"].to_list())
lin_reg02 = LinearRegression()
lin_reg02.fit(X_log_train, y_log_train)

其中第二个模型可以直接进行预测了:

# 0202的医学观察数为152700,输入
res = lin_reg02.predict(np.log([[152700]]))[0]
# 得出结果为2931
print(np.exp(res))

这里可以看到我们已经得出第一个结果了2931,我还是想试试第二个方案的结果,2931可以作为一个参考,后面可以将两个结果平均一下。


第二个方案,线性回归模型我们已经构建好了,接下来弄个时间序列模型来预测后面一天的医学观察数。

from statsmodels.tsa.arima_model import ARIMA
order = sm.tsa.arma_order_select_ic(log_watch_df, max_ar=7, max_ma=7, ic=['aic', 'bic', 'hqic'])
# 给出最优p q值
p, q =order.bic_min_order
train_X = log_watch_df[:]
arima_model = ARIMA(train_X, (p, 0, q)).fit()
# 预测未来两天数据
# 2020-02-03    11.974123
# 2020-02-04    11.945058
predict_data_02 = arima_model.predict(start=len(train_X), end=len(train_X) + 1, dynamic = False)
# 预测历史数据
# 2020-01-28    10.853324
# 2020-01-29    10.997501
# 2020-01-30    11.591271
# 2020-01-31    11.714462
# 2020-02-01    11.775772
# 2020-02-02    11.920444
predict_data = arima_model.predict(dynamic = False)

看看预测值和实际值:

comp = pd.DataFrame()
comp['original'] = train_X[:]
comp['predict'] = predict_data[:]
comp.plot(figsize=(12,6))

13.jpg

此时我们已经知道2020-02-03 11.974123是模型预测的明天的值,我们转换一下再将前面的误差综合一下,2020-02-03的预测医学观察数是:163739,根据第一个模型,输入明日医学观察数,得出明日新增确诊人数:

lin_reg01.predict([[163739]])
# 输出
array([3063.42234138])

目前可以得出以下结果:


  • 对于第一个方案,预测2020-02-03新增确诊人数是:3063

  • 对于第二个方案:预测2020-02-03新增确诊人数是:2931


我来取个中间值吧:2997


于是,我预测2020-02-03新增确诊人数是:2997,此结论仅仅作为参考,也肯定会在一定范围内波动,不要当真哈。

相关文章
|
2月前
|
存储 测试技术 定位技术
需要统计出轨迹点出入某个区域的信息,包括:驶入时间、驶出时间
Lindorm Ganos 通过内置的 `ST_TrajectoryProfile` 算子高效统计轨迹的出入信息,利用时空索引技术减少扫描量和内存使用,降低计算成本。它通过空间索引+过滤下推减少扫描量,聚合加速提升效率,并在聚合算子内部完成进出点判断和轨迹信息提取。然而,该算子受限于时间阈值设定,可能在轨迹点不均匀采集时产生误差。测试环境下,查询耗时在20秒内,具体表现取决于过滤后的数据量和空间范围复杂度。
14 0
|
6月前
|
SQL 分布式计算 关系型数据库
Spark 分析计算连续三周登录的用户数
本文介绍了如何使用窗口函数`range between`来查询`login_time`为2022-03-10的用户最近连续三周的登录数。首先在MySQL中创建`log_data`表并插入数据,接着定义需求为找出该日期前连续三周活跃的用户数。通过Spark SQL,分步骤实现:1)确定统计周期,2)筛选符合条件的数据,3)计算用户连续登录状态。在初始实现中出现错误,因未考虑日期在周中的位置,修正后正确计算出活跃用户数。
105 6
|
6月前
|
数据可视化 数据库
R语言人口期望寿命统计预测方法
R语言人口期望寿命统计预测方法
淘宝批量复制宝贝提示“当前类目大于48小时发货的发货时间不能大于15天,请调整”怎么解决?
要复制这个宝贝上传到淘宝店铺,只需要重新复制一次,然后在大淘营淘宝宝贝复制专家下载配置的第二步,选择一个小于或等于15天的发货时间(见下图),这样就可以复制宝贝上传到淘宝店铺了。
|
SQL 数据可视化 数据挖掘
如何在5分钟之内完成一个物联网统计指标?
本文介绍如何使用物联网平台的指标管理功能实现快速完成数据统计指标的开发。
如何在5分钟之内完成一个物联网统计指标?
如何对生产线上的物品进行检测并统计?
如何对生产线上的物品进行检测并统计?
157 0
如何对生产线上的物品进行检测并统计?
|
编解码
Google Earth Engine——臭氧总量绘图分光仪(TOMS)数据集代表了过去25年中可用于监测全球和区域臭氧总量趋势的主要长期、连续的卫星观测记录
Google Earth Engine——臭氧总量绘图分光仪(TOMS)数据集代表了过去25年中可用于监测全球和区域臭氧总量趋势的主要长期、连续的卫星观测记录
530 0
Google Earth Engine——臭氧总量绘图分光仪(TOMS)数据集代表了过去25年中可用于监测全球和区域臭氧总量趋势的主要长期、连续的卫星观测记录
|
编解码
Google Earth Engine——GRACE Tellus月度质量网格提供了相对于2004-2010年时间平均基线的月度引力异常值。该数据集所包含的数据是以 “等水厚度 “为单位,以厘米为单位
Google Earth Engine——GRACE Tellus月度质量网格提供了相对于2004-2010年时间平均基线的月度引力异常值。该数据集所包含的数据是以 “等水厚度 “为单位,以厘米为单位
156 0
Google Earth Engine——GRACE Tellus月度质量网格提供了相对于2004-2010年时间平均基线的月度引力异常值。该数据集所包含的数据是以 “等水厚度 “为单位,以厘米为单位
|
消息中间件 存储 算法
Gear2021 年月度更新——12 月
12 月达到的另一重要里程碑主要是对 Gear 平台的技术改进。
93 0
Gear2021 年月度更新——12 月
|
机器学习/深度学习 安全 算法
最新R0值3.11,疫情何时高峰难预测,这是你该知道的最新进展
也许对抗新型冠状病毒还需要更长的时间和更多的努力,但我们终将胜利。近日,在国内外多个团队的传播预测研究中,代表疫情传染速率及峰值等因素的 R0 值,也正在发生着变化。
168 0
最新R0值3.11,疫情何时高峰难预测,这是你该知道的最新进展