Python 3のARIMAを使用した時系列予測のガイド

前書き

時系列は、将来の価値を予測する機会を提供します。 以前の値に基づいて、時系列を使用して、経済学、天気、およびキャパシティプランニングの傾向を予測できます。 時系列データの特定のプロパティは、通常、特殊な統計手法が必要であることを意味します。

このチュートリアルでは、時系列の信頼できる予測を作成することを目指します。 自己相関、定常性、季節性の概念を紹介して議論することから始め、ARIMAとして知られる時系列予測に最も一般的に使用される方法の1つを適用します。

時系列の将来のポイントをモデル化および予測するPythonで利用可能な方法の1つは、* SARIMAX *として知られています。 ここでは、主にARIMAコンポーネントに注目します。これは、時系列データを近似して、時系列の将来のポイントをよりよく理解し、予測するために使用されます。

前提条件

このガイドでは、ローカルデスクトップまたはリモートサーバーで時系列分析を行う方法について説明します。 大きなデータセットの操作はメモリを集中的に使用する可能性があるため、どちらの場合でも、このガイドの計算の一部を実行するには、少なくとも* 2GBのメモリ*が必要になります。

このチュートリアルを最大限に活用するには、時系列と統計に関するある程度の知識が役立ちます。

このチュートリアルでは、* Jupyter Notebook *を使用してデータを操作します。 まだお持ちでない場合は、https://www.digitalocean.com/community/tutorials/how-to-set-up-jupyter-notebook-for-python-3 [インストールとセットアップのチュートリアルに従ってください。 Python 3用Jupyterノートブック]。

ステップ1-パッケージのインストール

時系列予測のために環境を設定するには、まずhttps://www.digitalocean.com/community/tutorial_series/how-to-install-and-set-up-a-local-programming-environment-に移動しましょうfor-python-3 [ローカルプログラミング環境]またはhttps://www.digitalocean.com/community/tutorials/how-to-install-python-3-and-set-up-a-programming-environment-on-an -ubuntu-16-04-server [サーバーベースのプログラミング環境]:

cd
. /bin/activate

ここから、プロジェクト用の新しいディレクトリを作成しましょう。 これを「」と呼び、ディレクトリに移動します。 プロジェクトに別の名前を付ける場合は、ガイド全体で「」の代わりに名前を使用してください

mkdir
cd

このチュートリアルでは、「+ warnings 」、「 itertools 」、「 pandas 」、「 numpy 」、「 matplotlib 」、および「 statsmodels 」ライブラリが必要です。 ` warnings `および ` itertools +`ライブラリは標準のPythonライブラリセットに含まれているため、インストールする必要はありません。

他のPythonパッケージと同様に、これらの要件は + pip +`でインストールできます。 +これで、 `+ pandas ++ statsmodels +、およびデータプロットパッケージ `+ matplotlib +`をインストールできます。 それらの依存関係もインストールされます。

pip install pandas numpy statsmodels matplotlib

この時点で、インストールされたパッケージの使用を開始するように設定されました。

ステップ2-パッケージのインポートとデータのロード

データの操作を開始するには、Jupyter Notebookを起動します。

jupyter notebook

新しいノートブックファイルを作成するには、右上のプルダウンメニューから[新規作成]> [Python 3]を選択します。

image:https://assets.digitalocean.com/articles/eng_python/JupyterNotebookPy3/jupyter-notebook-new.png [新しいPython 3ノートブックを作成]

これにより、ノートブックが開きます。

ベストプラクティスとして、ノートブックの上部に必要なhttps://www.digitalocean.com/community/tutorials/how-to-import-modules-in-python-3 [ライブラリのインポート]から始めます。

import warnings
import itertools
import pandas as pd
import numpy as np
import statsmodels.api as sm
import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight')

また、プロットに対してhttps://tonysyu.github.io/raw_content/matplotlib-style-gallery/gallery.html [+ matplotlib + style]のfivethirtyeightを定義しました。

1958年3月から2001年12月にかけてCO2サンプルを収集した、「ハワイ州マウナロア天文台の連続大気サンプルからの大気CO2」というデータセットを使用します。 このデータを次のように取り込むことができます。

