Home

固有値と固有ベクトル

固有分解/スペクトル分解

 

実対称行列Aの固有分解(eigen decomposition, characteristic decomposition;スペクトル分解, spectral decomposition)は、numpy.linalg.eigh(A)で簡単に求めることができる。

例えば、実対称行列に対してスクリプト

 

w, v = numpy.linalg.eigh(A)

 

を実行すると、wに固有値、vに固有ベクトルが返される。このとき、配列wには、固有値が小さいものから順に並べられていて、行列vには固有値の並びに対応する順に固有ベクトルが列ベクトルとして並べられている。これを、固有値の絶対値の大きいものからの順に並べ直すスクリプト例をリストに示した。スクリプトファイルは、圧縮したものFilesEigen.zipを用意した。ダウンロード展開して自由に利用することができる。

固有分解については、岡本(2019pp.61-62)あるいは岡本(2009pp.41-45)で説明している。

 

行列とベクトルおよび数値(スカラー)が次式

を満たすとき、数値を行列の固有値(eigenvaluecharacteristic value)と呼び、ベクトルを固有値に対する固有ベクトル(eigenvectorcharacteristic vector)と呼ぶ。

次の実対称行列は個の固有値をもつ。それらを、・・・、と書き、固有値に対する固有ベクトルを長さが1であるように調整したものをとおくと、次式(1)が成り立つ。

ここで、

である。

いま、

、 

とおくと、式(1)は

と書ける。

このとき、次式(2)が成り立つ。

式(2)から、固有値の大きいものが先にある方が、近似の精度の観点からは使い易いと思われる。リスト1では、固有値の大きいもから小さいものの順に並べ換えている。

 

 

リスト1 固有分解のスクリプト例

 

import numpy as np

 

A = np.array([[1,2,3],[4,5,6]])

B = A.T @ A                      #   実対称行列

print('B =\n', B)

 

lmbd, u = np.linalg.eigh(B)      #   固有分解

print('lmbd =\n', lmbd)

print('u =\n', u)

 

ck_idx = np.abs(lmbd) > 1.0e-7   #   実質的に0でないと見做される値

print('ck_idx =\n', ck_idx)

lmbd = lmbd[ck_idx]              #   0でない固有値の選択

print('lmbd =\n', lmbd)

u = u[:,ck_idx]                  #   0でない固有値に対応する固有ベクトル

print('u =\n', u)

 

ck_ord = np.argsort(-lmbd)       #   大きい値から小さい値に対応する添え字

print('ck_ord =\n', ck_ord)

 

lmbd = lmbd[ck_ord]              #   固有値の並べ替え

print('lmbd =\n', lmbd)

u = u[:,ck_ord]                  #   固有ベクトルの並べ替え

print('u =\n', u)

 

ck_B = u @ np.diag(lmbd) @ u.T   #   固有分解の確認

print('ck_B =\n', ck_B)

 

 

リスト1を実行すると、以下の出力を得る。

 

B =

 [[17 22 27]

 [22 29 36]

 [27 36 45]]

lmbd =

 [2.91325866e-15 5.97327474e-01 9.04026725e+01]

u =

 [[ 0.40824829 -0.80596391 -0.42866713]

 [-0.81649658 -0.11238241 -0.56630692]

 [ 0.40824829  0.58119908 -0.7039467 ]]

ck_idx =

 [False  True  True]

lmbd =

 [ 0.59732747 90.40267253]

u =

 [[-0.80596391 -0.42866713]

 [-0.11238241 -0.56630692]

 [ 0.58119908 -0.7039467 ]]

ck_ord =

 [1 0]

lmbd =

 [90.40267253  0.59732747]

u =

 [[-0.42866713 -0.80596391]

 [-0.56630692 -0.11238241]

 [-0.7039467   0.58119908]]

ck_B =

 [[17. 22. 27.]

 [22. 29. 36.]

 [27. 36. 45.]]

 

 

 

引用文献

岡本安晴(2009統計学を学ぶための数学入門――データ分析に活かす――培風館

岡本安晴(2019いまさら聞けないPythonでデータ分析――多変量解析、ベイズ統計分析(PyStan、PyMC)――丸善出版

 

Home