Наиболее часто встречающаяся структура предложений в русском языке по версии библиотеки Флибуста

Я программист php, но захотел расширить горизонты, узнать что ни будь новое. Поэтому решил поучить другие языки и технологии. Выбор пал пока на perl, python и mysql.

Был взят замечательный пакет pymorphy , библиотека Флибуста (только .fb2), sedna для хранения fb2, mysql percona 5.1 для хранения статистики и маленький напильник. Была создана примитивная myisam табличка куда записывалась сколько встречалось предложение, и описание частей речи этого предложения.

По описанию сделал уникальный текстовый индекс, а по числовому полю индекс сделать забыл (думал не пригодится).

Fb2 с флибустры поместил в базу sedna, получилось база где то в 90 GB.

Первым этапом я собрал все уникальные слова, встречающие в библиотеке. Получилось примерно 14 миллионов слов. Это были как уникальные слова, так и их формы, и прочий мусор.

Опытным путем было выявлено, что pymorphy в режиме pickle на инициализацию тратит довольно много времени, и просто его дергать из php через shell будет очень долго. Так как python я только начал изучать, а для получения части речи нужно было использовать pymorphy, то я принял решение последний запустить как сервер. Это сняло проблему долгой инициализации, и вот что примерно получилось:

#!/usr/bin/env python<br/>
# -*- coding: utf-8 -*-<br/>
from pymorphy import get_morph<br/>
import re,sys,socket,pprint,json,chardet,ConfigParser<br/>
 <br/>
def do_word(data):<br/>
    if(data == False or data == '')print "error incoming data !!!"<br/>
    tmpWord = re.sub(r"rn",'',data)<br/>
    word = tmpWord.decode('utf-8').upper()<br/>
    if(DEBUG == 1)print word<br/>
    info = morph._decline(word)<br/>
    if(DEBUG == 1)pprint.pprint(info)<br/>
    sjSon = json.dumps(info)<br/>
    return sjSon<br/>
 <br/>
config = ConfigParser.ConfigParser()<br/>
config.read('pymorphy_conf.ini')<br/>
DEBUG = config.getint('decline','DEBUG')<br/>
HOST = config.get('decline','HOST')<br/>
PORT = config.getint('decline','PORT')<br/>
 <br/>
morph = get_morph("/pymorphy/dicts/converted/ru/morphs.pickle",'pickle')<br/>
 <br/>
srv = socket.socket(socket.AF_INET,socket.SOCK_STREAM)<br/>
srv.bind((HOST,PORT))<br/>
while 1:<br/>
    if(DEBUG == 1)print "Слушаю порт ",PORT<br/>
    srv.listen(1)<br/>
    sock,addr = srv.accept()<br/>
    while 1:<br/>
       pal = sock.recv(1024)<br/>
        if not pal:<br/>
          break<br/>
        lap = do_word(pal)<br/>
        sock.send(lap)<br/>
    sock.close()



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

После чего осталось самое простое – собрать статистику. Собирал я ее 2 месяца, после чего надоело. Что стало узким местом сказать трудно. Поиск части речи слова ~ 0.0046 sec, остальные операции тоже вменяемые, коль просто слова получилось быстро собрать. Sedna тоже на прошлых этапах была протестирована, и конечно не летала, но слова ж с нее получилось собрать за пару часов, следовательно ее производительности было достаточно что бы и статистику по предложениям собрать.
В итоге получились следующие данные:

image

И т.д.
дополнено
По словам ( это данные не только Флибусты, тут еще чуток других текстов намешано)

