Как привести слова к одному виду?
Допустим есть 2 слова. собаку и кошка. Я хочу чтобы второе слово взяло теги первого. Чтобы на выходе получилось кошку.
Что попробовал
s1 = morph.parse(word1)[0] #собаку
s2 = morph.parse(word2)[0] #кошка
s3= s2.inflect({s1.tag.POS,s1.tag.case,s1.tag.number})
На выходе у нас кошку. С существительными работает. А вот если взять идти и шагал то тут всё рушится, так как у первого нет tag.case и tag.number.
Вопрос. Можно ли сделать что примерно такого
s3= s2.inflect({s1.tag})
Чтобы оно автоматом брало все теги из первого
Ответы (1 шт):
Свойство tag имеет класс OpencorporaTag, при передаче в метод inflect будет ругаться, что сравнение <= не поддерживается между объектами 'OpencorporaTag' и 'frozenset' (TypeError: '<=' not supported between instances of 'OpencorporaTag' and 'frozenset'). То есть нужно из объекта OpencorporaTag из вытащить набор граммем в виде множества (set или frozenset), для этого нужно обратиться к свойству grammemes:
import pymorphy2
morph = pymorphy2.MorphAnalyzer()
word1 = "собаку"
word2 = "кошка"
s1 = morph.parse(word1)[0]
s2 = morph.parse(word2)[0]
s3 = s2.inflect(s1.tag.grammemes)
print(s3.word) # Вывод: кошку
# ----
word1 = "идти"
word2 = "шагал"
s1 = morph.parse(word1)[0]
s2 = morph.parse(word2)[0]
s3 = s2.inflect(s1.tag.grammemes)
print(s3.word) # Вывод: шагать
Для слов с неоднозначностью может возникать ошибка. Например для слова "стали" без контекста не понятно, что это - существительное и глагол. Поэтому в идеале нужно учитывать не только первый разбор, а все разборы обоих слов.
Ниже пример, где учитываются все варианты разбора слова "стали":
import pymorphy2
morph = pymorphy2.MorphAnalyzer()
word1 = "стали"
word2 = "кошка"
s2 = morph.parse(word2)[0]
for s1 in morph.parse(word1):
gramemmes = set(s1.tag.grammemes)
if 'NOUN' in s2.tag:
# Для существительных убираем одушевленность и род, т.к. это не категории формы, а характеристика самого слова
# Например "кошка" всегда одушевленное, а "сталь" всегда неодушевленное,
# а слово "день" нельзя перевести в женский род при всем желании
gramemmes -= {'inan', 'anim', 'femn', 'masc', 'neut'}
s3 = s2.inflect(gramemmes)
if s3 is not None: # Если удалось просклонять, результат выводим
print(gramemmes)
print(s3.word)
Вывод:
{'sing', 'gent', 'NOUN'}
кошки
{'nomn', 'plur', 'NOUN'}
кошки
{'sing', 'datv', 'NOUN'}
кошке
{'sing', 'loct', 'NOUN'}
кошке
{'accs', 'plur', 'NOUN'}
кошек
В принципе результаты с одинаковой формой можно объединять (если их записывать в set), тогда получится три варианта: кошки, кошке, кошек