データ解析ならPythonが最高!第5回

2018.08.22

Lab研究員 北山

相関(共分散行列、相関行列)

変数が増えると、変数の組み合わせの数も増えます。例えば、東京証券取引所の第一部上場2,017社の全銘柄について、
株価の相関係数を求めようとすると、その組み合わせ数は膨大です。そんなとき Python の行列演算が役立ちます。
行列を用いると、複数のベクトルをまとめて扱うことができます。

スカラーからベクトルへ

スカラーの代数は、数を一般化して扱うことができます。
例えば「リンゴ3個とキウイ2個、合わせて何個でしょう」という問題は

Vol5-38.png

リンゴが3個とキウイが2個に限定された問題です。
これをスカラーの代数を用いることで「リンゴ x 個とキウイ y 個、合わせて何個でしょう」

Vol5-39.png

というリンゴとキウイの個数に限定されない一般化された問題になります。

では、次はどうでしょうか。
A さんはリンゴ x1 個とキウイ y1 個、B さんはリンゴ x2 個とキウイ y2 個を持っています。
AさんとBさんはそれぞれリンゴとキウイを合計何個持っているでしょうか。


Vol5-40.png

ベクトルを用いると、このようなスカラーの演算をまとめて一般化することができます。
次のように縦ベクトルを定義すると

Vol5-6-3.png

AさんとBさんをまとめて次のように表せます。


Vol5-41.png

分かりづらいですがベクトルは太字で表しています。

ベクトルから行列へ

これまでは標本の身長や体重を

Vol5-9.png

次のようなベクトルで表していました。

Vol5-10.png

行列を用いると、このようなベクトルをまとめて扱うことができます。
身長と体重のベクトルを行列にまとめると次のようになります。

Vol5-11.png
同様に身長と体重の平均

Vol5-12.png

を行列にまとめると次のようになります。

Vol5-13.png


そうすると、例えば行列の加減算で偏差を求めることができます。

Vol5-14.png

行列にまとめるベクトルの数、つまり変数の数は2つに限りません。
身長と体重に加えて腹囲を行列にまとめると

Vol5-15.png

このように行列の導入で、多変量をまとめて扱うことができます。

共分散行列

分散や共分散は、行列の積を用いて求めることができます。

その前にベクトルの内積について、もう一度、おさらいします。
ベクトルでは、内積を用いて偏差平方和や偏差積和を求めました。

内積

Vol5-16.png

偏差平方和

a を偏差ベクトルとすると、それ自身との内積は偏差平方和になります。

Vol5-18.png

つまり
Vol5-19.png
を偏差ベクトル a の内積を用いて次のように表わすことができます。
Vol5-20.png

偏差積和

同様に、ab を偏差ベクトルとすると、その内積は偏差積和になります。

Vol5-21.png
つまり
Vol5-22.png

を偏差ベクトル ab の内積を用いて次のように表わすことができます。
Vol5-23.png

行列の積

ここで、次のように偏差ベクトル ab を並べた行列 D を考えます。

Vol5-24.png

ここでは D を偏差行列と呼ぶことにします。偏差行列 D の積をとると

Vol5-25.png

右辺に偏差ベクトル ab の内積の全組み合わせが出てきます。
これを標本数 n で除すると、偏差ベクトル ab の分散と共分散を一網打尽に求めることができます。

Vol5-26.png

この行列を共分散行列あるいは分散共分散行列といいます。
共分散行列は、対角成分に分散が、非対角成分に共分散が並びます。

変数が3つの場合も同様に、偏差ベクトルを並べて

Vol5-27.png

分散と共分散の全組み合わせが一網打尽です。

変数が4つ以上のときも同様です。

ここでは共分散行列の記号として S を使っていますが、標準偏差で s と σ(シグマ) を使い分けるのと同様に、
母共分散行列であることを明示するときは大文字のΣ(シグマ)と表記します。
不偏共分散行列とするときは (n-1) で除します。
ここまでの式では n で除していますが、必要に応じて (n-1) で除してください。
なお、母共分散行列の記号 Σ と総和記号の Σ はどちらもシグマですが別物です。

