Руководство

Использование

Подготовка

Чтобы использовать морфологический анализатор, нужно сначала создать объект класса pymorphy.Morph:

from pymorphy import get_morph
morph = get_morph('dicts/ru')

pymorphy.get_morph принимает аргументы path, backend и cached (а также любые аргументы конструктора класса pymorphy.Morph).

Примечание

Обратите внимание, все методы Morph ожидают, что строковые аргументы (в.т.ч. пустые или латинские, если используется pymorphy-speedups) - это unicode-строки. Кроме того, слова для обработки должны быть в верхнем регистре.

Получение информации о слове

>>> word = u'Вася'.upper()
>>> info = morph.get_graminfo(word)[0]
>>> print info['norm']
ВАСЯ
>>> print info['class']
С
>>> print info['info']
мр,имя,ед,им
>>> print info['method']
lemma(ВАС).suffix(Я)

Morph.get_graminfo() возвращает list всех возможных вариантов разбора слова. Каждый вариант разбора - dict, в котором есть нормальная форма, часть речи, грамматическая информация и служебные данные для отладки. См. также Обозначения для грамматической информации в pymorphy.

Получение нормальных форм

>>> morph.normalize(u'БУТЯВКАМ')
set(u'БУТЯВКА')

Morph.normalize() возвращает множество (set) всех возможных нормальных форм слова.

Склонение

>>> morph.inflect_ru(u'БУТЯВКА', u'дт,мн')
БУТЯВКАМ

Morph.inflect_ru() возвращает слово в форме, которая соответствует переданной и меньше всего отличается от исходной. В случае, если такую форму найти не удается, возвращается исходное слово. См. также Обозначения для грамматической информации в pymorphy.

Постановка во множественное число

Простое:

>>> morph.pluralize_ru(u'БУТЯВКЕ')
БУТЯВКАМ

Согласованное с цифрой:

>>> morph.pluralize_inflected_ru(u'ПОПУГАЙ', 1)
ПОПУГАЙ
>>> morph.pluralize_inflected_ru(u'ПОПУГАЙ', 2)
ПОПУГАЯ
>>> morph.pluralize_inflected_ru(u'ПОПУГАЙ', 38)
ПОПУГАЕВ

См. Morph.pluralize_ru(), Morph.pluralize_inflected_ru().

Интеграция с django

Для django на настоящий момент готово несколько шаблонных фильтров, которые позволяют произвольно склонять слова.

Настройка

  1. Описываем в settings.py установленные словари:

    PYMORPHY_DICTS = {
        'ru': { 'dir': '/usr/share/pymorphy/ru' },
    }
    

    более сложный пример:

    PYMORPHY_DICTS = {
        'ru': {
            'dir': '/usr/share/pymorphy/ru',
            'backend': 'tch',
            'use_cache': True,
        },
    
        'en': {
            'dir': '/usr/share/pymorphy/en',
            'backend': 'shelve',
            'use_cache': True,
            'default': True
        },
    }
    
    dir:обязательный параметр, путь до папки с файлами
    backend:используемое key-value хранилище (‘sqlite’ по умолчанию)
    use_cache:использовать ли кэш (True по умолчанию),
    default:является ли словарь словарем по умолчанию (который будет использоваться в template-tag’ах). Бесполезен, т.к. поддержки нескольких словарей в тегах все равно нет.
  2. Добавляем pymorphy в INSTALLED_APPS

  3. Подключаем в шаблоне библиотеку тегов:

    {% load pymorphy_tags %}

Шаблонные фильтры

Фильтры из pymorphy_tags стараются сохранить написание больших-маленьких букв (обрабатываются варианты “ВСЕ СЛОВО БОЛЬШИМИ”, “С заглавной”, “все маленькими”).

Если по какой-то причине смена формы не удалась, возвращают исходную строку.

