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?
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:
Vous pouvez également modifier la taille des points, la couleur, etc. Bon réglage!