Визуализировать word2vec, сгенерированный из gensim

Я обучил doc2vec и соответствующий word2vec на своем собственном корпусе с помощью gensim. Я хочу визуализировать word2vec, используя t-sne со словами. Как и в, каждая точка на рисунке имеет "слово" также и с ней.

Я рассмотрел аналогичный вопрос: t-sne on word2vec

После этого у меня есть этот код:

import gensim import gensim.models как g

from sklearn.manifold import TSNE
import re
import matplotlib.pyplot as plt

modelPath="/Users/tarun/Desktop/PE/doc2vec/model3_100_newCorpus60_1min_6window_100trainEpoch.bin"
model = g.Doc2Vec.load(modelPath)

X = model[model.wv.vocab]
print len(X)
print X[0]
tsne = TSNE(n_components=2)
X_tsne = tsne.fit_transform(X[:1000,:])

plt.scatter(X_tsne[:, 0], X_tsne[:, 1])
plt.show()

Это дает фигуру с точками, но без слов. То есть я не знаю, какая точка является представителем какого слова. Как я могу отобразить слово с точкой?

Ответ 1

Две части ответа: как получить ярлыки слов и как построить надписи на диаграмме рассеяния.

Ярлыки Word в gensim word2vec

model.wv.vocab является типом {word: object of numeric vector}. Чтобы загрузить данные в X для t-SNE, я сделал одно изменение.

vocab = list(model.wv.vocab)
X = model[vocab]

Это выполняет две вещи: (1) он дает вам отдельный список vocab для окончательной диаграммы данных для построения, и (2) когда вы индексируете model, вы можете быть уверены, что знаете порядок слов.

Действуйте по-прежнему с помощью

tsne = TSNE(n_components=2)
X_tsne = tsne.fit_transform(X)

Теперь поставьте X_tsne вместе с списком vocab. Это легко с pandas, поэтому import pandas as pd, если этого еще нет.

df = pd.DataFrame(X_tsne, index=vocab, columns=['x', 'y'])

Теперь слова vocab являются индексами кадра данных.

У меня нет вашего набора данных, но в другом SO, который вы упомянули, пример df, который использует группы новостей sklearn, будет выглядеть примерно так:

                        x             y
politics    -1.524653e+20 -1.113538e+20
worry        2.065890e+19  1.403432e+20
mu          -1.333273e+21 -5.648459e+20
format      -4.780181e+19  2.397271e+19
recommended  8.694375e+20  1.358602e+21
arguing     -4.903531e+19  4.734511e+20
or          -3.658189e+19 -1.088200e+20
above        1.126082e+19 -4.933230e+19

разброс точек

Мне нравится объектно-ориентированный подход к matplotlib, так что это начинается немного иначе.

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

ax.scatter(df['x'], df['y'])

Наконец, метод annotate будет обозначать координаты. Первые два аргумента - текстовая метка и 2-кортеж. Используя iterrows(), это может быть очень кратким:

for word, pos in df.iterrows():
    ax.annotate(word, pos)

[Спасибо Рикардо в комментариях к этому предложению.]

Затем сделайте plt.show() или fig.savefig(). В зависимости от ваших данных вам, вероятно, придется столкнуться с ax.set_xlim и ax.set_ylim, чтобы увидеть в плотном облаке. Это пример группы новостей без каких-либо настроек:

scatterplot

Вы также можете изменить размер, цвет и т.д. Счастливая тонкая настройка!