【问题标题】:How to continue training Doc2Vec with a specific domain corpus after training with a generic corpus如何在使用通用语料库训练后继续使用特定领域语料库训练 Doc2Vec
【发布时间】:2020-11-16 10:29:23
【问题描述】:

我想使用通用语料库训练 Doc2Vec 模型,然后继续使用特定领域的语料库进行训练(我已阅读这是一种常见策略,我想测试结果)。

我有所有的文档,所以我可以在开头构建和标记词汇。

据我所知,我应该首先使用通用文档训练所有时期,然后使用临时文档重复这些时期。但是,通过这种方式,我不能将所有文档放在语料库迭代器中并调用 train() 一次(因为到处都建议这样做)。

所以,在构建全局词汇之后,我创建了两个迭代器,第一个用于通用文档,第二个用于临时文档,并调用了两次 train()。

这是最好的方式还是更合适的方式?

如果最好,我应该如何管理 alpha 和 min_alpha?在 train() 调用中不提及它们并让 train() 管理它们是一个好的决定吗?

最好的

阿尔伯托

【问题讨论】:

    标签: doc2vec custom-training


    【解决方案1】:

    感谢您快速而详尽的回答。只需几个 cmets 即可澄清问题。

    我之前有两个数据集开始训练,所以 build_vocab() 调用只使用一次迭代器完成所有标记文档,通用和特定领域。所以,第一个问题没有问题,训练的任何部分都不会出现新词。

    我真的同意你的看法。如果有足够多的特定领域文档可用,那么仅使用这些文档进行培训应该会产生更好的结果。但是文献中有一些参考资料说,最初使用通用语料库进行训练,然后在特定领域的语料库上进行一些训练,可以取得良好的效果。其他参考资料说,如果有足够的特定领域文档可用,最好只尝试这些文档。

    问题是我是大学的一名研究员,作为这项研究工作的一部分,我想做一些实验来比较两种方式的结果。

    所以,我目前的混合训练方法可以总结为:

    model = Doc2Vec(vector_size=20, window=8, alpha=0.025, min_alpha=0.00025, min_count=5, dm=1)

    model.build_vocab(corpus_data_both) # 对两组标记文档进行迭代

    model.train(corpus_data_gen, total_examples=#generic_docs, alpha=0.025, min_alpha=0.00025, epochs=20) # 通用语料库标记文档的迭代器

    model.train(corpus_data_ah, total_examples=#domain_docs, alpha=0.025, min_alpha=0.00025, epochs=20) # 域语料库标记文档的迭代器

    我主要关心的是两个调用 train() 中的 alpha 和 alpha_min 参数。我不确定是设置这些值还是根本不提供它们更好。

    再次感谢您的关注 阿尔贝托

    【讨论】:

    • 您已将此作为您问题的答案,当您可能希望将其作为 (1) 条评论发布在我的回答中时;或 (2) 编辑您的问题,提供更多背景信息;或 (3) cmets 在您的问题上提供上下文。
    • 仍然 - 我已经扩展了我的答案,以便在此处考虑您的额外信息。
    • 是的,我知道,但我的评论超出了评论允许的范围。可能我不知道正确的方法:)
    • 您可以随时编辑您的问题以修改和扩展它,并使用完整格式。
    【解决方案2】:

    这可能不是一个明智的策略,因为:

    • Python Gensim Doc2Vec 类在第一次调用 build_vocab() 后一直无法正确支持扩展其已知词汇表。 (至少在 3.8.3 之前,此类尝试通常会导致 Segmentation Fault 进程崩溃。)因此,如果有仅在您的域语料库中的单词,则对通用语料库的初始典型初始化/训练会将它们排除在外模型完全。 (您可以通过一些非典型的额外步骤来解决这个问题,但下面的其他问题仍然存在。)

    • 如果在您的通用语料库中使用的词/词义与您​​的领域语料库中使用的不同词/词义之间确实存在重要对比,则通用语料库中的词的影响可能不会有益,稀释领域-相关含义

    • 此外,任何仅使用所有文档子集(域语料库)的后续训练都只会更新该单词/词义子集的向量,并且模型的内部权重用于进一步的未见文档推断,在仅对领域语料库有意义的方向上。此类后期训练的向量可能会被任意微调,与未出现在域语料库中的其他词的可比性对齐,并且早期训练的向量将发现自己不再与模型的后来更新的内部权重相关。 (确切的程度取决于后续训练中的学习率alphaepochs 选择,以及后续训练对模型损失的优化程度。)

    如果您的域数据集足够,或者可以使用更多域数据进行扩展,则可能没有必要混合其他训练步骤/数据。但是,如果您认为必须尝试这样做,最好的方法是将所有训练数据混在一起,并在一个会话中训练,从一开始就知道所有单词,并且所有训练示例都以平衡、交错的方式呈现。 (或者可能,一些被认为非常重要的训练文本被过采样,但仍然与所有时代的所有可用文档的多样性混合在一起。)

    如果您看到权威消息来源建议使用 Doc2Vec 算法进行这样的“使用一个数据集进行训练,然后使用另一个不相交的数据集”方法,您应该向他们询问更多关于他们为实现该工作所做的工作的详细信息:确切的代码步骤,以及显示改善的评价。 (有某种方法来管理所有问题并非不可能!但我看到许多模糊的印象,即这种单独的预训练是直接的或有益的,并且零实际工作写的代码和评估指标表明它正在工作。)

    关于您在https://stackoverflow.com/a/64865886/130288 提供的额外说明的更新:

    即使在这种情况下,我的建议仍然是:不要将训练分成两批。与组合训练相比,几乎可以肯定模型会降级。

    我很想看看你提到的“文献中的参考资料”的链接。他们可能会感到困惑或谈论Doc2Vec(“段落向量”)算法以外的算法。

    如果有任何理由赋予您的域文档更多的权重,一个更好的方法是在合并的语料库中对它们进行过采样。

    无论如何,测试所有这些变体并发布相关结果。如果您正在探索不可靠的假设,我会忽略来自类似 StackOverflow 的来源的任何建议,只需运行您阅读文献所建议的所有变体,看看哪些有实际帮助。

    您正确地认识到alpha 参数的选择是一个模糊的领域,可能会严重影响此类附加培训的影响。没有正确的答案,所以你必须搜索和推理出什么是有意义的。我提到的这种子集跟踪训练的固有问题可能会导致即使您在某些组合中找到好处,它们也可能更多是数据和任意参数的幸运组合的产物,而不是可推广的实践。

    并且:您的具体问题“是否最好设置此类值或根本不提供它们”简化为:“您是否要使用默认值或创建模型时设置的值?”

    如果可行的话,哪些值可能是可行的,因为这种未经证实的技术需要通过实验来发现。也就是说,如果您想在这里获得可比较(或可发布)的结果,我认为您必须从自己的小说作品中证明一些特定策略来选择好的 alpha/epochs 和其他参数,而不是采用任何实践只是在 StackOverflow 答案中推荐的。

    【讨论】:

    • 您可以查看以下来自 Microsoft 研究人员的论文。 “用于生物医学自然语言处理的领域特定语言模型预训练”。在那里,他们说在某些情况下(很少有域内数据),混合方法可以产生良好的结果。但是,当然,这篇论文的目标是证明如果有足够的域内数据,使用域内语料库进行直接训练会更好。还必须说他们在实验中使用 BERT,而不是 Doc2Vec。
    • 我真的同意他们的观点,但无论如何,我的兴趣是自己测试不同的场景以观察我的数据的结果。当然,我打算测试不同的组合,但是,我不是 Doc2Vec 方面的专家(甚至不是机器学习方面的专家),欢迎有更多经验和知识的人发表任何评论,以避免幼稚的错误。感谢你的宝贵时间。阿尔贝托
    • BERT 是不同的,有大量工作展示了“微调”的确切步骤和结果。我还没有看到关于“段落向量”(Doc2Vec) 的此类文章,而且我不相信在两个不相交的数据批次上训练 Doc2Vec 模型必然类似于 BERT 的预训练和微调步骤。
    猜你喜欢
    • 1970-01-01
    • 2015-07-03
    • 1970-01-01
    • 2021-04-28
    • 2017-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多