pymorphy2
pymorphy2 copied to clipboard
Склонение фамилий
Если я точно знаю, что слово - фамилия в именительном падеже (например, Рыжиков), как мне это явно задать, чтобы фамилия склонялась правильно?
Обычно просто нужно выбрать правильное значение из списка значений -- то, что стоит в именительном падеже. Хуже, если такой фамилии там нет, как в данном случае -- тогда склонять её с помощью pymorphy не получится. Но фамилии достаточно регулярно склоняются, просто сделай свою карту склонений, если сильно нужно.
Правильную форму не находит, "ов" отбрасывает. Пишет: рыжик, котельник, слабик и т.п. В теге пишет Name plur. Как делается карта склонений?
"-ов", и.п. => м.р. , без окончания => р.п.: +а ("рыжикова") д.п.: +у ("рыжикову") в.п.: +а ("рыжикова") ... Впрочем, всё это уже забито в https://petrovich.nlpub.ru/ , попробуйте его.
Еще одно решение:
https://ws3.morpher.ru/russian/declension?format=json&s=Рыжиков
{
"Р": "Рыжикова",
"Д": "Рыжикову",
"В": "Рыжикова",
"Т": "Рыжиковым",
"П": "Рыжикове",
"ФИО": {
"Ф": "Рыжиков",
"И": "",
"О": ""
}
}
Спасибо! Лучше все же на питоне модуль, не веб-сервис. Помучаю Петровича.
Пожалуйста! Вот еще один питоновский модуль:
https://morpher.ru/python/
Кажется, такое нужно делать очень низкоуровнево, но всё же сделать можно.
import pymorphy2
m = pymorphy2.MorphAnalyzer()
Сначала нужно выяснить номер "правильной" парадигмы. Наверное, фамилию "Иванов" pymorphy2 знает и умеет склонять так, как надо.
>>> m.parse("Иванов")[0]
Parse(word='иванов', tag=OpencorporaTag('NOUN,anim,masc,Sgtm,Surn sing,nomn'), normal_form='иванов', score=0.962264, methods_stack=((DictionaryAnalyzer(), 'иванов', 37, 0),))
Здесь 37 - индекс парадигмы, а 0 - номер формы внутри парадигмы. Нам нужно число 37. Программно его можно достать так:
m.parse("Иванов")[0][4][0][2]
0 - самый вероятный разбор, 4 - methods_stack
, 0 - первый элемент стэка (то есть DictionaryAnalyzer
), 2 - элемент тюпла, в котором лежит индекс парадигмы.
Теперь воспользуемся этим номером парадигмы.
ru_dict = m._units[0][0].dict # словарь, инициализированный данными для русского языка
stem = "рыжиков"
paradigm = ru_dict .build_paradigm_info(37)
(в более общем случае stem = ru_dict.build_stem(ru_dict.paradigms[37], 0, "рыжиков")
или что-то такое)
И вот формы:
>>> for index, (_prefix, _tag, _suffix) in enumerate(paradigm):
... word = _prefix + stem + _suffix
... print(word, _tag)
...
рыжиков NOUN,anim,masc,Sgtm,Surn sing,nomn
рыжикова NOUN,anim,masc,Sgtm,Surn sing,gent
рыжикову NOUN,anim,masc,Sgtm,Surn sing,datv
рыжикова NOUN,anim,masc,Sgtm,Surn sing,accs
рыжиковым NOUN,anim,masc,Sgtm,Surn sing,ablt
рыжикове NOUN,anim,masc,Sgtm,Surn sing,loct
рыжикова NOUN,anim,femn,Sgtm,Surn sing,nomn
рыжиковой NOUN,anim,femn,Sgtm,Surn sing,gent
рыжиковой NOUN,anim,femn,Sgtm,Surn sing,datv
рыжикову NOUN,anim,femn,Sgtm,Surn sing,accs
рыжиковой NOUN,anim,femn,Sgtm,Surn sing,ablt
рыжиковой NOUN,anim,femn,Sgtm,Surn sing,loct
рыжиковы NOUN,anim,ms-f,Pltm,Surn plur,nomn
рыжиковых NOUN,anim,ms-f,Pltm,Surn plur,gent
рыжиковым NOUN,anim,ms-f,Pltm,Surn plur,datv
рыжиковых NOUN,anim,ms-f,Pltm,Surn plur,accs
рыжиковыми NOUN,anim,ms-f,Pltm,Surn plur,ablt
рыжиковых NOUN,anim,ms-f,Pltm,Surn plur,loct
Кажется, такое нужно делать очень низкоуровнево, но всё же сделать можно.
О, супер! Буду пробовать! Благодарю!