文本和关键字列表之间的亲和力?

时间:2011-01-13 13:27:15

标签: php mysql

我有一部分文字(500-1500个字符)

我有一个关键字列表(1000条记录)..

我该怎么做才能找到该列表中与我给定文本相关的关键字?

我正在考虑在列表中的每个关键字中搜索我的文本中这些关键字的内容,但我认为它有点“昂贵”

由于

2 个答案:

答案 0 :(得分:2)

如果关键字始终保持不变,则可以为它们创建索引,从而提高搜索速度(极大地提高)。处理这个问题的标准数据结构是trie,但更好(!)的替代方案是Aho-Corasick automaton或其他多模式搜索算法,例如多模式Horspool(也称为Wu-Manber算法) )。

最后,一个非常简单的替代方法是将所有关键字与管道(|)连接起来,并将结果用作正则表达式。从技术上讲,它接近Aho-Corasick自动机,并且更容易实现。

答案 1 :(得分:1)

我把帽子戴在戒指上......

function extractWords($text, $minWordLength = null, array $stopwords = array(), $caseIgnore = true)
{
    $pattern = '/\w'. (is_null($minWordLength) ? '+' : '{'.$minWordLength.',}') .'/';
    $matches = array();
    preg_match_all($pattern, $text, $matches);
    $words = $matches[0];

    if ($caseIgnore) {
        $words = array_map('strtolower', $words);
        $stopWords = array_map('strtolower', $stopwords);
    }

    $words = array_diff($words, $stopwords);

    return $words;
}

function countKeywords(array $words, array $keywords, $threshold = null, $caseIgnore = true) 
{   
    if ($caseIgnore) {
        $keywords = array_map('strtolower', $keywords);
    }

    $words = array_intersect($words, $keywords);
    $counts = array_count_values($words);
    arsort($counts, SORT_NUMERIC);

    if (!is_null($threshold)) {
        $counts = array_filter($counts, function ($count) use ($threshold) { return $count >= $threshold; });
    }

    return $counts;
}

用法:

$text = 'a b c a';  // your text
$keywords = array('a', 'b');  // keywords from your database

$words = extractWords($text);
$count = countKeywords($words, $keywords);
print_r($count);

$total = array_sum($count);
var_dump($total);

$affinity = ($total == 0 ? 0 : 1 / (count($words) / $total));
var_dump($affinity);

打印

  

阵   (       [a] => 2       [b] => 1   )
  INT(3)
  浮动(0.75)