All Projects → lepeap → DeepMorphy

lepeap / DeepMorphy

Licence: MIT license
Морфологический анализатор для русского языка на C# для .NET

Programming Languages

C#
18002 projects
python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to DeepMorphy

nerus
Large silver standart Russian corpus with NER, morphology and syntax markup
Stars: ✭ 47 (+104.35%)
Mutual labels:  morphology, russian
aot
Russian morphology for Java
Stars: ✭ 41 (+78.26%)
Mutual labels:  morphology, russian
mlmorph
Malayalam Morphological Analyzer using Finite State Transducer
Stars: ✭ 40 (+73.91%)
Mutual labels:  morphology
modular-assemblies
[NeurIPS 2019] Code for the paper "Learning to Control Self-Assembling Morphologies: A Study of Generalization via Modularity"
Stars: ✭ 98 (+326.09%)
Mutual labels:  morphology
ds
👨‍🔬 In Russian: Обновляемая структурированная подборка бесплатных ресурсов по тематикам Data Science: курсы, книги, открытые данные, блоги и готовые решения.
Stars: ✭ 102 (+343.48%)
Mutual labels:  russian
yantra
JavaScript Engine for .NET Standard
Stars: ✭ 32 (+39.13%)
Mutual labels:  net-standard
Samples-NET.Core-MVC-CSharp
ASP.NET Core 2.0 MVC C# samples for Stimulsoft Reports.Web reporting tool.
Stars: ✭ 28 (+21.74%)
Mutual labels:  net
Plotty
C language compiler from scratch for a custom architecture, with virtual machine and all
Stars: ✭ 33 (+43.48%)
Mutual labels:  net
ngraphql
GraphQL .NET Server and Client
Stars: ✭ 26 (+13.04%)
Mutual labels:  net
jdk-source-code-reading
JDK source code reading
Stars: ✭ 19 (-17.39%)
Mutual labels:  net
live-documenter
.NET documentation generator and live reader. Generate documentation from .NET code and xml comments, fast, quick and easy.
Stars: ✭ 64 (+178.26%)
Mutual labels:  net
bem-flashcards
Simple single-page flashcards application based on the bem-core/bem-history and BEM methodology
Stars: ✭ 19 (-17.39%)
Mutual labels:  russian
WPFControls-ThemePack
Custom designed themes for WPF controls to make your app look better. Simple to modify.
Stars: ✭ 28 (+21.74%)
Mutual labels:  net
RivWidthCloudPaper
A Google Earth Engine based algorithm that extracts river centerlines and widths from satellite images
Stars: ✭ 62 (+169.57%)
Mutual labels:  morphology
InMemoryNET
Exploring in-memory execution of .NET
Stars: ✭ 55 (+139.13%)
Mutual labels:  net
cadru
A Microsoft .NET Framework toolkit
Stars: ✭ 58 (+152.17%)
Mutual labels:  net-standard
Basic-Image-Processing
Implementation of Basic Digital Image Processing Tasks in Python / OpenCV
Stars: ✭ 102 (+343.48%)
Mutual labels:  morphology
YaraSharp
C# wrapper around the Yara pattern matching library
Stars: ✭ 29 (+26.09%)
Mutual labels:  net
yc.boilerplate
YC. Boilerplate is a set of loose coupling, flexible combination, complete functions, convenient development, and reduces the workload of development.
Stars: ✭ 333 (+1347.83%)
Mutual labels:  net
RooCMS
RooCMS - This is easy and convenient content management system designed to quickly create websites.
Stars: ✭ 21 (-8.7%)
Mutual labels:  russian

DeepMorphy

Nuget

DeepMorphy is a neural network based morphological analyzer for Russian language.


DeepMorphy - морфологический анализатор для русского языка. Доступен как .Net Standart 2.0 библиотека. Умеет:

  1. проводить морфологический разбор слова (определяет часть речи, род, число, падеж, время, лицо, наклонение, залог);
  2. приводить слова к нормальной форме;
  3. менять форму слова в рамках лексемы.

Терминология

Терминология в DeepMorphy частично заимствована из морфологического анализатора pymorphy2.

Граммема (англ. grammeme) - значение одной из грамматических категорий слова (например прошедшее время, единственное число, мужской род).

Грамматическая категория (англ. grammatical category) - множество из взаимоисключающих друг друга граммем, характеризующих какой-то общий признак (например род, время, падеж и тп). Список всех поддерживаемых в DeepMorphy категорий и граммем тут.

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

