使用 t-SNE and/or PCA 时的 Gensim Doc2Vec 可视化问题

Gensim Doc2Vec visualization issue when using t-SNE and/or PCA

我试图通过使用 public 电影评论数据集来熟悉 Doc2Vec 结果。我已经清理了数据和 运行 模型。如下所示,有 6 个 tags/genres。每个都是一个带有向量表示的文档。

doc_tags = list(doc2vec_model.docvecs.doctags.keys())
print(doc_tags)
X = doc2vec_model[doc_tags]
print(X)
['animation', 'fantasy', 'comedy', 'action', 'romance', 'sci-fi']
[[ -0.6630892    0.20754902   0.2949621    0.622197     0.15592825]
 [ -1.0809666    0.64607996   0.3626246    0.9261689    0.31883526]
 [ -2.3482993    2.410015     0.86162883   3.0468733   -0.3903969 ]
 [ -1.7452248    0.25237766   0.6007084    2.2371168    0.9400951 ]
 [ -1.9570891    1.3037877   -0.24805197   1.6109428   -0.3572465 ]
 [-15.548988    -4.129228     3.608777    -0.10240117   3.2107658 ]]

print(doc2vec_model.docvecs.most_similar('romance'))
[('comedy', 0.6839742660522461), ('animation', 0.6497607827186584), ('fantasy', 0.5627620220184326), ('sci-fi', 0.14199887216091156), ('action', 0.046558648347854614)]

“浪漫”和“喜剧”非常相似,而“动作”和“科幻”与“浪漫”相比是非常不同的类型。到目前为止,一切都很好。但是,为了可视化结果,我需要降低向量维度。因此,我先尝试 t-SNE,然后再尝试 PCA。这是代码和结果:

# TSNE
tsne = TSNE(n_components=2)
X_tsne = tsne.fit_transform(X)
df = pd.DataFrame(X_tsne, index=doc_tags, columns=['x', 'y'])
print(df)
                    x           y
animation -162.499695   74.153679
fantasy    -10.496888   93.687149
comedy     -38.886723  -56.914558
action     -76.036247  232.218231
romance    101.005371  198.827988
sci-fi     123.960182   20.141081

# PCA
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
df_1 = pd.DataFrame(X_pca, index=doc_tags, columns=['x', 'y'])
print(df_1)
                   x         y
animation  -3.060287 -1.474442
fantasy    -2.815175 -0.888522
comedy     -2.520171  2.244404
action     -2.063809 -0.191137
romance    -2.578774  0.370727
sci-fi     13.038214 -0.061030

出了点问题。当我可视化结果时,这一点更加明显:

TSNE:

主成分分析:

这显然不是模型产生的。我确定我缺少一些基本的东西。如果您有任何建议,我们将不胜感激。

  • t-SNE 嵌入:认为嵌入 space 中点(或簇)之间的距离是一个常见的错误与原始space中的距离成正比。这是 t-SNE 的主要缺点,有关详细信息,请参阅 here。因此,您不应从可视化中得出任何结论。

  • PCA embedding:PCA对应于将坐标系旋转到一个新的正交坐标系中,该坐标系最优地描述了数据的方差。当保留所有主成分时,(欧几里得)距离会被保留,但是当减少维度(例如到 2D)时,点将被投影到具有最大方差的轴上,并且距离可能不再对应于原始距离。同样,很难得出关于原始 space 中的点与嵌入的距离的结论。

首先,在进行 2D 投影时,您总是会失去 full-dimensionality 模型的某些品质,这是此类可视化所需要的。您只是希望 - 并尝试选择合适的 methods/parameters - 保留重要方面。因此,当特定可视化令人失望时,不一定有任何东西 'wrong'。

尤其是 high-dimensional 'dense embeddings' 和 word2vec/doc2vec 一样,完整嵌入中 方式 的信息比在二维投影。您可能会在这样的图中看到一些合理的 micro-relationships——在几个地方的近邻符合预期——但整体 'map' 几乎不会像真正 2D 的真实地图那样可解释表面。

而且:看起来您正在创建一个只有 6 个 document-tags 的 30 维 Doc2Vec 模型。由于 Doc2Vec 的工作方式,如果只有 5 个唯一标签,基本上就是您只在 5 个虚拟文档上训练,只是被分割成不同的片段。就好像您将所有 'comedy' 评论合并成一个大文档,所有 'romance' 评论等也是如此

对于 Doc2Vec 的许多用途,特别是在介绍底层 'Paragraph Vector' 算法的已发表论文中,更典型的做法是使用每个文档的唯一 ID 作为其 'tag',特别是因为许多下游使用需要每个文档 doc-vector,而不是 per-known-category。这可能会更好地 preserve/model 原始数据中的信息 - 而将所有内容折叠为仅 6 mega-documents 和 6 个摘要 tag-vectors,会施加更简单的隐含 category-shapes.

请注意,如果使用唯一 ID 作为标签,您不会自动结束每个类别的摘要 tag-vector,您可以从模型中读取该摘要。但是,您可以合成这样一个向量,也许可以通过简单地对某个类别中所有文档的向量进行平均来获得该类别的质心。

有时使用 known-labels 作为文档标签仍然很有价值,可以是 instead-of 唯一 ID(正如您在此处所做的那样),也可以是 in-addition-to 唯一 ID(使用选项more-than-one tag 每个训练文档)。

但是您应该知道使用 known-labels,并且只能使用 known-labels,因为标签可能会受到限制。 (例如,如果您改为为每个文档训练一个单独的向量,则您可以通过可视化绘制文档,并用 known-labels 为点着色,并查看哪些类别往往有较大的重叠,并突出显示某些数据点似乎在挑战类别,或者 nearest-neighbors 属于不同的类别。)