時系列分析などに取り組んでいると、必ず自己相関グラフ(コレログラム)と呼ばれるグラフが登場します。
これは、時系列グラフにおける、自己相関係数をプロットしたもので、時系列における季節性を調査する際によく、このコレログラムを用いたりします。
とはいえ、この自己相関係数が、そもそも時系列データにおける何を意味しているか理解しないと。コレログラムについて理解することはできないでしょう。
今回は、コレログラムを書くために、自己相関係数の解説と実際にPythonを用いてコレログラムを書く方法を解説します。
- 自己相関係数の定義をわかりやすく解説
- 自己相関グラフ(コレログラム)を解説
- コレログラムをPythonを用いて描く
自己相関係数の定義
時系列データにおける自己相関$r_k$の定義を先に示します。
自己相関を$r_k$とした時、自己相関係数は次のように定義される。
\begin{equation} \begin{split} r_k = \frac { \frac{ 1}{T} \sum_{t= k+1}^{T} ( y_t - \bar{y})(y_{t-k} - \bar{y})} { \frac{ 1}{T} \sum_{t= 1}^{T} ( y_t - \bar{y})^2} \end{split} \end{equation}
自己相関係数の解説
自己相関係数とは、パラメータを$k$として、時系列データを$k$秒ずらした時に、そのずらした時系列データが元の時系列(ずらす前)との一致度をはかる指標となっています。
冒頭で、自己相関係数は、時系列データの季節成分を調べる時に用いると書きましたが、例えば毎年のアイスクリームの売上のような、月毎に季節性のあるような時系列データに対して、$k=12$などで自己相関係数$r_k$を計算すると、$r_k$の値が大きくなり、12ヶ月の周期でデータが季節性があることを評価することができます。
(1)式の分子はまさに、ずらした時系列と元の時系列のズレを計算しています。
2変数の相関を示す指標である共分散と計算式が似ていることがわかりますね。実際に、(1)式の分子は自己共分散と呼ばれています。
\gamma_k = \frac{ 1}{T} \sum_{t= k+1}^{T} ( y_t - \bar{y})(y_{t-k} - \bar{y})
自己共分散については、こちらの記事で、詳しく解説しています。
自己共分散を用いて、(1)の自己相関係数を表現すると次のようになります。
ラグが$k$の自己共分散を$\gamma_k$とすると、自己相関係数$r_k$は次のようにかける。
\begin{equation} \begin{split} r_k = \frac { \gamma_k} { \gamma_0} \end{split} \end{equation}
また、(1)式の分母は、時系列データの分散になっています。自己相関係数の値自体は、実際のスケールによって大きく変わってしまうため、その時系列のスケールで割ることで企画しています。
ちょうど、ピアソンの相関係数の定義において、共分散の値を分散で割っているのと同じ理由ですね。
(1)の自己相関係数を計算することで、他の時系列間で自己相関の度合いを比較することができます。
自己相関グラフ(コレログラム)とは
自己相関グラフとは、時系列データにおける、自己相関係数をプロットしたグラフです。横軸は、(1)式における$k$で、このkは、ラグなどと呼ばれています。
コレログラムは次にようなグラフです。
このように、横軸にラグ($k$)をとり、縦軸が自己相関係数をとるグラフがコレログラムです。$k=0$の時は、自己相関係数が1になっていることがわかります。$k=0$の時は、元のグラフとずらしたグラフ(実際にはずらしていないが)が完全に一致するので、自己相関係数が最大値の1になることがわかります。
Pythonでコレログラム(自己相関係数のグラフ)をかく
それでは、Pythonでコレログラムを書いてみましょう。
データセットは今回は、周期性のある$cos$の関数に乱数を加えた時系列データを自作して見るところから始めてみます。
$y = cos(x) + 100$の関数に、平均0、標準偏差2の乱数を加えたデータ点を80個取得します。時系列生成のコードは次にようになっています。
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(1212)
fig, ax = plt.subplots(figsize=(10, 2), dpi=90)
x = np.linspace(0, 80, 80)
y = np.cos(x) + np.random.normal(0, 2, size=len(x)) + 100
ax.plot(x, y, color="g", linestyle=":")
続いて、自己相関係数を計算する関数calc_auto_coefficient を実装します。(2)より、自己相関係数は、自己共分散を計算することで間接的に求めることができるので、まず、自己共分散を計算するcalc_auto_covarianceを次のように実装し、その結果を利用して自己相関係数を実装します。
def calc_auto_covariance(k, data):
average = np.average(data)
return np.sum([ (data[i] - average) * (data[i - k] - average) for i in range(k, len(x))]) / len(data)
def calc_auto_coefficient(k, data):
return calc_auto_covariance(k, data) / calc_auto_covariance(0, data)
自己共分散の計算式は、定義で示したのをそのまま実装しただけです。
ここまで実装することができたら、コレロゴラムを書いてみます。
コレログラムは、下記のコードで書くことができます。
result = []
for k in range(0, 50):
result.append(calc_auto_coefficient(k, y))
fig, ax = plt.subplots(figsize=(10, 2), dpi=100)
ax.set_xlabel("k value")
ax.set_xticks(range(0, 50), minor=True)
ax.stem(range(0, 50), result, use_line_collection=True)
このようなコレログラムを描くことができました。
今回、元の時系列データを作るのに利用した関数$cos(x) +100$は周期が$2 \pi = 6.28 …$くらいなので、およそ6.28の倍数のところで自己相関係数の値が大きくなっていることが見て取れます。