疫情当前,共克时艰。
在新型冠状病毒感染的肺炎疫情牵动社会人心的关键时刻,本文将利用数据分析、数据挖掘、机器学习相关方法,围绕疫情态势展示、疫情走势预测进行分析,挖掘复杂异构多源数据之间的关联关系,以形象生动的方式呈现给大家,为夺取防控疫情的胜利贡献力量!
这里将使用传统时间序列模型Prophet、深度学习模型Seq2seq和传染病模型SIR进行确诊人数预测。
数据来源:https://www.kaggle.com/sudalairajkumar/novel-corona-virus-2019-dataset
该数据集为2019年新型冠状病毒全球感染病例数、死亡人数和恢复情况的信息。请注意,这是一个时间序列数据,因此任何一天的病例数都是累积数。数据从2020年1月22日开始提供,每天都将进行更新。
数据集:
-2019ncovdata.csv
-time_series_2019_ncov_confirmed.csv
-time_series_2019_ncov_deaths.csv
-time_series_2019_ncov_recovered.csv
Sno - 序列号
Date - 观察日期和时间(MM/DD/YYYY HH:MM:SS)
Province / State - 观察的省或州(丢失时可以为空)
Country - 国家
Last Update - 以UTC为单位的时间,在该时间为给定的省或国家更新行。(目前没有标准化。所以请在使用前清洗)
Confirmed - 确诊人数
Deaths - 死亡人数
Recovered - 治愈人数
本文主要使用2019ncovdata.csv数据
1.基本导入
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import scipy.stats as stats
%matplotlib inline
plt.style.use('ggplot')
import plotly.express as px
import plotly.graph_objs as go
from plotly.offline import iplot, init_notebook_mode
import plotly.figure_factory as ff
from plotly import subplots
from plotly.subplots import make_subplots
init_notebook_mode(connected=True)
from datetime import datetime, date, timedelta
from fbprophet import Prophet
import warnings
warnings.filterwarnings('ignore')
pd.set_option('display.max_columns', 100)
pd.set_option('display.max_rows', 100)
2. 数据导入
import os
for dirname, _, filenames in os.walk('/kaggle/input'):
for filename in filenames:
print(os.path.join(dirname, filename))
输出:
/kaggle/input/novel-corona-virus-2019-dataset/2019_nCoV_data.csv
/kaggle/input/novel-corona-virus-2019-dataset/time_series_2019_ncov_deaths.csv
/kaggle/input/novel-corona-virus-2019-dataset/time_series_2019_ncov_confirmed.csv
/kaggle/input/novel-corona-virus-2019-dataset/time_series_2019_ncov_recovered.csv
df = pd.read_csv('/kaggle/input/novel-corona-virus-2019-dataset/2019_nCoV_data.csv')
df.head(5)
3.缺失值处理
可以看到省/州这列存在明显缺失,详细查看一下原因。
df[df['Province/State'].isnull()]
对于一些国家是没有省/州相关信息的,所以为空。
4.已确诊情况可视化
首先是全球情况
fig = px.bar(df, x='Date', y='Confirmed', hover_data=['Province/State', 'Deaths', 'Recovered'], color='Country')
annotations = []
annotations.append(dict(xref='paper', yref='paper', x=0.0, y=1.05,
xanchor='left', yanchor='bottom',
text='Confirmed bar plot for each country',
font=dict(family='Arial',
size=30,
color='rgb(37,37,37)'),
showarrow=False))
fig.update_layout(annotations=annotations)
fig.show()
这里是中国的确诊情况
fig = px.bar(df.loc[dataset['Country'] == 'Mainland China'], x='Date', y='Confirmed', hover_data=['Province/State', 'Deaths', 'Recovered'], color='Province/State')
annotations = []
annotations.append(dict(xref='paper', yref='paper', x=0.0, y=1.05,
xanchor='left', yanchor='bottom',
text='Confirmed bar plot for Mainland China',
font=dict(family='Arial',
size=30,
color='rgb(37,37,37)'),
showarrow=False))
fig.update_layout(annotations=annotations)
fig.show()
中国死亡人数情况
湖北地区死亡人数/治愈人数
数据聚合
confirmed_training_dataset = pd.DataFrame(dataset[dataset.Country=='China'].groupby('Date')['Confirmed'].sum().reset_index()).rename(columns={'Date': 'ds', 'Confirmed': 'y'})
confirmed_training_dataset.head()
日期特征没有等距间隔,这是因为数据是在一天中的某个时间存储的,而不是实时的。此处我们假设为每天真实的确诊数据,以便分析和预测
Facebook 所提供的 prophet 算法不仅可以处理时间序列存在一些异常值的情况,也可以处理部分缺失值的情形,还能够几乎全自动地预测时间序列未来的走势。prophet 所做的事情就是:
输入已知的时间序列的时间戳和相应的值;
输入需要预测的时间序列的长度;
输出未来的时间序列走势。
输出结果可以提供必要的统计指标,包括拟合曲线,上界和下界等。
from fbprophet import Prophet
from fbprophet.diagnostics import cross_validation, performance_metrics
from fbprophet.plot import plot_cross_validation_metric, add_changepoints_to_plot, plot_plotly
我们从建立基本的baseline模型开始,包括每日趋势。( 当然这不一定会有用,因为日期中的时间不是新确认病例登记的真实时间,所以会存在各种干扰因素)。
prophet = Prophet(
yearly_seasonality=False,
weekly_seasonality = False,
daily_seasonality = True,
seasonality_mode = 'additive')
prophet.fit(confirmed_training_dataset)
future = prophet.make_future_dataframe(periods=7)
confirmed_forecast = prophet.predict(future)
对结果进行可视化分析
fig = plot_plotly(prophet, confirmed_forecast)
annotations = []
annotations.append(dict(xref='paper', yref='paper', x=0.0, y=1.05,
xanchor='left', yanchor='bottom',
text='确诊人数预测',
font=dict(family='Arial',
size=30,
color='rgb(37,37,37)'),
showarrow=False))
fig.update_layout(annotations=annotations)
fig
Prophet中有年、周和日季节性参数,现在我们试着去掉每日的季节性重新预测。
prophet = Prophet(
yearly_seasonality=False,
weekly_seasonality = False,
daily_seasonality = False,
seasonality_mode = 'additive')
prophet.fit(confirmed_training_dataset)
future = prophet.make_future_dataframe(periods=7)
confirmed_forecast_2 = prophet.predict(future)
效果变得非常的差,接下来看看这两个模型的平均绝对百分比误差(MAPE)。
def mean_absolute_percentage_error(y_true, y_pred):
y_true, y_pred = np.array(y_true), np.array(y_pred)
return np.mean(np.abs((y_true - y_pred) / y_true)) * 100
max_date = prophet.ds.max()
y_true = prophet.y.values
y_pred_daily = confirmed_forecast.loc[confirmed_forecast['ds'] <= max_date].yhat.values
y_pred_daily_2 = confirmed_forecast_2.loc[confirmed_forecast_2['ds'] <= max_date].yhat.values
print('包含日季节性 MAPE: {}'.format(mean_absolute_percentage_error(y_true,y_pred_daily)))
print('不包含日季节性 MAPE: {}'.format(mean_absolute_percentage_error(y_true,y_pred_daily_2)))
输出:
包含日季节性 MAPE: 39.37057017194978
不包含日季节性 MAPE: 162.6290389271529
很明显这些模型的性能很差,我们可以尝试在两个模型中添加一些参数,看看是否有什么变化,希望有所改进。
在 Prophet 中,般可以设置以下四种参数:
Capacity:在增量函数是逻辑回归函数的时候,需要设置的容量值。
Change Points:可以通过 n_changepoints 和 changepoint_range 来进行等距的变点设置,也可以通过人工设置的方式来指定时间序列的变点。
季节性和节假日:可以根据实际的业务需求来指定相应的节假日。
光滑参数: changepoint_prior_scale 可以用来控制趋势的灵活度, seasonality_prior_scale 用来控制季节项的灵活度, holidays prior scale 用来控制节假日的灵活度。
如果不想设置的话,使用 Prophet 默认的参数即可。
Prophet具体介绍,请参考:https://zhuanlan.zhihu.com/p/52330017
后续文章会对Seq2seq和SIR预测疫情进行详细介绍
参考链接:
https://www.kaggle.com/shubhamai/coronavirus-eda-future-predictions
https://www.kaggle.com/parulpandey/wuhan-coronavirus-a-geographical-analysis
往期精彩回顾
适合初学者入门人工智能的路线及资料下载机器学习在线手册深度学习在线手册AI基础下载(pdf更新到25集)备注:加入本站微信群或者qq群,请回复“加群”获取一折本站知识星球优惠券,请回复“知识星球”喜欢文章,点个在看