我们拥有数量为n的文档。当用户提交新文档时,我们的目标是告知用户可能存在已有文档的重复(就像Stack Overflow会提示问题可能已经有答案一样)。
在我们的系统中,每分钟都会上传新文档,且大多是关于相同主题的(因此有更多的重复机会)。
我们当前的实现包括在文档上训练的gensim doc2vec模型(标记有唯一的文档ID)。我们为新文档推断向量,并找到与之最相似的文档(ID)。选择doc2vec模型的原因是我们希望利用语义来改善结果。据我们所知,它不支持在线训练,因此我们可能需要安排定时任务或类似的东西来定期更新模型。但定时任务的安排将是不利的,因为文档是以突发形式出现的。用户可能在模型尚未针对新数据训练时就上传了重复文档。另外,考虑到数据量巨大,训练时间将更长。
所以我想知道大公司是如何处理这种情况的。有没有更好的替代方案?或者解决此类问题更好的算法?
回答:
您无需关闭旧模型即可开始训练新模型,因此尽管存在训练延迟或新文档的突发情况,您始终会有一个实时模型尽其所能地工作。
根据文档空间随时间变化的程度,您可能会发现重新训练的益处可以忽略不计。(一个建立在大型历史记录上的良好模型,可能在无限期推断新向量时仍然有效。)
请注意,调整推断以使用更多的steps
(特别是对于短文档),或者使用较低的起始alpha
(更接近训练默认值0.025),可能会带来更好的结果。
如果有词向量可用,还有一种名为“词移动距离”(WMD)的文档相似性计算方法,这可能在识别接近的重复文档方面表现得更好。不过,请注意,它的计算可能相当昂贵——您可能只想针对可能的候选子集进行计算,或者需要添加许多并行处理器来批量处理。还有另一种较新的距离度量方法称为“软余弦相似度”(在最近的gensim中可用),其复杂度介于简单向量到向量的余弦相似度和完整的WMD之间,可能值得一试。
在词汇没有扩展的范围内,您可以加载旧的Doc2Vec
模型,并继续train()
它——从已经工作的模型开始可能有助于您以更少的传递次数达到相似的结果。但请注意:它目前不支持学习新词,最安全的做法是用所有已知例子的混合重新训练,并交错排列。(如果您只在增量的新例子上训练,模型可能会失去对未重新展示的老文档的平衡理解。)
(如果您主要关注的是重复的精确词语序列,而不是仅仅相似的话题,您可以考虑混合使用其他技术,比如将文档分解为字符n-gram的集合,或者像在抄袭检测应用程序中常见的“shingleprinting”。)