Vol5-28.png

相関行列

共分散行列と同様に、相関係数を並べた行列を相関行列といいます。

Vol5-29.png

変数が3つのときは次のようになります。


Vol5-30.png

相関行列が求まると、変数の全ての組み合わせについて、相関係数が求まります。
相関係数は共分散を標準偏差で規格化した値でした。

Vol5-31.png

共分散行列の各要素を標準偏差で規格化すると相関行列になります。

Vol5-32.png

Pythonで共分散行列、相関行列

共分散行列と相関行列を求めます。

import numpy as np
X = np.array([
[6, 1, 0],
[4, 0, 7],
[7, 8, 1],
[6, 5, 4]
])
# 標本数
n = X.shape[0]
# 平均
Xbar = np.mean(X, axis=0)
# 偏差
D = X - Xbar
# 共分散行列
S = D.T.dot(D)/n
# 共分散行列の対角成分を切り出し
v = np.diag(S)
# 標準偏差
s = np.sqrt(v)
# 相関係数
R = S/s[:, None]/s[None, :]
np.set_printoptions(precision=3)
print('共分散行列')
print(S)
print('共分散行列の対角成分')
print(v)
print('標準偏差')
print(s)
print('相関行列')
print(R)<

(実行結果)

共分散行列
[[ 1.188 2.875 -2.5 ]
[ 2.875 10.25 -3.5 ]
[ -2.5 -3.5 7.5 ]]
共分散行列の対角成分
1.188 10.25 7.5 ]
標準偏差
[ 1.09 3.202 2.739]
相関行列
[[ 1. 0.824 -0.838]
[ 0.824 1. -0.399]
[-0.838 -0.399 1. ]]

処理を補足します。


># 共分散行列の対角成分を切り出し
> v = np.diag(S)

np.diag() 関数は、引数に行列を指定すると対角成分を返します。
引数に1次元配列を指定すると、それを対角成分とした対角行列を返します。
ここでは、共分散行列の対角成分の分散を切り出しています。

># 標準偏差
> s = np.sqrt(v)


切り出した分散の平方根をとると標準偏差が求まります。
Vol5-33.png

> # 相関係数
> R = S/s[:, None]/s[None, :]

標準偏差で共分散行列の各要素を規格化し、相関行列を求めています。
ここではブロードキャスト機能を用いて、少しトリッキーな処理を行なっています。

1次元配列の標準偏差

Vol5-34.png

を、2次元の縦ベクトル、横ベクトルに変形します。

Vol5-35.png

ここで、None は新たな軸を追加するという意味です。
詳細は NumPyの newaxis を参照してください。

これらで共分散行列を除すると

Vol5-36.png

となりますが、ここで行列のサイズが一致しないため NumPyのブロードキャスト機能が働きます。
これにより次の演算が行なわれることになります。

Vol5-37.png

これで相関行列が求まりました。

共分散行列、相関行列を求める関数

共分散行列、相関係数は NumPy の関数で求めることができます。

import numpy as np
X = np.array([[6, 1, 0],[4, 0, 7],[7, 8, 1],[6, 5, 4]])
# 分散共分散行列
S = np.cov(X, rowvar=0, ddof=0)
# 相関行列
R = np.corrcoef(X,rowvar=0)
np.set_printoptions(precision=3)
print('共分散行列')
print(S)
print('相関行列')
print(R)

(実行結果)


共分散行列
[[ 1.188 2.875 -2.5 ]
[ 2.875 10.25 -3.5 ]
[ -2.5 -3.5 7.5 ]]
相関行列
[[ 1. 0.824 -0.838]
[ 0.824 1. -0.399]
[-0.838 -0.399 1. ]]

今回はここまで。次回は重回帰分析の予定です。

  • LINE
  • Mail