У меня проблема с большой проблемой, и более конкретная проблема, которую я надеюсь, когда-нибудь решит - решить большую проблему. Я бы очень признателен, если у кого-нибудь есть идеи для меня попробовать.Преобразовать огромную разреженную матрицу в data.table для более быстрого подмножества в R
В основном у меня огромная разреженная матрица (около 300k x 150k, первоначально матрица Term-Document, созданная с пакетом R {tm}), который сохраняется как простая триплетная матрица, используя пакет {slam}, и я запускаю функция, которая пересекает множество терминов, а затем подмножает ее на основе этих терминов. К сожалению, процесс подмножества является чрезмерно медленным.
При попытке выяснить, как подмножество быстрее, я наткнулся на пакет data.table, который очень хорошо выполнялся в некоторых тестах, которые я запускал с ним. Однако, когда я пытаюсь преобразовать свою разреженную матрицу в data.table, я получаю
Error in vector(typeof(x$v), nr * nc) : vector size cannot be NA
In addition: Warning message:
In nr * nc : NAs produced by integer overflow
Я понимаю, что это потому, что он пытается преобразовать его в стандартную матрицу первой, которая является технически вектором R, и 300k * 150k значительно выше .Machine$integer.max
.
Итак, мой вопрос: кто-нибудь знает, как преобразовать простую матрицу триплетов в data.frame или data.table, не преобразовывая ее сначала в матрицу, тем самым избегая целочисленного переполнения?
Если нет, то у кого-нибудь есть другое обходное решение или b) есть ли какие-либо советы по быстрому подмножеству огромных разреженных матриц и/или простых тройных матриц?
Ниже приведен воспроизводимый пример, с которым можно столкнуться. На моей машине цикл, который подмножает каждый из первых 10 строк, занимает около 3 секунд. Как только мы перейдем к сотням тысяч строк, которые быстро становятся непомерно высокими. Заранее спасибо за помощь:
require(slam)
STM <- simple_triplet_matrix(i = as.integer(runif(10000000,1,300000)),
j = as.integer(runif(10000000,1,150000)),
v = rep(rnorm(10), 1000000),
nrow = 300000,
ncol = 150000)
start <- Sys.time()
for (i in 1:10) {
vec <- as.matrix(STM[,i])
}
Sys.time() - start
Sidenote: обратите внимание, что если вы пытаетесь STMm <- as.matrix(STM)
вы получите ту же ошибку переполнения я показал выше.
матрица триплет в основном 3 векторы, содержащие координаты ненулевых элементов в 1-м столбцах 2 и значение в 3-м. Возможный подход (я его не тестировал) заключался бы в использовании RCpp-пакета для написания вашего подмножества в C++, передающего триплет на C++ в виде списка из 3 векторов. Должно быть так же быстро, как все, что вы можете сделать в R. – dww