【SCM分析4】需要データの階差数列が定常過程になることをADF検定する
物流データの基礎となる需要データは、ある一定期間における需要数を時系列に並べたものです。
このようなデータを時系列データといいます。
時系列データは定常性を仮定して分析するのが普通です。
では定常性とは何でしょうか?
定常性はどうやって検定できるのでしょうか?
また定常性が成り立たない場合はどうしたらいいのでしょうか?
ある需要データを例にとり、Pythonで実際に試してみました。
定常過程とは?
時系列データにおける定常性とは、時間によらず期待値と自己共分散が一定であることです。
自己共分散とはk個前のデータとどのくらい似ているかを表し、自己相関に似ています。
自己相関については前の記事【SCM分析3】Pythonで出荷データから周期変動と長期トレンドを分離するにも出てきました。
横軸がk、縦軸がそれに対応する相関係数を表すコレログラムで可視化することができます。
ある需要データについてのコレログラムは次のようでした。
この需要データは1週間の周期があるため、常に7個前のデータとほぼ一定の相関があります。
時間によらず自己相関(または自己共分散)が一定とは、このようにk個前のデータとの相関係数が常に一定ということです。
これで定常性の1つの条件、「時間によらず自己共分散が一定」という条件が満たされました。
もう1つの条件である「時間によらず期待値が一定」はどうでしょうか?
これも前回作ったグラフを見ればわかります。
このグラフは元の需要データ(原系列)を長期トレンドと周期変動と残差に分解したものです。
長期トレンドを見ると、時間によって期待値が明らかに変化していることがわかります。
従って、この需要データは定常性を満たす定常過程ではなく、非定常過程である可能性が高いことがわかります。
単位根過程とは?
昔、数学の授業で階差数列というのを習った記憶はないでしょうか?
数字が並んだ数列において、隣の数字との差を並べた数列のことです。
先程の需要データの階差数列を取るとどうなるでしょうか?
Pythonならdiff()を使って次のようにコーディングできます。(データフレームdata_dfに元の需要データ、つまり原系列が入っています)
# 階差数列
data_df_diff1 = data_df.diff(1).dropna()
plt.plot(data_df_diff1)
ちなみに原系列のグラフはこうです。
長期トレンドが取り除かれていることがわかります。
ということは、時間によらず期待値が一定ということで、定常過程になっている可能性が高いでしょう。
このように原系列は非定常過程だけれども、階差数列が定常過程になるような時系列データを単位根過程といいます。
つまり、単位根過程は非定常過程の一種です。
PythonでADF検定
ADF検定(Augmented Dickey-Fuller test)で、時系列データが単位根過程になっているかを調べることができます。
これは帰無仮説を単位根過程、 対立仮説を定常過程とした検定です。
ADF検定の難しい原理は後回しにして、実際にこの需要データをPythonで検定してみましょう。
statsmodelsライブラリーの中のadfullerを使うことで簡単に検定できます。
ADF検定では「単位根過程(非定常過程)である」が帰無仮説になります。
そしてこの帰無仮説が棄却されることにより定常過程であることがいえます。
原系列
from statsmodels.tsa.stattools import adfuller
# ADF検定(原系列)
adf_test0 = adfuller(data_df.S00239)
adf_test0
---
(-2.751607695268342,
0.06552564018991494,
6,
175,
{'1%': -3.4682803641749267,
'5%': -2.8782017240816327,
'10%': -2.5756525795918366},
2380.3243769001815)
結果はタプル形式でいろいろな値が表示されますが、一番最初の値である-2.7516が検定統計量です。
そして、この分布の1%点と5%点と10%点が下の方に出てきます。
5%点を見ると-2.8782になっていて、検定統計量はこれより内側にあります。
従って、この原系列は単位根過程であるという帰無仮説を棄却できません。
平たくいうと(厳密ではありませんが)原系列は単位根過程(非定常過程)ということです。
階差数列
# ADF検定(階差数列)
adf_test1 = adfuller(data_df_diff1.S00239)
adf_test1
---
(-13.488462552030544,
3.1401357087584845e-25,
5,
175,
{'1%': -3.4682803641749267,
'5%': -2.8782017240816327,
'10%': -2.5756525795918366},
2370.1046538075643)
今度は検定統計量が-13.48846になりました。
これは5%点である-2.8782よりも外側にあります。
従って帰無仮説は棄却され、階差数列は定常過程であるといえます。
まとめ
需要データの階差数列は、前日からの需要の増減を表しています。
長期トレンドが上昇していたり下降していたとしても、前日からの差には影響がほとんどないため、長期トレンドの影響を取り除くことができます。
曜日による周期変動は完全に取り除くことはできませんが、小さくなり、その結果、単位根過程(非定常過程)が定常過程になりました。
このように需要データは階差数列を取ることにより定常過程になることが多く、これにより有名な需要予測手法であるSARIMAモデルが使えるようになります。
【Pythonで需要予測②】SARIMAモデルの自動構築で出荷数量を予測してみた