機械学習・自然言語処理の勉強メモ

学んだことのメモやまとめ

numpyで特異値分解

特異値分解は、行列を複数の行列の積に分解する方法。

こんな感じで分解。
X=U\Lambda {V  }^{T  }
f:id:kento1109:20171123141025p:plain

import numpy as np

X = np.array([[3,4,1]
             ,[7,3,2]
             ,[5,4,2]
             ,[1,2,1]
             ,[2,3,2]])

U, s, V = np.linalg.svd(X, full_matrices=True)
print s
>> [ 12.12789287   2.81497791   0.99504463]

固有値分解で解くと、

import numpy as np
import math

X = np.array([[3,4,1]
             ,[7,3,2]
             ,[5,4,2]
             ,[1,2,1]
             ,[2,3,2]])

la, vec = np.linalg.eig(np.dot(X.T,X))
print [math.sqrt(x) for x in la]
>> 
[12.127892872406234, 2.8149779144663403, 0.9950446304084475]

値は一致する。

X=\sum _{ i=1 }^{ q }{ { \sqrt { \lambda  }  }_{ i } } {  u}_{  i}{v  }_{ i }^{ T }
特異値分解した低近似ランクの総和は元の行列と一致)なので、

SU1 = np.array(np.dot(s[0],U[:,0]),ndmin=2)
V1 = np.array(V[0],ndmin=2)
val1 = np.dot(SU1.T,V1)

SU2 = np.array(np.dot(s[1],U[:,1]),ndmin=2)
V2 = np.array(V[1],ndmin=2)
val2 = np.dot(SU2.T,V2)
##
SU3 = np.array(np.dot(s[2],U[:,2]),ndmin=2)
V3 = np.array(V[2],ndmin=2)
val3 = np.dot(SU3.T,V3)
##
print val1 + val2 + val3
[[ 3.  4.  1.]
 [ 7.  3.  2.]
 [ 5.  4.  2.]
 [ 1.  2.  1.]
 [ 2.  3.  2.]]