python - 稀疏矩阵的 R 内部处理
问题描述
我一直在比较 Python 和 R 的几个 PCA 实现的性能,并注意到一个有趣的行为:
虽然在 Python 中计算稀疏矩阵的 PCA 似乎是不可能的(唯一的方法是scikit-learn 的TruncatedSVD,但它确实不支持等同于 PCA 的协方差解决方案所需的均值居中。他们的论点是,它会破坏矩阵的稀疏性。其他实现,如 Facebook 的 PCA 算法或 scikit learn 中的 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)
矩阵乘法步骤是至关重要的一步,所以让我们看看当我们用居中的 A 尝试相同的事情时会发生什么。居中的 A 的矩阵公式(center
作为具有平均列值的向量和ones
作为 1 的向量)是:
A_center=A-ones*transpose(center)
因此,如果我们将迭代算法应用于这个新矩阵,我们将得到
v=A*v-dotproduct(center,v)*ones
由于 A 是稀疏的,我们可以在 (A,v) 上使用稀疏矩阵向量积,-dotproduct(center,v)*ones
只需从结果向量中减去 center 和 v 的点积,该向量在 的维度上是线性的A
。
推荐阅读
- reactjs - 实时跟踪网络地理位置
- vba - 可能知道何时需要凭证
- excel - 如何实现变量并优化以下代码?
- spring - Maven 中缺少的方法:org.springframework.hateoas:spring-hateoas:1.0.0.M3 库 Entitylinks 类
- javascript - 如果数组结束 javascript 从头开始切片
- java - 杰克逊:无法在不提供 id 的情况下明确指示多态性中的目标类?
- c# - 如何查找 Windows 日语键盘设置的注册表项?
- javascript - 如何正确切换课程?
- mysql - 如何从mysql中的每个表中导出N条记录?
- laravel - 如何为更新帖子制作路由?