Лемма (англ. lemma) - нормальная форма слова.

Лемматизация (англ. lemmatization) - приведение слова к нормальной форме.

Лексема - набор всех форм одного слова.

Принцип работы

Основным элементом DeepMorphy является нейронная сеть. Для большинства слов морфологический анализ и лемматизация выполняется сетью. Некоторые виды слов обрабатываются препроцессорами.

Препроцессоры

Имеется 3 препроцессора:

  • Словарь. Часть токенов просто смотрится в словаре. Используется для местоимений, предикативов, предлогов, союзов, частиц, междометий и числительных. Так же в словарь добавляются слова из датасета, в которых сеть после обучения все еще делает ошибки.
  • Препроцессор для наращенных числительных (например 1-й, 1917-й).
  • Препроцессор на регулярных выражениях для пунктуации, целых цифр, римских цифр и неизвестных токенов (если токен в основном состоит не из кириллицы).

Нейронная сеть

Сеть построена и обучена на фреймворке tensorflow. В качестве датасета выступает словарь Opencorpora. В .Net интегрирована через TensorFlowSharp.

Граф вычислений для разбора слов в DeepMorphy состоит из 11 "подсетей":

  • 8 двунаправленных рекурентных сетей, по одной для каждой поддерживаемой грамматической категории (определяет граммему в категории);
  • 1 двунаправленная рекурентная сеть для определения самых вероятных тегов. Для каждой комбинации граммем из датасета заведен 1 тег (всего 229 тегов), сеть обучается на определение к каким классам может принадлежать данное слово. На этапе работы берется 4 самых вероятных тега;
  • 1 seq2seq модель для лемматизации.

Задача изменения формы слов решается 1 seq2seq сетью.

Примерная схема сети для разбора слов

Обучение производится последовательно, сначала обучаются сети по категориям (порядок не имеет значения). Далее обучается главная классификация по тегам, лемматизация и сеть для изменения формы слов. Обучение проводилось на 3-х GPU Titan X. Метрики работы сети на тестовой датасете для последнего релиза можно посмотреть тут.

Руководство пользователя

DeepMorphy для .NET представляет собой библиотеку .Net Standart 2.0. В зависимостях только библиотека TensorflowSharp (через нее запускается нейронная сеть).

Установка

Библиотека опубликована в Nuget, поэтому проще всего устанавливать через него.

Если есть менеджер пакетов:

 Install-Package DeepMorphy

Если проект поддерживает PackageReference:

 <PackageReference Include="DeepMorphy"/> 

Если кто-то хочет собрать из исходников, то C# исходники лежат тут. Для разработки используется Rider (без проблем все должно собраться и в студии).

Начало использования

Все действия осуществляются через объект класса MorphAnalyzer:

var morph = new MorphAnalyzer();

В идеале, лучше использовать его как синглтон, при создании объекта какое-то время уходит на загрузку словарей и сети. Потокобезопасен. При создании в конструктор можно передать следующие параметры:

  • withLemmatization - возвращать ли леммы при разборе слов (по умолчанию - false). Если нужна лемматизация при разборе, то необходимо выставить в true, иначе лучше не включать (без флага работает быстрее).
  • useEnGrams - использовать английские названия граммем и грамматических категорий (по умолчанию - false).
  • withTrimAndLower - производить ли обрезку пробелов и приведение слов к нижнему регистру (по умолчанию - true).
  • maxBatchSize - максимальный батч, который скармливается нейронной сети (по умолчанию - 4096). Если есть уверенность, что оперативной памяти хватит, то можно увеличивать (увеличит скорость обработки для большого количества слов). Примеры использования тут.

Морфологический разбор

Для разбора используется метод Parse (на вход принимает IEnumerable со словами для анализа, возвращает IEnumerable с результатом анализа).

var results = morph.Parse(new string[]
{
    "королёвские",
    "тысячу",
    "миллионных",
    "красотка",
    "1-ый"
}).ToArray();
var morphInfo = results[0];

Список поддерживаемых грамматических категорий, граммем и их ключей тут. Если необходимо узнать самую вероятную комбинацию граммем (тег), то нужно использовать свойство BestTag объекта MorphInfo.

// выводим лучшую комбинацию граммем для слова
Console.WriteLine(morphInfo.BestTag);

По самому слову не всегда возможно однозначно установить значения его грамматических категорий (см. омонимы), поэтому DeepMorphy позволяет посмотреть топ тегов для данного слова (свойство Tags).

