ARIMA・SARIMAを用いてCOVID-19の感染者数を予測する
はじめに
最近、新型コロナウイルスが世間を騒がせており、研究者が続々論文を発表したり、SIGNATEなどコンペサイトでも感染者数の予測コンペが行われるなど、様々な取り組みが行われています。
ここでは、時系列データ分析手法の一つであるARIMAとSARIMAを用いて日本の感染者数の予測を行いました。
ARIMAとSARIMAについて
ARIMAやSARIMAは複数の時系列データ分析手法を組み合わせたモデルになっています。
モデルの関係について、一般的に以下のような表で表されます。
ARIMA
ARモデル、MAモデル、ARMAモデルはいずれも定常過程を対象とした時系列モデルです。
定常過程に従う時系列データは、一定の周期で同程度の変動をしているデータのことです。
しかし、常に一定のデータは滅多になく、非定常過程のデータであることが多いため、非定常過程の時系列データに対応した手法を用いる必要があります。
ARIMAモデルは非定常過程に対応したモデルの一つです。
ARIMAモデルは前後のデータ間の差分dを定義しており、ARモデルに関する次数p、MAモデルに関連する次数qと合わせてARIMA(p, d, q)と表すことができます。
SARIMA
SARIMAはARIMAモデルに長期的な季節変動を取り入れたモデルになります。 実際の時系列データでは季節に合わせた周期性があるデータも多いため、それらを考慮したモデルとなっています。
予測で用いるデータ
COVID-19の感染者情報が載っているサイトはいくつかありますが、今回は以下のサイトからcsvファイルをインポートして用いました。
読み込んだcsvファイルを加工し、1/15~4/20の日本全体の感染者数を抽出しました。
コレログラムと季節成分分解
元のデータと元のデータから時間をずらしたデータとの相関のことを自己相関といい、これを表したグラフをコレログラムと言います。コレログラムを見ることで、データの周期性を調べることができます。
グラフを見た感じ、ほとんど周期性はなく、時間が経つにつれて相関性が小さくなっていることが分かります。
次に、季節成分分解をします。これにより、トレンド・季節性・残差に分解することができ、データにどのようなトレンド性があるのかなどについて知ることができます。
グラフを見ると、時間の後半にかけてトレンドの数値が大きくなっていることが分かります。
ARIMAでの予測
今回のデータは非定常過程のデータとみられることから、まずARIMA(p, d, q)を構築して予測してみることにしました(本当はデータが定常か非定常かについて検定をする必要がありますが、今回は省略しました、、、もっと勉強しなきゃ、、、)。
上記した通り、ARIMAにはp, d, qの3つのパラメータがあります。このうち、p, qはある程度自動推定してくれる機能があり、以下の通り実行します。
params = sm.tsa.arma_order_select_ic(diff, ic='aic', trend='nc') print(params)
すると、以下のような結果が得られます。このうち、'aic_min_order': (4, 2)
がp, qのパラメータになります。
{'aic': 0 1 2 0 NaN 1055.125479 1054.226782 1 1055.344019 1054.737810 1055.721728 2 1055.676846 1055.374114 1058.681375 3 1056.655811 1056.810369 NaN 4 1057.383730 1057.394580 1027.192160, 'aic_min_order': (4, 2)}
次に、差分dは自分で決めなければいけません。今回は差分回数は1で決め打ちします。差分データは以下の通り計算します。
diff = ts.diff() diff = diff.dropna()
これでp, d, qの3つのパラメータが揃ったので、ARIMAモデルを構築します。tsは時系列データです。
from statsmodels.tsa.arima_model import ARIMA arima_model = ARIMA(ts, order=(4,1,2)).fit(dist=False)
ここで、モデルから推測される値と実測値の差(残差)を表示してみます。後半になるにつれ残差が大きいことが分かります。
次に、構築したARIMAモデルを用いて予測をしてみます。青い線が1/15 ~ 4/20の実際の値、オレンジ色の線が4/20 ~ 5/10の予測値になります。かなり大きくぶれていて、あまり上手く予測できていなさそうなのが分かります。
SARIMAでの予測
SARIMA(p, d, q)(P, D, Q)[s]はARIMAのモデルのパラメータに加え、季節調整のsというパラメータとP, D, Qというパラメータが必要になります。
ここで、今回のデータはコレログラムでは周期性が見られませんでしたが、ドメイン知識として毎週月曜日は検査数が減るため感染者数も減るという事が分かっています。そこで、今回は7日ごと周期性があると仮定して、s=7でモデル構築を行いました。
P, D, Qは本来はグリッドサーチなどで最適な値を求める必要がありますが、今回はいずれも1で決め打ちしました。
sarima_model = sm.tsa.SARIMAX(ts, order=(4,1,2), seasonal_order=(1,1,1,7)).fit()
残差をプロットしてみると以下のようになりました。ARIMAモデルより振り幅が小さいことが分かります。
構築したSARIMAモデルを用いた予測結果は以下の通りです。ARIMAモデルと同じく、青い線が1/15 ~ 4/20の実際の値、オレンジ色の線が4/20 ~ 5/10の予測値になります。ARIMAモデルよりもそれっぽい予測が出来ていることが分かります。
まとめ
時系列データに対してARIMAモデルとSARIMAモデルを用いて予測を行うことで、それっぽい結果を得ることができました。ただ、この結果はあくまで時系列データしか使っていないため、実際は様々な外的要因によって変化していくと思われます。
今回、初めて時系列データのモデル構築に挑戦したので、おかしいところがあればぜひご指摘下さい。
あと、グラフの時間軸が上手くプロットできなかったのが今後の課題です。。。
プログラム
分析で用いたプログラムはGitHubで公開しています。 github.com