【问题标题】:Algorithm to detect similar documents in python script [closed]在python脚本中检测相似文档的算法[关闭]
【发布时间】:2008-09-19 12:47:32
【问题描述】:

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

【问题讨论】:

标签: python algorithm diff


【解决方案1】:

贝叶斯过滤器正是为此目的。这是您在大多数识别垃圾邮件的工具中都能找到的技术。

例如,检测一种语言(来自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)]

但它可以检测你将训练它的任何类型:技术文本、歌曲、笑话等。只要你能提供足够的材料让工具了解你记录的内容是什么样的。

【讨论】:

    【解决方案2】:

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

    您首先为每个文档计算一个唯一的哈希值。如果这些相同,那么您就完成了。

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

    一旦您有了这些带状疱疹,您就可以计算每个带状疱疹的身份哈希并比较这些带状疱疹的哈希以确定文档是否实际上相同。

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

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

    祝你好运!

    【讨论】:

      【解决方案3】:

      无需分类即可轻松找到相似性。试试这个 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
      

      【讨论】:

      • 仅供参考,这在 Python 3 中通过将复数 s 放入集合 (sets->set) 中起作用。谢谢你。
      【解决方案4】:

      您可以使用或最后学习 Python 标准库中的 difflib 来编写代码。

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

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

      这不是解决方案,但也许是一个开始。

      【讨论】:

        【解决方案5】:

        您需要使您的问题更加具体。如果您已经阅读过指纹识别论文,那么您已经知道工作原理,因此在这里描述常用方法将无益。如果你还没有,你还应该看看斯坦福、谷歌、雅虎和 MS 近年来发表的关于“重复检测”的论文和各种网络垃圾邮件检测相关的论文。

        您在对所描述的算法进行编码时遇到具体问题吗?

        开始有问题?

        我可能要做的第一件事是将标记化(提取“单词”或其他合理序列的过程)与重复检测逻辑分开,以便为不同语言插入不同的解析器并保持重复检测片相同。

        【讨论】:

          【解决方案6】:

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

          【讨论】:

            【解决方案7】:

            如果您准备为要在其中搜索的文件编制索引,Xapian 是一款出色的引擎,并提供 Python 绑定:

            http://xapian.org/

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

            【讨论】:

              【解决方案8】:

              如果您尝试检测讨论同一主题的文档,您可以尝试收集最常用的单词,将stop words 扔掉。具有相似分布的最常用词的文档可能在谈论相似的事情。如果您想要更高的准确性,您可能需要做一些stemming 并将概念扩展到n-grams。如需更高级的技术,请查看机器学习。

              【讨论】:

                【解决方案9】:

                我认为 Jeremy 已经一针见血了 - 如果您只是想检测文件是否不同,像 MD5 或 SHA1 这样的哈希算法是一个不错的选择。

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

                【讨论】:

                  【解决方案10】:

                  您可能需要研究 this paper 中概述的 DustBuster 算法。

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

                  与使用 MD5 或 SHA1 哈希的建议类似,DustBuster 方法在很大程度上依赖于比较文件大小作为主要信号。听起来很简单,但对于初始的第一关来说还是相当有效的。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2015-07-28
                    • 1970-01-01
                    • 1970-01-01
                    • 2020-01-25
                    • 2019-10-23
                    • 2020-12-23
                    相关资源
                    最近更新 更多