我正在编写一个软件来比较文章。我正在寻找一种有效而准确的算法来计算两篇文章之间的差异(变化)。变化应完全取决于单词而不是字母。我已经尝试了levenshtein()
,但它的时间复杂度为 O(n * m),这在文章等大文本上执行时非常昂贵。我还试过similar_text()
,其时间复杂度高于 O(n * m * 3)。此外,levenshtein()
和similar_text()
计算将一个字符串转换为另一个字符串所需的操作数,这不是计算两篇大文章之间差异的准确方法。
我还有其他选择吗?
<小时/> 修改
我正试图从搜索引擎(Google)的角度大致计算出变化。
答案 0 :(得分:1)
PostgreSQL使用tsvector进行全文搜索功能。也许这对你来说非常方便。
答案 1 :(得分:1)
如果您可以定义如何根据单词测量文本相似度,那么您就完成了一半。例如:您可以计算两篇文章中每个单词的出现次数,然后创建两个列表的简单差异。但是,这不符合意义相似性。
如果您有数据库,请使用其全文功能。如前所述,PostGres提供了这样的功能。我使用MSSQL,您可以简单地调用FREETEXT函数,该函数将计算一个'rank',表示两个文本的相似程度。
我强烈建议您使用成熟的产品,而不是尝试自己编写产品。
答案 2 :(得分:1)
无法比较两篇文章。 levenshtein()
和similar_text()
旨在比较两个单词,而不是文章。
最简单的算法是用文字来爆炸你的文章,逐字逐句地找到相似的东西并做一些数学运算,这取决于你的任务,如下:
// not tested!
function similar_articles($articleA, $articleB) {
$wordsA = array_unique(preg_split('@[\W]+@', $articleA));
$wordsB = array_unique(preg_split('@[\W]+@', $articleA));
$resultSimilarity = 0;
foreach($wordsA as $wordA) {
$wordSimilarity = 0;
foreach($wordsB as $wordB) {
similar_text($wordA, $wordB, $percent);
$wordSimilarity = max($wordSimilarity, $percent);
}
$resultSimilarity += $wordSimilarity;
}
return($resultSimilarity / count($wordsA));
}
注意:similar_articles($artileA, $articleB)
!= similar_articles($artileB, $articleA)
因为similar_text($wordA, $wordB)
!= similar_text($wordB, $wordA)
。
答案 3 :(得分:0)
计算距离类型的简单方法是比较参考。另一种方法是根据字典选择一些关键词,并按社会相关性的顺序计算距离。
另外,为了使用Levenshtein distance,请查看stringmetric。
答案 4 :(得分:0)
就我而言,我需要计算两篇文章之间的差异。所以,我发现非常简单的解决方案非常适合我。它的工作原理是简单地将相似度计算为两篇文章之间的常用词除以 max(文章A中的词数,文章B中的词数) 即可。然后通过从100减去相似性来计算变化以获得变化百分比。下面的代码解释了这一切。
function get_variation($article1,$article2){
$wordsA = array_unique(preg_split('@[\W]+@', $article1));
$wordsB = array_unique(preg_split('@[\W]+@', $article2));
$intersection = array_intersect($wordsA, $wordsB);
$similarity = (count($intersection)/ (max(count($wordsA),count($wordsB))) * 100);
$similarity = number_format($similarity, 2, '.', '');
$variation = 100-$similarity;
return $variation;
}