Применить вложения 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
Другие вопросы по тегам