python - 如何使用 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)
我什至尝试过转置但没有运气
我知道问题的标题可能不太清楚,所以请随意更改,这里有一些与数据相关的信息
我通过减去平均人脸来集中数据
我试图通过找到协方差矩阵(MM')的特征向量来解决,但是当我尝试显示 PCA1 时它只显示黑色图像
请帮帮我
解决方案
没有为矩形矩阵定义特征值,但奇异值是相关的。至于特征向量,您总是有一组跨越列和行空间的左右特征向量。
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'M
MM'
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:的大小,其中是对角线。M
M_tilde
r
r
U, S, V
(400 x r), (r x r), (r x 17)
S
我不知道您正在使用哪个函数,但这就是正在发生的事情:零奇异值被丢弃,因为(m x n)
矩阵最多可以具有秩min(m, n)
(在您的情况下为 17)。
推荐阅读
- python - 在子图直方图上绘制范数曲线
- c# - 如何使文本显示所有 8 位数字并在此之后清除文本?
- numpy - 将 numpy 数组作为 jpeg 写入缓冲区
- javascript - Web-Worker 导入的脚本可以依次导入另一个脚本吗?
- java - 如何将java库连接到项目以测试库
- python - 无法使用 df.iterrows 从数据框中提取值?
- python - 如何进行列表和证明数字?
- node.js - 获取删除文档 mongoose 的 id
- python - 使用 Kale 将我的 Jupyter Notebook 转换为 Kubeflow 管道时出现索引超出范围错误
- python - 熊猫:计算列中相同的值但来自不同的索引