如何替换和计算单词或单词序列的频率?

时间:2010-10-12 15:41:01

标签: php nlp word frequency-analysis word-frequency

我需要做两件事,首先,找一个最常用的单词单词序列(限于 n )的给定文本。 例如:

  

Lorem * ipsum * dolor 坐下来,奉献精灵。 Nunc auctor urna sed urna mattis nec interdum magna ullamcorper。 Donec ut lorem eros,id rhoncus nisl。 Praesent sodales lorem vitae sapien volutpat et accumsan lorem viverra。 Proin lectus elit ,cursus ut feugiat ut,porta sit amet leo。 Cras est nisl,aliquet quis lobortis sit amet ,viverra non erat。 Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;整数euismod scelerisque quam,et aliquet nibh dignissim at。 Pellentesque ut elit neque。 Etiam facilisis nisl eu mauris luctus in consequat libero volutpat。 Pellentesque auctor,justo in suscipit mollis,erat justo sollicitudin ipsum ,在cursus erat ipsum id turpis。在tincidunt hendrerit scelerisque。

(有些话我已被省略,但这是一个例子)。

我希望坐下来,而不是 amet

关于如何开始的任何想法?

其次,我需要将给定文件中给定列表中匹配的所有单词或单词序列包装起来。

为此,我认为通过降低长度对结果进行排序,然后在替换函数中处理每个字符串,以避免在我有另一个字时将坐下来包裹在我的清单中。 这是一个好方法吗?!

谢谢

2 个答案:

答案 0 :(得分:0)

我前段时间试图解决第一部分,请看这里:

http://corexii.com/freqwordseq/

关于Lorem Ipsum的例子(不是你的,而是其中一个):

http://corexii.com/freqwordseq/?file=loremipsum&minfreq=2&minseq=1&maxseq=4

这很慢,但这是一个开始。你想做的是权衡匹配,以便匹配中的单词越多,权重越高,使序列比构成这些序列的单个单词更重要。然后你可能想要优化例程。

答案 1 :(得分:0)

这是一个功能性解决方案,仍然可以使用一些清理。我的一般算法是:

  1. 将所有字词分解为列表 w , 剥去多余的空白和 标点符号
  2. 找到所有 n -length的数组 w 的块,从偏移0开始
  3. 找到所有 n -length的数组 w 的块从偏移量1开始
    • ...继续,直到找到从 n -1
    • 开始的 n - 长度数组的数组
    • 注意:如果 w 的最后一块不是 n -length,请不要将其作为块数组的一部分包含在内
  4. 将所有块数组连接为 c
  5. 查找每个值的频率 C

  6. $sample = 'Lorem *ipsum* dolor sit amet, consectetur adipiscing elit. Nunc auctor urna sed urna mattis nec interdum magna ullamcorper. Donec ut lorem eros, id rhoncus nisl. Praesent sodales lorem vitae sapien volutpat et accumsan lorem viverra. Proin lectus elit, cursus ut feugiat ut, porta sit amet leo. Cras est nisl, aliquet quis lobortis sit amet, viverra non erat. Vestibulum ante ipsum  primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer euismod scelerisque quam, et aliquet nibh dignissim at. Pellentesque ut elit neque. Etiam facilisis nisl eu mauris luctus in consequat libero volutpat. Pellentesque auctor, justo in suscipit mollis, erat justo sollicitudin ipsum, in cursus erat ipsum id turpis. In tincidunt hendrerit scelerisque.';
    
    function buildPhrases($string, $length) {
    
        $onlyWords = preg_replace('/\p{P}/', '', $string);
        $wordArray = preg_split('/\s+/s', $onlyWords);
    
        function buildPhraseChunks($wordArray, $length, $offset = 0)    
        {
            if ($offset >= $length) {
                return array();
            } else {
                $offsetWordArray = array_slice($wordArray, $offset);
                return array_merge(
                    array_chunk($offsetWordArray, $length),             
                    buildPhraseChunks(
                        $wordArray, $length, $offset + 1
                    )
                );
            }
        }
    
        $onlyLengthN = function ($n) {
            return function($a) use ($n) {
                return count($a) == $n;
            };
        };
    
        $concatWords = function ($a, $b) {
            return $a . ' ' . $b;
        };
    
        $reduce = function ($a) use ($concatWords) {
            return array_reduce($a, $concatWords);
        };
    
        $format = function ($a) {
            return strtolower(trim($a));
        };
    
        $chunks = array_filter(
            buildPhraseChunks($wordArray, $length),
            $onlyLengthN($length)
        );
        $phrases = array_map($reduce, $chunks);
        $formattedPhrases = array_map($format, $phrases);
    
        return $formattedPhrases;
    
    }
    
    $phrases = buildPhrases($sample, 1);
    $dropOnes = function($a) {
        return $a != 1;
    };
    $freqCount = array_filter(
        array_count_values($phrases),
        $dropOnes
    );
    
    arsort($freqCount);
    
    print_r($freqCount);