Mímisbrunnr知恵の泉

← 時系列分析 一覧

🎓 レベル:標準 | 重要度:A(必須)

📎 前提:定常性と自己相関 | 数理:確率過程(マルコフ連鎖・ポアソン過程)(統計)

要点(BLUF)

1. ランダムウォーク=単位根過程

AR(1) xt=ϕxt1+εtx_t=\phi x_{t-1}+\varepsilon_tϕ=1\phi=1 にしたのがランダムウォークです。

xt=xt1+εt=s=1tεs+x0x_t=x_{t-1}+\varepsilon_t=\sum_{s=1}^{t}\varepsilon_s+x_0

前回値にノイズを足すだけ」。係数 ϕ=1\phi=1 は特性方程式の根が1(単位根)であることを意味し、ここが非定常の境目です(ϕ<1|\phi|<1 なら定常、ϕ=1\phi=1 で単位根)。累積和なので分散が

Var[xt]=tσ2\mathrm{Var}[x_t]=t\,\sigma^2

と時間とともに発散し、平均回帰しません。見た目は右肩上がり/下がりの「トレンド」に見えますが、それは偶然のノイズの積み重なりで、方向は毎回変わります。

2. なぜ厄介か

3. 単位根検定(ADF)

ADF(拡張ディッキー–フラー)検定は単位根の有無を調べます。差分の式

Δxt=(ϕ1)xt1+iδiΔxti+εt\Delta x_t=(\phi-1)\,x_{t-1}+\sum_i \delta_i \Delta x_{t-i}+\varepsilon_t

で「ϕ1=0\phi-1=0(=単位根 ϕ=1\phi=1)」を帰無仮説に検定します。帰無仮説=非定常なので、

と読みます(「有意なら定常」で、ふつうの検定と帰無の向きが逆な点に注意)。

4. コード:ADF で判定する

ランダムウォーク・定常 AR(1)・差分後の3つを ADF にかけます。

import numpy as np
from statsmodels.tsa.stattools import adfuller

rng = np.random.default_rng(2)
n = 500
rw = np.cumsum(rng.normal(0, 1, n))                 # 非定常:ランダムウォーク
ar = np.zeros(n)
for t in range(1, n): ar[t] = 0.5*ar[t-1] + rng.normal(0, 1)   # 定常:AR(1)
rw_diff = np.diff(rw)                                # ランダムウォークの1階差分

def report(name, x):
    stat, p = adfuller(x)[:2]
    verdict = "定常(単位根を棄却)" if p < 0.05 else "非定常(単位根を棄却できず)"
    print(f"{name:<22} ADF統計量={stat:>7.3f}  p値={p:.3f}{verdict}")

print("ADF:帰無仮説=単位根あり(非定常)。p<0.05 で定常")
report("ランダムウォーク", rw)
report("AR(1) φ=0.5(定常)", ar)
report("ランダムウォークの差分", rw_diff)

出力:

ADF:帰無仮説=単位根あり(非定常)。p<0.05 で定常
ランダムウォーク               ADF統計量= -0.466  p値=0.898  → 非定常(単位根を棄却できず)
AR(1) φ=0.5(定常)        ADF統計量=-13.392  p値=0.000  → 定常(単位根を棄却)
ランダムウォークの差分            ADF統計量=-22.604  p値=0.000  → 定常(単位根を棄却)

出力の意味:ランダムウォークは p=0.898p=0.898 で非定常と正しく判定(単位根を棄却できない)。定常 AR(1) は p=0.000p=0.000 で定常。そしてランダムウォークを1階差分すると p=0.000p=0.000 で定常に変わります——差分が単位根を取り除いたのです。

5. 差分による定常化(ARIMA の I)

ランダムウォークの差分は Δxt=xtxt1=εt\Delta x_t=x_t-x_{t-1}=\varepsilon_t、つまりホワイトノイズ(定常)。一般に「dd 回差分すれば定常になる」系列を dd 次和分 I(d)I(d) と呼び、これが ARIMA(p,d,qp,d,q) の中央の dd です(ARMA・ARIMAモデル)。

flowchart LR
  NS["非定常系列<br/>(ADF: p≥0.05・ACFが高止まり)"] --> D["1階差分 Δx_t = x_t − x_{t-1}"]
  D --> S["定常系列<br/>(ADF: p<0.05)→ ARMA でモデル化"]

季節性のある非定常なら季節差分 xtxtsx_t-x_{t-s}、分散が時間で増えるなら対数変換、と原因に応じて使い分けます。

⚠️ よくある誤解

関連ノート