Преобразование матрицы документов в матрицу с большим количеством данных приводит к переполнению
Позвольте сделать текстовую обработку
Здесь я стою с матрицей терминов документов (из пакета tm
)
dtm <- TermDocumentMatrix(
myCorpus,
control = list(
weight = weightTfIdf,
tolower=TRUE,
removeNumbers = TRUE,
minWordLength = 2,
removePunctuation = TRUE,
stopwords=stopwords("german")
))
Когда я делаю
typeof(dtm)
Я вижу, что это "список", и структура выглядит как
Docs
Terms 1 2 ...
lorem 0 0 ...
ipsum 0 0 ...
... .......
Итак, я попробую
wordMatrix = as.data.frame( t(as.matrix( dtm )) )
Это работает для 1000 документов.
Но когда я пытаюсь использовать 40000, этого больше нет.
Я получаю эту ошибку:
Fehler in vector(typeof(x$v), nr * nc) : Vektorgröße kann nicht NA sein
Zusätzlich: Warnmeldung:
In nr * nc : NAs durch Ganzzahlüberlauf erzeugt
Ошибка в векторе...: Вектор не может быть NA
Дополнительно:
В nr * nc NA, созданных при переполнении целых чисел
Итак, я посмотрел на as.matrix, и получается, что каким-то образом функция преобразует ее в вектор с as.vector и, чем с матрицей.
Преобразование в вектор работает, но не одно из вектора в матрицу dosen't.
Есть ли у вас какие-либо предложения, что может быть проблемой?
Спасибо, Капитан
Ответы
Ответ 1
Переполнение целых чисел сообщает вам, в чем проблема: с 40000 документами у вас слишком много данных. Именно в преобразовании в матрицу проблема начинается с btw, что можно увидеть, если вы посмотрите на код базовой функции:
class(dtm)
[1] "TermDocumentMatrix" "simple_triplet_matrix"
getAnywhere(as.matrix.simple_triplet_matrix)
A single object matching ‘as.matrix.simple_triplet_matrix’ was found
...
function (x, ...)
{
nr <- x$nrow
nc <- x$ncol
y <- matrix(vector(typeof(x$v), nr * nc), nr, nc)
...
}
Это строка, на которую ссылается сообщение об ошибке. То, что происходит, можно легко моделировать:
as.integer(40000 * 60000) # 40000 documents is 40000 rows in the resulting frame
[1] NA
Warning message:
NAs introduced by coercion
Функция vector()
принимает аргумент с длиной, в данном случае nr*nc
Если это больше, чем appx. 2e9 (.Machine$integer.max
), он будет заменен на NA. Этот NA недействителен как аргумент для vector()
.
Bottomline: Вы попадаете в рамки R. На данный момент работа на 64-битном не поможет. Вам придется прибегать к различным методам. Одна из возможностей - продолжить работу с указанным вами списком (dtm - это список), выбрав нужные данные, используя манипуляции с списками, и оттуда оттуда.
PS: Я создал объект dtm
require(tm)
data("crude")
dtm <- TermDocumentMatrix(crude,
control = list(weighting = weightTfIdf,
stopwords = TRUE))
Ответ 2
Вот очень простое решение, которое я недавно обнаружил
DTM=t(TDM)#taking the transpose of Term-Document Matrix though not necessary but I prefer DTM over TDM
M=as.big.matrix(x=as.matrix(DTM))#convert the DTM into a bigmemory object using the bigmemory package
M=as.matrix(M)#convert the bigmemory object again to a regular matrix
M=t(M)#take the transpose again to get TDM
Обратите внимание, что передача транспонирования TDM для получения DTM абсолютно необязательна, это мое личное предпочтение играть с матрицами таким образом
P.S. Не мог ответить на вопрос 4 года назад, поскольку я был просто свежей записью в моем колледже.
Ответ 3
На основании ответа Жориса Мейса я нашел решение. Документация "vector()" относительно аргумента "длина"
... Для длинного вектора, т.е. Length > .Machine $integer.max, он должен иметь тип "double"...
Итак, мы можем сделать крошечное исправление as.matrix():
as.big.matrix <- function(x) {
nr <- x$nrow
nc <- x$ncol
# nr and nc are integers. 1 is double. Double * integer -> double
y <- matrix(vector(typeof(x$v), 1 * nr * nc), nr, nc)
y[cbind(x$i, x$j)] <- x$v
dimnames(y) <- x$dimnames
y
}