我正在尝试使用一个公共的电影评论数据集来熟悉Doc2Vec的结果。我已经清理了数据并运行了模型。如您所见,共有6个标签/类型。每个标签都是一个带有其向量表示的文档。
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。这是代码和结果:
# TSNEtsne = TSNE(n_components=2)X_tsne = tsne.fit_transform(X)df = pd.DataFrame(X_tsne, index=doc_tags, columns=['x', 'y'])print(df) x yanimation -162.499695 74.153679fantasy -10.496888 93.687149comedy -38.886723 -56.914558action -76.036247 232.218231romance 101.005371 198.827988sci-fi 123.960182 20.141081# PCApca = 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 yanimation -3.060287 -1.474442fantasy -2.815175 -0.888522comedy -2.520171 2.244404action -2.063809 -0.191137romance -2.578774 0.370727sci-fi 13.038214 -0.061030
这里有问题。当我可视化结果时,这一点更加明显:
t-SNE:
PCA:
这显然不是模型产生的。我确信我遗漏了一些基本的东西。如果您有任何建议,将不胜感激。
回答:
首先,当进行2D投影时,您总是会失去一些完整维度模型的特性,这是此类可视化所必需的。你只是希望——并尝试选择适当的方法/参数——重要的方面得以保留。因此,当特定的可视化结果令人失望时,不一定有什么“错误”。
特别是对于像word2vec/doc2vec这样的高维“密集嵌入”,完整嵌入中的信息要比2D投影中显示的多得多。您可能会在这样的图表中看到一些合理的微观关系——在几个地方符合预期的近邻——但总体的“地图”不会像真正的2D表面的地图那样易于解释。
但还有:看起来您正在创建一个只有6个文档标签的30维Doc2Vec
模型。由于Doc2Vec
的工作方式,如果只有5个独特的标签,实际上相当于您仅在5个虚拟文档上进行训练,只是将它们分割成不同的片段。就好像您将所有“喜剧”评论连接成一个大文档,同样处理所有“浪漫”评论,等等。
对于Doc2Vec
的许多用途,特别是在介绍底层“段落向量”算法的已发表论文中,更常见的是使用每个文档的唯一ID作为其“标签”,尤其是因为许多下游用途随后需要每个文档的文档向量,而不是每个已知类别。这可能更好地保留/建模原始数据中的信息——而将一切都归结为仅6个超大文档和6个摘要标签向量,则施加了更简单的隐含类别形状。
请注意,如果使用唯一ID作为标签,您不会自动获得每个类别的一个摘要标签向量,这些向量可以从模型中读取。但是,您可以合成这样的向量,或许通过简单地平均某个类别中所有文档的向量来获得该类别的中心点。
使用已知标签作为文档标签,有时仍然是有价值的,要么代替唯一ID(如您在这里所做的那样),要么除了唯一ID之外(使用每个训练文档可以有多个tag
的选项)。
但您应该知道仅使用已知标签,并且只有已知标签,作为标签可能会有限制。(例如,如果您反而为每个文档训练一个单独的向量,然后您可以通过可视化来绘制文档,并用已知标签为点着色,您就可以看到哪些类别往往有很大的重叠,并突出显示某些似乎挑战类别的数据点,或者在不同类别中有最近邻的数据点。)