data = sm.datasets.co2.load_pandas()
y = data.data

先に進む前に、データを少し前処理しましょう。 週単位のデータは時間が短いため、取り扱いが難しい場合があります。代わりに月単位の平均を使用してみましょう。 「+ resample 」関数を使用して変換を行います。 簡単にするために、https://www.digitalocean.com/community/tutorials/an-introduction-to-the-pandas-package-and-its-data-structures-in-python-3#handling- missing-values [` fillna()+` function]を使用して、時系列に欠損値がないことを確認します。

# The 'MS' string groups the data in buckets by start of the month
y = y['co2'].resample('MS').mean()

# The term bfill means that we use the value before filling in missing values
y = y.fillna(y.bfill())

print(y)
Outputco2
1958-03-01  316.100000
1958-04-01  317.200000
1958-05-01  317.433333
...
2001-11-01  369.375000
2001-12-01  371.020000

データの視覚化としてこの時系列eを調べてみましょう。

y.plot(figsize=(15, 6))
plt.show()

image:https://assets.digitalocean.com/articles/eng_python/arima/part_2_fig_1.png [図1:CO2レベルの時系列]

データをプロットすると、いくつかの識別可能なパターンが表示されます。 時系列には明らかな季節性パターンがあり、全体的に増加傾向にあります。

時系列の前処理の詳細については、「https://www.digitalocean.com/community/tutorials/a-guide-to-time-series-visualization-with-python-3 [時間ガイド上記のステップがより詳細に説明されています。

データを変換して調査したので、ARIMAを使用した時系列予測に進みましょう。

ステップ3-ARIMA時系列モデル

時系列予測で使用される最も一般的な方法の1つはARIMAモデルと呼ばれ、 A utoreg R essive I integrated M oving A を表します平均。 ARIMAは、時系列の将来のポイントをよりよく理解または予測するために、時系列データに適合できるモデルです。

ARIMAモデルのパラメーター化に使用される3つの異なる整数( + p ++ d ++ q +)があります。 そのため、ARIMAモデルは「+ ARIMA(p、d、q)+」という表記で示されます。 これら3つのパラメーターを合わせて、データセットの季節性、傾向、およびノイズを説明します。

  • `+ p +`はモデルの_auto-regressive_部分です。 これにより、過去の値の効果をモデルに組み込むことができます。 直観的には、これは過去3日間暖かかった場合、明日は暖かくなる可能性が高いと述べることに似ています。

  • `+ d +`はモデルの_統合された部分です。 これには、差分の量を組み込むモデルの用語が含まれます(つまり、 時系列に適用するために、現在の値から減算する過去の時点の数)。 直観的には、これは、過去3日間の気温の差が非常に小さい場合、明日は同じ気温になる可能性が高いと述べることに似ています。

  • `+ q +`はモデルの_移動平均_の部分です。 これにより、過去の過去の時点で観測されたエラー値の線形結合としてモデルのエラーを設定できます。

季節の影響を扱う場合、seasonal ARIMAを使用します。これは、「+ ARIMA(p、d、q)(P、D、Q)s 」と示されています。 ここで、「(p、d、q)」は上記の非季節パラメータであり、「(P、D、Q)」は同じ定義に従いますが、時系列の季節成分に適用されます。 「 s 」という用語は、時系列の周期性です(四半期ごとに「+4」、年ごとに「12」など)。

季節のARIMAメソッドは、複数のチューニングパラメーターが関係しているため、気が遠くなる可能性があります。 次のセクションでは、季節的なARIMA時系列モデルの最適なパラメーターセットを識別するプロセスを自動化する方法について説明します。

ステップ4-ARIMA時系列モデルのパラメーター選択

時系列データを季節ARIMAモデルで近似する場合、最初の目標は、対象のメトリックを最適化する `+ ARIMA(p、d、q)(P、D、Q)s `の値を見つけることです。 この目標を達成するための多くのガイドラインとベストプラクティスがありますが、ARIMAモデルの正しいパラメーター化は、ドメインの専門知識と時間を必要とする骨の折れる手動プロセスになる可能性があります。 ` R `のような他の統計プログラミング言語はhttps://www.rdocumentation.org/packages/forecast/versions/7.3/topics/auto.arima [この問題を解決する自動化された方法]を提供していますが、まだ移植されていませんPythonへ。 このセクションでは、Pythonコードを記述して、 ` ARIMA(p、d、q)(P、D、Q)s +`時系列モデルの最適なパラメーター値をプログラムで選択することにより、この問題を解決します。

