Я ищу эффективный способ создания матрицы совпадений терминов для (каждого) целевого слова в корпусе, чтобы каждое вхождение слова составляло свой собственный вектор (строку) вtcm, где столбцы - это слова контекста (т. е. модель совместного использования на основе токенов).Это контрастирует с более распространенным подходом, используемым в векторной семантике, где каждый член (тип) получает строку и столбец в симметричном tcm, а значения агрегируются по (со) вхождениям токенов типов.
Очевидно, что это можно сделать с нуля, используя базовую функциональность R, или взломать, отфильтровав tcm, сгенерированный одним из существующих пакетов, которые делают это, но данные корпуса, с которыми я имею дело, довольно велики (миллионыслова) - и для R уже есть хорошие пакеты корпусов / НЛП, которые эффективно выполняют такие задачи и сохраняют результаты в разреженных матрицах, таких как text2vec
(функция tcm
), quanteda (fcm
)) и тидитекст (cast_dtm
).Поэтому, кажется, нет смысла пытаться заново изобрести колесо (с точки зрения итераторов, хэширования и тому подобного).Но я не могу найти простой способ создания токена на основе токена с любым из них;отсюда этот вопрос.
Минимальный пример:
library(text2vec)
library(Matrix)
library(magrittr)
# default approach to tcm with text2vec:
corpus = strsplit(c("here is a short document", "here is a different short document"), " ")
it = itoken(corpus)
tcm = create_vocabulary(it) %>% vocab_vectorizer() %>% create_tcm(it, . , skip_grams_window = 2, weights = rep(1,2))
# results in this:
print(as.matrix(forceSymmetric(tcm, "U")))
different here short document is a
different 0 0 1 1 1 1
here 0 0 0 0 2 2
short 1 0 0 2 1 2
document 1 0 2 0 0 1
is 1 2 1 0 0 2
a 1 2 2 1 2 0
Попытка получить модель на основе токена, для целевого слова "short":
i=0
corpus = lapply(corpus, function(x)
ifelse(x == "short", {i<<-i+1;paste0("short", i)}, x )
) # appends index to each occurrence so itoken distinguishes them
it = itoken(corpus)
tcm = create_vocabulary(it) %>% vocab_vectorizer() %>% create_tcm(it, . , skip_grams_window = 2, weights = rep(1,2))
attempt = as.matrix(forceSymmetric(tcm, "U") %>%
.[grep("^short", rownames(.)), -grep("^short", colnames(.))]
) # filters the resulting full tcm
# yields intended result but is hacky/slow:
print(attempt)
different here document is a
short2 1 0 1 0 1
short1 0 0 1 1 1
Что лучше/ более быстрая альтернатива этому подходу для получения токена на основе токена, как в последнем примере?(возможно, с использованием одного из пакетов R, которые уже делают tcms на основе типов)