Размер
Лемматизатор в грамматическом словаре
Play

Лемматизатор в грамматическом словаре

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

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

Где скачать библиотеку русского лемматизатора

Компоненты лемматизатора (динамическая библиотека и файл данных с моделью языка для MS Windows 32/64 бит и Linux 32/64 бит) и примеры его использования входят в состав SDK Грамматического Словаря. Исходные тексты библиотеки на C++ доступны в репозитории проекта. Для прототипирования NLP алгоритмов на Питоне есть библиотека rulemma, доступная на гитхабе.

Особенности реализации лемматизатора

Данный вариант лемматизатора имеет следующие особенности:

1. Аккуратная лемматизация русских слов - для всех словоформ, присутствующих в текущей версии словаря, лемматизация выполняется безошибочно. Если слово допускает неоднозначную лемматизацию (роем - рыть или рой), то лемматизатор может найти все альтернативные варианты начальной формы слова.

2. Минимальный объем потребляемой памяти, данные хранятся на диске в сжатом виде, после открытия базы она занимает в памяти около 1 Мб в экономном режиме (см. флаги sol_LoadLemmatizator).

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

4. Встроенная вероятностная модель морфологии, обучаемая на эталонном корпусе, с помощью которой при лемматизации учитывается контекст слова и уменьшаться количество ошибочных результатов (см. функцию sol_LemmatizePhrase[W,A,8]).

5. Возможна лемматизация даже тех слов, которые отсутствуют в основном лексиконе. Это возможно благодаря тому, что в состав базы данных лемматизатора входят автоматически выводимые правила. Эти правила хорошо справляются с продуктивными суффиксами слов, используемыми в русском языке для образования новых слов.

На каких платформах выполняется лемматизация

Динамическая библиотека лемматизации lemmatizator.dll ( lemmatizator.so ) собирается для 32х и 64х битных платформ Windows и Linux, а также Mac OS X.

Для платформы .NET в состав SDK включена обертка lemmatizator_fx.dll и пример использования на C#.

Лемматизатор не требует наличия других библиотек из состава SDK, так как содержит все необходимые алгоритмы, словарную базу и вероятностную модель морфологии в двух своих файлах.

Очень простой API и отсутствие какой-либо привязки к C++ позволяет легко создавать обертки для вызова лемматизатора из других языков программирования.

Вероятностная лемматизация с учетом контекста

В лемматизатор входит вероятностная модель морфологии - обучаемая по специально размеченному корпусу числовая база данных. При первом обращении к функции sol_LemmatizePhrase[W,A,8] движок подгружает эту модель в оперативную память и затем использует ее для выбора более вероятной леммы. Увеличение точности, привносимое этой моделью, полностью определяется процессом обучения и ограничениями самой модели. В лабораторных условиях вероятностная модель морфологии позволяет улучшить точность примерно до 98-99%.

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

Проиллюстрировать использование морфологической модели в лемматизаторе можно с помощью консольного отладчика Syntax. После его запуска введите директиву #lemmatize и затем предложение "мы ели суп, а вдоль аллеи стояли раскидистые ели". В этом предложении слово "ели" встречается два раза и представляет формы двух разных частей речи - глагола и существительного. Лемматизатор учтет эти факторы и выведет:

В результате первое вхождение слова приведено к инфинитиву "есть", второе - к форме именительного падежа единственного числа "ель".

Для использования вероятностной модели морфологии от прикладной программы не требуется никаких дополнительных действий, помимо вызова функции API sol_LemmatizePhrase[W,A,8]. Если модель морфологии отсутствует в базе данных, то данная функция будет работать фактически через вызов sol_GetLemmas[W,A,8] для каждого слова.

Ограничения вероятностной лемматизации определяются двумя основными факторами.

Во-первых, вероятностная модель не знает ничего о смысле слов, поэтому не всегда может заметить недопустимость применения похожего паттерна.

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

Отличие лемматизатора от функций морфологического разбора

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

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

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

Unicode, ASCII и UTF-8 варианты функций

Некоторые функции API лемматизатора реализованы в 3х вариантах для удобства использования на разных платформах и языках программирования:

суффикс W - юникод, широкие строки (wchar_t, WideChar)

суффикс A - однобайтовая кодировка ASCII текущей локали

суффикс 8 - многобайтовая кодировка utf-8

Программный интерфейс лемматизатора

Открытие базы данных

HLEM sol_LoadLemmatizatorW ( const wchar_t * Filepath , int Flags )

HLEM sol_LoadLemmatizatorA ( const char * Filepath , int Flags )

HLEM sol_LoadLemmatizator8 ( const char * Filepath , int Flags )

Открывается база лемматизатора, созданная при компиляции словаря с опцией -save_lemmatizer.

Filepath - путь к базе лемматизатора, обычно в рамках проекта это файл lemmatizator.db.

Flags - дополнительные параметры для управления работы лемматизатором. Значение LEME_DEFAULT открывает базу в самом экономном, но самом медленном режиме лемматизации. При указании флага LEME_FASTER движок будет работать немного быстрее, несколько увеличив потребление памяти. Наконец, флаг LEME_FASTEST многократно ускорит лемматизацию, но загрузит базу данных в оперативную память, увеличив свои накладные расходы.

При любом значении флагов таблицы вероятностной модели загружаются только при первом вызове функции sol_LemmatizePhrase.