「グリッド検索」を使用して、パラメーターのさまざまな組み合わせを繰り返し探索します。 パラメーターの組み合わせごとに、新しい季節ARIMAモデルを `+ statsmodels `モジュールの ` SARIMAX()+`関数で適合させ、その全体的な品質を評価します。 パラメータの全体像を調べた後、最適なパラメータのセットが、関心のある基準に対して最高のパフォーマンスをもたらすものになります。 評価するパラメータのさまざまな組み合わせを生成することから始めましょう。

# Define the p, d and q parameters to take any value between 0 and 2
p = d = q = range(0, 2)

# Generate all different combinations of p, q and q triplets
pdq = list(itertools.product(p, d, q))

# Generate all different combinations of seasonal p, q and q triplets
seasonal_pdq = [(x[0], x[1], x[2], 12) for x in list(itertools.product(p, d, q))]

print('Examples of parameter combinations for Seasonal ARIMA...')
print('SARIMAX: {} x {}'.format(pdq[1], seasonal_pdq[1]))
print('SARIMAX: {} x {}'.format(pdq[1], seasonal_pdq[2]))
print('SARIMAX: {} x {}'.format(pdq[2], seasonal_pdq[3]))
print('SARIMAX: {} x {}'.format(pdq[2], seasonal_pdq[4]))
OutputExamples of parameter combinations for Seasonal ARIMA...
SARIMAX: (0, 0, 1) x (0, 0, 1, 12)
SARIMAX: (0, 0, 1) x (0, 1, 0, 12)
SARIMAX: (0, 1, 0) x (0, 1, 1, 12)
SARIMAX: (0, 1, 0) x (1, 0, 0, 12)

上記で定義したパラメーターのトリプレットを使用して、さまざまな組み合わせでARIMAモデルをトレーニングおよび評価するプロセスを自動化できます。 Statistics and Machine Learningでは、このプロセスはモデル選択のグリッド検索(またはハイパーパラメーター最適化)として知られています。

さまざまなパラメーターに適合した統計モデルを評価および比較する場合、データに適合しているか、または将来のデータポイントを正確に予測する能力に基づいて、それぞれをランク付けできます。 + AIC +(赤池情報量基準)値を使用します。この値は、 `+ statsmodels `を使用して適合したARIMAモデルで便利に返されます。 「 AIC 」は、モデルの全体的な複雑さを考慮しながら、モデルがデータにどの程度適合するかを測定します。 多くの特徴を使用しながらデータに非常によく適合するモデルには、同じ適合度を達成するために少ない特徴を使用するモデルよりも大きなAICスコアが割り当てられます。 したがって、最小の「 AIC +」値を生成するモデルを見つけることに関心があります。

以下のコードチャンクはパラメーターの組み合わせを反復処理し、 `+ statsmodels `の ` SARIMAX `関数を使用して、対応するSeasonal ARIMAモデルに適合させます。 ここで、 ` order `引数は `(p、d、q)`パラメーターを指定し、 ` seasonal_order `引数は季節の `(P、D、Q、S)`季節成分を指定しますARIMAモデル。 各 ` SARIMAX()`モデルを適合させた後、コードはそれぞれの ` AIC +`スコアを出力します。

warnings.filterwarnings("ignore") # specify to ignore warning messages

for param in pdq:
   for param_seasonal in seasonal_pdq:
       try:
           mod = sm.tsa.statespace.SARIMAX(y,
                                           order=param,
                                           seasonal_order=param_seasonal,
                                           enforce_stationarity=False,
                                           enforce_invertibility=False)

           results = mod.fit()

           print('ARIMA{}x{}12 - AIC:{}'.format(param, param_seasonal, results.aic))
       except:
           continue

パラメーターの組み合わせによっては数値の指定ミスを引き起こす可能性があるため、警告メッセージの過負荷を避けるために、警告メッセージを明示的に無効にしました。 これらの誤った仕様もエラーにつながり、例外をスローする可能性があるため、これらの例外をキャッチし、これらの問題を引き起こすパラメーターの組み合わせを無視するようにします。

上記のコードでは次の結果が得られます。これには時間がかかる場合があります。

OutputSARIMAX(0, 0, 0)x(0, 0, 1, 12) - AIC:6787.3436240402125
SARIMAX(0, 0, 0)x(0, 1, 1, 12) - AIC:1596.711172764114
SARIMAX(0, 0, 0)x(1, 0, 0, 12) - AIC:1058.9388921320026
SARIMAX(0, 0, 0)x(1, 0, 1, 12) - AIC:1056.2878315690562
SARIMAX(0, 0, 0)x(1, 1, 0, 12) - AIC:1361.6578978064144
SARIMAX(0, 0, 0)x(1, 1, 1, 12) - AIC:1044.7647912940095
...
...
...
SARIMAX(1, 1, 1)x(1, 0, 0, 12) - AIC:576.8647112294245
SARIMAX(1, 1, 1)x(1, 0, 1, 12) - AIC:327.9049123596742
SARIMAX(1, 1, 1)x(1, 1, 0, 12) - AIC:444.12436865161305
SARIMAX(1, 1, 1)x(1, 1, 1, 12) - AIC:277.7801413828764

コードの出力は、 `+ SARIMAX(1、1、1)x(1、1、1、12)`が277.78の最も低い ` AIC +`値をもたらすことを示唆しています。 したがって、これは検討したすべてのモデルの中で最適なオプションであると考えるべきです。

ステップ5-ARIMA時系列モデルのあてはめ

グリッド検索を使用して、時系列データに最適なモデルを生成する一連のパラメーターを特定しました。 この特定のモデルをさらに詳細に分析することができます。

最適なパラメーター値を新しい「+ SARIMAX +」モデルにプラグインすることから始めます。

mod = sm.tsa.statespace.SARIMAX(y,
                               order=(1, 1, 1),
                               seasonal_order=(1, 1, 1, 12),
                               enforce_stationarity=False,
                               enforce_invertibility=False)

results = mod.fit()

print(results.summary().tables[1])
Output==============================================================================
                coef    std err          z      P>|z|      [0.025      0.975]
------------------------------------------------------------------------------
ar.L1          0.3182      0.092      3.443      0.001       0.137       0.499
ma.L1         -0.6255      0.077     -8.165      0.000      -0.776      -0.475
ar.S.L12       0.0010      0.001      1.732      0.083      -0.000       0.002
ma.S.L12      -0.8769      0.026    -33.811      0.000      -0.928      -0.826
sigma2         0.0972      0.004     22.634      0.000       0.089       0.106
==============================================================================

`+ SARIMAX `の出力から得られる ` summary `属性は大量の情報を返しますが、係数のテーブルに注意を集中します。 「 coef 」列には重みが表示されます(つまり、 重要度)および各機能が時系列に与える影響。 ` P> | z | `列は、各特徴の重みの重要性を示しています。 ここでは、各重みのp値は「+0.05」よりも低いか、それに近いため、モデルにすべての重みを保持するのが妥当です。

季節性ARIMAモデル(およびその他のモデル)をフィッティングする場合、モデル診断を実行して、モデルによって行われた仮定に違反していないことを確認することが重要です。 `+ plot_diagnostics +`オブジェクトを使用すると、モデル診断をすばやく生成し、異常な動作を調査できます。

results.plot_diagnostics(figsize=(15, 12))
plt.show()

image:https://assets.digitalocean.com/articles/eng_python/arima/part_2_fig_2.png [図2:モデル診断]

私たちの主な関心事は、モデルの残差が無相関で、平均ゼロで正規分布することを保証することです。 季節性ARIMAモデルがこれらの特性を満たさない場合、さらに改善できることを示す良い兆候です。

