【问题标题】:How to check an array for values similars to a given string?如何检查数组中与给定字符串相似的值?
【发布时间】:2016-04-27 14:17:36
【问题描述】:

目前正在做以下项目:

  1. 在大量文本中获取 2 到 5 个单词之间最常用的短语(都很好)
  2. 返回一个包含 $phrase => $occurrences 的数组

我现在想获取这个数组中的每个值,并检查数组的其余部分是否有类似的值,如果有,将它们合并为一个并总结它们的出现次数。

我想使用 similar_text() 来比较短语的相似程度,如果 > 95,那么我想将它们合并。

最有效的方法是什么?我正在尝试以毫秒为单位进行优化。

目前,我正在使用它……但是 10/30k 字的文章很糟糕。尤其是当我循环浏览其中的几十个时。

function merge_similar_phrases( $original, $threshold = 90 ) {

    foreach ( $original as $phrase => $occurrences ) {

        foreach ( $original as $s => $n ) {

            similar_text( $phrase, $s, $percent );

            if( $percent > 92.5 ) {

                $original[$phrase] = $occurrences + $n;
                unset( $original[$s] );

            }

        }

    }

    return $original;

}

谢谢!

【问题讨论】:

  • 你目前的方法是什么?
  • 不幸的是,文本相似度函数在 PHP 中的运行时间很差。例如,Levenshtein 的最坏情况为 O(nm)。
  • 你不能“优化”similar_text()。它做它做的事,如果不优化底层 php 源代码,你就无法改变它,这意味着编译你自己的自定义 php 版本。
  • @Nadir 我编辑了原文并添加了我的方法

标签: php arrays string sorting similarity


【解决方案1】:

为了提高性能,您可以为自己节省一个 foreach 循环并将其替换为 array_filter。我想到了这样的事情:

foreach ( $original as $phrase => $occurrences ) {

    $similarities = array_filter($original, function($key) use($phrase, $threshold) {
        similar_text( $phrase, $key, $percent );
        if($percent > $threshold){
            return true;
        }
        return false;
    }, ARRAY_FILTER_USE_KEY);
    unset($similarities[$phrase]);
    //do the magic with similarities
}

您必须使用 php 5.6+ 才能使用 ARRAY_FILTER_USE_KEY 标志(如文档中所述:http://php.net/manual/en/function.array-filter.php

但我不知道你可以通过这样做节省多少时间..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-05
    • 1970-01-01
    • 1970-01-01
    • 2014-08-13
    相关资源
    最近更新 更多