den*_*ger 26 python r sparse-matrix pca scikit-learn
我一直在比较Python和R的几个PCA实现的性能,并注意到一个有趣的行为:
虽然在Python中计算稀疏矩阵的PCA似乎是不可能的(唯一的方法是scikit-learn的 TruncatedSVD,但它确实如此)不支持平均居中要求等同于PCA的协方差解决方案.他们的论证是,它会破坏矩阵的稀疏性.其他实现如Facebook的PCA算法或scikit中的PCA/randomPCA方法学习不支持稀疏矩阵出于类似的原因.
虽然所有这些对我来说都是有意义的,但是几个R包,如irlba,rsvd等,能够处理稀疏矩阵(例如生成rsparsematrix),甚至允许特定的center=True参数.
我的问题是,R如何在内部处理它,因为它似乎比类似的Python实现更有效.R是否仍然通过绝对缩放来保持稀疏性(这理论上会伪造结果,但至少保持稀疏性)?或者有没有任何方法可以明确地为零值存储均值,并且只存储一次(而不是分别存储每个值)?
为了得到推迟:R内部如何存储具有均值中心的矩阵而不会爆炸RAM使用.希望足够简洁....
这里的关键是部分 SVD 的底层实现(重新启动的 Lanczos 双对角化 C 代码)不存储矩阵。相反,您可以记录应用于从上一次迭代获得的一小组向量的矩阵的线性运算的结果。
我不会解释 C 代码中使用的具体方法,这是相当先进的(参见论文的描述),我将用一个更简单的算法来解释它,该算法捕获了如何从稀疏性中保持效率的关键思想:功率方法(或子空间迭代方法,将其推广到多个特征值)。该算法通过迭代应用线性算子返回矩阵 A 的最大特征值,然后归一化(或在子空间迭代的情况下正交化一小组向量)
你在每次迭代中所做的事情是
v=A*v
v=v/norm(v)
Run Code Online (Sandbox Code Playgroud)
矩阵乘法步骤是关键的一步,所以让我们看看当我们对中心 A 尝试相同的操作时会发生什么。中心 A 的矩阵公式(作为center具有平均列值的向量和ones作为 1 的向量)是:
A_center=A-ones*transpose(center)
Run Code Online (Sandbox Code Playgroud)
因此,如果我们将迭代算法应用于这个新矩阵,我们会得到
v=A*v-dotproduct(center,v)*ones
Run Code Online (Sandbox Code Playgroud)
由于 A 是稀疏的,我们可以在 (A,v) 上使用稀疏矩阵向量积,并且-dotproduct(center,v)*ones只需从结果向量中减去中心和 v 的点积,该向量在 的维度上呈线性A。