時系列予測の基礎:ARIMAモデルの理論とPython実装

AR、MA、ARIMAモデルの数学的定義からパラメータ選択(ACF/PACF)、statsmodelsによる実装、季節性を扱うSARIMAまでを解説します。

はじめに

時系列データの予測は、需要予測、株価分析、気象予報など幅広い分野で必要とされます。**ARIMA(AutoRegressive Integrated Moving Average)**モデルは、時系列予測の古典的かつ強力な手法です。

本記事では、ARIMAの構成要素であるAR・MA・差分の数理を解説し、statsmodelsによるPython実装を紹介します。

AR(自己回帰)モデル

AR(\(p\))モデルは、過去 \(p\) 時点の値を用いて現在の値を表現します。

\[X_t = c + \sum_{i=1}^{p} \phi_i X_{t-i} + \varepsilon_t \tag{1}\]

ここで \(\phi_i\) は自己回帰係数、\(\varepsilon_t \sim \mathcal{N}(0, \sigma^2)\) はホワイトノイズです。

定常性条件: 特性方程式 \(1 - \phi_1 z - \cdots - \phi_p z^p = 0\) の根がすべて単位円の外側にある必要があります。

MA(移動平均)モデル

MA(\(q\))モデルは、過去 \(q\) 時点のノイズの線形結合で表現します。

\[X_t = \mu + \varepsilon_t + \sum_{j=1}^{q} \theta_j \varepsilon_{t-j} \tag{2}\]

MA モデルは常に定常です。

ARMA モデル

AR と MA を組み合わせた ARMA(\(p, q\)) モデルです。

\[X_t = c + \sum_{i=1}^{p} \phi_i X_{t-i} + \varepsilon_t + \sum_{j=1}^{q} \theta_j \varepsilon_{t-j} \tag{3}\]

ARIMA モデル

非定常な時系列に対して、\(d\) 回の差分をとって定常化した後に ARMA モデルを適用するのが ARIMA(\(p, d, q\)) です。

\[\Delta^d X_t = c + \sum_{i=1}^{p} \phi_i \Delta^d X_{t-i} + \varepsilon_t + \sum_{j=1}^{q} \theta_j \varepsilon_{t-j} \tag{4}\]

ここで \(\Delta X_t = X_t - X_{t-1}\) は1次差分です。

  • \(p\): 自己回帰の次数
  • \(d\): 差分の回数(通常0, 1, 2)
  • \(q\): 移動平均の次数

パラメータの選択

ACF(自己相関関数)と PACF(偏自己相関関数)

パターンACFPACFモデル
AR(\(p\))徐々に減衰ラグ \(p\) で急に0PACF でpを決定
MA(\(q\))ラグ \(q\) で急に0徐々に減衰ACF でqを決定
ARMA(\(p,q\))徐々に減衰徐々に減衰AIC/BIC で選択

情報量規準

AIC(赤池情報量規準)やBICを使って、複数の \((p, d, q)\) の組み合わせから最適なモデルを選択します。

\[\text{AIC} = -2\ln(L) + 2k \tag{5}\]

ここで \(L\) は最大尤度、\(k\) はパラメータ数です。

Python実装

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.stattools import adfuller
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

# --- データ生成(AR(2)プロセス + トレンド) ---
np.random.seed(42)
n = 300
noise = np.random.normal(0, 1, n)
data = np.zeros(n)
for t in range(2, n):
    data[t] = 0.5 * data[t-1] - 0.3 * data[t-2] + noise[t]
data += np.linspace(0, 10, n)  # トレンドを追加

ts = pd.Series(data, index=pd.date_range('2024-01-01', periods=n, freq='D'))

# --- 定常性の検定(ADF検定) ---
result = adfuller(ts)
print(f"ADF統計量: {result[0]:.4f}, p値: {result[1]:.4f}")

# 差分をとって定常化
ts_diff = ts.diff().dropna()
result_diff = adfuller(ts_diff)
print(f"1次差分後 - ADF統計量: {result_diff[0]:.4f}, p値: {result_diff[1]:.4f}")

# --- ACF/PACFのプロット ---
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
plot_acf(ts_diff, ax=axes[0], lags=20, title='ACF (1st Difference)')
plot_pacf(ts_diff, ax=axes[1], lags=20, title='PACF (1st Difference)')
plt.tight_layout()
plt.show()

# --- ARIMAモデルのフィッティング ---
train = ts[:250]
test = ts[250:]

model = ARIMA(train, order=(2, 1, 0))  # AR(2), d=1, MA(0)
fitted = model.fit()
print(fitted.summary())

# --- 予測 ---
forecast = fitted.forecast(steps=len(test))

# --- 可視化 ---
plt.figure(figsize=(12, 5))
plt.plot(train.index, train, label='Train')
plt.plot(test.index, test, label='Test')
plt.plot(test.index, forecast, 'r--', label='Forecast')
plt.xlabel('Date')
plt.ylabel('Value')
plt.title('ARIMA(2,1,0) Forecast')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

SARIMA(季節性ARIMA)

季節性を持つデータには SARIMA(\(p, d, q\))(\(P, D, Q\))\(_s\) を使います。

\[\Phi_P(B^s) \phi_p(B) \Delta^d \Delta_s^D X_t = \Theta_Q(B^s) \theta_q(B) \varepsilon_t \tag{6}\]

ここで \(s\) は季節周期(月次データなら12)、\(B\) は後退オペレータ(\(B X_t = X_{t-1}\))です。

from statsmodels.tsa.statespace.sarimax import SARIMAX

# 季節周期s=12のSARIMAモデル
model = SARIMAX(train, order=(1, 1, 1), seasonal_order=(1, 1, 1, 12))
fitted = model.fit(disp=False)

モデル選択の自動化

pmdarimaauto_arima で最適なパラメータを自動探索できます。

import pmdarima as pm

auto_model = pm.auto_arima(train, seasonal=False,
                           stepwise=True, suppress_warnings=True)
print(auto_model.summary())

関連記事

参考文献

  • Box, G. E. P., Jenkins, G. M., Reinsel, G. C., & Ljung, G. M. (2015). Time Series Analysis: Forecasting and Control (5th ed.). Wiley.
  • Hyndman, R. J., & Athanasopoulos, G. (2021). Forecasting: Principles and Practice (3rd ed.).
  • statsmodels ARIMA documentation