この場合、モデル診断により、モデルの残差は次のことに基づいて正規分布することが示唆されます。

  • 右上のプロットでは、赤い + KDE +`行が `+ N(0,1)+`行( `+ N(0,1)+)と密接に続いていることがわかります。平均値が「0」で標準偏差が「1」の正規分布)。 これは、残差が正規分布していることを示しています。

  • 左下のhttps://en.wikipedia.org/wiki/Q%E2%80%93Q_plot[qq-plot]は、残差(青い点)の順序付けられた分布が、 `+ N(0、1)+`を使用した標準正規分布。 繰り返しますが、これは残差が正規分布していることを強く示しています。

  • 経時的な残差(左上のプロット)は明らかな季節性を示さず、ホワイトノイズのように見えます。 これは自己相関によって確認されます(つまり、 correlogram)は、右下のプロットであり、時系列残差はそれ自体の時間差バージョンとの相関が低いことを示しています。

これらの観察により、モデルは時系列データを理解し、将来の値を予測するのに役立つ満足のいく近似を生成すると結論付けられます。

満足のいく適合がありますが、季節のARIMAモデルのいくつかのパラメーターを変更して、モデルの適合を改善することができます。 たとえば、グリッド検索ではパラメーターの組み合わせの制限されたセットのみが考慮されているため、グリッド検索を広げるとより良いモデルが見つかる場合があります。

ステップ6-予測の検証

時系列のモデルを取得し、これを使用して予測を作成できます。 予測値を時系列の実際の値と比較することから始めます。これは、予測の精度を理解するのに役立ちます。 `+ get_prediction()`および ` conf_int()+`属性により、時系列の予測の値と関連する信頼区間を取得できます。

pred = results.get_prediction(start=pd.to_datetime('1998-01-01'), dynamic=False)
pred_ci = pred.conf_int()

上記のコードでは、1998年1月に予測を開始する必要があります。

`+ dynamic = False +`引数により、1ステップ先の予測が生成されます。つまり、各ポイントでの予測は、そのポイントまでの完全な履歴を使用して生成されます。

CO2時系列の実際の値と予測値をプロットして、どの程度うまくいったかを評価できます。 日付インデックスをスライスすることにより、時系列の終わりにズームインしたことに注目してください。

ax = y['1990':].plot(label='observed')
pred.predicted_mean.plot(ax=ax, label='One-step ahead Forecast', alpha=.7)

ax.fill_between(pred_ci.index,
               pred_ci.iloc[:, 0],
               pred_ci.iloc[:, 1], color='k', alpha=.2)

ax.set_xlabel('Date')
ax.set_ylabel('CO2 Levels')
plt.legend()

plt.show()

image:https://assets.digitalocean.com/articles/eng_python/arima/part_2_fig_3.png [図3:CO2レベルの静的予測]

全体として、予測は真の値と非常によく一致しており、全体的な増加傾向を示しています。

予測の精度を定量化することも役立ちます。 予測の平均誤差を要約するMSE(平均二乗誤差)を使用します。 各予測値について、真の値までの距離を計算し、結果を二乗します。 全体の平均を計算するときに正/負の差が互いに相殺されないように、結果を二乗する必要があります。

y_forecasted = pred.predicted_mean
y_truth = y['1998-01-01':]

# Compute the mean square error
mse = ((y_forecasted - y_truth) ** 2).mean()
print('The Mean Squared Error of our forecasts is {}'.format(round(mse, 2)))
OutputThe Mean Squared Error of our forecasts is 0.07

ワンステップ先の予測のMSEは、「+ 0.07+」の値を生成します。これは、0に近いため非常に低い値です。 MSEが0の場合、推定器はパラメーターの観測値を完全な精度で予測します。これは理想的なシナリオですが、通常は不可能です。

ただし、動的予測を使用すると、真の予測力をより適切に表すことができます。 この場合、特定の時点までの時系列からの情報のみを使用し、その後、以前の予測された時点からの値を使用して予測が生成されます。

以下のコードチャンクでは、1998年1月以降の動的予測と信頼区間の計算を開始するように指定しています。

pred_dynamic = results.get_prediction(start=pd.to_datetime('1998-01-01'), dynamic=True, full_results=True)
pred_dynamic_ci = pred_dynamic.conf_int()

