固有値・固有ベクトルの解釈・意味

固有値・固有ベクトルの解釈・意味#

線形代数的な解釈#

いまいちど定義を振り返る

定義

nN,ARn×n,xRn,λRについて

Ax=λx

が成り立つとき、スカラーλA固有値(eigenvalue)といい、x(0)Aλに対応する固有ベクトル(eigenvector)と呼ぶ。

定義より、線形変換Axと、ベクトルの定数倍λxが等しい。つまり、

Tip

線形変換Ax をしたときに、向きは変わらず、大きさだけがλ倍に変わるようなベクトルxが固有ベクトルで、その倍率λが固有値

と解釈できる。

統計学的な解釈#

データを行列で表したときの話

学習データの分散が最大になる方向への線形変換を求める手法である 主成分分析 を例に考える。

主成分分析

D次元のデータx=(x1,,xD)TN個あるとする。i番目の観測値を行ベクトルxiとして表し、データを行列X=(x1,,xN)Tと表す。

各変数の平均のベクトルx¯=(x¯1,...,x¯D)Tを引き算した行列をX¯=(x1x¯,...,xNx¯)Tとおけば、共分散行列Σ

Σ=Var[X¯]=1NX¯TX¯

で定義される。

係数ベクトルaj=(aj1,...,ajD)T (j=1,...,D)を用いてX¯を線形変換したベクトルをsjとする。

sj=(s1j,...,sNj)T=X¯aj

このデータの分散は

Var[sj]=1NsjTsj=1N(X¯aj)TX¯aj=1NajTX¯TX¯aj=ajTVar[X¯]aj

となる。

このままmaxajVar[sj]を解くと単にaj=が解になってしまうので、係数ベクトルajのノルム制約条件をかけた最大化問題を解くことにする。

制約条件付き分散最大化問題

maxaj Var[sj]subject to ||aj||22=1

この分散が最大となる射影ベクトルは、ラグランジュ関数

L(aj)=ajTVar[X¯]ajλ(ajTaj1)

を最大にするajである。(λはラグランジュ未定乗数)

微分して0とおけば

L(aj)aj=2Var[X¯]aj2λaj=0

より

Var[X¯]aj=λaj

となる。

これは固有値・固有ベクトルの定義で見かけたAx=λxと同じ形になっている。このλajは固有値問題を解くことにより得られる。

主成分分析は、データXと係数ajの線形変換sjの分散を最大化するような係数ajを求める問題

maxaj Var[sj]subject to ||aj||22=1

を解析的に解くために

Var[X¯]aj=λaj

という式を立てて固有ベクトルajを求めるものだった。なので、

Tip

  • 分散を最大化する軸の方向が固有ベクトルaj

  • その軸方向のデータのばらつきの大きさが固有値λ

と捉えることができる。

数値例#

このようなデータがあったとする

Hide code cell source
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm

w = 0.3
n = 300
x1 = norm.rvs(loc=0, scale=1, size=n, random_state=0)
x2 = w * x1 + (1 - w) * norm.rvs(loc=0, scale=1, size=n, random_state=1)
X = np.append(x1.reshape(-1, 1), x2.reshape(-1, 1), axis=1)

fig, ax = plt.subplots()
ax.scatter(x1, x2)
ax.set(xlabel="x1", ylabel="x2")
fig.show()
../../../_images/b438d151e44c7a93efb6b8a41ff101ae00829f4a61c211d6d91842de73943845.png

固有値問題を解いてλajを推定していく。

x_bar = X.mean(axis=0)
X_bar = X - x_bar
Sigma = (1 / n) * X_bar.T @ X_bar
lambdas, vectors = np.linalg.eig(Sigma)
print(f"""
λ={lambdas}
a1={vectors[:, 0].round(3)}
a2={vectors[:, 1].round(3)}
""")
λ=[1.17427995 0.37150396]
a1=[0.886 0.464]
a2=[-0.464  0.886]

主成分を表す固有ベクトルの傾きに直線をプロットすると以下の通り。

係数ベクトルajはノルムが1になるように制約がかけられているので、図にしても長さは同じ。

PC1方向の変換s1ajに対してλ1=1.17倍ということ。

Hide code cell source
o = [0, 0]
a1 = vectors[:, 0]
a2 = vectors[:, 1]

fig, ax = plt.subplots()
ax.scatter(x1, x2)
ax.arrow(*o, *a1, width=0.02, color="coral", length_includes_head=True, alpha=0.7, label="PC1")
ax.arrow(*o, *a2, width=0.02, color="orange", length_includes_head=True, alpha=0.7, label="PC2")
ax.set(xlabel="x1", ylabel="x2")
ax.legend()
fig.show()
../../../_images/e44f7c8b45130fea655cd8bca7580b5cc4d53a8550bec94ebc37aec320162a5f.png

推定できたaの任意の次元数を使って線形変換s=X¯aを作って散布図にするとこうなる

Hide code cell source
S = X_bar @ vectors

fig, ax = plt.subplots()
ax.scatter(S[:, 0], S[:, 1])
ax.set(xlabel="s1", ylabel="s2")
fig.show()
../../../_images/913fbfd652ba2beadb040ddbb83255664291cffb54eb082c079328ec993c6307.png

参考#