可视化从 gensim 生成的 word2vec
Visualise word2vec generated from gensim
我使用gensim在我自己的语料库上训练了一个doc2vec和相应的word2vec。我想使用带有单词的 t-sne 来可视化 word2vec。如图所示,图中的每个点都带有 "word"。
我在这里看了一个类似的问题:t-sne on word2vec
接着,我有这段代码:
导入gensim
将 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()
这给出了一个带点但没有文字的图形。那就是不知道哪个点代表哪个词。如何显示带点的单词?
答案分为两个部分:如何获取单词标签,以及如何在散点图上绘制标签。
gensim 的 word2vec 中的词标签
model.wv.vocab
是 {word: object of numeric vector} 的字典。为了将 t-SNE 的数据加载到 X
,我做了一处更改。
vocab = list(model.wv.key_to_index)
X = model.wv[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 词现在是数据帧的索引。
我没有你的数据集,但在你提到的 other SO 中,一个使用 sklearn 新闻组的例子 df
看起来像
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
方法会标注坐标。前两个参数是文本标签和二元组。使用 iterrows()
,这可以非常简洁:
for word, pos in df.iterrows():
ax.annotate(word, pos)
[感谢里卡多对此建议的评论。]
然后执行 plt.show()
或 fig.savefig()
。根据您的数据,您可能不得不弄乱 ax.set_xlim
和 ax.set_ylim
才能看到密集的云。这是没有任何调整的新闻组示例:
您也可以修改点的大小、颜色等。快乐微调!
通过以下方式,您可以将模型转换为 TSV,然后使用 this page 进行可视化。
with open(self.word_tensors_TSV, 'bw') as file_vector, open(self.word_meta_TSV, 'bw') as file_metadata:
for word in model.wv.vocab:
file_metadata.write((word + '\n').encode('utf-8', errors='replace'))
vector_row = '\t'.join(str(x) for x in model[word])
file_vector.write((vector_row + '\n').encode('utf-8', errors='replace'))
:)
我使用gensim在我自己的语料库上训练了一个doc2vec和相应的word2vec。我想使用带有单词的 t-sne 来可视化 word2vec。如图所示,图中的每个点都带有 "word"。
我在这里看了一个类似的问题:t-sne on word2vec
接着,我有这段代码:
导入gensim 将 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()
这给出了一个带点但没有文字的图形。那就是不知道哪个点代表哪个词。如何显示带点的单词?
答案分为两个部分:如何获取单词标签,以及如何在散点图上绘制标签。
gensim 的 word2vec 中的词标签
model.wv.vocab
是 {word: object of numeric vector} 的字典。为了将 t-SNE 的数据加载到 X
,我做了一处更改。
vocab = list(model.wv.key_to_index)
X = model.wv[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 词现在是数据帧的索引。
我没有你的数据集,但在你提到的 other SO 中,一个使用 sklearn 新闻组的例子 df
看起来像
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
方法会标注坐标。前两个参数是文本标签和二元组。使用 iterrows()
,这可以非常简洁:
for word, pos in df.iterrows():
ax.annotate(word, pos)
[感谢里卡多对此建议的评论。]
然后执行 plt.show()
或 fig.savefig()
。根据您的数据,您可能不得不弄乱 ax.set_xlim
和 ax.set_ylim
才能看到密集的云。这是没有任何调整的新闻组示例:
您也可以修改点的大小、颜色等。快乐微调!
通过以下方式,您可以将模型转换为 TSV,然后使用 this page 进行可视化。
with open(self.word_tensors_TSV, 'bw') as file_vector, open(self.word_meta_TSV, 'bw') as file_metadata:
for word in model.wv.vocab:
file_metadata.write((word + '\n').encode('utf-8', errors='replace'))
vector_row = '\t'.join(str(x) for x in model[word])
file_vector.write((vector_row + '\n').encode('utf-8', errors='replace'))
:)