在文献中闲逛(或在Google中搜索“截断的SVD算法”)会发现很多使用以各种方式截短的,并声称(令人沮丧的是,通常没有引证)有快速的算法可以对其进行计算,但是没有人似乎在指出这些算法是什么。
我想看到的是一组精确且不精确的算法,适合理解系统的工作原理(但不一定要实际实现它们!)。
有人对这种事情有很好的参考吗?
在文献中闲逛(或在Google中搜索“截断的SVD算法”)会发现很多使用以各种方式截短的,并声称(令人沮丧的是,通常没有引证)有快速的算法可以对其进行计算,但是没有人似乎在指出这些算法是什么。
我想看到的是一组精确且不精确的算法,适合理解系统的工作原理(但不一定要实际实现它们!)。
有人对这种事情有很好的参考吗?
Answers:
从广义上讲,有两种方法来计算特征值或奇异值分解。一种方法是对角线化矩阵,这实际上会同时产生整个特征值/奇异值分解(整个特征值谱),请参见此处的概述:计算奇异值分解(SVD)的有效算法是什么?另一种选择是使用一种迭代算法,该算法一次生成一个(或几个)特征向量。在计算出所需数量的特征向量之后,可以停止迭代。
我认为没有专门针对SVD的迭代算法。这是因为,可以计算a的SVD 矩阵乙通过执行一个正方形对称的特征分解(Ñ + 米)× (Ñ + 米)矩阵甲 = (0 乙乙 ⊤ 0)。因此,您应该问的不是问什么算法可以计算出截断的SVD,而是要问什么迭代算法可以计算出特征分解的:截断SVD的算法≈ 迭代求特征分解的算法。
最简单的迭代算法称为 幂迭代,实际上非常简单:
所有更复杂的算法最终都基于功率迭代思想,但确实变得相当复杂。必要的数学由Krylov子空间给出。这些算法是Arnoldi迭代(用于平方非对称矩阵),Lanczos迭代(用于平方对称矩阵)及其变体,例如“隐式重启Lanczos方法”等。
您可以在以下教科书中找到相关说明:
所有合理的编程语言和统计信息包(Matlab,R,Python numpy,您都可以使用它)都使用相同的Fortran库来执行特征/奇异值分解。这些是LAPACK和ARPACK。ARPACK代表ARnoldi PACKage,全都与Arnoldi / Lanczos迭代有关。例如,在Matlab中,SVD有两个功能:svd
通过LAPACK执行完全分解,并svds
通过ARPACK计算给定数量的奇异矢量,并且它实际上只是eigs
对“平方化”矩阵的调用的包装。
更新资料
这些方法也有一个Fortran库,称为PROPACK:
软件包PROPACK包含一组函数,用于计算大型和稀疏或结构化矩阵的奇异值分解。SVD例程基于具有部分正交化(BPRO)的Lanczos双角化算法。
但是,PROPACK似乎不如ARPACK标准,并且标准编程语言本身不支持。它由拉斯穆斯·拉森(Rasmus Larsen)撰写,他有1998年的长达90页的大型论文Lanczos双角化和部分正交化,并且看起来很不错。感谢@MichaelGrant通过此计算科学SE线程。
在最近的论文中,最受欢迎的似乎是Baglama&Reichel,2005, Augmented隐式重启Lanczos的对角化方法,这可能是最新技术。感谢@Dougal在评论中提供了此链接。
更新2
实际上,您自己引用的概述文件中确实有一种完全不同的方法:Halko等。2009,寻找具有随机性的结构:用于构造近似矩阵分解的概率算法。我对评论还不够了解。
这是我过去成功使用的一种技术(在Netflix数据集上)用于计算截短的SVD。它取自本文。在协作过滤设置中,我应该注意,大多数值都丢失了,而关键是要对其进行预测,因此要使用截短的SVD解决此类问题,必须使用在该条件下有效的技术。简短说明: