Склонение словосочетаний

705 views
Skip to first unread message

Serge Slepov

unread,
Apr 19, 2014, 2:56:08 PM4/19/14
to pymo...@googlegroups.com
Сейчас прочитал в документации, что pymorphy может просклонять "тридцать восемь попугаев и Удав" одним вызовом inflect:"дт":


Что, правда?  Было бы круто.

Mikhail Korobov

unread,
Apr 19, 2014, 4:15:51 PM4/19/14
to pymo...@googlegroups.com
Привет! Это работало довольно коряво, т.к. каждое слово просто склонялось отдельно - никакого разбора не велось. Но для определенного класса словосочетаний это работало хорошо (однородные члены, существительное+прилагательное и т.п.).

Для pymorphy2 есть отдельный проект, который работает чуть умнее - см. https://github.com/summerisgone/pyphrasy. Насколько понял, там реализованы эвристики, которые работают для более широкого круга фраз (разбора по грамматике нет).

воскресенье, 20 апреля 2014 г., 0:56:08 UTC+6 пользователь Serge Slepov написал:

Mikhail Korobov

unread,
Apr 19, 2014, 4:21:57 PM4/19/14
to pymo...@googlegroups.com
1-в-1 аналог джанго-тега inflect из pymorphy, но работающий с pymorphy2, есть тут: https://github.com/Yuego/django-pymorphy2. Еще несколько проектов, связанных с pymorpy2, можно в вики посмотреть: https://github.com/kmike/pymorphy2/wiki

воскресенье, 20 апреля 2014 г., 2:15:51 UTC+6 пользователь Mikhail Korobov написал:

Serge Slepov

unread,
Apr 19, 2014, 6:36:26 PM4/19/14
to pymo...@googlegroups.com
Классно!  Спасибо за ссылки!  Особенно порадовал "аналог Томиты".  Это здорово.  Народ что-то пишет, причем открытое - это вдвойне здорово.  Так глядишь я тоже скоро питоноводом стану :)

pyphrasy тоже прикольная вещь, хотя склонять ФИО, похоже, задачей не ставилось. Подход с помощью "эвристик" (if-else-и-такой-то-матери) имеет свои ограничения, а именно когда их становится слишком много, менять что-то становится все проблематичнее. Я в этот потолок уже уперся и сейчас делаю версию своей библиотеки склонения словосочетаний с использованием грамматики. Как всегда, сначала не удержался и изобрел велосипед, написав свой Пролог и парсер на его основе. Вроде работает, компилирует сам себя и перевозит волка, овцу и капусту через реку, но пока очень "голый".  Не хватает некоторых фич, в частности предикатов второго порядка, да и инструментарий разработки пока бедноват, но уже есть графический отладчик.  Лиха беда начало!

Да, обидно, что столько народу работает в этом направлении, но каждый по сути сам за себя.  И я тому яркий пример.  Причин много. Отчасти это страх перед изучением нового языка программирования (ну, не люблю я слабо типизированные языки - все равно, что БД без ограничений), отчасти опять же страх "а как же это я отдам все свои наработки?".  Не многие у нас знают разницу между GPL и MIT.  Раз плохо лежит - значит, можно пользоваться. Отчасти - желание все самому досконально изучить и сделать "под себя".  Не знаю, стоит ли с этим бороться?

Спасибо, что дочитали :)

Думаю, что "аналог Томиты" я помучаю. Может, действительно так проще получится, чем свой изобретать. 

Yuri Baburov

unread,
Apr 20, 2014, 11:31:43 AM4/20/14
to pymo...@googlegroups.com
Привет,

Увы, определение синтаксиса фразы без учета вероятности тех или иных
слов и их сочетаний недостаточно качественно работает.
Такие подходы сейчас уже считаются каменным веком.

Первый попавшийся пример из головы:
он шёл с трудом vs он шёл с другом vs он шёл со шпалой

Разборы принципиально разные, хотя и выглядят похоже.