TOP 1500 и
меньше
150 и
меньше
15 и меньше
нет 60300 подоконник 1500 гитлеровцев 150 Эйх 15
я 53847 деревянный 1500 покривил 150 Лантер 15
да 50813 сбросил 1499 Юре 150 Бутовсан 15
что 48819 именами 1499 загробной 150 иксайтов 15
так 45926 росла 1499 ларьков 150 трагги 15
все 44672 высоком 1499 Аллу 150 Аткаль 15
это 42825 ГЛУБОКАЯ 1499 баранам 150 Юмми 15
он 42154 активно 1499 переложила 150 моллюскором 15
ты 38073 чудес 1498 лазеров 150 медвяны 15
меня 35976 Объясните 1498 транспортёра 150 хронохирургов 15
а 35900 прозвучало 1498 брюнетки 150 Ивашуры 15
его 35394 ворвался 1498 школьницы 150 хроноускорителя 15
как 34347 фигурой 1498 ворам 150 осцилляций 15
мне 34078 ночей 1498 разведчикам 150 пентарха 15
и 33836 ПРОИЗВЕДЕНИЯ 1498 физиологических 150 Горшиным 15
она 31373 окей 1498 поэтической 150 роиды 15
хорошо 30932 недовольство 1498 задрали 150 маршалессы 15
вы 30738 баксов 1497 цилиндров 150 эвменарх 15
здесь 29969 звонила 1497 тройное 150 эвменарха 15
есть 29579 повернула 1497 дебатов 150 хроноген 15
было 29297 рванул 1497 минимумом 150 Ковалях 15
но 29009 шампанское 1497 характеристикой 150 Ягья 15
там 28955 бомба 1497 налете 150 энергоинформационные 15
ну 28612 требовала 1496 конторки 150 консортлинию 15
ничего 28605 размышлений 1496 сослан 150 эфанализа 15
дело 27653 восторгом 1496 генетических 150 псисферы 15
же 26973 осмотреть 1496 летия 150 форинг 15
вот 26898 дошла 1495 старенькой 150 рефлезианцев 15
еще 26640 источников 1495 пустыря 150 рефлезианцы 15
ее 26556 обратилась 1495 луковицу 150 слэйеры 15
человек 26415 приподнялся 1495 генератором 150 Левиков 15
сейчас 26408 вытянул 1495 простенькое 150 Гленке 15
надо 25657 серая 1495 обертки 150 Ирраши 15
конечно 25568 несчастью 1494 аппетитные 150 камра 15
почему 25216 разглядывал 1494 повернуло 150 Арварохе 15
может 25012 поразительно 1494 табличками 150 Уандук 15
мы 24847 дяди 1493 подслушивания 150 шефатташе 15
ЗНАЮ 24843 проверки 1493 тараканами 150 Тархановым 15
они 24070 приглашения 1493 скудную 150 гнорр 15
тебя 23922 тяжелыми 1493 просеки 150 Орнумхониоров 15
в 23600 вмешаться 1493 небывалым 150 Ганфалы 15
время 23598 уверенный 1493 намеченному 150 Гамелинам 15
их 22956 видал 1493 прибылей 150 Урайном 15
вас 22780 продолжения 1492 питая 150 Эллата 15
то 22730 возразила 1492 комментируя 150 Урайну 15
раз 22508 целого 1492 шикарного 150 гервериты 15
теперь 22488 Ейбогу 1492 предприятиями 150 Харрены 15
не 22450 начну 1492 поволокой 150 гиазира 15
тебе 22107 снимок 1492 Дроздов 150 Котлеткин 15
ему 22014 Поймите 1491 действительных 150 черномагическое 15
сказал 21970 встреч 1491 послушается 150 Дурневу 15
нас 21950 жаром 1491 туманном 150 Котлеткина 15
глаза 21763 прыгать 1491 выезду 150 Спуриус 15
кто 21740 вообразить 1491 Равнодушная 150 РОБУСГРОБУС 15
себя 21656 загадка 1491 привычны 150 Йоха 15
будет 21642 василий 1491 именуемого 150 Тетлуцоакля 15
один 21576 звучало 1490 валерьянки 150 Яраат 15
потом 21438 связана 1490 смахивало 150 маголодий 15
быть 21415 смирно 1490 ядрами 150 Лигулом 15
люди 21368 медленнее 1490 отвечающие 150 Ламаса 15
жизнь 21322 вчерашнего 1489 нарисованным 150 Варнана 15
правда 20972 тонкими 1489 слышное 150 Белирии 15
с 20645 поведал 1489 лесенки 150 Нимробец 15
только 20603 нырнул 1489 водяными 150 Дюнка 15
жизни 20517 возвращении 1489 безудержной 150 Легиара 15
о 20516 флаг 1489 цивилизациями 150 Чарлок 15
ли 20450 кверху 1489 скандальной 150 Мидуинтер 15
больше 20328 зов 1489 англичанину 150 Уклод 15
сказать 20318 верность 1489 протестовали 150 Зорик 15
себе 20299 сменил 1488 задушу 150 запределье 15
чем 20291 серьезного 1488 круглому 150 Бьярта 15
тогда 20244 смена 1488 кастрюльку 150 Ренальдо 15
лучше 20047 владимир 1488 тогдашним 150 Самоненко 15
вам 20024 атмосферу 1487 насмешливая 150 Дюшка 15
дальше 19819 убежала 1487 предельную 150 Морфичев 15
где 19600 противоположной 1487 реву 150 Варыкин 15
руки 19545 плаще 1487 дьявольскую 150 Грызач 15
делать 19525 фыркнула 1487 мясе 150 Цончик 15
если 19522 старшим 1487 туфельках 150 Гроулис 15
на 19444 начинался 1487 нарекли 150 Лебединская 15
лет 19444 тащить 1487 минеральную 150 Валюшок 15
дома 19361 парой 1487 преданиях 150 Яхотела 15
него 19096 отступить 1487 захлопнулся 150 Щааас 15
слова 19026 непонятное 1487 такието 150 Гугима 15
можно 18966 приветливо 1487 авантюристы 150 глонгов 15
этого 18860 вдова 1487 романтическим 150 Оберпоручик 15
день 18772 ошиблась 1486 дубленку 150 Бекхэма 15
зачем 18730 отдали 1486 дотрагиваясь 150 Вкаком 15
людей 18680 отдала 1486 вылечили 150 Кутеванова 15
тоже 18583 подождем 1486 красила 150 копачей 15
был 18450 свежей 1486 ответственную 150 Стробач 15
бы 18438 свежие 1486 культурными 150 Зонова 15
значит 18361 фото 1486 смешения 150 Портфелия 15
человека 18312 раб 1486 прочтете 150 Лаэль 15
ним 18293 фонари 1485 интимную 150 Бепе 15
вопрос 18276 обстановки 1485 продовольственные 150 кластапуги 15
назад 18186 успев 1485 недостойной 150 Куплинг 15
нам 18167 поведении 1485 Содрогнувшись 150 Куплинга 15
или 18155 предмета 1485 новоприбывших 150 Столоки 15
такое 18116 результата 1485 ошейнике 150 Мощина 15


