【问题标题】:SVD with numpy - intepretation of results带有 numpy 的 SVD - 结果解释
【发布时间】:2018-12-20 03:24:47
【问题描述】:

我正在尝试使用奇异值分解 (SVD)。我发现这个YouTube Lecture 包含一个示例。但是,当我在 numpy 中尝试这个示例时,我得到了“某种”不同的结果。在这个例子中,输入矩阵是

A = [ [1,1,1,0,0], [3,3,3,0,0], [4,4,4,0,0], [5,5,5,0,0], [0,2,0,4,4], [0,0,0,5,5], [0,1,0,2,2] ]
A = np.asarray(A)
print(A)

[[1 1 1 0 0]
 [3 3 3 0 0]
 [4 4 4 0 0]
 [5 5 5 0 0]
 [0 2 0 4 4]
 [0 0 0 5 5]
 [0 1 0 2 2]]

这个矩阵的秩是 3 (np.linalg.matrix_rank(A))。讲座指出奇异值的数量是矩阵的秩,在示例中,Sigma 矩阵 S 的大小确实为 3=3。但是,当我执行时

U, S, V = np.linalg.svd(A)

矩阵 S 包含 5 个值。另一方面,前 3 个值与示例中的值匹配,其他 2 个基本上为 0。由于 SVD 背后的数值算法和实数的有限表示,我可以假设得到比排名更多的奇异值吗在计算机上 - 或类似的东西?

【问题讨论】:

  • 这看起来像是数字不准确,因为np.allclose(A, np.dot(U * S, V)) 仍然返回True

标签: python numpy linear-algebra svd


【解决方案1】:

正如this 页面所述,numpy 内部使用 LAPACK 例程 _gesdd 来获得 SVD 分解。现在,如果你看到 _gesdd documentation,它会提到,

要找到一般矩阵 A 的 SVD,请调用 LAPACK 例程 ?gebrd 或 ?gbbrd 用于将 A 简化为酉矩阵 B (正交)变换:A = QBPH。然后调用?bdsqr,形成 双对角矩阵的 SVD:B = U1ΣV1H。

所以,这里涉及到两个步骤:

  • 正交变换的双对角化(户主变换)
  • 使用隐式零位移 QR 算法获取双对角矩阵的 SVD。

QR 算法是一种迭代算法,这意味着您不会得到“准确”的答案,但每次迭代都会获得越来越好的近似值,并且如果值的变化低于阈值则停止,因此它是“近似的”那种感觉。

因此,由于实数的有限机器表示导致数值精度问题,即使我们有无限的表示能力,由于迭代性质,我们也会得到“近似”结果(如果我们在有限时间内运行算法)算法。

【讨论】:

  • 感谢您的详细解释。只是补充一下,在我将所有 3 个矩阵“缩小”到预期的形状之后,例如U = np.delete(U, np.s_[rank:], 1) 等,并根据收缩矩阵重构Anp.allclose() 也返回True
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-10
  • 2017-06-13
  • 1970-01-01
  • 2017-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多