Томита-парсер, будучи LR-парсером, позволяет обходить это с помощью
трудоёмкого задания классов слов:
с+<болезнь/абстр> vs с+<одуш> vs c+<предмет>
1) Если нужный класс не определён, хороших результатов не будет,
например: "он шёл с воплями", а мы забыли определить, что слово
"вопли" принадлежит к классу абстракций, а не предметов.
Для разных сочетаний слов состав классов разный (например, допустимо
говорить "смотрел с болью", "сидел с болью" или "смирился с
трусостью", но недопустимо говорить "дружил с болью", "смотрел с
ангиной" или "видел с трусостью"), поэтому подобных классов слов
необходимо определить более миллиона (по моим оценкам, порядка 10-20
миллионов). Вручную это сделать практически невозможно.
2) В том случае, когда возможные классы пересекаются, Томита всё равно
не сможет выбрать правильный вариант разбора.
Например, "он шёл с тяжестью" или "а он что?".
Или, например, слово "и" может быть союзом или частицей и
присоединяться практически к любому слову слева: "ну ты и друг" —
неснимаемая на уровне синтаксиса неоднозначность.
В более сложных предложениях таких разветвлений гораздо больше, и на
первое место выходит задача поиска наилучшего разбора, а он задаётся
вероятностью. Например, "он шёл с костью на суп" — о чём речь: кость
идёт на суп, его добавят в суп, или его пригласили есть суп?
Аналогично, "он шёл к кинотеатру с Машей" — шёл к кинотеатру и Маше
или они с Машей шли к кинотеатру?
Ещё есть такая неоднозначность: первая буква предложения заглавная,
независимо от того, начинается ли слово с заглавной буквы. Наиболее
популярные такие слова в pymorphy: Того, Из, Иза.
Например, "Того не нашли" — Того-государство vs того-местоимение.
Многие подобные слова в базу pymorphy просто не добавлены, но при их
добавлении количество неоднозначностей существенно увеличится.
3) на каждое служебное слово: "ровно", "зачем", "рядом", "и", "но",
"так как", "всё же", итп., нужно писать свои собственные правила
разбора. Аналогично для тире, запятых, кавычек и других знаков
препинания. Например: Кинотеатр "Аврора". То, чего не может быть. "он
шёл рядом с поездом"

Я поэтому прошёл этап всяких Томита-парсеров, потом вручную написанных
вероятностых парсеров, сделал большой перерыв, и сейчас готовлюсь
серьёзно заняться deep learning для автоматического построения
подобной вероятностной базы правил разбора. И тебе того советую.
Вообще, я всегда в поиске единомышленников. Присоединяйся!
> --
> Вы получили это сообщение, поскольку подписаны на группу "pymorphy".
> Чтобы отменить подписку на эту группу и больше не получать от нее сообщения,
> отправьте письмо на электронный адрес pymorphy+u...@googlegroups.com.
> Чтобы настроить другие параметры, перейдите по ссылке
> https://groups.google.com/d/optout.



--
Best regards, Yuri V. Baburov, Skype: yuri.baburov

Serge Slepov

unread,
Apr 20, 2014, 12:17:42 PM4/20/14
to pymo...@googlegroups.com
Юрий, спасибо за то, что поделился опытом.  Я сейчас занимаюсь автоматическим склонением по падежам и в этой задаче семантика не так уж важна: с чем бы ты ни шел, оно склоняться все равно не будет, т.к. уже стоит в косвенном падеже (кошка с мышкой, кошке с мышкой, кошкой с мышкой...)  Поэтому Tomita-style-rule-based parser - это то, что мне сейчас нужно :)

А куда можно присоединиться?

Mikhail Korobov

unread,
Apr 20, 2014, 2:37:11 PM4/20/14
to pymo...@googlegroups.com

воскресенье, 20 апреля 2014 г., 4:36:26 UTC+6 пользователь Serge Slepov написал:
Классно!  Спасибо за ссылки!  Особенно порадовал "аналог Томиты".  Это здорово.  Народ что-то пишет, причем открытое - это вдвойне здорово.  Так глядишь я тоже скоро питоноводом стану :)

pyphrasy тоже прикольная вещь, хотя склонять ФИО, похоже, задачей не ставилось. Подход с помощью "эвристик" (if-else-и-такой-то-матери) имеет свои ограничения, а именно когда их становится слишком много, менять что-то становится все проблематичнее. Я в этот потолок уже уперся и сейчас делаю версию своей библиотеки склонения словосочетаний с использованием грамматики. Как всегда, сначала не удержался и изобрел велосипед, написав свой Пролог и парсер на его основе. Вроде работает, компилирует сам себя и перевозит волка, овцу и капусту через реку, но пока очень "голый".  Не хватает некоторых фич, в частности предикатов второго порядка, да и инструментарий разработки пока бедноват, но уже есть графический отладчик.  Лиха беда начало!

Да, обидно, что столько народу работает в этом направлении, но каждый по сути сам за себя.  И я тому яркий пример.  Причин много. Отчасти это страх перед изучением нового языка программирования (ну, не люблю я слабо типизированные языки - все равно, что БД без ограничений), отчасти опять же страх "а как же это я отдам все свои наработки?".  Не многие у нас знают разницу между GPL и MIT.  Раз плохо лежит - значит, можно пользоваться. Отчасти - желание все самому досконально изучить и сделать "под себя".  Не знаю, стоит ли с этим бороться?

Питон обычно считается сильно типизрованным языком, но с динамической типизацией. Это значит, что в большинстве случаев неявное преобразование типов выкинет исключение (в отличие, например, от JavaScript или PHP), но произойдет это во время работы программы, а не на этапе компиляции. Так что не так все плохо :) Ну а с пилением "под себя" - если  понимаешь, как работают аналоги, и знаешь, как сделать лучше, и проще заново написать, чем аналог ковырять, или просто хочется поразбираться - то почему бы и нет.
 

