【问题标题】:Visualise word2vec generated from gensim可视化从 gensim 生成的 word2vec
【发布时间】:2017-10-02 06:15:25
【问题描述】:

我已经使用 gensim 在我自己的语料库上训练了一个 doc2vec 和相应的 word2vec。我想使用带有单词的 t-sne 来可视化 word2vec。如图,图中的每个点都带有“单词”。

我在这里看到了一个类似的问题: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()

这给出了一个带点但没有单词的图形。那就是我不知道哪个点代表哪个单词。如何显示带点的单词?

【问题讨论】:

    标签: scikit-learn data-visualization gensim word2vec


    【解决方案1】:

    答案分为两部分:如何获取单词标签,以及如何在散点图上绘制标签。

    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_tsnevocab 列表放在一起。使用 pandas 很容易,所以import pandas as pd 如果你还没有的话。

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

    词汇词现在是数据框的索引

    我没有你的数据集,但在你提到的 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 方法将标记坐标。前两个参数是文本标签和 2 元组。使用iterrows(),可以非常简洁:

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

    [感谢 cmets 的 Ricardo 提出这个建议。]

    然后执行plt.show()fig.savefig()。根据您的数据,您可能不得不使用ax.set_xlimax.set_ylim 才能看到密集的云。这是没有任何调整的新闻组示例:

    您也可以修改点的大小、颜色等。祝您微调愉快!

    【讨论】:

    • 干得好!我建议简化此代码:df = pd.DataFrame(X2, vocab, ['x', 'y']),然后是for word, pos in df.iterrows(): plt.annotate(word, pos)。即使用单词作为索引。你可以去掉concat和其他行。
    • 进行了两项更改:vocab 作为 df 索引和iterrows 简化。谢谢,@RicardoCruz!
    • @NielsJoaquin,我们应该做哪些改变来仅可视化特定单词的相似单词?
    • AttributeError: The vocab attribute was removed from KeyedVector in Gensim 4.0.0. Use KeyedVector's .key_to_index dict, .index_to_key list, and methods .get_vecattr(key, attr) and .set_vecattr(key, attr, new_val) instead.
    【解决方案2】:

    通过以下内容,您可以将模型转换为 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'))
    

    :)

    【讨论】:

      猜你喜欢
      • 2018-11-02
      • 2021-11-13
      • 2017-07-16
      • 2019-07-01
      • 2017-04-30
      • 2017-07-11
      • 1970-01-01
      • 1970-01-01
      • 2014-04-02
      相关资源
      最近更新 更多