lepeap / DeepMorphy

Морфологический анализатор для русского языка на C# для .NET
MIT License
48 stars 8 forks source link

Получение окончаний слова #7

Closed dem-in closed 3 years ago

dem-in commented 3 years ago

Здравствуйте. Есть ли возможность получить форму слова без окончания и все возможные окончания? Например, у слова "федеральный" получить форму: "федеральн" и возможные окончания слова: ый, ым, ом, ого, ому

lepeap commented 3 years ago

Здравствуйте! Добавил такую возможность в версии 2.0.2.

Работает следующий образом:

  1. получается лексема для слова;
  2. для перечисления нужных слов вызывается метод расширения GetLongestCommonPrefixWithEndings

Пример:

var morph = new MorphAnalyzer();
var lexeme = morph.Lexeme("федеральный", morph.TagHelper.CreateTag("прил", gndr: "муж", nmbr: "ед", @case: "им"));
// оставляем из лексемы только прилагательные
var prils = lexeme.Where(x => x.tag.Has("прил"));
// для получившегося списка получаем общее начало "федеральн" (stem) и окончания (endings)
var stem = prils.GetLongestCommonPrefixWithEndings(out string[] endings);

// если нужен только стем без окончаний, то можно использовать
var stem = prils.GetLongestCommonPrefix();
dem-in commented 3 years ago

Спасибо за полезные расширения. Но в данном случае мы получаем лексему, создавая её "руками", т.е. с помощью метода morph.TagHelper.CreateTag. А есть ли возможность получить окончания имея только слово и больше никакой информации о нем? Т.е. у меня есть слово "Федеральный" и больше я ничего о нем не знаю. Ни то, что оно прилагательное, ни другие характеристики.

lepeap commented 3 years ago

Можно вот так (только надо пробовать на 2.0.3, ранее выкидывало исключение в некоторых случаях):

var morph = new MorphAnalyzer();
var word = "федеральный";
var tag = morph.Parse(word).First().BestTag;
var lexeme = morph.Lexeme(word, tag);
var stem = lexeme.GetLongestCommonPrefixWithEndings(out string[] endings);

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

dem-in commented 3 years ago

В моем случае, при появлении лексем "человек - люди", я могу сделать фильтр по числу(ед/мн) и отсечь ненужные мне формы слова:

var stem = lexeme
                .Where(l => l.tag.GramsDic["число"] == tag.GramsDic["число"])
                .GetLongestCommonPrefixWithEndings(out string[] endings);

Спасибо за помощь!