python 如何在 gensim 上分别识别 doc2vec 实例
How to identify doc2vec instances seperately in gensim in python
我有一个包含 1000 个文档的列表,其中前 500 个属于 movies
中的文档(即从 0
到 499
的列表索引),其余 500 个属于文档在 tv series
中(即从 500
到 999
的列表索引)。
对于电影,document tag
以 movie_
开头(例如,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 个词的结果最有趣。)
我有一个包含 1000 个文档的列表,其中前 500 个属于 movies
中的文档(即从 0
到 499
的列表索引),其余 500 个属于文档在 tv series
中(即从 500
到 999
的列表索引)。
对于电影,document tag
以 movie_
开头(例如,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 个词的结果最有趣。)