statsmodelsでかばん検定 (自己相関の検定)

時系列データを分析をするとき、そのデータが自己相関を持つかどうかはとても重要です。
データが自己相関を持っていたらその構造を記述できるモデルを構築して、予測等に使えるからです。
逆に自己相関を持っていないと、時系列分析でできることはかなり限られます。
過去のデータが将来のデータと関係ないわけですから当然ですね。
(どちらも沖本本の 1.4 自己相関の検定から)

ということで今回行うのは自己相関の検定です。

自己相関が全てゼロという帰無仮説、つまり
$H_0:\rho_1=\rho_2=\cdots=\rho_m=0$を、
$H_1:$少なくとも1つの$k\in[1,m]$において、$\rho_k\neq0$
という対立仮説に対して検定します。

この検定はかばん検定(portmanteau test)と呼ばれているそうです。
検定量は色々考案されているそうですが、 Ljung and Box が考案されたものがメジャーとのこと。

具体的な数式や、numpyでの計算例は次回に譲るとして、とりあえずpythonのライブラリでやってみましょう。
statsmodels に acorr_ljungbox という関数が用意されています。

statsmodels.stats.diagnostic.acorr_ljungbox
(完全に余談ですが、statsmodelsのドキュメントで portmanteau という関数を探していたので、これを見つけるのに結構苦労しました)

あからさまに7点周期を持つデータを準備し、1から10までのmに対して検定を実施したコードがこちらです、
acorr_ljungbox は lb値と、p値をそれぞれのmに対して返します。


import pandas as pd
import numpy as np
from statsmodels.stats.diagnostic import acorr_ljungbox

# 7点ごとに周期性のあるデータを準備
series = pd.Series([1, 1, 1, 1, 1, 1, 5]*10)
# 乱数追加
series += np.random.randn(70)

lbvalues, pvalues = acorr_ljungbox(series, lags=10)
lag = 1
for lb, p in zip(lbvalues, pvalues):
    print(lag, lb, p)
    lag += 1

# 出力
1 4.095089120802025 0.04300796255246615
2 4.223295881654548 0.1210383379718042
3 6.047027807671336 0.10934450247698609
4 6.312955422660912 0.1769638685520115
5 6.457291061922424 0.26422887039323306
6 9.36446186985462 0.15409458108816818
7 40.47102807634717 1.0226763047711032e-06
8 45.2406378234939 3.312995830103468e-07
9 45.24892593869829 8.298135787344997e-07
10 46.35530787049628 1.2365386593885822e-06

lag が7未満の時は、p値が0.05を超えているので、帰無仮説$H_0$を棄却できず、
7以上の時は棄却できていることがわかります。

念の為ですが、lag が 8,9,10の時に棄却できているのは、
どれもデータが7点周期を持っていることが理由であり、
8,9,10点の周期性を持っていること意味するものではありません。