// выводим все теги для слова + их вероятность
foreach (var tag in morphInfo.Tags)
    Console.WriteLine($"{tag} : {tag.Power}");

Есть ли комбинация граммем в каком-нибудь из тегов:

// есть ли в каком-нибудь из тегов прилагательные единственного числа
morphInfo.HasCombination("прил", "ед");

Есть ли комбинация граммем в самом вероятном теге:

// ясляется ли лучший тег прилагательным единственного числа
morphInfo.BestTag.Has("прил", "ед");

Получение определенных из лучшего тега грамматических категорий:

// выводит часть речи лучшего тега и число
Console.WriteLine(morphInfo.BestTag["чр"]);
Console.WriteLine(morphInfo.BestTag["число"]);

Теги применяются для случаев, если нужна информация сразу о нескольких грамматических категориях (например часть речи и число). Если вас интересует только одна категория, то можно использовать интерфейс к вероятностям значений грамматических категорий объектов MorphInfo.

// выводит самую вероятную часть речи
Console.WriteLine(morphInfo["чр"].BestGramKey);

Так же можно получить распределение вероятностей по грамматической категории:

// выводит распределение вероятностей для падежа
foreach (var gram in morphInfo["падеж"].Grams)
{
    Console.WriteLine($"{gram.Key}:{gram.Power}");
}

Лемматизация

Если вместе с морфологическим анализом нужно получать леммы слов, то анализатор надо создавать следующим образом:

var morph = new MorphAnalyzer(withLemmatization: true);

Леммы можно получить из тегов слова:

Console.WriteLine(morphInfo.BestTag.Lemma);

Проверка, есть ли у данного слова лемма:

morphInfo.HasLemma("королевский");

Метод CanBeSameLexeme может быть использован для нахождения слов одной лексемы:

// выводим все слова, которые могут быть формой слова королевский
var words = new string[]
{
    "королевский",
    "королевские",
    "корабли",
    "пересказывают",
    "королевского"
};

var results = morph.Parse(words).ToArray();
var mainWord = results[0];
foreach (var morphInfo in results)
{
    if (mainWord.CanBeSameLexeme(morphInfo))    
        Console.WriteLine(morphInfo.Text);
}

Если необходима только лемматизация без морфологического разбора, то нужно использовать метод Lemmatize:

var tasks = new []
{
    new LemTask("синяя", morph.TagHelper.CreateTag("прил", gndr: "жен", nmbr: "ед", @case: "им")),
    new LemTask("гуляя", morph.TagHelper.CreateTag("деепр", tens: "наст"))
};

var lemmas = morph.Lemmatize(tasks).ToArray();
foreach (var lemma in lemmas)
    Console.WriteLine(lemma);

Изменение формы слова

DeepMorphy умеет изменять форму слова в рамках лексемы, список поддерживаемых словоизменений тут. Словарные слова возможно изменять только в рамках тех форм, которые доступны в словаре. Для изменения формы слов используется метод Inflect, на вход принимает перечисление объектов InflectTask (содержит исходное слово, тег исходного слова и тег, в который слово нужно поставить). На выходе перечисление с требуемыми формами (если форму не удалось обработать, то null).

var tasks = new[]
{
    new InflectTask("синяя", 
        morph.TagHelper.CreateTag("прил", gndr: "жен", nmbr: "ед", @case: "им"),
        morph.TagHelper.CreateTag("прил", gndr: "муж", nmbr: "ед", @case: "им")),
    new InflectTask("гулять", 
        morph.TagHelper.CreateTag("инф_гл"),  
        morph.TagHelper.CreateTag("деепр", tens: "наст"))
};

var results = morph.Inflect(tasks);
foreach (var result in results)
    Console.WriteLine(result);

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

var word = "лемматизировать";
var tag = m.TagHelper.CreateTag("инф_гл");
var results = m.Lexeme(word, tag).ToArray();

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

var tasks = new[]
{
    new InflectTask("победить", 
        m.TagHelper.CreateTag("инф_гл"),  
        m.TagHelper.CreateTag("гл", nmbr: "ед", tens: "буд", pers: "", mood: "изъяв"))
};
Console.WriteLine(m.Inflect(tasks).First());

Cтруктура репозитория

Планы по возмодным доработкам

  • Обновление версии tensorflow.
  • Подумать над использованием трансформеров.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].