使用 bigmemory 和 irlba 的大型矩阵的 SVD 问题
Problems with SVD of a large matrix using bigmemory and irlba
我目前正在尝试使用 bigmemory 和 irlba 实现一个非常大的矩阵的 SVD。据我所知,我必须调整 irlba 包中的 mult 命令,我是这样做的:
mult <- function(A, B, transpose=FALSE) {
if(is.null(dim(B))) B <- cbind(B)
if(transpose)
return(cbind((t(B) %*% A)[]))
cbind((A %*% B)[])
}
但是,使用 irlba 对 运行 大矩阵上的 SVD 不起作用:
irlbaObject <- irlba(big, nv = 10, mult = mult)
为了可复制性,这里有一个我想对其进行 SVD 的大矩阵示例:
big <- file("big.txt", open = "a")
replicate(20, {
x <- matrix(rnorm(100 * 100), nrow = 10)
write.table(x, file = 'big.txt', append = TRUE,
row.names = FALSE, col.names = FALSE)
})
big <- read.big.matrix("big.txt", separated = FALSE,
type = "double",
backingfile = "big.bk",
backingpath = "/tmp",
descriptorfile = "big.desc")
这是我收到的错误消息:
Error in A %*% B : requires numeric/complex matrix/vector arguments
Called from: cbind((A %*% B)[])
有没有人知道如何避免这个错误?
这应该有效:
library(bigalgebra)
library(irlba)
## --> CHANGES HERE <--
setMethod("%*%", signature(x = "big.matrix", y = "numeric"),
function(x, y) x %*% as.matrix(y))
setMethod("%*%", signature(x = "numeric", y = "big.matrix"),
function(x, y) t(x) %*% y)
mult <- function(A, B) (A %*% B)[]
# Repdata
x <- matrix(rnorm(20 * 100 * 100), nrow = 20 * 10)
big <- as.big.matrix(x)
# Computation
irlbaObject <- irlba(big, nv = 10, mult = mult)
# Verification
svd <- svd(x, nu = 10, nv = 10)
plot(irlbaObject$u, svd$u)
plot(irlbaObject$v, svd$v)
注意 1:我认为 irlba 中的算法已更改,现在仅使用矩阵向量乘法。
注意 2:mult 是一个已弃用的参数(它将在下一版本中消失)。
注意 3:我不确定这个解决方案是否会很快。如果您想要一个快速算法来计算部分 SVD,请尝试 package bigstatsr 的函数 big_randomSVD(免责声明:我是作者)。
我目前正在尝试使用 bigmemory 和 irlba 实现一个非常大的矩阵的 SVD。据我所知,我必须调整 irlba 包中的 mult 命令,我是这样做的:
mult <- function(A, B, transpose=FALSE) {
if(is.null(dim(B))) B <- cbind(B)
if(transpose)
return(cbind((t(B) %*% A)[]))
cbind((A %*% B)[])
}
但是,使用 irlba 对 运行 大矩阵上的 SVD 不起作用:
irlbaObject <- irlba(big, nv = 10, mult = mult)
为了可复制性,这里有一个我想对其进行 SVD 的大矩阵示例:
big <- file("big.txt", open = "a")
replicate(20, {
x <- matrix(rnorm(100 * 100), nrow = 10)
write.table(x, file = 'big.txt', append = TRUE,
row.names = FALSE, col.names = FALSE)
})
big <- read.big.matrix("big.txt", separated = FALSE,
type = "double",
backingfile = "big.bk",
backingpath = "/tmp",
descriptorfile = "big.desc")
这是我收到的错误消息:
Error in A %*% B : requires numeric/complex matrix/vector arguments
Called from: cbind((A %*% B)[])
有没有人知道如何避免这个错误?
这应该有效:
library(bigalgebra)
library(irlba)
## --> CHANGES HERE <--
setMethod("%*%", signature(x = "big.matrix", y = "numeric"),
function(x, y) x %*% as.matrix(y))
setMethod("%*%", signature(x = "numeric", y = "big.matrix"),
function(x, y) t(x) %*% y)
mult <- function(A, B) (A %*% B)[]
# Repdata
x <- matrix(rnorm(20 * 100 * 100), nrow = 20 * 10)
big <- as.big.matrix(x)
# Computation
irlbaObject <- irlba(big, nv = 10, mult = mult)
# Verification
svd <- svd(x, nu = 10, nv = 10)
plot(irlbaObject$u, svd$u)
plot(irlbaObject$v, svd$v)
注意 1:我认为 irlba 中的算法已更改,现在仅使用矩阵向量乘法。
注意 2:mult 是一个已弃用的参数(它将在下一版本中消失)。
注意 3:我不确定这个解决方案是否会很快。如果您想要一个快速算法来计算部分 SVD,请尝试 package bigstatsr 的函数 big_randomSVD(免责声明:我是作者)。