Применить вложения text2vec к новым данным
Я использовал text2vec для генерации пользовательских встраиваний слов из набора проприетарных текстовых данных, которые содержат много отраслевого жаргона (поэтому стандартные вложения, подобные тем, которые доступны в Google, не будут работать). Аналогии работают отлично, но мне сложно применить вложения для оценки новых данных. Я хочу использовать вложения, которые я уже обучил, чтобы понять отношения в новых данных. Подход, который я использую (описан ниже), кажется запутанным и мучительно медленным. Есть ли лучший подход? Возможно, что-то уже встроено в пакет, который я просто пропустил?
Вот мой подход (предложенный с наиболее близким к воспроизводимому коду кодом, который я могу сгенерировать, учитывая, что я использую собственный источник данных):
d = список, содержащий новые данные. каждый элемент имеет классовый характер
vecs = слово векторизации, полученное из реализации text2vec для перчатки
new_vecs <- sapply(d, function(y){
it <- itoken(word_tokenizer(y), progressbar=FALSE) # for each statement, create an iterator punctuation
voc <- create_vocabulary(it, stopwords= tm::stopwords()) # for each document, create a vocab
vecs[rownames(vecs) %in% voc$vocab$terms, , drop=FALSE] %>% # subset vecs for the words in the new document, then
colMeans # find the average vector for each document
}) %>% t # close y function and sapply, then transpose to return matrix w/ one row for each statement
Для моего случая использования мне нужно хранить результаты отдельно для каждого документа, поэтому все, что включает в себя вставку вместе элементов d, не будет работать, но, безусловно, должен быть лучший способ, чем то, что я собрал вместе. Я чувствую, что, должно быть, упускаю что-то довольно очевидное
Любая помощь будет оценена.
1 ответ
Вам нужно сделать это в "пакетном" режиме, используя эффективные операции матрицы линейной алгебры. Идея состоит в том, чтобы иметь документ-матрицу для документов d
, Эта матрица будет содержать информацию о том, сколько раз каждое слово встречается в каждом документе. Тогда нужно просто умножить dtm
по матрице вложений:
library(text2vec)
# we are interested in words which are in word embeddings
voc = create_vocabulary(rownames(vecs))
# now we will create document-term matrix
vectorizer = vocab_vectorizer(voc)
dtm = itoken(d, tokenizer = word_tokenizer) %>%
create_dtm(vectorizer)
# normalize - calculate term frequaency - i.e. divide count of each word
# in document by total number of words in document.
# So at the end we will receive average of word vectors (not sum of word vectors!)
dtm = normalize(dtm)
# and now we can calculate vectors for document (average of vecors of words)
# using dot product of dtm and embeddings matrix
document_vecs = dtm %*% vecs