Возвращаемое значение является дескриптором объекта лемматизатора. Дескриптор указывается почти во всех остальных функциях API.

Удаление лемматизатора

void sol_DeleteLemmatizator ( HLEM hEngine )

Закрывается база, подсоединенная предыдущим вызовом sol_LoadLemmatizator[W,A,8] . Освобождаенся память, занятая загруженными таблицами. Дескриптор hEngine становится невалидным и не должен более использоваться.

Лемматизация слова

int sol_GetLemmaW ( HLEM hEngine , const wchar_t * Word , wchar_t * Result , int BufSize )

int sol_GetLemmaA ( HLEM hEngine , const char * Word , char * Result , int BufSize )

int sol_GetLemma8 ( HLEM hEngine , const char * Word , char * Result , int BufSize )

Выполняется лемматизация слова Word , результат копируется в буфер Result длиной BufSize символов. Слово представляет из себя цепочку символов, заканчивающуюся нулём.

Число вариантов лемматизации, если 1 - значит найдена и возвращена в буфере единственная нормальная форма, если > 1, то в буфер помещается какая-то первая из списка. Ниже описаны функции, которые могут работать со всеми вариантами лемматизации.

Для оценки количества слов, которые приводятся к более чем одной нормальной форме, можно воспользоваться словарем, загруженным в MS SQL и запросом:

Он дает такую табличку для русского лексикона:

Таким образом, доля слов, которые имеют более одной нормальной формы, не превышает 1%, если не учитывать частотность употребления слов в тексте.

HLEMMAS sol_GetLemmasW ( HLEM hEngine , const wchar_t * Word )

HLEMMAS sol_GetLemmasA ( HLEM hEngine , const char * Word )

HLEMMAS sol_GetLemmas8 ( HLEM hEngine , const char * Word )

Выполняется лемматизация слова Word и все альтернативные варианты возвращаются в виде дескриптора списка. Для работы с этим списком далее описано несколько функций.

Лемматизация фразы с учетом контекста каждого слова

HLEMMAS sol_LemmatizePhraseW ( HLEM hEngine , const wchar_t * Sentence , int Flags , int WordSeparator )

HLEMMAS sol_LemmatizePhraseA ( HLEM hEngine , const char * Sentence , int Flags , int WordSeparator )

HLEMMAS sol_LemmatizePhrase8 ( HLEM hEngine , const char * Sentence , int Flags , int WordSeparator )

Выполняется лемматизация слов в предложении Sentence с учетом контекста каждого слова. Возвращается список выбранных лемм, по одному самому вероятному варианту для каждого слова.

Аргумент Flags в текущей версии должен всегда задаваться как 0.

Аргумент WordSeparator должен передавать код широкого символа (wchar_t), который использован для разделения слов в фразе. Обратите внимание, что задача токенизации, то есть разбивка на слова, должна быть предварительно выполнена прикладным кодом самостоятельно. Лемматизатор берет из входной строки все символы, ограниченные заданным символом WordSeparator или началом/концом строки, и рассматривает их как одно слово.

Работа со списком лемм

int sol_CountLemmas ( HLEMMAS hList )

Возвращает количество элементов в списке лемматизаций hList .

int sol_CountLemmas ( HLEMMAS hList )

Возвращает количество элементов в списке лемматизаций hList .

int sol_GetLemmaStringW ( HLEMMAS hList , int Index , wchar_t * Result , int Bufsize )

int sol_GetLemmaStringA ( HLEMMAS hList , int Index , char * Result , int Bufsize )

int sol_GetLemmaString8 ( HLEMMAS hList , int Index , char * Result , int Bufsize )

Копирование в предоставленный буфер Result размером BufSize строки с индексом Index из списка лемматизаций hList .

void sol_DeleteLemmas ( HLEMMAS hList )

Удаляется список нормальных форм, возвращенный sol_GetLemmasX .

Функции PHP лемматизации

function Lemmatize ( $ word )

Возвращает лемму для слова-аргумента, символы должны быть в кодировке cp1251.

function LemmatizePhrase ( $ str )

Возвращает лемматизированную строку - каждое слово из входной строки проходит нормализацию. Текст должен быть в кодировке cp1251.

Пример использования

В составе SDK Грамматического Словаря есть исходный код примера вызова вышеописанных процедур для C++ и C#, а также проекты для VisualStudio и make-файлы для сборки примеров.

Основной пример на C++ располагается в подкаталоге . \demo\ai\solarix\Grammar_Engine\Lemmatizator\C . Пример компилируется для всех поддерживаемых платформ - 32- и 64-битных Windows, Linux и Mac OS X. Он имеет двойное назначение.

Во-первых, он демонстрирует использование всех функций API лемматизатора.

Во-вторых, он проверяет корректность приведения слов к базовым формам по эталонным спискам. Сами эти списки экспортированы из SQL хранилища словаря с помощью несложных запросов, и содержат исчерпывающий перечень для двух случаев - когда слово приводится однозначно к единственной лемме, и когда слово является формой двух словарных статей. Например, список слов, которые лемматизируются двумя альтернативными путями, используется такой запрос для MS SQL:

Результаты выполнения запроса выгружаются прямо из SQL Server Management Studio в текстовый файл, в кодировке utf-8.

📎📎📎📎📎📎📎📎📎📎