なので、今回はその理論に注目する
- SVDは代数学・幾何学的側面を持つ。
- SVDは主成分分析、パイプロット、正準相関分析や、対応分析の基盤。
- ある行列のSVDとは、行列を形式が簡単で幾何的な解釈が可能な3つの行列の積へと分解すること。
- 任意のI×J実数行列Aは、
と分解出来る。
はK個の正数からなる対角行列。KはAのランクである。U、VはそれぞれI×K、J×K行列。UもVも直交行列。
- つまり、Aのランクは、Aの情報量を意味しているから、Aの情報量の次元の対角行列まで中間で落とすことが出来る!というイメージ。
- SVDのベクトル表現では、
とする。αがAの特異値。uとvはそれぞれ、左特異値ベクトル、右特異値ベクトル、となる。
- 固有値分解はSVDの特殊なケース。
- SVDの一意性の議論の前に、一度コードでの理解を挟む。
- numpy.linalg.svdで特異値分解が出来る!(有り難い)
-
import numpy as npA = np.array([[1, 2, 0, 2],[2, 3, -1, 1],[1, 1, 2, 1]])U, D, V = np.linalg.svd(A, full_matrices=True)print(U,"U")print(D,"D")print(V,"V")[[-0.58144675 0.10449684 0.80684577][-0.74218635 -0.47438475 -0.47341158][-0.33328531 0.87409354 -0.3533856 ]] U[4.96291015 2.32956629 0.9708984 ] D[[-0.48340685 -0.75011188 0.01523617 -0.45101867][ 0.01280104 -0.14597869 0.95407108 0.26129433][-0.508151 -0.1647225 -0.24035432 0.81048063][-0.71269665 0.62360956 0.17817416 -0.26726124]] V
- ここまでで、Dは対角行列で、正数を取っていることが分かる。
- ここで一旦脱線して、この行列Aの成分を正規分布(平均0、分散1)に従って生成させた時に、この特異値がどうなるかを知りたい。
-
import numpy as npimport matplotlibimport matplotlib.pyplot as plt
dn_r = []for i in range(1000000):A = np.array([[normal(0,1),normal(0,1),normal(0,1),normal(0,1)],[normal(0,1),normal(0,1),normal(0,1),normal(0,1)],[normal(0,1),normal(0,1),normal(0,1),normal(0,1)],[normal(0,1),normal(0,1),normal(0,1),normal(0,1)],[normal(0,1),normal(0,1),normal(0,1),normal(0,1)]])U,D,V = np.linalg.svd(A, full_matrices = True)dn_r.append(sum(D))
xn_r = np.array(dn_r)plt.hist(xn_r, bins= 50,density=True) - 5×4の行列Aの特異値行列Dのトレースの分布を調べた。1000000個のAを生成させて出てきたグラフがこちら。
- 正規分布では無いが、間違いなく何らかの意味(Aのスケール5とか4とかに影響された)があるのは間違いない。この分布の正体を知るには、ランダム行列理論の勉強が出てくる。
- 2×2行列ならこんな感じ。
-
今は良いとしよう。
バイバイ!