如何使用numpy python更改SVD的顺序

时间:2018-09-08 12:22:31

标签: python numpy pca svd

我正在使用奇异值分解(SVD)进行图像的主成分分析(PCA)。

我有17张20 X 20的图片 所以我创建了图像矩阵

M =  dim(400 X 17)

当我应用SVD(M = u @ d @ v)时,它会给我

u = dim(400 X 17)
d = dim(17 X 17)   
v = dim(17 X 17)

但是我想找到u = dim(400 X 400)d =(400 X 400)v =(400 X 17),因为将有400个特征向量和400个特征值。

我什至尝试做移调,但是没有运气

我知道问题的标题可能不太清楚,因此请根据需要进行更改,这是一些与数据有关的信息

  1. 我通过减去平均脸来集中数据

  2. 我试图通过找到协方差矩阵(MM')的特征向量来进行变通,但是当我尝试显示PCA1时,它仅显示黑色图像

请帮帮我

1 个答案:

答案 0 :(得分:3)

特征值未为矩形矩阵定义,但奇异值是相关的。对于特征向量,您总是会有一组左右特征向量跨越列和行空间。

SVDMM'M'M

的特征值分解有关
  • M'M = V (S'S) V'
  • MM' = U (SS') U'

现在

  • V的列是M'M的特征向量,在您的情况下,其大小为(17 x 17)。因此,V(17 x 17)
  • U的列是MM'的特征向量,在您的情况下,其大小为(400 x 400)。因此,U(400 x 400)

现在S的大小是多少? S的非零元素(奇异值)是M'MMM'的非零特征值的平方根。可以看出,这两个具有相同的非零特征值集,因此在第一种情况下S(17 x 17),在第二种情况下(400 x 400)。我们如何与SVD为M = USV'的事实协调起来?我们用17个非零特征值的平方根构建rectangular diagonal matrix (400 x 17)

您可以从scipy使用SVD:

import scipy

u, s, vh = scipy.linalg.svd(M, full_matrices=True)
print(u.shape, s.shape, vh.shape)

给出

((400, 400), (17,), (17, 17))

要将您的S转到(400 x 17)

s = np.concatenate([np.diag(s), np.zeros((400-17, 17))], axis=0)

检查SVD的正确性:

res = u@s@vh
np.allclose(res, a)

True

低秩矩阵逼近

有时候,您想近似使用排名M的低排名M_tilde的矩阵r,如果要最小化两者之间采用Frobenius范数,只需保持r最大奇异值(Eckhart-Young定理)。 U, S, V的大小变为:(400 x r), (r x r), (r x 17),其中S是对角线。

我不知道您正在使用哪个函数,但这就是正在发生的事情:零奇异值被丢弃了,因为(m x n)矩阵最多可以具有min(m, n)级(在您的案子17)。