评估 doc2vec 准确性

Assessing doc2vec accuracy

我正在尝试根据 here 中的代码评估 doc2vec 模型。基本上,我想知道推断文档的百分比被发现与自身最相似。这是我当前的代码:

    for doc_id, doc in enumerate(cur.execute('SELECT Text FROM Patents')):
        docs += 1
        doc = clean_text(doc)
        inferred_vector = model.infer_vector(doc)
        sims = model.docvecs.most_similar([inferred_vector], topn=len(model.docvecs))
        rank = [docid for docid, sim in sims].index(doc_id)
        ranks.append(rank) 

    counter = collections.Counter(ranks)
    accuracy = counter[0] / docs

此代码非常适合较小的数据集。但是,由于我有一个包含数百万文档的巨大文件,这段代码变得太慢了,需要几个月的时间来计算。我分析了我的代码,大部分时间都花在了以下行上:sims = model.docvecs.most_similar([inferred_vector], topn=len(model.docvecs)).

如果我没记错的话,这是必须将每个文档与其他每个文档进行比较。我认为如果我将其更改为 topn=1 计算时间可能会大大减少,因为我唯一想知道的是最相似的文档是否本身。这样做基本上会获取每个文档(即 inferred_vector),测量其最相似的文档(即 topn=1),然后我只看它是否本身。我怎么能实现这个?欢迎任何帮助或想法。

只有 most_similar() return 一个最相似的文档,就像指定 topn=1.

一样简单

然而,要知道数百万文档中的哪一个与单个目标向量最相似,必须计算与所有候选文档的相似度并进行排序。 (即使漏掉一篇文献,也可能是排名第一的!)

确保绝对没有发生虚拟内存交换将有助于确保尽可能快地进行暴力比较,所有这些都在 RAM 中进行——但是对于数百万文档,它仍然很耗时。

您正在尝试的是一个相当简单的“自我检查”,以确定训练是否导致了自洽模型:文档的重新推理是否创建了一个“非常接近”相同文档的向量-批量训练遗留下来的向量。失败将表明文档准备或培训中存在一些大问题,但这并不是衡量模型对任何实际任务的“准确性”的真实衡量标准,最好根据您的预期用途评估模型的价值。

此外,因为这种“重新推理自检”只是粗略的健全性检查,所以没有必要对每个 文档都进行。选择一千(或一万,或其他)随机文件会给你一个代表性的想法,说明大多数重新推断的向量是否具有这种质量。

同样,您可以简单地检查重新推断的向量与同一文档 ID 的单个模型内向量的相似性,并检查它们是否“足够相似”。 (这会快得多,但也可以只对文档的随机样本进行。)“足够相似”没有神奇的适当阈值;您必须选择一个似乎符合您其他目标的。例如,使用 scikit-learncosine_similarity() 来比较两个向量:

from sklearn.metrics.pairwise import cosine_similarity

# ...

    inferred_vector = model.infer_vector(doc_words)
    looked_up_vector = model.dv[doc_id]
    self_similarity = cosine_similarity([inferred_vector], [looked_up_vector])[0]
    # then check that value against some threshold

(您必须将列表中的单个向量包装为 cosine_similarity() 的参数,然后访问 return 值的第 0 个元素,因为它通常设计用于更大的向量列表.)

通过此计算,您将不知道,例如,其他一些存储文档向量是否更接近您的推断目标 - 但无论如何,这可能并不那么重要。这些文档可能真的很相似!如果训练中存在重大缺陷,最初的“最接近自身”自检将惨遭失败,但即使是训练有素的模型也可能会出现一些情况,即自然模型抖动会阻止每个文档“最接近自身”。 (在相同数量的维度内有更多的文档,或者某些语料库有很多非常相似的文档,这会变得更常见......但不是任何模型问题的相关指标。)