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

3

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

我有17张20x20大小的图片,所以我创建了图片矩阵。

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时,它只显示黑色图像。
请帮忙解决。

矩阵的秩为17,拥有400个特征向量和400个特征值?不可能。 - user6655984
1个回答

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)。那么我们如何将其与我们的SVDM = USV'协调一致呢?我们构建一个矩形对角矩阵(400 x 17),其中包含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

低秩矩阵逼近

有时候你想用秩为r的低秩矩阵M_tilde逼近矩阵M,在这种情况下,如果你想要最小化两者之间的Frobenius范数,你只需要保留r个最大的奇异值(Eckhart-Young定理)。U, S, V的大小变为:(400 x r), (r x r), (r x 17),其中S是对角线矩阵。

我不知道你使用的是哪个函数,但是这就是发生的事情:零奇异值被抛弃了,因为一个(m x n)的矩阵最多只能有秩min(m, n)(在你的情况下是17)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接