2017-05-04 58 views
10

Wyszkoliłem doc2vec i odpowiedni word2vec na moim własnym korpusie używając gensim. Chcę wizualizować słowo 2vec używając t-sne ze słowami. Tak jak w przypadku, każda kropka na rysunku zawiera również "słowo".Wizualizuj słowo2vec generowane z gensim

Spojrzałem na podobnym pytaniem tutaj: t-sne on word2vec

po nim, mam ten kod:

import gensim gensim.models import jak 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() 

Daje to postać z kropki, ale bez słów. Nie wiem, która kropka jest reprezentatywna dla tego słowa. Jak wyświetlić słowo za pomocą kropki?

Odpowiedz

20

Dwie części odpowiedzi: jak zdobyć etykiety słów i jak narysować etykiety na wykresie rozrzutu.

etykiety słowne w gensim za word2vec

model.wv.vocab jest DICT z {słowo: Przedmiot wektora numerycznej}. Aby załadować dane do X dla t-SNE, wprowadziłem jedną zmianę.

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

Ten realizuje dwie rzeczy: (1) to dostaje autonomicznego vocab listy do finału dataframe inwestycyjnym, oraz (2), kiedy wskaźnik model, możesz być pewien, że wiesz, kolejność słów .

postępować jak poprzednio z

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

Teraz postawmy X_tsne wraz z wykazem vocab. To jest łatwe z pandami, więc import pandas as pd, jeśli jeszcze tego nie masz.

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

W vocab słowa są indeksy z dataframe teraz.

nie mam swój zestaw danych, ale w other SO wspomniałeś, przykładem df który używa grup dyskusyjnych sklearn byłby wyglądać

     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 

Scatterplot

lubię zorientowane obiektowo podejście do matplotlib, więc to zaczyna się trochę inaczej.

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

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

Wreszcie metoda annotate będzie etykieta współrzędnych. Pierwsze dwa argumenty to etykieta tekstowa i 2-krotna. Korzystanie iterrows(), może to być bardzo zwięzłe:

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

[Dzięki Ricardo w komentarzach do tej sugestii.]

Następnie zrobić plt.show() lub fig.savefig().W zależności od twoich danych prawdopodobnie będziesz musiał zadzierać z ax.set_xlim i ax.set_ylim, aby zobaczyć gęstą chmurę. Jest to przykład dyskusyjna bez szczypanie:

scatterplot

Można modyfikować wielkość kropki, kolor itp też. Szczęśliwe dostrajanie!

+1

Świetna robota! Proponuję to uproszczenie kodu: 'df = pd.DataFrame (X2, vocab, ['x', 'y'])' a następnie 'dla słowa, pos w df.iterrows(): plt.annotate (słowo, pos) '. tj. użyj słów jako indeksu. Możesz pozbyć się 'concat' i innych linii. –

+2

Wprowadzono dwie zmiany: 'vocab' jako indeks df i uproszczenie' iterrows'. Dzięki, @RicardoCruz! –