首页 > 解决方案 > 如何使用 numpy python 更改 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)and因为会有 400 个特征向量和 400 个特征值d =(400 X 400)v =(400 X 17)

我什至尝试过转置但没有运气

我知道问题的标题可能不太清楚,所以请随意更改,这里有一些与数据相关的信息

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

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

请帮帮我

标签: pythonnumpypcasvd

解决方案


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

SVD与和的特征值分解MM'有关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的非零特征值的平方根。可以看出这两个具有相同的非零特征值集,因此在第一种情况下是和在第二种情况下。我们如何协调这与我们的 SVD 是 的事实?我们用 17 个非零特征值的平方根构建一个矩形对角矩阵。M'MMM'S(17 x 17)(400 x 400)M = USV' (400 x 17)

您可以从以下位置使用 SVD scipy

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

低秩矩阵逼近

有时您想用 rank 的低秩来近似矩阵,在这种情况下,如果您想最小化两者之间的 Frobenius 范数,您只需保留最大的奇异值(Eckhart-Young 定理)。become:的大小,其中是对角线。MM_tilderrU, S, V(400 x r), (r x r), (r x 17)S

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


推荐阅读