Соответствующие слова и векторы в gensim модели Word2Vec

У меня был gensim Word2Vec вычислить некоторые слова вложения для меня. Насколько мне известно, все было совершенно фантастически; теперь я собираю создаваемые слова векторов, надеясь получить семантические группировки.

В качестве следующего шага я хотел бы взглянуть на слова (а не на векторы), содержащиеся в каждом кластере. То есть если у меня есть вектор вложений [x, y, z], я хотел бы узнать, какое фактическое слово представляет этот вектор. Я могу получить слова/элементы Vocab, вызвав model.vocab и векторы слов через model.syn0. Но я не мог найти место, где они явно совпадают.

Это было сложнее, чем я ожидал, и я чувствую, что, возможно, я пропустил очевидный способ сделать это. Любая помощь приветствуется!

Проблема:

Сопоставьте слова с векторами вложения, созданными Word2Vec () - как это сделать?

Мой подход:

После создания модели (код ниже *) теперь я хотел бы сопоставить индексы, назначенные каждому слову (в фазе build_vocab()), векторной матрице, выводимой как model.syn0. Таким образом,

for i in range (0, newmod.syn0.shape[0]): #iterate over all words in model
    print i
    word= [k for k in newmod.vocab if newmod.vocab[k].__dict__['index']==i] #get the word out of the internal dicationary by its index
    wordvector= newmod.syn0[i] #get the vector with the corresponding index
    print wordvector == newmod[word] #testing: compare result of looking up the word in the model -- this prints True
  • Есть ли лучший способ сделать это, например. путем подачи вектора в модель в соответствии с словом?

  • Это даже дает мне правильные результаты?

* Мой код для создания векторов слов:

model = Word2Vec(size=1000, min_count=5, workers=4, sg=1)

model.build_vocab(sentencefeeder(folderlist)) #sentencefeeder puts out sentences as lists of strings

model.save("newmodel")

Я нашел этот вопрос, который аналогичен, но на самом деле не был дан ответ.

Ответ 1

Итак, я нашел простой способ сделать это, где nmodel - это имя вашей модели.

#zip the two lists containing vectors and words
zipped = zip(nmodel.wv.index2word, nmodel.wv.syn0)

#the resulting list contains `(word, wordvector)` tuples. We can extract the entry for any `word` or `vector` (replace with the word/vector you're looking for) using a list comprehension:
wordresult = [i for i in zipped if i[0] == word]
vecresult = [i for i in zipped if i[1] == vector]

Это основано на gensim code. Для более старых версий gensim вам может потребоваться сбросить wv после модели.

Ответ 2

Я искал долгое время, чтобы найти сопоставление между матрицей syn0 и лексикой... вот ответ: используйте model.index2word, который является просто списком слов в правильном порядке!

Это не в официальной документации (почему?), но она может быть найдена непосредственно внутри исходного кода: https://github.com/RaRe-Technologies/gensim/blob/3b9bb59dac0d55a1cd6ca8f984cead38b9cb0860/gensim/models/word2vec.py#L441

Ответ 3

Если все, что вы хотите сделать, это сопоставить слово с вектором, вы можете просто использовать оператор [], например. model["hello"] даст вам вектор, соответствующий привет.

Если вам нужно восстановить слово из вектора, вы можете прокрутить список векторов и проверить соответствие, как вы предлагаете. Однако это неэффективно, а не питонично. Удобным решением является использование метода similar_by_vector для модели word2vec, например:

import gensim

documents = [['human', 'interface', 'computer'],
 ['survey', 'user', 'computer', 'system', 'response', 'time'],
 ['eps', 'user', 'interface', 'system'],
 ['system', 'human', 'system', 'eps'],
 ['user', 'response', 'time'],
 ['trees'],
 ['graph', 'trees'],
 ['graph', 'minors', 'trees'],
 ['graph', 'minors', 'survey']]

model = gensim.models.Word2Vec(documents, min_count=1)
print model.similar_by_vector(model["survey"], topn=1)

который выводит:

[('survey', 1.0000001192092896)]

где число представляет сходство.

Однако этот метод все еще неэффективен, так как он все же должен сканировать все словарные векторы для поиска наиболее похожих. Лучшим решением вашей проблемы является найти способ отслеживания ваших векторов во время процесса кластеризации, чтобы вам не приходилось полагаться на дорогие обратные сопоставления.

Ответ 4

Как упоминал @bpachev, у gensim есть возможность поиска по вектору, а именно similar_by_vector.

Однако он реализует линейный поиск грубой силы, т.е. вычисляет сходство косинусов между заданным вектором и векторами всех слов в лексике и выдает верхние соседи. Альтернативный вариант, как указано в другом , заключается в использовании приблизительного алгоритма поиска ближайшего соседа, такого как FLANN.

Разделяя суть, демонстрируя то же самое: https://gist.github.com/kampta/139f710ca91ed5fabaf9e6616d2c762b