時系列の観測値と予測値をプロットすると、動的予測を使用している場合でも全体的な予測が正確であることがわかります。 すべての予測値(赤線)はグラウンドトゥルース(青線)にほぼ一致しており、予測の信頼区間内に十分収まっています。

ax = y['1990':].plot(label='observed', figsize=(20, 15))
pred_dynamic.predicted_mean.plot(label='Dynamic Forecast', ax=ax)

ax.fill_between(pred_dynamic_ci.index,
               pred_dynamic_ci.iloc[:, 0],
               pred_dynamic_ci.iloc[:, 1], color='k', alpha=.25)

ax.fill_betweenx(ax.get_ylim(), pd.to_datetime('1998-01-01'), y.index[-1],
                alpha=.1, zorder=-1)

ax.set_xlabel('Date')
ax.set_ylabel('CO2 Levels')

plt.legend()
plt.show()

image:https://assets.digitalocean.com/articles/eng_python/arima/part_2_fig_4.png [図4:CO2レベルの動的予測]

ここでも、MSEを計算することにより、予測の予測パフォーマンスを定量化します。

# Extract the predicted and true values of our time series
y_forecasted = pred_dynamic.predicted_mean
y_truth = y['1998-01-01':]

# Compute the mean square error
mse = ((y_forecasted - y_truth) ** 2).mean()
print('The Mean Squared Error of our forecasts is {}'.format(round(mse, 2)))
OutputThe Mean Squared Error of our forecasts is 1.01

動的予測から得られた予測値のMSEは1.01です。 これは、時系列からの履歴データが少ないことに依存していることを考えると、1つ先のステップよりもわずかに高くなります。

一歩先の予測と動的予測の両方により、この時系列モデルが有効であることが確認されます。 ただし、時系列予測に関する関心の多くは、将来の値を前もって予測する機能です。

ステップ7-予測の作成と視覚化

このチュートリアルの最後のステップでは、季節のARIMA時系列モデルを活用して将来の値を予測する方法について説明します。 時系列オブジェクトの `+ get_forecast()+`属性は、指定されたステップ数先の予測値を計算できます。

# Get forecast 500 steps ahead in future
pred_uc = results.get_forecast(steps=500)

# Get confidence intervals of forecasts
pred_ci = pred_uc.conf_int()

このコードの出力を使用して、時系列と将来値の予測をプロットできます。

ax = y.plot(label='observed', figsize=(20, 15))
pred_uc.predicted_mean.plot(ax=ax, label='Forecast')
ax.fill_between(pred_ci.index,
               pred_ci.iloc[:, 0],
               pred_ci.iloc[:, 1], color='k', alpha=.25)
ax.set_xlabel('Date')
ax.set_ylabel('CO2 Levels')

plt.legend()
plt.show()

image:https://assets.digitalocean.com/articles/eng_python/arima/part_2_fig_5.png [図5:時系列と将来価値の予測]

生成した予測と関連する信頼区間の両方を使用して、時系列をさらに理解し、予想される内容を予測できるようになりました。 私たちの予測は、時系列が安定したペースで増加し続けると予想されることを示しています。

将来に向かってさらに予測すると、私たちの価値に自信がなくなるのは自然なことです。 これは、モデルによって生成された信頼区間に反映されます。信頼区間は、将来に進むにつれて大きくなります。

結論

このチュートリアルでは、Pythonで季節限定ARIMAモデルを実装する方法を説明しました。 `+ pandas `および ` statsmodels +`ライブラリを広範に使用し、モデル診断の実行方法と、CO2時系列の予測の作成方法を示しました。

他にも試すことができるものがいくつかあります。

  • 動的予測の開始日を変更して、予測の全体的な品質にどのように影響するかを確認します。

  • パラメーターの組み合わせをさらに試して、モデルの適合度を改善できるかどうかを確認してください。

  • 別のメトリックを選択して、最適なモデルを選択します。 たとえば、 `+ AIC +`メジャーを使用して最適なモデルを見つけましたが、代わりにサンプル外平均二乗誤差を最適化することもできます。

さらに練習するために、別の時系列データセットを読み込んで、独自の予測を作成することもできます。

Related