【時系列解析】自己共分散とは?定義とPythonでの実装で詳しく解説

Posted: , Category: 時系列分析

自己共分散(Auto Covariance)は、時系列解析に登場する概念の1つです。

意味合いとしては、時刻$t$のデータが、それよりも以前の時刻のデータと相関があるかどうかを示すような統計量となっています。

ARIMAモデルなどの古典的な時系列解析を行う場合は、この自己共分散の基本的な概念として押さえておく必要性があるので、学んでいきましょう。

本記事の内容
  • 自己共分散の定義を理解する
  • 自己共分散をPythonで計算する

自己共分散の定義

まず最初に自己共分散の定義を示します。

時系列解析における自己共分散の定義
\begin{equation}
\begin{split}
\gamma_k = \frac{ 1}{T} \sum_{t= k+1}^{T} ( y_t - \bar{y})(y_{t-k} - \bar{y})
\end{split}
\end{equation}

ここで、$k$は共分散における、時系列データのズレを表す定数です。また、$\bar{y}$は全時系列データの平均値を示しています。

共分散は、2つの変数において、それぞれ平均からのずれの総和をデータ数で割った量になっていましたが、時系列解析における自己共分散は、自身の時系列データと、それをk秒ずらした時系列データとの共分散になっています。

自己共分散の計算イメージ

(1)式を見ても中々理解しにくいと思うので、イメージしやすいように、下記のような時系列の自己共分散を考えます。

データ点$y$は、y = [4, 2, 6, 1, 9, 7, 1, 2, 7, 6] でプロットしており、平均は4.5で、平均値のところに赤い点線が引かれています。

ここで、$k=1$の自己共分散を考えます。

この図は、k=1の場合で、青色の実線が時系列データ$y_t$を、赤色の線が時系列の平均$\bar{y_t}$を示しています。

ここで、(1)式で定義した、数式における$( y_t – \bar{y})(y_{t-k} – \bar{y})$が、上図における同じ線の色の掛け算を示しています。

よって、(1)式全体としては、上の図における同じ色の部分を掛けて、その総和をとった後の平均に相当することになります。

$k=2$の時は、このようになります。同じ色の部分を掛け算して足し算することで、自己共分散の分子を計算できます。

図形だと、少しは自己共分散についてイメージすることができたでしょうか。

自己共分散については、時系列データ特有の概念で、中々理解が難しいところなので、自分の中で理解できるまで確認してみてください。

Pythonで自己共分散を計算する

Pythonで自己共分散を計算してみましょう。

まずは今回、扱うダミーの時系列データを作成します。$sin(x) + 10$ に、平均0、分散1の正規分布からサンプリングしたノイズを加えた時系列データを用意します。

import numpy as np
import matplotlib.pyplot as plt
np.random.seed(5656)

fig, ax = plt.subplots(figsize=(10, 2), dpi=100)

x = np.linspace(0, 50, 50)
y = np.sin(x) + np.random.normal(0, 1, size=len(x)) + 10

ax.plot(x, y, color="red", linestyle="-")
この時系列を用いて、自己共分散を計算してみましょう。

自己共分散を計算するメソッド calc_auto_covariance は、(1)の自己共分散の定義から、次のように実装できます。

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)

この関数を$k$の値を1~49まで変化させてプロットしてみます。

プロットには下記のコードを用います。

result = []
for k in range(1, 50):
    result.append(calc_auto_covariance(k, y))
    
fig, ax = plt.subplots(figsize=(10, 2), dpi=100)

ax.set_xlabel("k value")
ax.set_xticks(range(1, 50), minor=True)
ax.stem(range(1, 50), result, use_line_collection=True)

このように自己共分散をプロットすることができました。

この図をよく観察してみると、実は$2\pi$の整数倍の時に、自己共分散の値が大きくなっていることがわかります。

これは、元々の関数 $sin(x) + 10$ が 周期 $2\pi$で増減しているためであり、同一周期になると自己共分散が高くなります。

自己共分散は(1)データ間での大きさに比較する際には、データの大きさに依存して値が変わってしまうので、時系列間で自己共分散を比較する際には、自己相関係数を用いることがあります。

自己相関係数については、また別の記事で紹介します。

【広告】
統計学的にあなたの悩みを解決します。
仕事やプライベートでお悩みの方は、ベテラン占い師 蓮若菜にご相談ください。

機械学習と情報技術