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

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

Примечание

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

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

pymorphy.contrib.tokenizers.extract_tokens(text)

Разбивает текст на токены - слова, пробелы, знаки препинания и возвращает полученный массив строк.

pymorphy.contrib.tokenizers.extract_words(text)

Разбивает текст на слова. Пунктуация игнорируется. Слова, пишущиеся через дефис, считаются 1 словом. Пример использования:

from pymorphy.contrib import tokenizers

for word in tokenizers.extract_words(text):
    print word

Возвращает генератор, выдающий слова из текста (не list).

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

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

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

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

В pymorphy реализована вторая часть: склонять фамилии можно с помощью функций из модуля pymorphy.contrib.lastnames_ru, который реализует правила склонения фамилий, описанные на gramota.ru.

Предупреждение

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

Склонение фамилий использует алгоритм, похожий на алгоритм предсказания склонения слов, отсутствующих в словаре.

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

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

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

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

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

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

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

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

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

pymorphy.contrib.lastnames_ru.decline(lastname)

Склоняет фамилию и возвращает все возможные формы

pymorphy.contrib.lastnames_ru.normalize(morph, lastname, gender_tag)

Возвращает нормальную форму (именительный падеж) фамилии для заданного рода

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

Вернуть вариант фамилии который соотвествует данной грамматической форме

Параметры:

  • morph - объект Morph
  • lastname - фамилия которую хотим склонять
  • gram_form - желаемые характеристики грам. формы (если ‘жр’ отсутствует в этом параметре, то по-умолчанию принимается ‘мр’, или ‘мр-жр’, если указано ‘мн’)
pymorphy.contrib.lastnames_ru.get_graminfo(lastname)

Вернуть грамматическую информацию о фамилии и её нормальную форму

pymorphy.contrib.lastnames_ru.pluralize(morph, lastname, gram_form=u'')

Вернуть фамилию во множественном числе.

Параметры:

  • morph - объект Morph
  • lastname - фамилия которую хотим склонять
  • gram_form - желаемые характеристики грам. формы

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

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

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

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

pymorphy.contrib.lastnames_ru.pluralize_inflected(morph, lastname, gender_tag, num)

Вернуть фамилию в форме, которая будет сочетаться с переданным числом. Например: 1 Попугаев, 2 Попугаевых, 5 Попугаевых.

Параметры:

  • morph - объект Morph
  • lastname - фамилия которую хотим склонять
  • gender_tag - род фамилии (‘мр’ или ‘жр’)
  • num - число

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

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

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