抗击肺炎:新冠肺炎疫情数据可视化及疫情预测分析
- 2020 年 2 月 19 日
- 筆記
写在前面
疫情当前,共克时艰。
在新型冠状病毒感染的肺炎疫情牵动社会人心的关键时刻,本文将利用数据分析、数据挖掘、机器学习相关方法,围绕疫情态势展示、疫情走势预测进行分析,挖掘复杂异构多源数据之间的关联关系,以形象生动的方式呈现给大家,为夺取防控疫情的胜利贡献力量!
这里将使用传统时间序列模型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()

模型预测 – Prophet
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)

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