计算R中bigmatrix的零空间

时间:2017-09-16 11:45:04

标签: r matrix r-bigmemory large-data

我找不到任何函数或包来计算R中bigmatrix(来自library(bigmemory))的零空间或(QR分解)。例如:

library(bigmemory)

a <- big.matrix(1000000, 1000, type='double', init=0)

我尝试了以下但是显示了错误。如何找到bigmemory对象的空格?

a.qr <- Matrix::qr(a)
# Error in as.vector(data) : 
#   no method for coercing this S4 class to a vector
q.null <- MASS::Null(a)
# Error in as.vector(data) : 
#   no method for coercing this S4 class to a vector

2 个答案:

答案 0 :(得分:9)

如果要计算矩阵的完整SVD,可以使用包 bigstatsr 按块执行计算。 FBM代表Filebacked Big Matrix,是一个类似于 bigmemory 包的文件备份big.matrix对象的对象。

library(bigstatsr)
options(bigstatsr.block.sizeGB = 0.5)

# Initialize FBM with random numbers
a <- FBM(1e6, 1e3)
big_apply(a, a.FUN = function(X, ind) {
  X[, ind] <- rnorm(nrow(X) * length(ind))
  NULL
}, a.combine = 'c')

# Compute t(a) * a
K <- big_crossprodSelf(a, big_scale(center = FALSE, scale = FALSE))

# Get v and d where a = u * d * t(v) the SVD of a
eig <- eigen(K[])
v <- eig$vectors
d <- sqrt(eig$values)

# Get u if you need it. It will be of the same size of u
# so that I store it as a FBM.
u <- FBM(nrow(a), ncol(a))
big_apply(u, a.FUN = function(X, ind, a, v, d) {
  X[ind, ] <- sweep(a[ind, ] %*% v, 2, d, "/")
  NULL
}, a.combine = 'c', block.size = 50e3, ind = rows_along(u),
a = a, v = v, d = d)

# Verification
ind <- sample(nrow(a), 1000)
all.equal(a[ind, ], tcrossprod(sweep(u[ind, ], 2, d, "*"), v))

我的电脑大约需要10分钟。

答案 1 :(得分:2)

@Mahon @ user20650 @F.Privė为了清楚起见,我抓住了大记忆团队并要求

  

基本上,是否存在适用于大内存矩阵的QR函数(QR分解)的实现?

我觉得澄清问题的原始问题是有用的。 @F.Privė - 很好的答案。希望您的回答和他们的回应将有助于指导未来的人们。他们的答复如下:

  

谢谢你的说明。目前没有qr分解的实现。理想情况下,您可以使用Householder反射(如果矩阵是密集的)或Givens旋转(如果它是稀疏的)来实现这一点。

     

irlba包 与bigmemory兼容。它提供截断的奇异值分解。因此,如果矩阵相对稀疏,则可以截断矩阵的等级。这可能是你最好的选择。如果您不知道排名,那么您可以使用该包迭代地更新截断。

     

请注意,如果您的基质是(高而瘦,或短而脂肪),那么SO解决方案就可以了。但是,无论何时您使用计算交叉乘积,都会失去一些数值稳定性。如果您计划反转矩阵,这可能是一个问题。