Как заменить и посчитать частоту слова или последовательности слов? - PullRequest
0 голосов
/ 12 октября 2010

Мне нужно сделать две вещи, во-первых, найти заданный текст, который является наиболее часто используемым словом и последовательности слов (ограничено n ). Пример:

Lorem * ipsum * dolor sit amet , элиты. Nunc auctor urna sed urna mattis nec interdum magna ullamcorper. Donec ut lorem eros, id rhoncus nisl. Praesent sodales Lorem Vitae Sapien Volutpat и 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 у 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 в последующем libero volutpat. Pellentesque auctor, justo в suscipit mollis, erat justo sollicitudin ipsum , в cursus erat ipsum id turpis. В tincidunt hendrerit scelerisque.

(некоторые слова my были опущены, но это пример).

Я бы хотел получить с сит амет , а не с сит и амет

Есть идеи как начать?

Во-вторых, мне нужно обернуть все слова или словосочетания, соответствующие определенному списку в данном файле.

Для этого я думаю упорядочить результат по убыванию длины, а затем обработать каждую строку в функции замены, чтобы избежать переноса sit amet , если у меня есть другое слово sit в моем список. Это хороший способ сделать?!

Спасибо

Ответы [ 2 ]

0 голосов
/ 12 октября 2010

Это функциональное решение, которое все еще может использовать некоторую очистку. Мой общий алгоритм таков:

  1. Разнести все слова в список w , удаление лишних пробелов и пунктуация
  2. Найти массив всех n -длин куски w , начиная со смещения 0
  3. Найти массив всех n -длин куски ш , начиная со смещения 1
    • ... продолжайте, пока не найдете массив кусков n длины, начиная со смещения n -1
    • Примечание: если последний кусок в w не имеет длины n , не включайте его как часть массива фрагментов
  4. Объединить все массивы фрагментов как c
  5. Найти частоту каждого значения в с

$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);
0 голосов
/ 12 октября 2010

Я пытался решить первую часть некоторое время назад, смотрите здесь:

http://corexii.com/freqwordseq/

Пример Lorem Ipsum (не ваш, а один из них):

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

Это довольно медленно, но это начало.То, что вы хотите сделать, это взвесить совпадения так, чтобы чем больше слов в совпадении, тем больший вес, чтобы последовательности были более важными, чем отдельные слова, составляющие эти последовательности.И тогда вы, вероятно, захотите оптимизировать рутину.

...