pymorphy2 и склонение городов.

1,484 views
Skip to first unread message

288...@gmail.com

unread,
Jun 10, 2014, 9:35:34 AM6/10/14
to pymo...@googlegroups.com
Здравствуйте.

Есть проблема со склонением городов.
Вот тестовый код:

#coding=utf-8

import pymorphy2

morph = pymorphy2.MorphAnalyzer()

city_atoms = [u'Москва',u'Волгоград',u'Нижний Новгород',u'Домодедово',u'Люберцы',u'деревня Квакино']
for city_atom in city_atoms:
    print  morph.parse(city_atom)[0].inflect({'loct'}).word

Вот что на выходе:

москве
волгограде
нижний новгороде
домодедове
люберцах
деревня квакином

Москву и Волгоград - просклонял нормально. Нижний Новгород просклонялся только вторым словом. Домодедово - вообще не должно вроде как склоняться, Люберцы - точно не знаю если честно как правильно будет, а деревня Квакино вообще кажется просклонялась как фамилия. 

По сему ест вопросы:
  • Как сие безобразие побороть, может какие словари по городам есть.
  • Как (если это возможно) заставить систему не менять регистр. А то одно дело Нижний Новгород а другое дело Ростов-На-Дону или "поселок Запупеево"

Mikhail Korobov

unread,
Jun 10, 2014, 4:04:47 PM6/10/14
to pymo...@googlegroups.com
Добрый вечер.

Ошибки все разные.

* Нижний Новгород - pymorphy2 работает с отдельными словами, а не с фразами. В простых случаях можно просклонять слова из словосочетания по-отдельности:

from pymorphy2.shapes import restore_capitalization

def inflect_all(morph, text, required_grammemes):
    tokens = text.split()
    inflected = [
        restore_capitalization(
            morph.parse(tok)[0].inflect(required_grammemes).word,
            tok
        )
        for tok in tokens
    ]
    return " ".join(inflected)

И потом (пишу без u'', т.к. Python3):

In [22]: inflect_all(morph, 'Нижний Новгород', {'loct'})
Out[22]: 'Нижнем Новгороде'

Для восстановления  строчных/Заглавных букв используется функция restore_capitalization. С Ростовами она тоже разобраться должна правильно.
Функция inflect_all - это не 100% хороший код - возможно, лучше брать не первый вариант разбора, а как-то более умно его выбирать; разбивать на токены и соединять все обратно можно и получше (вариант со split не будет обрабатывать пунктуацию). Ну и не всегда правильно склонять обе части.

* Домодедово - в словаре предложный падеж - "Домодедове". Правильны, насколько могу судить, оба варианта. В таких случаях лучше дополнять словарь. Тикеты можно заводить вот тут: https://github.com/OpenCorpora/opencorpora/issues ; про Домодедово завел: https://github.com/OpenCorpora/opencorpora/issues/35.

* Люберцы - просклонялись по словарю, вроде правильно.

* деревня Квакино - с строчными/заглавными буквами и словами в несколько токенов см. выше. Для Квакино pymorphy2 не предлагает вариант разбора "географическое название", считая, что квакино - это что-то вроде кино, и склоняется так же. В данном случае повезло, и ответ будет правильный.

Функция inflect_all должна все города из примера просклонять правильно, но ошибки где-то в других примерах все равно будут. Если что-то используется в продакшне, то лучше делать возможность поправить разбор руками. Например, по такому алгоритму:

1. Посмотреть, если ли слово в нужной форме в базе данных;
2. если есть, то вернуть его;
2. если нет, просклонять через pymorphy2, добавить в БД и вернуть результат.

При этом можно начать с пустой базы, а можно использовать какую-то готовую. Вот была ссылка: http://habrahabr.ru/post/37134/
Если у кого-то есть идеи, как задачу решать лучше, то welcome :)

В идеале - хорошо бы

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

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

вторник, 10 июня 2014 г., 19:35:34 UTC+6 пользователь 288...@gmail.com написал:

Serge Slepov

unread,
Jun 11, 2014, 8:11:27 AM6/11/14
to pymo...@googlegroups.com, 288...@gmail.com
Названия городов и стран хорошо склоняет веб-сервис "Морфер".  Вот пример его вызова из PHP: 


Для Python пример пока не написал.  Если поможете, буду благодарен.

Есть также функция образования прилагательных: Москва - московский, Нижний Новгород - нижегородский и т.п.: http://morpher.ru/adjectivizer

288...@gmail.com

unread,
Jun 11, 2014, 8:24:39 AM6/11/14
to pymo...@googlegroups.com
Спасибо за развернутый ответ.

среда, 11 июня 2014 г., 0:04:47 UTC+4 пользователь Mikhail Korobov написал:

anton....@gmail.com

unread,
Nov 12, 2014, 8:47:57 AM11/12/14
to pymo...@googlegroups.com
Спасибо за подскаску по оптимизации склонения городов. Но вот у меня есть еще довесок к этой задаче: хочется автоматизировать подстановку предлога перед названием года, чтобы коректно генерить фразы:
1. в Москве
2. в Волгограде
3. во Владимере
Reply all
Reply to author
Forward
0 new messages