我在txt文件中有一个矩阵60 000 x 60 000,我需要得到这个矩阵的svd。我使用R但我不知道R是否可以生成它。
答案 0 :(得分:11)
我认为使用svd
包和irlba
以及bigmemory
计算(部分)bigalgebra
而不使用大量内存是可能的。
首先让我们创建一个20000 * 20000矩阵并将其保存到文件中
require(bigmemory)
require(bigalgebra)
require(irlba)
con <- file("mat.txt", open = "a")
replicate(20, {
x <- matrix(rnorm(1000 * 20000), nrow = 1000)
write.table(x, file = 'mat.txt', append = TRUE,
row.names = FALSE, col.names = FALSE)
})
file.info("mat.txt")$size
## [1] 7.264e+09 7.3 Gb
close(con)
然后您可以使用bigmemory::read.big.matrix
bigm <- read.big.matrix("mat.txt", sep = " ",
type = "double",
backingfile = "mat.bk",
backingpath = "/tmp",
descriptorfile = "mat.desc")
str(bigm)
## Formal class 'big.matrix' [package "bigmemory"] with 1 slots
## ..@ address:<externalptr>
dim(bigm)
## [1] 20000 20000
bigm[1:3, 1:3]
## [,1] [,2] [,3]
## [1,] -0.3623255 -0.58463 -0.23172
## [2,] -0.0011427 0.62771 0.73589
## [3,] -0.1440494 -0.59673 -1.66319
现在我们可以使用优秀的irlba
包,如包装插图中所述。
第一步包括定义矩阵乘法运算符,它可以与big.matrix
对象一起使用,然后使用irlba::irlba
函数
### vignette("irlba", package = "irlba") # for more info
matmul <- function(A, B, transpose=FALSE) {
## Bigalgebra requires matrix/vector arguments
if(is.null(dim(B))) B <- cbind(B)
if(transpose)
return(cbind((t(B) %*% A)[]))
cbind((A %*% B)[])
}
dim(bigm)
system.time(
S <- irlba(bigm, nu = 2, nv = 2, matmul = matmul)
)
## user system elapsed
## 169.820 0.923 170.194
str(S)
## List of 5
## $ d : num [1:2] 283 283
## $ u : num [1:20000, 1:2] -0.00615 -0.00753 -0.00301 -0.00615 0.00734 ...
## $ v : num [1:20000, 1:2] 0.020086 0.012503 0.001065 -0.000607 -0.006009 ...
## $ iter : num 10
## $ mprod: num 310
我忘记设置种子以使其可再现,但我只想表明在R中可以这样做。
编辑
如果您使用的是新版本的软件包irlba
,则上述代码会抛出错误,因为函数matmult
的{{1}}参数已重命名为irlba
。因此,您应该更改代码的这一部分
mult
通过
S <- irlba(bigm, nu = 2, nv = 2, matmul = matmul)
我要感谢@FrankD指出这一点。
答案 1 :(得分:2)
在R 3.x +中你可以构造一个这个大小的矩阵,矢量大小的上限是2 ^ 53(或者可能是2 ^ 53-1),从2 ^ 31- 1之前的原因是Andrie在他过时的装置上犯了一个错误。它通常需要每个数字元素10个字节。无论如何:
> 2^53 < 10*60000^2
[1] FALSE # so you are safe on that account.
它也适合64GB(但不是32GB):
> 64000000000 < 10*60000^2
[1] FALSE
一般来说,为了做任何认真的工作,你需要的尺寸至少是你最大物体尺寸的3倍,所以即使使用新的扩展矢量/矩阵,这似乎也非常临界。