TermDocumentMatrix as.matrix использует большой объем памяти

В настоящее время я использую пакет tm для извлечения терминов для кластеризации для обнаружения дубликатов в базе данных приличного размера из 25 тыс. Элементов (30 МБ), это запускается на моем рабочем столе, но когда я пытаюсь запустить его на своем сервере, кажется, безбожное количество времени. При ближайшем рассмотрении я обнаружил, что потратил 4 ГБ свопа, запустив строку apply (posts.TmDoc, 1, sum), чтобы вычислить частоту терминов. Более того, даже при запуске as.matrix на моем рабочем столе создается документ размером 3 ГБ см. http://imgur.com/a/wllXv < / а>

Это необходимо только для генерации частотного подсчета для 18 тысяч терминов по 25 тысячам элементов? Есть ли другой способ сгенерировать счетчик частоты без принуждения TermDocumentMatrix к матрице или вектору?

Я не могу удалить термины из-за разреженности, поскольку именно так реализован фактический алгоритм. Он ищет термины, которые являются общими как минимум для 2, но не более чем для 50, и группирует по ним, вычисляя значение сходства для каждой группы.

Вот код в контексте для справки

min_word_length = 5
max_word_length = Inf
max_term_occurance = 50
min_term_occurance = 2


# Get All The Posts
Posts = db.getAllPosts()
posts.corpus = Corpus(VectorSource(Posts[,"provider_title"]))

# remove things we don't want
posts.corpus = tm_map(posts.corpus,content_transformer(tolower))
posts.corpus = tm_map(posts.corpus, removePunctuation)
posts.corpus = tm_map(posts.corpus, removeNumbers)
posts.corpus = tm_map(posts.corpus, removeWords, stopwords('english'))

# grab any words longer than 5 characters
posts.TmDoc = TermDocumentMatrix(posts.corpus, control=list(wordLengths=c(min_word_length, max_word_length)))

# get the words that occur more than once, but not more than 50 times
clustterms = names(which(apply(posts.TmDoc, 1, sum) >= min_term_occurance  & apply(posts.TmDoc, 1, sum) < max_term_occurance))

person Matt Bucci    schedule 08.12.2014    source источник
comment
Посчитайте: 18e3 * 25e3 * 8 / 1024^3 дает 3,3 ГБ. Так что да, это потребление памяти матрицей. Вместо этого используйте разреженные матрицы.   -  person Andrie    schedule 08.12.2014
comment
Ваш вопрос похож на stackoverflow.com/questions / 14426925 /   -  person Andrie    schedule 08.12.2014
comment
@Andrie, похоже, что подход Sparse все еще требует преобразования его в обычную матрицу, прежде чем, к сожалению, фактически генерировать разреженную матрицу. После преобразования он составляет около 800 КБ, но до этого преобразования он находится в памяти. Я собираюсь попробовать построчный подход, найденный во второй ссылке, используя inspect для извлечения одной строки за раз, а затем сохраняя результат rowSums в именованный список   -  person Matt Bucci    schedule 08.12.2014
comment
@Andrie, оба предыдущих ответа на самом деле оказались не самым эффективным / элегантным решением. Я отправил ответ   -  person Matt Bucci    schedule 08.12.2014


Ответы (1)


Поскольку на самом деле мне никогда не нужны подсчеты частоты, я могу использовать команду findFreqTerms

setdiff(findFreqTerms(posts.TmDoc, 2), findFreqTerms(posts.TmDoc, 50))

такой же как

names(which(apply(posts.TmDoc, 1, sum) >= min_term_occurance  & apply(posts.TmDoc, 1, sum) < max_term_occurance))

но пробегает мгновенно

person Matt Bucci    schedule 08.12.2014
comment
Плюс один за поиск лучшего пути! - person Andrie; 08.12.2014