如何检查文本是否包含在另一个文本中?

时间:2012-06-16 08:38:08

标签: php text levenshtein-distance

我正在开发一个文档系统,每次创建一个新系统时,它必须检测并丢弃大约500.000条记录的数据库中的重复项。

目前,我正在使用搜索引擎检索20个最相似的文档,并将它们与我们尝试创建的新文档进行比较。问题是我必须检查新文档是否相似(使用similar_text很容易),或者即使它包含在其他文本中,所有这些操作都考虑到文本可能已被用户部分更改(这里是问题)。我怎么能这样做?

例如:

<?php

$new = "the wild lion";

$candidates = array(
  'the dangerous lion lives in Africa',//$new is contained into this one, but has changed 'wild' to 'dangerous', it has to be detected as duplicate
  'rhinoceros are native to Africa and three to southern Asia.'
);

foreach ( $candidates as $candidate ) {
  if( $candidate is similar or $new is contained in it) {
       //Duplicated!!
  }
}

当然,在我的系统中,文件超过3个字:)

2 个答案:

答案 0 :(得分:1)

这是我正在使用的时间解决方案:

function contained($text1, $text2, $factor = 0.9) {
    //Split into words
    $pattern= '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/u';
    $words1 = preg_split($pattern, mb_strtolower($text1), -1, PREG_SPLIT_NO_EMPTY);
    $words2 = preg_split($pattern, mb_strtolower($text2), -1, PREG_SPLIT_NO_EMPTY);

    //Set long and short text
    if (count($words1) > count($words2)) {
        $long = $words1;
        $short = $words2;
    } else {
        $long = $words2;
        $short = $words1;
    }

    //Count the number of words of the short text that also are in the long
    $count = 0;
    foreach ($short as $word) {
        if (in_array($word, $long)) {
            $count++;
        }
    }

    return ($count / count($short)) > $factor;
}

答案 1 :(得分:0)

您可能进行或进一步调查的一些想法是:

  1. 索引文档,然后搜索类似的文档。因此,SolrSphinxZend Search Lucene等开源索引/搜索系统可以派上用场。

  2. 您可以使用sim hashing algorithmshingling。简而言之,simhash算法将允许您为类似文档计算类似​​的哈希值。因此,您可以将此值存储在每个文档中,并检查各种文档的相似程度。


  3. 您可能会发现有助于从中获取一些想法的其他算法:

    1。 Levenshtein distance

    2。 Bayesian filtering - SO Questions re Bayesian filtering。此列表项中的第一个链接指向Wiki上的贝叶斯垃圾邮件过滤文章,但此算法可以适应您要执行的操作。