Python、C 或 Fortran 中的可更新 SVD 实现?

计算科学 线性代数 Python
2021-12-12 09:37:45

我想使用 SVD 进行进化因子分析:

给定m×n数据矩阵A,并且对于每个i从 1 到m,我想计算奇异值:

A[1:i, 1:n]

如果有一种方法可以在添加行后更新计算的 SVDA.

我很确定确实存在这样的算法:是否有可用于 Python 的开放实现?指向 C 或 Fortran 中的开放实现的指针也很有用。

2个回答

SVD 的 rank-1 更新算法(也称为增量 SVD)确实存在,但我无法在任何地方找到类似 LAPACK 的实现。

我看到反复提到的是 Brand (2003)。这个网站来看,使用现有的 LAPACK 和 BLAS 例程作为构建块来实现 Brand 的算法似乎相对简单,这或许可以解释为什么没有大牌公司费心编写专门的实现。

您可以在此处此处此处找到各种算法的 MATLAB 实现最后一个指向 IncPACK 的链接还提到了隐藏在 Trilinos 开发分支中的 C++ 实现。

Brand 算法的 Python 实现(来自他 2006 年的一篇论文)可以在0.5.0 版包的类的svdAddCols方法中找到。(注意:我在 0.8.4 版本中找不到这种方法;类似的方法0.7.4 版本中存在。)LsiModelgensimgensimsvdUpdategensim

Gu 的另一种算法是在包isvd中实现的,该包使用 C 或 C++(没有查看源代码来判断哪个;我从这里的链接到达这个项目,其中讨论了 isvd 的编译标志)。另一个 C++(不幸的是,基于 Windows)的实现隐藏在 Netflix 推荐算法Netflix 推荐算法似乎经常使用增量 SVD,并且可能是另一个潜在的实现来源。

这是我能用我的 Google-fu 做的最好的事情。

这是基于 Mathew Brand 的“薄奇异值分解的快速低秩修改”的开放实现

manual_svd_update.py

这是它的测试代码

test_manual_svd_update.py