Mikhail Korobov

unread,
Apr 20, 2014, 3:17:21 PM4/20/14
to pymo...@googlegroups.com
Юра, привет. Я про Томиту - мне кажется, ее обычно для другого используют: предложения целиком ей не разбирают, и разобрать весь русский язык цели не ставят; это скорее удобный (ну как, с оговорками) инструмент для написания правил выделения фраз / кусков предложений, когда конечная цель - найти какую-то информацию, извлечь факты из текста в какой-то сильно ограниченной предметной области.

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

1) Делать полный синтаксический анализ предложений и писать какие-то алгоритмы, которые бы из деревьев вытаскивали информацию;
2) делать статистический теггер, работающий просто на цепочке слов без учета синтаксиса;
3) писать правила по типу томиты для выделения данных по шаблонам (сущности, связи между ними).

У (1) недостаток в том, что правильно разобрать предложение целиком сложно - там много ошибок и шума даже для английского; не все данные сформулированы в виде законченных предложений; большинство синтаксических анализаторов натренировано на газетных текстах, сильно отличающихся от текстов в задаче; работает это сравнительно медленно; могут быть проблемы с настройкой парсера под задачу, т.к. перетренировывать его - не вариант (собирать нужное количество данных времени нет), нужно поэтому какие-то хаки и эвристики делать, пост-процессинг деревьев и т.п. Ну и после того, как с синтаксисом разобрались, нужно еще правила над деревьями писать.

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

Вариант (3) - это, по сути, (1), но без необходимости разбирать предложение целиком (и, соответственно, без всех минусов этого); остаются только правила, вытаскивающие информацию из деревьев. Даже POS-тегов не надо, правила в духе BATTALION located at CITY. У меня в задаче язык был английский, да и лицензия яндексовской томиты мне не подходила; сделал на NLTK (правда, с разными хаками), вполне приемлемо работало, и по времени это не так много заняло (несколько дней).

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

воскресенье, 20 апреля 2014 г., 21:31:43 UTC+6 пользователь Yuri Baburov написал:
> отправьте письмо на электронный адрес pymorphy+unsubscribe@googlegroups.com.

Yuri Baburov

unread,
Apr 21, 2014, 12:16:01 AM4/21/14
to pymo...@googlegroups.com
Ну, что-то в этом есть, но от regexp-ов это отличается не сильно. В
общем-то, язык регулярных выражений позволяет делать подобный разбор.
Убираешь знаки препинания, и делаешь себе CITY = "…|…", BATTALION =
"…|…", RULE1 = BATTALION+" located at "+CITY и потом re.findall …
А согласования можно проверить после выделения. Да и
последовательность свёрток можно считать последовательным применением
регэкспов.
Такое программируется за полчаса. Правда, у Томиты всё готовое, бери и
пиши сразу правила. Но зато хрен настроишь грамматику на задачу, да и
язык страшненький.
Сам недавно делал подобное для поиска и ликвидации повторяющихся
абзацев в новостных статьях с точностью до дат, чисел, имён и тем.
Только новостных статей у меня 200 миллионов.
Недостатки те же в общем случае — цепляет мусор и пропускает
незапрограммированные варианты. Например, я пропустил в словаре Sept
как вариацию Sep (сентябрь)… Заметил только через неделю.
Если результаты позволяют ручную пост-обработку или верификацию по
словарям, то всё будет ок с любым наивным алгоритмом, а вот если
данных много и словари открытые…
Для небольших задач Tomita даёт некоторое удобство, да.
Переиспользуемость правил между задачами.
Но если правила разрастаются, то обычно получается кусок обычного
синтаксиса языка. Ну и плюс сам парсер нужно дописывать постоянно,
чтобы он умел согласования и прочую "грамматическую" часть языка.
В общем, Томита — это промежуточный вариант для бизнеса, чтобы не
программировать полную грамматику, а делать только её нужную часть.
В целом, идея разумная.

P.S. И кстати, Томита тоже достаточно медленная.
Её С-шная версия быстрее раз в 10-50, чем полная грамматика на питоне
(но полная грамматика учитывает сложные предложения, правда, там
скорость быстро падает по мере роста количества вариантов — но там
пока и отсечений нет).
>> > pymorphy+u...@googlegroups.com.
>> > Чтобы настроить другие параметры, перейдите по ссылке
>> > https://groups.google.com/d/optout.
>>
>>
>>
>> --
>> Best regards, Yuri V. Baburov, Skype: yuri.baburov
>
> --
> Вы получили это сообщение, поскольку подписаны на группу "pymorphy".
> Чтобы отменить подписку на эту группу и больше не получать от нее сообщения,
> отправьте письмо на электронный адрес pymorphy+u...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages