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

Posted

技术标签:

【中文标题】如何使用 numpy python 更改 SVD 的顺序【英文标题】:How change order of SVD using numpy python 【发布时间】:2019-02-13 13:28:29 【问题描述】:

我正在使用奇异值分解 (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 个特征值。

我什至尝试过转置但没有成功

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

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

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

请帮帮我

【问题讨论】:

“400 个特征向量和 400 个特征值”——对于 17 阶的矩阵?没有。 【参考方案1】:

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

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 的非零元素(奇异值)是 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_tilder,在这种情况下,如果你想最小化两者之间的 Frobenius 范数,您只需保留r 最大奇异值(Eckhart-Young 定理)。 U, S, V 的大小变为:(400 x r), (r x r), (r x 17),其中S 是对角线。

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

【讨论】:

以上是关于如何使用 numpy python 更改 SVD 的顺序的主要内容,如果未能解决你的问题,请参考以下文章

在python中设置svd算法的维度

使用numpy求解Zoepritz 方程矩阵伪逆时报错: SVD did not converge

使用 Numpy (np.linalg.svd) 进行奇异值分解

Python加速奇异值分解

成功解决numpy.linalg.LinAlgError: SVD did not converge

如何使用 sklearn 获得所有三个 SVD 矩阵?