Pull to refresh

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

Reading time6 min
Views4K
Я программист 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
Tags:
Hubs:
+41
Comments43

Articles

Change theme settings