В настоящее время я пытаюсь реализовать SVD очень большой матрицы с использованием bigmemory и irlba. Насколько я понимаю, мне нужно настроить команду mult в пакете irlba, что я сделал следующим образом:
mult <- function(A, B, transpose=FALSE) {
if (is.null(dim(B))) B <- cbind(B)
if (transpose)
return(cbind((t(B) %*% A)[]))
cbind((A %*% B)[])
}
Однако запустить SVD на большой матрице с помощью irlba не получится:
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)[])
Есть ли у кого-нибудь идеи, как избежать этой ошибки?
@ F.Privé Я загрузил пакет, но все равно получаю ту же ошибку.
Это должно работать:
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, попробуйте функцию big_randomSVD из пакет bigstatsr (отказ от ответственности: я автор).
теперь работает отлично. Большое спасибо! Я обязательно попробую big_randomSVD из вашего пакета.
Я протестировал ваше решение, и оно работает. Однако с некоторыми матрицами результаты не такие, как у простого SVD из базового пакета. Вы знаете, почему это может происходить?
нашел решение: irlbaObject <- irlba (bigicds, nv = 10, mult = mult, tol = 1e-14, work = 30). Результаты такие же.
Что я знаю, так это то, что алгоритм, который раньше использовался irlba (все еще используется?), Недостаточно точен (точность хороша только для первых ПК).
Если вам нужны матричные продукты, я думаю, вам нужно загрузить пакет bigalgebra.