Matlab - 截断 SVD / PCA 的快速计算

计算科学 matlab svd
2021-12-08 18:54:52

我正在使用 Matlab 代码库,其中我试图通过用其最大主成分A*c = b逼近(方形)矩阵来解决(基本上使用 rank- PCA 近似)。我目前正在通过编写 来做到这一点,其中最大奇异值是这行得通;但是,即使,该方法也很慢,因为我认为 Matlab正在计算引擎盖下的完整 SVD,而像 power 方法这样更简单的方法就足够了。AqqAc = pinv(A, tol)*btolqAq=1pinvA

是否有更合适/更快的 Matlab 例程来近似A基于其截断/增量 SVD 的逆?例如,有没有办法只获得 的最大q奇异向量/值A,而不计算任何其他奇异向量/值?我一直在计算完整的[U,S,V]=svd(A)然后取我想要的列/值,但这效率不高。

我知道我可以自己实现幂方法和通货紧缩 - 并且最终可能会这样做 - 但我的具体问题是关于使用内置 Matlab 例程完成这项任务的计算效率最高的方法(并且少至可能的)。如果 Matlab 没有很好的内置方法来做到这一点,我也愿意接受第三方 Matlab 软件包的建议,这将有效地提供此功能;例如,我见过IncPACK2,它乍一看似乎是在做正确的事情(尽管它不再被维护......)。

1个回答

可以使用 SVD 计算伪逆A=USV经过:

A+=VΣ+U
在哪里Σ+Σ通过取所有非零元素的倒数。考虑到这一点,您可以svds按如下方式使用 MATLAB 的函数:

[U,S,V] = svds(A,k); 
Ainv = V*diag(1./diag(S))*U';

这里k指的是秩,svds只计算奇异值和向量的子集。由于使用了 Krylov 子空间方法,它还允许限制其他因素,例如子空间维度。