在python脚本中检测类似文档的算法

时间:2008-09-19 12:47:32

标签: python algorithm diff

我需要编写一个模块来检测类似的文档。我已经阅读了许多关于文档技术和其他指纹的论文,但我不知道如何编写代码或实现这样的解决方案。该算法应适用于中文,日文,英文和德文,或与语言无关。我怎么能做到这一点?

10 个答案:

答案 0 :(得分:18)

贝叶斯过滤器正是出于这个目的。这是大多数识别垃圾邮件的工具中的技术。

示例,检测语言(来自http://sebsauvage.net/python/snyppets/#bayesian):

from reverend.thomas import Bayes
guesser = Bayes()
guesser.train('french','La souris est rentrée dans son trou.')
guesser.train('english','my tailor is rich.')
guesser.train('french','Je ne sais pas si je viendrai demain.')
guesser.train('english','I do not plan to update my website soon.')

>>> print guesser.guess('Jumping out of cliffs it not a good idea.')
[('english', 0.99990000000000001), ('french', 9.9999999999988987e-005)]

>>> print guesser.guess('Demain il fera très probablement chaud.')
[('french', 0.99990000000000001), ('english', 9.9999999999988987e-005)]

但是它可以检测你将训练它的任何类型:技术文本,歌曲,笑话等。只要你能提供一些材料让工具知道你的文档是什么样的。

答案 1 :(得分:9)

如果这些是纯文本文档,或者您有从文档中提取文本的方法,则可以使用称为shingling的技术。

首先为每个文档计算唯一的哈希值。如果它们是相同的,那么你就完成了。

如果没有,则将每个文档分成较小的块。这些是你的“带状疱疹”。

一旦你有了带状疱疹,你就可以为每个木瓦计算身份哈希值,并比较带状疱疹的哈希值,以确定文件是否真的相同。

您可以使用的另一种技术是生成整个文档的n-gram并计算每个文档中类似n-gram的数量,并为每个文档生成加权分数。基本上,n-gram将一个单词拆分成更小的块。 'apple'会变成'a','ap','app','ppl','ple','le'。 (这在技术上是3克)这种方法在大量文档或两个非常大的文档上可能变得非常昂贵。当然,常见的n-gram','th,'th'等需要加权才能将它们降低。

我在我的博客上发布了这个帖子,帖子中有一些关于该主题Shingling - it's not just for roofers的其他文章的链接。

祝你好运!

答案 2 :(得分:6)

您可以使用或最后一次学习来自Python的stdlib的difflib来编写代码。

它非常灵活,并且具有查找字符串列表之间差异的算法,并指出这些差异。然后,您可以使用get_close_matches()查找类似的字词:

>>> get_close_matches('appel', ['ape', 'apple', 'peach', 'puppy'])
['apple', 'ape']

这不是解决方案,但可能是一个开始。

答案 3 :(得分:6)

无需分类即可轻松找到相似性。试试这个O(n2)但工作正常。

def jaccard_similarity(doc1, doc2):
    a = sets(doc1.split())
    b = sets(doc2.split())
    similarity = float(len(a.intersection(b))*1.0/len(a.union(b))) #similarity belongs to [0,1] 1 means its exact replica.
    return similarity

答案 4 :(得分:2)

你需要让你的问题更具体。如果您已经阅读过指纹识别论文,那么您已经了解了工作中的原则,因此在此处描述常用方法并不会有益。如果还没有,你还应该查看近年来从斯坦福,谷歌,雅虎和MS出来的“重复检测”和各种网络垃圾邮件检测相关论文的论文。

您在编写所描述的算法时遇到了具体问题吗?

开始麻烦?

我可能做的第一件事就是将重复检测逻辑中的标记化(提取“单词”或其他敏感序列的过程)分开,这样就可以很容易地为不同的语言插入不同的解析器并保持重复检测件相同。

答案 5 :(得分:2)

Google Techtalks上有一个相当不错的talk on neural networks,它讨论了使用分层Boltzmann机器生成文档的特征向量,然后可以用来测量文档距离。主要问题是需要设置大量样本文档来训练网络以发现相关特征。

答案 6 :(得分:1)

如果您准备索引要搜索的文件,Xapian是一个很好的引擎,并提供Python绑定:

http://xapian.org/

http://xapian.org/docs/bindings/python/

答案 7 :(得分:0)

如果您尝试检测正在讨论相同主题的文档,您可以尝试收集最常用的单词,丢弃stop words。具有相似分布的最常用单词的文档可能正在讨论类似的事情。如果您想要更高的准确度,可能需要执行一些stemming并将概念扩展到n-grams。有关更高级的技术,请参阅机器学习。

答案 8 :(得分:0)

我认为Jeremy已经敲定了头 - 如果你只是想检测文件是否不同,那么像MD5或SHA1这样的哈希算法是一个很好的方法。

Linus Torvalds的Git源代码控制软件以这种方式使用SHA1哈希 - 检查文件何时被修改。

答案 9 :(得分:0)

您可能需要查看this paper中列出的DustBuster算法。

从论文中,他们能够检测重复的页面,甚至无需检查页面内容。当然,检查内容会提高效率,但使用原始服务器日志足以检测重复页面的方法。

与使用MD5或SHA1哈希的建议类似,DustBuster方法在很大程度上依赖于将文件大小作为主要信号进行比较。听起来很简单,它对初始第一次传球非常有效。