【问题标题】:How to effectively tune the hyper-parameters of Gensim Doc2Vec to achieve maximum accuracy in Document Similarity problem?如何有效调整 Gensim Doc2Vec 的超参数以在文档相似性问题中实现最大准确性?
【发布时间】:2023-10-21 11:40:01
【问题描述】:

我有大约 20k 个 60 - 150 字的文档。在这 20K 个文档中,有 400 个文档已知类似文档。这 400 个文档作为我的测试数据。

目前我正在删除这 400 个文档并使用剩余的 19600 个文档来训练 doc2vec。然后我提取训练和测试数据的向量。现在对于每个测试数据文档,我发现它与所有 19600 个训练文档的余弦距离,并选择余弦距离最小的前 5 个。如果标记的类似文件出现在前 5 个中,则认为它是准确的。准确率% = 准确记录数/记录总数。

我找到类似文档的另一种方法是使用最相似的 doc2Vec 方法。然后使用上面的公式计算准确率。

以上两个精度不匹配。每个时期一个增加另一个减少。

我正在使用这里给出的代码:https://medium.com/scaleabout/a-gentle-introduction-to-doc2vec-db3e8c0cce5e。用于训练 Doc2Vec。

我想知道如何调整超参数,以便我可以使用上述公式获得准确性。我应该使用余弦距离来查找最相似的文档还是应该使用 gensim 的最相似函数?

【问题讨论】:

    标签: python nlp gensim doc2vec sentence-similarity


    【解决方案1】:

    您引用的文章对Doc2Vec 算法进行了合理的阐述,但其示例代码包含一个非常有害的反模式:在循环中多次调用train(),同时手动管理alpha这绝不是一个好主意,而且很容易出错。

    相反,不要更改默认的min_alpha,只需使用所需的epochs 调用一次train(),并让该方法顺利​​管理alpha 本身。

    您的一般方法是合理的:根据一些先前的想法,开发一种可重复的模型评分方法,然后尝试各种模型参数并选择得分最高的参数。

    当您说您自己的两种准确度计算方法不匹配时,这有点令人担忧,因为 most_similar() 方法实际上会根据所有已知的 doc-vector 检查您的查询点,并返回带有最大余弦相似度。这些应该与您计算出的具有最小余弦距离的那些相同。如果您在问题中添加了您的确切代码——如何计算余弦距离,以及如何调用most_similar()——那么很可能会清楚哪些细微的差异或错误是导致差异的原因。 (不应该有任何本质的区别,但考虑到:您可能希望使用most_similar() 结果,因为它们已知没有错误,并使用可能比任何循环更快的高效批量数组库操作你已经创作了。)

    请注意,您不必保留一组已知高度相似的文档对。由于Doc2Vec 是一种无监督算法,因此您不会在训练期间为其提供首选的“确保这些文档相似”的结果。在全套文档上进行训练是相当合理的,然后选择最能捕捉您想要的最相似关系的模型,并相信包含更多文档实际上可以帮助您找到最佳参数。

    (但是,这样的过程可能会略微高估未来未见文档或其他一些假设的“其他 20K”培训文档的预期准确性。但根据您的培训,它仍然可以合理地找到“可能的最佳”元参数数据。)

    (如果您在训练期间没有将它们全部喂完,那么在测试期间您将需要使用 infer_vector() 来获取看不见的文档,而不是仅仅查找从训练中学习到的向量。您还没有展示您的此类评分/推理的代码,但这是另一个可能做错的步骤。如果您只是将所有可用文档的向量一起训练,则消除了出错的可能性。)

    检查所需文档是否在最相似的前 5(或前 N)中只是对模型进行评分的一种方法。另一种方法是在一些原始的“段落向量”(Doc2Vec) 论文中使用,对于每一对这样的对,还选择另一个 random 文档。每次报告已知相似文档比第三个随机选择的文档彼此更接近时,都将模型计算为准确。在最初的“段落向量”论文中,现有的搜索排名系统(它报告某些文本 sn-ps 以响应相同的探测查询)或手工策划的类别(如在 Wikipedia 或 Arxiv 中)被用来生成这样的评估对:检查同一搜索结果页面或同一类别中的文本,以查看它们在模型中是否比其他随机文档“更接近”。

    如果您的问题被扩展为更多地描述您尝试过的一些初始参数(例如您提供给Doc2Vectrain() 的完整参数),以及似乎有帮助或有伤害的内容,然后可能会建议其他值得检查的参数范围。

    【讨论】:

    • 嘿!非常感谢您提供的宝贵信息。我几乎没有疑问 - 如果我放入 bi-grams 和 tri-grams 或字符 shingles 是否有意义?如果是,那怎么办?如果不是,那么概念问题将是什么。论文中写道,PV-DM 的性能优于 PV-DBOW,但在我的数据集上却完全相反。你能解释一下为什么吗?
    • character-n-grams、word-bigrams 或 word-trigrams 是否适合您的语料库和最终目的是您必须评估的。 (可能会,但这取决于,一旦您对模型进行可重复的定量评估以返回您喜欢的结果类型,您就可以检查这些选项。)Doc2Vec 只接受您提供的任何令牌列表:如果您要预处理您的语料库以将单词拆分为 char-n-grams,或者将单词组合成 word-bigrams/etc,这就是 Doc2Vec 的工作原理。 (它在外面,在Doc2Vec 工作之前。)
    • 我不记得原始论文声称 PV-DM 必然或通常更好。 PV-DBOW 通常表现良好,尤其是在较小的文本上,并且由于它非常快,可能允许测试更多的训练周期或参数变体。两者都值得尝试——尽管如果你需要模型也提供词向量,你要么需要使用 PV-DM,要么将可选的dbow_words=1 参数添加到 PV-DBOW——否则,PV-DBOW 永远不会训练词——向量(让模型中的值随机初始化)。