Всего было обработано 90 611 059 предложений.

Забыв сразу сделать индекс по числовому полю я столкнулся с серьезной проблемой. После того, как получилась таблица в 58 миллионов записей и размером в 12 GB индекс строился по ней больше суток и так и не построился. Выручил
myisam_sort_buffer_size=1024MB
установленный в 1 GB, индекс построился за часы.

Ps. Конфигурация сервера: AMD Athlon(tm) II X4 635 Processor, 16 gb DDR3,WDC WD7500AACS-00D6B1
Реклама
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее

Комментарии 43

    0
    Интересно, а с помощью Google Fusion Tables можно произвести анализ твоей таблицы.
      0
      мда, там ограничение You can use Fusion Tables to import a file of up to 100 MB of these file types…
        +2
        Я б настоятельно не советовал с такими базами — моя 21G работать через кого-то типа Google Fusion Tables или слабый хостинг. Конфигурация моего сервера думаю не из самых слабых. Я так понял, что когда таблицы переваливают за какой-то порог вопросы быстродействия железа, канала доступа, настроек сервера становятся очень остро. Цена ошибки — сутки, а в моем случае месяцы работы сервера. В частности — php скрипт который собирал статистку был запущен с включенным zend_debuger без оптимизаторов типа xcache и прочих. В итоге, думаю задержки которые при прочих условиях дали бы секунды простоя вылились в часы и сутки добавочного времени. При чем в моем случае я сделал вывод что задержки были еще и из-за IO (медленный винт)
        +2
        помню как-то одна программа по определению части речи распознала слово «хрюша» как существительное, прилагательное и деепричастие («тихо хрюша колесами, автобус ...»)
          +1
          Морфологические анализаторы часто возвращают все возможные варианты разбора слова (желательно — в порядке убывания вероятности). В простейшем случае потом берется наиболее вероятный вариант. Если нужна большая точность, то задача выбора правильного варианта разбора (дизамбигуация) решается каким-то кодом уровнем чуть выше, который смотрит уже не только на само слово, но и на его контекст.

          Так что наличие варианта разбора «хрюши» как деепричастия — это скорее плюс) Без такого варианта фразу «тихо хрюша колесами, автобус» правильно уже не разобрать.
            0
            Все верно. Но на первых парах даже примитивные действия заняли много времени. Что уж говорить о коде, который будет выбирать часть речи, опираясь на контекст. Но для выявления общих закономерностей статистика вполне годится, тем более что еде то на 100 000 повторения структуры предложения почти закончились, а из 90 000 000 это уже результат.
            +3
            Да, да… Что делая? «Батарея! Батарея тоже деепричастие ;)
              +3
              И еще «вокзал» (что делал?) мне очень нравится :) Прошу прощения за флуд.
            0
            Как-то непонятно, почему самое частое предложение — «С»? Есть какие-нибудь примеры? (Кроме «Оглавление», «Вступление», и «Тоска...»?) Боюсь, там всё-таки проблемы с омонимией.
              0
              Ну видимо, таких предложений все-же больше, чем остальных комбинаций. Ведь, чем проще конструкция, тем чаще она будет встречаться.
                0
                Объясняется это очень просто. Книг проанализировано примерно 86 556, в которых фразы типа 'умри!' или 'пойдем...' повторялись довольно часто. Название глав, и прочее. Поэтому первые 4 результата вполне очевидны.
                  +1
                  Всё равно не очень понятно… Примеры, которые Вы привели — глаголы, а не существительные. Как раз в них поверить просто, но вот предложения из одного существительного, на мой взгляд, редкость. У Вас нет примеров?
                    0
                    «Ночь, улица, фонарь, аптека… „
                      0
                      Кажись, это предложение из 4-х существительных…
                  0
                  Метель. Снег. Мороз. Дом. Окно. Дым. Дверь. Скрип. Шаг. Крик.

                  Можно целый рассказ написать из одних существительных.
                    0
                    Шикарный номер КВН
                    Высшая лига (2008) 1/4 — Байкал — СТЭМ «Существительные»
                    www.youtube.com/watch?v=a9kItP3Zcv8
                      0
                      Так себе, если честно. Там, кстати, прилагательные проскакивали и частицы.
                    0
                    Мать!..
                    0
                    посчитайте, каких вариантов больше — глагол+сказуемое или сказуемое+глагол.
                      0
                      э-э… то есть я хотел сказать существительное+глагол. VSO/SVO короче.
                        0
                        По ощущениям — одинаково. И статистика это показывает. Но попытки увидеть такие предложения в книгах к успеху не привели: все двухсловне предложения, которые удалось увидеть — какие-то странные «А ты?», «Очень хорошо», «Давай, заноси» и т.п. Попадаются исключительно в репликах.
                          0
                          я недостаточно четко выразился. :(
                          строчки
                          С Г 312017
                          Г С 288641
                          я вижу.

                          Интересуют конечно же предложения с любым количеством слов, для которых можно определить порядок подлежащее-сказуемое.
                          Но простая статистика тут может ошибаться, потому что надо учитывать глубинный синтаксис. Например, предложения "Петя кушает кашу" и "Кашу кушает Петя" выглядят одинаково для поверхностного анализа — «Сущ. Глагол. Сущ.», но по-разному на уровне синтаксиса: «Подлежащее сказуемое дополнение» или «дополнение сказуемое подлежащее» соответственно.
                          Русский язык не имеет строгого правила насчет порядка слов, поэтому любопытно было бы оценить статистический разброс на такой большой выборке.
                            0
                            Русский однозначно тяготеет к SVO.
                    • НЛО прилетело и опубликовало эту надпись здесь
                        0
                        Статистику решил собрать скорее из баловства. И, если честно, я не ожидал, что такая на первый взгляд тривиальная задача займет столько время. Поэтому и технологии не выбирал. Впредь конечно нужно будет прикидывать, сколько времени, какие телодвижения могут занять. Еще из наблюдений, при работе скрипта не наблюдались нагрузки, и за пару дней в базе было уже 30 лямов записей. А вот остальные 60 и собирались остальное время. Возможно innodb с выделением под нее много памяти (таковая имелась) помогла бы.
                        • НЛО прилетело и опубликовало эту надпись здесь
                            0
                            memcache от есть, только я не совсем понял каким боком он поможет при решении данной задачи — библиотека (.fb2) прогонялась один раз, и собиралась статистика в базе. Cобственно кешировать то нечего? Повторно ни чего не использовалось.
                          0
                          В Percona даже MyIsam — InnoDB
                          –2
                          Поэтому решил поучить другие языки и технологии. Выбор пал пока на perl, python и mysql.

                          Поправьте меня, если я не прав, но мне всегда казалось что MySQL — это субд.
                            +2
                            И поэтому её даже технологией назвать нельзя!
                              +2
                              Ну так как в этом топике цепляться к словам — хороший тон, то MySQL — это вполне себе технология.
                                0
                                " языки и технологии " mysql — это субд и SQL ( «язык структурированных запросов») + как технологию я его рассматриваю с точки зрения настройки под конкретные задачи.
                                +1
                                Это не структура предложения, а состав. Вы же не анализировали связи между частями речи. Это раз. Два! Вы о чем рассказываете? Сначала про обучение, потом про поднятие pythona, потом про то что вам стало скучно.
                                Не вводите читателей в заблуждение. А то я уже кофе сварил, чтобы почитать что-то интересное, а тут.
                                  0
                                  Ну если б я сделал полный разбор предложений с учетом контекста, всей возможной морфологии и прочего. Собрал полную развернутую статистику и… пошел бы в гугл работать )))) Понятно дело — это только первые шаги, и думаю не каждый эти шаги с лету пройти сможет. Когда тебя поддерживают и верят что ты на верном пути и делать хочется, к когда с порога хаят — все желание пропадает )
                                  ИИ и ЕЯ — это не один язык, технология, мнение… Это куча всего. Что-то подходит к одному, что-то к другому, на чем то быстрее, на чем то медленнее. Я поделился опытом, а это уже повод другим не наступать на мои грабли в будущем.
                                    –1
                                    Можно дельный совет?
                                    +1
                                    Огромное спасибо за ссылку, я что-то подобное надеялся найти около 2 лет.
                                      0
                                      А можете ссылку на архив флибусты скинуть в личку? Попробую дома повторить на python + mongodb.

                                      Ещё не понял немного…

                                      > После чего осталось самое простое – собрать статистику. Собирал я ее 2 месяца, после чего надоело.

                                      Что именно вы делали два месяца?
                                        0
                                        ждал пока отработает скрипт (((
                                        0
                                        Еще бы топ слов построить, было бы интересно.
                                          0
                                          эт можно — могу сегодня запустить, думаю через пару дней будет статистика))) — дополню статью ей
                                          +2
                                          А теперь несколько замечаний по коду:

                                          1).
                                          import re,sys,socket,pprint,json,chardet,ConfigParser

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

                                          2).
                                          if(data == False or data == ''): print "error incoming data !!!"

                                          Скобки не нужны. А вот как можно и нужно (ну зачем условие то в одну строку?):
                                          if not data:
                                              print "error incoming data !!!"


                                          3).
                                          if(DEBUG == 1): print word

                                          Аналогично:
                                          if DEBUG:
                                              print word


                                          4).
                                          while 1:

                                          В Python принято:
                                          while True:


                                          Спасибо за статью, удачи в изучении языка!
                                          0
                                          Ну я PHP-пист ))) спасибо за замечания, учту. Разные языки — разная религия.
                                          а вот этот момент
                                          if(data == False or data == ''): print "error incoming data !!!"

                                          — это танцы с типами, в php достаточно:
                                          data == ''

                                          — в python же так не получилось
                                          Но конструкция
                                          if not data:
                                              print "error incoming data !!!"
                                          


                                          явно красивее смотрится, еще раз спасибо )

                                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                          Самое читаемое