Gensim docvecs.most_similar 返回不存在的 Id



我正在尝试创建一种算法,该算法能够显示类似于特定文档的前n个文档。 为此,我使用了gensim doc2vec。代码如下:

model = gensim.models.doc2vec.Doc2Vec(size=400, window=8, min_count=5, workers = 11, 
dm=0,alpha = 0.025, min_alpha = 0.025, dbow_words = 1)
model.build_vocab(train_corpus)
for x in xrange(10):
model.train(train_corpus)
model.alpha -= 0.002
model.min_alpha = model.alpha
model.train(train_corpus)
model.save('model_EN_BigTrain')
sims = model.docvecs.most_similar([408], topn=10)

sims var 应该给我 10 个元组,第一个元素是文档的 id,第二个元素是分数。 问题是某些 id 与我的训练数据中的任何文档都不对应。

一段时间以来,我一直在尝试理解不在我的训练数据中的 id,但我看不到任何逻辑。

Ps:这是我用来创建train_corpus的代码

def readData(train_corpus, jData):
print("The response contains {0} properties".format(len(jData)))
print("n")
for i in xrange(len(jData)):
print "> Reading offers from Aux array"
if i % 10 == 0: 
print ">>", i, "offers processed..."
train_corpus.append(gensim.models.doc2vec.TaggedDocument(gensim.utils.simple_preprocess(jData[i][1]), tags=[jData[i][0]]))
print "> Finished processing offers"

作为 aux 数组的每个位置,一个数组在女巫中位置 0 是一个 int(我想成为 id),位置 1 是一个描述

提前谢谢。

您是否使用纯整数ID作为tags,但没有完全使用从0到MAX_DOC_ID的所有整数?

如果是这样,这可以解释该范围内标签的出现。当你使用普通整数时,gensim Doc2Vec 避免创建字典将提供的标签映射到其内部向量数组中的索引位置——而只使用整数本身。

因此,必须分配该内部向量数组以包含MAX_DOC_ID + 1行。与未使用 ID 相对应的任何行仍被初始化为随机向量,就像所有位置一样,但不会从实际文本示例中接收任何训练以将它们推送到有意义的相对位置。因此,这些随机初始化但未经训练的向量可能会出现在以后most_similar()的结果中。

为避免这种情况,请仅使用从 0 到所需最后一个 ID 的连续整数。或者,如果您能负担得起字符串到索引映射的内存成本,请使用字符串标记而不是普通整数。或者,保留有效 ID 的额外记录,并从结果中手动过滤不需要的 ID。

另外:通过在 Doc2Vec 模型初始化中不指定iter=1,默认值iter=5将生效,这意味着每次调用train()都会对数据进行 5 次迭代。奇怪的是,你的xrange(10)for 循环包括两个单独的调用来train()每次迭代(第一个只是使用已经到位的任何 alpha/min_alpha)。所以你实际上是在对数据进行 10 * 2 * 5 = 100 次传递,有一个奇怪的学习率时间表。

我建议相反,如果您希望 10 次传递仅设置iter=10,请保持默认alpha/min_alpha不变,然后只调用train()一次。该模型将执行 10 次传递,从起始值到结束值顺利管理 alpha。

我也遇到了这个问题,我正在使用以下内容初始化我的doc2vec:

for idx,doc in data.iterrows():
alldocs.append(TruthDocument(doc['clean_text'], [idx], doc['label']))

我正在向它传递一个具有一些 wonk 索引的数据帧。 我所要做的就是。

df.reset_index(inplace=True)

相关内容

最新更新