Преобразование матрицы документов в матрицу с большим количеством данных приводит к переполнению

Позвольте сделать текстовую обработку

Здесь я стою с матрицей терминов документов (из пакета 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
}