SVD近似:
M m ⋅ n ≈ U m ⋅ k S k ⋅ k ( V T ) k ⋅ n M_{m·n}≈U_{m·k}S_{k·k}(V^T)_{k·n} Mm⋅n≈Um⋅kSk⋅k(VT)k⋅n
SVD分解:
M m ⋅ n ≈ U m ⋅ m S m ⋅ n ( V T ) n ⋅ n M_{m·n}≈U_{m·m}S_{m·n}(V^T)_{n·n} Mm⋅n≈Um⋅mSm⋅n(VT)n⋅n
代码如下:
代码的前半部分是svd近似,代码的后半部分是svd分解
前半部分的svd近似中,k=min(m,n)
#-*- coding:utf-8 -*-
import sys
reload(sys)
from numpy import *
import numpy as np
sys.setdefaultencoding("utf-8")
data = mat([[1,2,3,4,5,6,7,8,9],
[5,6,7,8,9,0,8,6,7],
[9,0,8,7,1,4,3,2,1],
[6,4,2,1,3,4,2,1,5]])
print"data的维度:",np.shape(data)
U,sigma,VT = np.linalg.svd(data,full_matrices=False)
print"-----------------1-U----------------------"
print U
print np.shape(U)
print"-----------------1-Σ-----------------------"
print sigma
print np.shape(sigma)
print"------------------1-VT---------------------"
print VT
print np.shape(VT)
print"##########################################################"
print"------------------2-U---------------------"
U,sigma,VT = np.linalg.svd(data,full_matrices=True)
print U
print np.shape(U)
print"-------------------2---------------------"
print sigma
print np.shape(sigma)
print"-------------------2-VT--------------------"
print VT
print np.shape(VT)
##############################################################
那么如果想指定k值怎么办呢?
#-*- coding:utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
from scipy import sparse,stats
import numpy as np
from numpy import *
from math import *
n,m = (4,3)
print("------------------------------")
A=np.asarray([ [1,2,3,4,5,6,7,8,9],
[5,6,7,8,9,0,8,6,7],
[9,0,8,7,1,4,3,2,1],
[6,4,2,1,3,4,2,1,5]]).astype(float)
print("------------------------------")
print(type(A))
u,d,vt = np.linalg.svd(A,full_matrices=0)
k=2
u,d,vt = u[:,:k],d[:k],vt[:,:k]
print("------U-----")
print(u)
print("------S-----")
print(d)
print("------VT-----")
print(vt)
print("--------------------------下面是svd近似-----------------------------------------------------")
u,d,vt = sparse.linalg.svds(A,k)
u,d,VT = u[:,::-1],d[::-1],vt[::-1,:]
#::-1表示翻转
print("------U-----")
print(u)
print("------S-----")
print(d)
print("------VT-----")
print(VT)
如果想通过计算svd结果来恢复原来的矩阵咋办?
注意需要把S处理成对角阵才能恢复成最初的矩阵。