Home

Python特異値分解

 

行列の特異値分解(Singular Value Decomposition, SVD)については、岡本(2009pp. 47-49、あるいは岡本(2019pp. 67-72で説明している。

 

特異値分解は次式

 

 

で与えられる。特異値分解はumpyの関数numpy.linalg.svdにより得ることができる。

リスト1にサンプルスクリプトを示す。スクリプトファイルは圧縮ファイルFilesSVD.zipとして用意した。ダウンロード展開すれば自由に利用できる。

特異値分解は次のコードで行っている。

 

U, S, Vh = np.linalg.svd(a, full_matrices = False)

 

行列aの特異値分解が、USVhとして得られる。パラメータfull_matrices = Falseについては、本ウェブサイトの後半で説明している。

特異値Sは降順で並べられている。リスト1では、0であるかどうかの判定を次のコードで行っている。

 

ck_idx = S > 1.0e-7

 

特異値が0でないものを集めて、次のコードで特異値分解が得られていることを確認している。

 

ck_a = U @ np.diag(S) @ Vh     

print('ck_a =\n', ck_a)

 

 

リスト1 特異値分解の例

 

import numpy as np

 

a = np.array([[1,2,3,4],[8,7,6,5],[1,1,1,1]])

print('a =\n', a)

 

U, S, Vh = np.linalg.svd(a, full_matrices = False)   #   特異値分解

print('U =\n', U)

print('S =\n', S)

print('Vh =\n', Vh)

 

ck_idx = S > 1.0e-7                       #   0でないと見做せるか?

print('ck_idx =\n', ck_idx)

 

U = U[:,ck_idx]                           #   特異値0に対応するものを除く

print('U =\n', U)

S = S[ck_idx]                             #   特異値0に対応するものを除く

print('S =\n', S)

Vh = Vh[ck_idx]                           #   特異値0に対応するものを除く

print('Vh =\n', Vh)

 

ck_a = U @ np.diag(S) @ Vh                #   特異値分解の確認

print('ck_a =\n', ck_a)

 

 

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

 

a =

 [[1 2 3 4]

 [8 7 6 5]

 [1 1 1 1]]

U =

 [[ 0.33741061  0.9349363  -0.10976426]

 [ 0.93075201 -0.34878718 -0.10976426]

 [ 0.14090696  0.06512768  0.98787834]]

S =

 [1.41310647e+01 2.88322914e+00 1.74222008e-16]

Vh =

 [[ 0.560774    0.51878556  0.47679711  0.43480867]

 [-0.62091265 -0.17567455  0.26956356  0.71480166]

 [ 0.26126424  0.01045822 -0.80470915  0.53298669]]

ck_idx =

 [ True  True False]

U =

 [[ 0.33741061  0.9349363 ]

 [ 0.93075201 -0.34878718]

 [ 0.14090696  0.06512768]]

S =

 [14.13106471  2.88322914]

Vh =

 [[ 0.560774    0.51878556  0.47679711  0.43480867]

 [-0.62091265 -0.17567455  0.26956356  0.71480166]]

ck_a =

 [[1. 2. 3. 4.]

 [8. 7. 6. 5.]

 [1. 1. 1. 1.]]

 

 

パラメータfull_matrices

 

リスト1におけるSVDのパラメータfull_matricesの比較を行うスクリプトをリスト2に用意した。

次のコードは、リスト1と同じくfull_matrices = Falseと設定されている。

 

U, S, Vh = np.linalg.svd(a, full_matrices = False)

 

これに対して、比較のために次のコードも用意した。

 

Uc, Sc, Vhc = np.linalg.svd(a, full_matrices = True)

 

パラメータがfull_matrices = Falseのとき、式(1)に合わせた形でUVhが得られるが、パラメータの指定がfull_matrices = Trueのときは正方行列の形(必要ならば拡張して)でUcVhcが得られる。この正方行列(直交行列)への拡張は、固有分解の場合について岡本(2009pp. 105-106で論じられているが、参考になると思う。

 

 

リスト2 パラメータfull_matricesの比較

 

import numpy as np

 

a = np.array([[1,2,3,4],[8,7,6,5],[1,1,1,1]])

print('a =\n', a)

 

U, S, Vh = np.linalg.svd(a, full_matrices = False)      #   特異値分解

print('U =\n', U)

print('S =\n', S)

print('Vh =\n', Vh)

 

Uc, Sc, Vhc = np.linalg.svd(a, full_matrices = True)    #   特異値分解

print('Uc =\n', Uc)

print('S =\n', Sc)

print('Vhc =\n', Vhc)

ck_Vh = Vhc.T @ Vhc

print('ck_Vh =\n', ck_Vh)

 

 

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

 

a =

 [[1 2 3 4]

 [8 7 6 5]

 [1 1 1 1]]

U =

 [[ 0.33741061  0.9349363  -0.10976426]

 [ 0.93075201 -0.34878718 -0.10976426]

 [ 0.14090696  0.06512768  0.98787834]]

S =

 [1.41310647e+01 2.88322914e+00 1.74222008e-16]

Vh =

 [[ 0.560774    0.51878556  0.47679711  0.43480867]

 [-0.62091265 -0.17567455  0.26956356  0.71480166]

 [ 0.26126424  0.01045822 -0.80470915  0.53298669]]

Uc =

 [[ 0.33741061  0.9349363  -0.10976426]

 [ 0.93075201 -0.34878718 -0.10976426]

 [ 0.14090696  0.06512768  0.98787834]]

S =

 [1.41310647e+01 2.88322914e+00 1.74222008e-16]

Vhc =

 [[ 0.560774    0.51878556  0.47679711  0.43480867]

 [-0.62091265 -0.17567455  0.26956356  0.71480166]

 [ 0.26126424  0.01045822 -0.80470915  0.53298669]

 [-0.48139485  0.83659466 -0.22900478 -0.12619503]]

ck_Vh =

 [[ 1.00000000e+00 -1.11022302e-16 -3.05311332e-16 -8.32667268e-17]

 [-1.11022302e-16  1.00000000e+00 -5.55111512e-17 -9.71445147e-17]

 [-3.05311332e-16 -5.55111512e-17  1.00000000e+00 -1.70002901e-16]

 [-8.32667268e-17 -9.71445147e-17 -1.70002901e-16  1.00000000e+00]]

 

VhcVhの直交行列への拡張であることが確認できる・

 

 

引用文献

 

岡本安晴(2009)統計学を学ぶための数学入門[下].培風館

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

 

 

Home