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

标签 python numpy pca

我正在阅读 Abdi & Williams (2010)“主成分分析”,我正在尝试重做 SVD 以获得进一步 PCA 的值。

文章指出以下 SVD:

X = P D Q^t

我将数据加载到 np.array X 中。

X = np.array(data)
P, D, Q = np.linalg.svd(X, full_matrices=False)
D = np.diag(D)

但是我在检查时没有得到上面的相等性

X_a = np.dot(np.dot(P, D), Q.T)

X_a 和 X 是相同的维度,但是值不一样。我是否遗漏了什么,或者 np.linalg.svd 函数的功能是否与论文中的方程不兼容?

最佳答案

TL;DR:numpy 的 SVD 计算 X = PDQ,因此 Q 已经转置。

SVD 将矩阵 X 有效地分解为旋转 PQ 以及对角矩阵 D。我为 PQ 返回正向旋转的 linalg.svd() 版本。您不想在计算 X_a 时转换 Q

import numpy as np
X = np.random.normal(size=[20,18])
P, D, Q = np.linalg.svd(X, full_matrices=False)
X_a = np.matmul(np.matmul(P, np.diag(D)), Q)
print(np.std(X), np.std(X_a), np.std(X - X_a))

我得到:1.02、1.02、1.8e-15,表明 X_a 非常准确地重构了 X

如果您使用的是 Python 3,@ 运算符可实现矩阵乘法并使代码更易于理解:

import numpy as np
X = np.random.normal(size=[20,18])
P, D, Q = np.linalg.svd(X, full_matrices=False)
X_a = P @ diag(D) @ Q
print(np.std(X), np.std(X_a), np.std(X - X_a))
print('Is X close to X_a?', np.isclose(X, X_a).all())

关于python - 使用 Numpy (np.linalg.svd) 进行奇异值分解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24913232/

相关文章:

python - 如何在python中将一个函数的变量运行到另一个函数?

Python-对于每个for循环迭代,附加到不同的列表中

python - 如何在不更改原始数组的情况下操作数组的副本?

python - PCA——取均值之差

python - R 稀疏矩阵的内部处理

python - Django Rest Framework JWT 单元测试

python - 在 np.array 中使用颜色

python - GDAL ReadAsArray() 不断返回 None

python - 使用 Numpy 缓解浮点逼近问题

r - 如何使用 stat_ellipse 更改 ggplot2 中椭圆的线型?