Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R程序中超大矩阵的奇异值分解_R_Matrix_Svd_Large Data - Fatal编程技术网

R程序中超大矩阵的奇异值分解

R程序中超大矩阵的奇异值分解,r,matrix,svd,large-data,R,Matrix,Svd,Large Data,我有一个txt文件中的矩阵6000x60000,我需要得到这个矩阵的svd。我使用R,但我不知道R是否能生成它。在r3.x+中,你可以构造一个这样大小的矩阵,向量大小的上限是2^53(或者可能是2^53-1),而之前是2^31-1,这就是为什么安德里在他过时的安装中抛出错误的原因。每个数字元素通常需要10个字节。无论如何: > 2^53 < 10*60000^2 [1] FALSE # so you are safe on that account. >2^53640000000

我有一个txt文件中的矩阵6000x60000,我需要得到这个矩阵的svd。我使用R,但我不知道R是否能生成它。

在r3.x+中,你可以构造一个这样大小的矩阵,向量大小的上限是2^53(或者可能是2^53-1),而之前是2^31-1,这就是为什么安德里在他过时的安装中抛出错误的原因。每个数字元素通常需要10个字节。无论如何:

> 2^53 < 10*60000^2
[1] FALSE  # so you are safe on that account.
>2^53<10*60000^2
[1] 错,因此你是安全的。
它还可以容纳64GB(但不能容纳32GB):

>64000000000<10*60000^2
[1] 假的

一般来说,要做任何严肃的工作,你需要至少3倍于你最大物体的大小,因此即使使用新的扩展向量/矩阵,这看起来也很接近。我认为计算(部分)是可能的
svd
使用
irlba
包和
bigmemory
bigalgera
而不使用大量内存

首先,让我们创建一个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)
现在,我们可以使用优秀的
irlba
包,如包vignette中所述

第一步包括定义矩阵乘法运算符,它可以处理
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


欢迎来到stackoverflow。您可能会从以下关于提出好问题的指导原则中获益:。特别是,请提供一个最小的、可重复的答案,并解释到目前为止您为解决自己的问题所做的努力。可能不会
n@Andrie:在我的机器上:错误:无法分配大小为13.4 Gb的向量。所以可能只是有足够的记忆的问题。至少在R3.x上,我们可以有长数组,我想。@asb这是一个加载的“only”。如果你只需要13.4Gb来创建矩阵,我想你至少需要双倍的容量来做任何有意义的事情。也许三倍。(假设没有使用ff或bigmemory之类的基于磁盘的解决方案。)我认为组合
bigmemory
+
irlba
是一个不错的选择(或者
scidb
,但我发现在我的linux机器上安装它非常困难。)使用
R版本3.0.0(2013-04-03)#平台:x86_64-w64-mingw32/x64(64位)
我得到了
##错误:无法分配大小为26.8 Gb的向量。
我是否需要升级到3.0.1+?+1以进行勾选,并因其R安装过时而退出。哈!:-)我想这可能不是安德烈失败的唯一原因。它可能也会在我六年前的Mac电脑上失败,因为它的最大内存是32GB,所以我得到的唯一分数就是对它的贬低?这有多蹩脚?+1表示方法,看起来很棒。。。但是60e3*60e3怎么样?这是数据的9倍。我想知道这个问题上的大人物是什么?有什么想法吗?:-)@SimonO101从理论上讲,这应该可以处理更大的数据,但只需要更多的时间(现在需要多少时间?)。我会尽快更新它,我们会对bigojist有一个想法,即irlba中的
matmul
参数已重命名为
mult
,这将导致上面的代码抛出错误。仅供参考:“如此处所述”()中的链接不再有效。@Johnnystring谢谢,我想我们现在可以参考套餐小插曲。我将编辑我的答案。再次感谢
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
### 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
S <- irlba(bigm, nu = 2, nv = 2, matmul = matmul)
S <- irlba(bigm, nu = 2, nv = 2, mult = matmul)