Фильтры inflect и plural не склоняют все, что заключено в двойные квадратные скобки. Фильтр inflect_marked наоборот, работает только с тем, что в двойных квадратных скобках. Можно указать другие разделители (обязательно 2х-символьные), определив в settings.py переменные PYMORPHY_MARKER_OPEN и PYMORPHY_MARKER_CLOSE.

inflect

Меняет грамматическую форму каждого слова на указанную в параметрах. Про доступные параметры можно почитать тут: Обозначения для грамматической информации в pymorphy

Пример:

{% load pymorphy_tags %}

{# в переменной city "Нижний Новгород" #}
Мы начали работу в {{ city|inflect:"пр" }}!

{# выведет "Мы начали работу в Нижнем Новгороде!" #}

Пример с несклоняемой частью:

{% load pymorphy_tags %}

Не осталось у нас {{ "лошадь [[Пржевальского]]"|inflect:"рд,мн" }}.

{# выведет "Не осталось у нас лошадей Пржевальского" #}

inflect_marked

Идентичен фильтру inflect за исключением того, что противоположным образом трактует [[ ]]

{% load pymorphy_tags %}
Не осталось у нас {{ "[[лошадь]] Пржевальского"|inflect_marked:"рд,мн" }}.
{# выведет "Не осталось у нас лошадей Пржевальского" #}

plural

Ставит слово в форму, которая согласуется с заданным числом (1 попугай, 2 попугая, 5 попугаев).

Пример:

{% load pymorphy_tags %}

{# в переменной num число попугаев (пусть = 38) #}
На дереве {{ num }} {{ "попугай"|plural:num }}.
{# выведет "На дереве 38 попугаев." #}

{# в переменной animal - "лошадь" #}
А еще есть {{ num }} {{ animal|plural:num }}.
{# выведет "А еще есть 38 лошадей." #}

Выбор хранилища для словарей

pymorphy поддерживает разные форматы для хранения словарей. Формат по умолчанию - sqlite. Этот формат поддерживается везде, не требует настройки, но, одновременно, является самым медленным.

Более быстрые альтернативы - cdb, bsddb, tcb, tch - имеют свои плюсы и минусы, отличаются друг от друга способом установки, скоростью и потреблением памяти.

Самый быстрый вариант - это загрузка словарей целиком в память (через pickle backend). В этом случае нет задержек на чтение данных с диска и преобразование их в нужный формат (все читается сразу), но расходуется 200-300Мб оперативной памяти. В этот формат словари можно преобразовать с помощью скрипта encode_dicts.py (лежит в репозитории с исходным кодом).

Более подробно обо всем этом можно узнать тут: Поддерживаемые типы хранилищ.

Скорость

С pymorphy можно ожидать разбор нескольких сотен русских слов в секунду “из коробки”. После дополнительной настройки можно получить производительность в несколько тысяч слов в секунду.

Этой скорости достаточно для многих задач (например, для различных экспериментов и задач, связанных с web), но pymorphy в нынешнем виде, думаю, не подойдет, если нужно быстро обрабатывать очень большие объемы данных. В этом случае лучше использовать lemmatizer или mystem.

У pymorphy нет цели быть быстрым, приоритет отдается качеству разбора и легкости сопровождения. С учетом того, что это хобби-opensource-проект, код и алгоритмы должны быть максимально простыми и понятными, чтобы облегчить внесение изменений и доработку под конкретные задачи.

На данный момент pymorphy можно заставить работать быстрее несколькими способами:

  • перейти на более быстрое хранилище (sqlite → cdb → pickle);

  • отключить ненужные предсказатели;

  • установить simplejson (для упрощения установки pymorphy его не требует и использует по умолчанию встроенный медленный модуль):

    $ pip install simplejson
  • поставить пакет pymorphy-speedups, который содержит авто-подключаемое Cython-расширение:

    $ pip install pymorphy-speedups

Примечание

Для установки pymorphy-speedups и simplejson потребуются заголовочные файлы питона и среда с компилятором (как и для сборки любых других расширений).