Дополнительные возможности
==========================

Разбиение текста на слова и токены
----------------------------------

.. note::

    В библиотеке `nltk <nltk.org>`_ реализовано большое число классов
    для разбора текста на токены (см. `nltk.tokenize`_), которыми можно
    пользоваться, если функции из pymorphy чем-то не подходят.

    Установка nltk не всегда тривиальная, а в написанном по-быстрому
    регэкспе можно легко не учесть какие-то детали, поэтому в pymorphy
    все-таки появился :mod:`pymorphy.contrib.tokenizers`.


.. automodule:: pymorphy.contrib.tokenizers

    .. autofunction:: extract_tokens

    .. autofunction:: extract_words

.. _nltk.tokenize: http://nltk.googlecode.com/svn/trunk/doc/api/nltk.tokenize-module.html


.. _names-inflection:

Склонение имен и фамилий
------------------------

.. py:currentmodule:: pymorphy.contrib.lastnames_ru

Склонение фамилий
^^^^^^^^^^^^^^^^^

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

* знать, что слово - фамилия;
* уметь склонять фамилии по специальным правилам.

В pymorphy реализована вторая часть: склонять фамилии можно с помощью функций
из модуля :mod:`pymorphy.contrib.lastnames_ru`, который реализует правила
склонения фамилий, описанные на
`gramota.ru <http://www.gramota.ru/spravka/letters/?rub=rubric_482>`_.

.. warning::

    Работа с фамилиями в pymorphy сейчас экспериментальная, и не все методы
    обычного анализатора доступны (в частности, не завершена работа над
    постановкой фамилий во множественную форму), API может поменяться в
    последующих релизах.

Склонение фамилий использует алгоритм, похожий на
:ref:`алгоритм <prediction-algo>` предсказания склонения слов,
отсутствующих в словаре.

Угадывание леммы и суффикса
"""""""""""""""""""""""""""

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

Например, слово "Петровичу" будет разделено на составляющие "петров", "-ич-" и
"у". Где "петров" - лемма, "-ич-" - суффикс фамилии, а "у" будет
проигнорировано. Согласно правилам склонения фамилий с суффиксом -ич-,
слово "петров[-ич-]" будет склонено в шести падежах как "петрович",
"петровича", "петровичу"... для мужского рода, и "петрович", "петрович",
"петрович"... для женского.

Нормализация фамилий
""""""""""""""""""""

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

Если из входного слова могут быть выделены лемма и суффикс, но в то же время
оно не является вариантом склонения этой фамилии, то это расценивается как
ложное срабатывание. Пример: слово "кроссовый" хоть и подходит под шаблон
фамилии "кросс[-ов-]", но, по правилам склонения фамилий, не может быть её
производным.

Если :func:`decline` не нашла характерных признаков фамилии, входное слово
будет склонено как обычное (не фамилия) соответствующего рода в именительном
падеже. Например, в случае нормализации слова "кроссового", вызов
``lastnames_ru.normalize(morph, u'КРОССОВОГО', u'мр')`` будет аналогичен
вызову ``morph.inflect_ru(u'КРОССОВОГО', u'им,ед,мр')``.

Известные ограничения
"""""""""""""""""""""

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

.. automodule:: pymorphy.contrib.lastnames_ru

    .. autofunction:: decline

    .. autofunction:: normalize

    >>> from pymorphy.contrib import lastnames_ru
    >>> print lastnames_ru.normalize(morph, u'СУВОРОВУ', u'мр')
    СУВОРОВ
    >>> print lastnames_ru.normalize(morph, u'СУВОРОВУ', u'жр')
    СУВОРОВА

    .. autofunction:: inflect

    .. autofunction:: get_graminfo

    .. autofunction:: pluralize

Если в gram_form явно указать род - это будет использовано как подсказка.

     >>> print lastnames_ru.pluralize(morph, u'СУВОРОВУ', u'')
     СУВОРОВЫМ
     >>> print lastnames_ru.pluralize(morph, u'СУВОРОВУ', u'жр')
     СУВОРОВЫХ
     >>> print lastnames_ru.pluralize(morph, u'СУВОРОВУ', u'жр,дт')
     СУВОРОВЫМ

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

Указания на число ('ед' и 'мн') игнорируются.

    .. autofunction:: pluralize_inflected


Склонение имен людей
^^^^^^^^^^^^^^^^^^^^

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

    >>> print morph.inflect_ru(u'КАТЯ', u'дт')  # катя бочку
    КАТЯ
    >>> print morph.inflect_ru(u'КАТЯ', u'дт', u'С') # теперь правильно
    КАТЕ


