固有値、固有ベクトルの話というのは、世の中に死ぬほど記事出ていると思います。
この記事でもその焼き直しになると思いますが、より高度な概念につなげていくためにはこれらの理解は必須のため、固有値と固有ベクトルについてまとめていきます。
またPythonを用いて、固有ベクトルは行列の演算に対して方向が変わらないという性質を、可視化します。
- 固有値・固有ベクトルの定義
- 固有値・固有ベクトルの幾何学的な特徴をPythonで可視化して確認する
固有値・固有ベクトルの定義
まず、固有値の定義について触れていきます。
$A$をn次の正方行列とした時、
\begin{equation} \begin{split} A\bm{x} &= \lambda\bm{x} \\ \bm{x} &\neq \bm{0} \end{split} \end{equation}
(1)の条件にを満たす、定数$\lambda$とベクトル$\bm{x}$が存在するとき、$\lambda$とベクトル$\bm{x}$をそれぞれ、Aに対する固有値(eigenvalue)と固有ベクトル(eigenvector)とする。
ただし、$\bm{x}$はn次のベクトルである。
固有値・固有ベクトルの解釈
固有値と固有ベクトルの定義を確認したところで、固有値と固有ベクトルの解釈をしてみましょう。
通常、行列とベクトルを演算すると、ベクトルの方向が変わります。
しかし(1)式をベクトル$\bm{x}$を中心に見ると、左辺では、$\bm{x}$に対して左から行列Aをかけていますが、右辺ではベクトルを定数$\lambda$倍していることから、方向は変わらないことになっています。
つまり、固有値と固有ベクトルは、n次の正方行列に対して、方向が変わらないベクトルと$\bm{x}$、定数倍される比率と捉えることができる。ちなみに固有値・固有ベクトルは、n×nの正方行列にのみ定義されるものであることは意識しておく必要性があります。
固有値・固有ベクトルを図形で確認する
固有ベクトルはn次の正方行列で変換しても方向が変わらないベクトルだと言いましたが、実際にそれを確認してみましょう。
今回はPythonを用いて固有値と固有ベクトルを確認してみます。
下記の2次の正方行列固有値・固有ベクトルを求める
\begin{equation} A = \begin{pmatrix} -2 & 1 \\ -4 & 3 \\ \end{pmatrix} \end{equation}
Python を用いて固有値を導出する場合、numpyやscipyなどのライブラリが計算用のライブラリを提供しています。今回はnumpyのlinalgモジュールを用いて、固有値と固有ベクトルを計算してみます。
まずはライブラリをインポートします。
import matplotlib.pyplot as plt
import numpy as np
from numpy import linalg
固有値と固有ベクトルを計算するには、linalg.eig() メソッドを用いることで簡単に計算できます。
linalg.eig()メソッドは、最初の返り値に固有値・二番目の返り値に固有ベクトルを返します。
A = np.array([[-2,1],[-4,3]])
eigenvalues, eigenvectors = linalg.eig(A)
上のコードを実行すると、下記のような固有値と固有ベクトルを得ることができます。eigenvectorsは、縦ベクトルになっていることに注意してください。
eigenvalues
# => array([-1., 2.])
eigenvectors
# => array([[-0.70710678, -0.24253563],
[-0.70710678, -0.9701425 ]])
2次の正方行列では、通常は2つの固有値とそれに対応する2つの固有ベクトルを得ることができます。
今回は、2つ得られた固有値と固有ベクトルのうち、1つだけ図形で図示して、固有ベクトルの性質を見ていきます。
\lambda = 2 \\ \bm{x} = \begin{pmatrix} -0.24253563\\ -0.9701425 \\ \end{pmatrix}
まず最初に、ベクトル$x$を図示してみます。
fig, ax = plt.subplots(figsize=(10, 10), dpi=40)
ax.set_xlim(-2.5, 2.5)
ax.set_ylim(-2.5, 2.5)
x, y = 0.5, 1 # 固有ベクトル以外のベクトル(比較用)
eigen_x, eigen_y = eigenvectors[:, 1] # 固有ベクトル
ax.quiver(0, 0, eigen_x, eigen_y, color="red", angles='xy', scale_units='xy', scale=1)
ax.quiver(0, 0, x, y, color="green", angles='xy', scale_units='xy', scale=1)
plt.text(-1.8, -0.5, "red: eigenvectors", fontsize=20)
plt.text(-1.8, 1.2, "green: not eigenvectors", fontsize=20)
plt.show()
このように図示できました。赤色が行列$A$に対する固有ベクトルです。緑色は比較用の、適当に用意した2次元ベクトルです。
ここで、これらの2つのベクトルを行列$A$で変換して結果を見てみましょう。
# 行列Aを左からかける
after_eigen_x, after_eigen_y = np.dot(A, eigenvectors[:, 1])
after_x, after_y = np.dot(A, np.array([x, y]))
2つのベクトルに対して、行列Aをかけました。
fig, ax = plt.subplots(figsize=(10, 10), dpi=40)
ax.set_xlim(-2.5, 2.5)
ax.set_ylim(-2.5, 2.5)
x, y = 0.5, 1 # 固有ベクトル以外のベクトル(比較用)
eigen_x, eigen_y = eigenvectors[:, 1] # 固有ベクトル
ax.quiver(0, 0, eigen_x, eigen_y, color="red", angles='xy', scale_units='xy', scale=1)
ax.quiver(0, 0, x, y, color="green", angles='xy', scale_units='xy', scale=1)
ax.quiver(0, 0, after_eigen_x, after_eigen_y, color="red", angles='xy', scale_units='xy', scale=1, hatch='ooo', facecolor='red')
ax.quiver(0, 0, after_x, after_y, color="green", angles='xy', scale_units='xy', scale=1,hatch='ooo', facecolor='green')
plt.text(-1.8, -0.5, "red: eigenvectors", fontsize=20)
plt.text(-1.8, 1.2, "green: not eigenvectors", fontsize=20)
plt.show()
図示した結果がこのようになりました。
赤いベクトルが行列$A$に対する固有ベクトルで、行列$A$による変換をしても、方向が変わらず、大きさが固有値$\lambda = 2$倍されています。
一方で、固有ベクトルではない緑色のベクトルは、方向が変わっているのがわかると思います。
固有値を学ぶ必要性
固有値は工学分野で多数登場する、非常に重要な概念です。通信分野でも機械学習でも多く登場するので、その定義と図形的・幾何学的な意味について覚えておくようにしましょう。