抗擊肺炎:新冠肺炎疫情數據可視化及疫情預測分析
- 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