Анализ книги законов Ципфа с использованием Perl - PullRequest
1 голос
/ 09 июля 2020

Предположим, что есть книга в текстовом файле, книга домена publi c, так что нет никаких ограничений на то, что с ней делать, например «Война миров» Герберта Уэллса (1898 г.):

enter image description here

it starts like this:

CHAPTER ONE

THE EVE OF THE WAR

No one would have believed in the last years of the nineteenth century that this world was being watched keenly and closely by intelligences greater than man’s and yet as mortal as his own ...

to count the ocurrences of each word it is used the next perl script:

perl -0777 -lape's/\s+/\n/g' worlds.txt | sort | uniq -c | sort -nr > occurenaces.txt

and then is generated a text file like this:

   4395 the
   2317 and
   2282 of
   1524 a
   1204 I
   1155 to
    901 in
    830 was
    707 that
    557 had
    432 with
    411 my
    402 as
    ...
 

to plot it in a graph it is used:

gnuplot -e "set logscale y 2; set ytics 2; set grid; set title 'Occurenaces vs Word'; set xlabel 
'Word Rank'; set ylabel 'Number of Occurenaces'; set terminal png size 800,600; set output 'occurenaces.png'; plot 
'occurenaces.txt' with points pt 7 lc rgb 'red'; pause -1"

введите описание изображения здесь

У меня есть некоторые проблемы, но мой скрипт считает некоторые слова, которые совпадают более одного раза, например:

4395 the
340 The 

или, например:

62 Martian 
12 Martian,
4 Martian’s
3 Martian.
1 Martian!’

Как избежать этой проблемы?

1 Ответ

3 голосов
/ 09 июля 2020

Это задание, которое я даю в Learning Perl классах. Фактически, я однажды дал его студенту-стажеру, потому что у него было это задание на урок статистической механики. Большинство людей использовали короткий текст и считали вручную. Так что я попросил его написать Moby Dick , а затем Библию KJV. Мои дополнительные инструкции заключались в том, чтобы раскрыть результаты для Библии только после того, как он поразит всех Моби Диком . Хорошие времена. Зипф берет огромную книгу, чтобы объяснить все это: Человеческое поведение и принцип наименьшего усилия .

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

  • Удалить весь «нетекстовый» текст. Вот что написал Герберт Уэллс, а затем метатекст, такой как «Глава».
  • Нормализовать слова. «The» и «the» одинаковы, но имеют разные падежи. «Марсианин» и «марсианин» немного разные, потому что они представляют разные идеи. Как вы об этом судите, зависит от вас.
  • Подсчитайте счет. Здесь вам не нужен конвейер, потому что Perl может все это делать. Использование слова в качестве ключа ha sh уже обрабатывает часть уникальности.
LINE: while( <> ) {
    chomp;
    my @words = map normalize($_), split /\s+/;
    $Count{$_}++ for @words;
    }

sub normalize {
    my $s = lc shift;
    $s = s/[^a-z]//ig; # might reduce too much
    ... whatever else you need ...
    }

Как только у вас есть ha sh, вы можете выводить его любым способом. Ключи уже уникальны, и вы можете их отсортировать, я думаю, но сюжету все равно.

Оттуда вы заметите другие странности в списке слов, внизу, в хвосте. Вы можете игнорировать их из-за их небольшого количества, но если вам нужна высокая точность, вы попадете в словари, которые вы поддерживаете отдельно для особых случаев.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...