python 如何在 gensim 上分别识别 doc2vec 实例

How to identify doc2vec instances seperately in gensim in python

我有一个包含 1000 个文档的列表,其中前 500 个属于 movies 中的文档(即从 0499 的列表索引),其余 500 个属于文档在 tv series 中(即从 500999 的列表索引)。

对于电影,document tagmovie_ 开头(例如,movie_fast_and_furious),对于电视剧,文档标签以 tv_series_ 开头(例如,tv_series_the_office)

我使用这些电影和电视剧数据集构建了一个 doc2vec 模型,如下所示。

from gensim.models import doc2vec
from collections import namedtuple

dataset = json.load(open(input_file))

docs = []
analyzedDocument = namedtuple('AnalyzedDocument', 'words tags')

for description in dataset:
    tags = [description[0]]
    words = description[1]
    docs.append(analyzedDocument(words, tags))

model = doc2vec.Doc2Vec(docs, vector_size = 100, window = 10, min_count = 1, workers = 4, epochs = 20)

现在对于每个 movie,我想得到它最近的 5 tv series 以及它们的余弦相似度。

我知道,gensim提供的功能model.docvecs.most_similar。但是,这样做的结果也包括电影(这不是我的本意)。是否可以在 gensim 中执行此操作(我假设文档向量是按照我们提供的 documents list 的顺序创建的)。

如果需要,我很乐意提供更多详细信息。

所有 tags 都是 Doc2Vec 的不透明标识符。因此,如果您的数据存在内部差异,则您需要自己对其进行建模和过滤。

因此,我的主要建议是请求比您需要的 topn 大得多的结果,然后丢弃那些您不想要的类型的结果,或者超出您实际需要的数量的结果。

(请注意,most_similar() 的每次计算都需要与整个已知的 doc-tags 集进行比较,使用较小的 topn 只会在对这些完整结果进行排序时节省一些计算. 因此,使用更大的 topn,甚至达到已知 doc-tags 的完整大小,并不像您担心的那样昂贵。)

只有两个类别,要获得最接近查询电影的 10 tv-shows,您可以使 topn 等于电影的数量减去 1(查询),再加上 10 –那么在绝对 worst-case 中,所有电影都比第一个 tv-show 更接近,你仍然会得到 10 个有效 tv-show 结果。

(most_similar() 函数还包含一个 restrict_vocab 参数。它采用 int 计数,并将结果限制为内部存储顺序中的第一个 that-many 项。所以如果实际上第 1 个 500 个文档都是 tv-shows,restrict_vocab=500 将只给出该子集的结果。但是,我不建议依赖它,因为 (a) 它只适用于一个front-loaded 的类别,而不是任何其他类别;(b) 理想情况下,您 不会 将所有相似的文档聚集在一起,而是将它们打乱以散布在对比文件中。通常 Word2Vec vector-sets 被排序为将 highest-frequency 单词放在第一位 – 不管原始数据中的 order-of-appearance。这使得 restrict_vocab 在那里更有用,因为经常只有具有最强向量的 most-common 个词的结果最有趣。)