Если я правильно понял, решение lapply
, вероятно, способ ответить на ваш вопрос. Это тот же подход, как и ответ, что Вы связываетесь, но вот самодостаточный пример, который мог бы быть ближе к прецеденту:
библиотекам нагрузки и воспроизводимым данным (пожалуйста, включите их в своих будущих вопросах здесь)
library(tm)
library(RWeka)
data(crude)
Ваш биграмм токенизатор ...
#Tokenizer for n-grams and passed on to the term-document matrix constructor
BigramTokenizer <- function(x) NGramTokenizer(x, Weka_control(min = 2, max = 2))
txtTdmBi <- TermDocumentMatrix(crude, control = list(tokenize = BigramTokenizer))
Убедитесь, что он работал путем проверки случайной выборки ...
inspect(txtTdmBi[1000:1005, 10:15])
A term-document matrix (6 terms, 6 documents)
Non-/sparse entries: 1/35
Sparsity : 97%
Maximal term length: 18
Weighting : term frequency (tf)
Docs
Terms 248 273 349 352 353 368
for their 0 0 0 0 0 0
for west 0 0 0 0 0 0
forced it 0 0 0 0 0 0
forced to 0 0 0 0 0 0
forces trying 1 0 0 0 0 0
foreign investment 0 0 0 0 0 0
Вот ответ на ваш вопрос:
Теперь используйте lapply
функцию для вычисления связанных слов для каждого элемента вектора точки в матрице термина документа. Вектор термина наиболее просто доступен с txtTdmBi$dimnames$Terms
. Например, txtTdmBi$dimnames$Terms[[1005]]
- это «иностранные инвестиции».
Здесь я использовал llply
из пакета plyr
, поэтому у нас может быть индикатор выполнения (утешительный для больших заданий), но он в основном такой же, как и базовая функция lapply
.
library(plyr)
dat <- llply(txtTdmBi$dimnames$Terms, function(i) findAssocs(txtTdmBi, i, 0.5), .progress = "text")
Выход список, где каждый элемент списка представляет собой вектор именованных чисел, где имя это термин, и число это значение корреляции.Например, чтобы увидеть условие, связанное с «иностранными инвестициями», мы можем получить доступ к списку как так:
dat[[1005]]
и здесь термины, связанные с этим термином (я только что вставил в топе несколько)
168 million 1986 was 1987 early 300 mln 31 pct
1.00 1.00 1.00 1.00 1.00
a bit a crossroads a leading a political a population
1.00 1.00 1.00 1.00 1.00
a reduced a series a slightly about zero activity continues
1.00 1.00 1.00 1.00 1.00
advisers are agricultural sector agriculture the all such also reviews
1.00 1.00 1.00 1.00 1.00
and advisers and attract and imports and liberalised and steel
1.00 1.00 1.00 1.00 1.00
and trade and virtual announced since appears to are equally
1.00 1.00 1.00 1.00 1.00
are recommending areas for areas of as it as steps
1.00 1.00 1.00 1.00 1.00
asia with asian member assesses indonesia attract new balance of
1.00 1.00 1.00 1.00 1.00
Это то, что вы хотите сделать?
Кстати, если матрица терм-документ очень большой, вы можете попробовать эту версию findAssocs
:
# u is a term document matrix
# term is your term
# corlimit is a value -1 to 1
findAssocsBig <- function(u, term, corlimit){
suppressWarnings(x.cor <- gamlr::corr(t(u[ !u$dimnames$Terms == term, ]),
as.matrix(t(u[ u$dimnames$Terms == term, ])) ))
x <- sort(round(x.cor[(x.cor[, term] > corlimit), ], 2), decreasing = TRUE)
return(x)
}
Это можно сделать следующим образом:
dat1 <- llply(txtTdmBi$dimnames$Terms, function(i) findAssocsBig(txtTdmBi, i, 0.5), .progress = "text")
Преимущество это то, что он использует другой способ преобразования TDM в матрицу tm:findAssocs
. Этот другой метод использует память более эффективно и поэтому предотвращает такое сообщение: Error: cannot allocate vector of size 1.9 Gb
от происходящего.
Быстрый бенчмаркинга показывает, что обе findAssocs
функции примерно с той же скоростью, так что главное различие заключается в использовании памяти:
library(microbenchmark)
microbenchmark(
dat1 <- llply(txtTdmBi$dimnames$Terms, function(i) findAssocsBig(txtTdmBi, i, 0.5)),
dat <- llply(txtTdmBi$dimnames$Terms, function(i) findAssocs(txtTdmBi, i, 0.5)),
times = 10)
Unit: seconds
expr min lq median
dat1 <- llply(txtTdmBi$dimnames$Terms, function(i) findAssocsBig(txtTdmBi, i, 0.5)) 10.82369 11.03968 11.25492
dat <- llply(txtTdmBi$dimnames$Terms, function(i) findAssocs(txtTdmBi, i, 0.5)) 10.70980 10.85640 11.14156
uq max neval
11.39326 11.89754 10
11.18877 11.97978 10
Благодаря Бен! Мне удалось найти ассоциации для всех биграмм в моей терминологической матрице. Однако в переменной 'dat' я заменил' txtTdmBi $ dimnames $ Terms' на 'txtTdmBi', так как я продолжал получать ошибку:' 0% Ошибка в UseMethod ("findAssocs", x): не применяется применимый метод для 'findAssocs' к объекту класса «character» ' – Grote
В дополнение к этой теме; функция 'findAssocsBig' в вашем примере - отличное решение для сохранения памяти. Как подать заявку на несколько терминов. Также подход 'lapply'? – Grote
Благодарим за ошибку, я исправил свой ответ и добавил, как вы можете использовать другую функцию. – Ben