特異値分解をnumpyで実装してみる
特異値分解
特異値分解とは
固有値分解は正方行列にしか適用できませんでした。
それを任意のサイズの行列に適用できるように拡張したのが特異値分解と呼ばれるものです。
行列を下記のように3つの行列に分解することを特異値分解といいます。
ここで、とは直行行列、は行列の特異値を降順にi行i列に並べて残りを0にした行列です。
ここで特異値とは、の固有値の平方根で求められる値のことです。
つまり、正方行列にしか適用できなかった固有値分解を任意のサイズの行列で疑似的にできるように拡張したのが特異値分解と呼ばれる手法になります。
numpyでの実装
numpyのnp.linalg.svdメソッドを使うことで特異値分解をすることができます。
ちなみには対角成分(特異値)のみが返されるので、元の行列に復元したいときなどはnp.diagを使うなどして対角行列に戻す必要があります。
import numpy as np A = np.array([[1, 3, 4, 2], [1, -1, 2, -5], [-2, 2, -1, 3]]) U, S, VT = np.linalg.svd(A) print("U") print(U) print("Sigma") print(S) print("V^T") print(VT) print("") print("AA^Tの固有値の平方根") eigen_val, eigen_vec = np.linalg.eig(np.dot(A, A.T)) print(np.sqrt(eigen_val))
実行結果はこちら。
U [[-0.33922653 -0.93622648 -0.09168066] [ 0.7463714 -0.32718841 0.57954937] [-0.57258632 0.1281707 0.80976366]] Sigma [ 6.99488133 5.27073893 1.5135872 ] V^T [[ 0.22192192 -0.4159075 0.10127734 -0.87607905] [-0.28833837 -0.42217034 -0.85897888 0.02807978] [-0.7476666 0.5053795 -0.01148765 -0.43064399] [-0.55552344 -0.62720389 0.50176311 0.21504133]] AA^Tの固有値の平方根 [ 6.99488133 5.27073893 1.5135872 ]