web-dev-qa-db-fra.com

Visualisez Word2vec généré à partir de gensim

J'ai formé un doc2vec et Word2vec correspondant sur mon propre corpus à l'aide de gensim. Je veux visualiser le Word2vec en utilisant t-sne avec les mots. Comme dans, chaque point de la figure contient également le "mot".

J'ai regardé une question similaire ici: t-sne sur Word2vec

À la suite, j'ai ce code:

importation gensim importation gensim.models as 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()

Cela donne un chiffre avec des points mais pas de mots. C'est-à-dire que je ne sais pas quel point est représentatif de quel mot. Comment afficher le mot avec le point?

15
Dreams

Deux parties à la réponse: comment obtenir les étiquettes Word et comment tracer les étiquettes sur un nuage de points.

Étiquettes de mots dans Word2vec de gensim

model.wv.vocab Est un dict de {Word: objet du vecteur numérique}. Pour charger les données dans X pour t-SNE, j'ai effectué une modification.

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

Cela accomplit deux choses: (1) il vous obtient une liste autonome vocab pour la trame de données finale à tracer, et (2) lorsque vous indexez model, vous pouvez être sûr que vous connaissez l'ordre des mots.

Procédez comme avant avec

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

Mettons maintenant X_tsne Avec la liste vocab. C'est facile avec les pandas, alors import pandas as pd Si vous ne l'avez pas encore.

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

Les mots de vocab sont les indices de la trame de données maintenant.

Je n'ai pas votre jeu de données, mais dans le autre SO que vous avez mentionné, un exemple df qui utilise les groupes de discussion de sklearn ressemblerait à quelque chose comme

                        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

Diagramme de dispersion

J'aime l'approche orientée objet de matplotlib, donc cela commence un peu différemment.

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

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

Enfin, la méthode annotate étiquetera les coordonnées. Les deux premiers arguments sont l'étiquette de texte et le 2-Tuple. En utilisant iterrows(), cela peut être très succinct:

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

[Merci à Ricardo dans les commentaires pour cette suggestion.]

Ensuite, faites plt.show() ou fig.savefig(). Selon vos données, vous devrez probablement jouer avec ax.set_xlim Et ax.set_ylim Pour voir dans un nuage dense. Voici l'exemple de newsgroup sans aucun ajustement:

scatterplot

Vous pouvez également modifier la taille des points, la couleur, etc. Bon réglage!

37
Niels Joaquin