Модуль морфологического анализа, проверки орфографии и лемматизации русского языка
Модель описания словоизменения
Физическое устройство словаря
Физическое устройство страницы словаря
Сканирование словаря
Особенности реализации
"Классический" программный интерфейс
Структуры данных и терминология
Проверка правописания
Лемматизация
Построение словоформы по ее идентификатору
Построение словоформы по ее грамматическому описанию
Итератор по идентификаторам лексем
Низкоуровневая подсказка
Извлечение информации о лексеме
CXX-интерфейс
Структуры данных и терминология
Доступ к интерфейсам
Проверка правописания
Лемматизация
Построение формы слова
Построение форм возможных лексем
Орфографическая подсказка
Интерфейс вероятностного морфологического анализатора
Структуры данных и терминология
Доступ к интерфейсам
Лемматизация
Построение формы слова
PHP-интерфейс
Библиотека расширения
Проверка правописания
Лемматизация
Построение словоформы по ее идентификатору
Модель описания словоизменения.
Для описания словоизменения слово, точнее, его нормальная форма,представленная в словнике, разбивается на 4 формальных фрагмента:- псевдооснова - неизменяемая графическая последовательность;
- псевдосуффикс;
- чередующаяся часть основы;
- окончание.
В случае, если в основе слова есть чередования, то определяется,какой фрагмент чередуется с каким (подбирается таблица чередований в основе), а от основы отщепляется фрагмент, соответствующий нормальной форме слова.
Псевдосуффиксы генерируются автоматически и используются лишь для уменьшения физического размера словаря, поэтому на них подробнее останавливаться не имеет смысла.
В перечисленных ниже примерах чередующийся фрагмент основы выделен жирным шрифтом, а окончание - косым:
- кош-к-а - кош-ек
- кноп-к-а - кноп-ок
- ос-ел - ос-л-а
- л-ед - л-ьд-а
- в-обр-ать - в-бер-у
При работе анализатора нужная ступень чередования выбирается по жестким формальным правилам, которые в этом документе не приводятся.
Физическое устройство словаря
Словарь разбит на страницы средним объемом 0xF000 байт. Такой размер обусловлен, с одной стороны, тем, что ссылки между таблицами в этом случае можно делать шестнадцатибитными, с другой строны - стремлением увеличить до минимума размер одной страницы словаря, что положительно сказывается на производительности программы в целом. Существует индекс по этим страницам, но на нем подробнее останавливаться смысла нет, так как и интересного там ничего нет.
Физическое устройство страницы словаря
Каждая страница словаря представляет собою дерево, в каждом узле которого, можно считать, находится таблица, ставящая в соответствие каждому символу смещение аналогичной таблицы следующего уровня.Пусть словарь содержит лишь слова "стол", "столешница", "стоять", "стоить", "стрелять", "судить" и "ты". Тогда, после отщепления всех изменчивых фрагментов, мы получим (в порядке следования) графические псевдоосновы "стол", "столешниц", "сто", "сто", "стрел", "су" и "т". Дерево, строящееся из них, можно представить следующим образом:

Сканирование словаря
При сканировании устроенного таким образом словаря фактически идет перебор элементов таблицы очередного уровня (0 - для первой буквы слова, 1 - для второй и т. д).Рассмотрим этот процесс на примере изображенного выше словаря. Пусть на обработку поступило слово "суд". Тогда, находясь в корне дерева, мы можем утверждать, что если такое слово в словаре есть, то оно находится на ветви, начинающейся от буквы "с".
Переходим на второй уровень. Теперь текущая буква слова - "у". Допустимые буквы после "с" в нашем словаре - "т" и "у". Если искомое слово в словаре есть, оно лежит на ветви дерева, на которую ссылается буква "у".
На третьем уровне таблица пуста, что означает, что возможно лишь отождествление по окончаниям. Понятно, что на таблице чередований "д/ж/ж" (судить - сужу - суженный) и таблице окончаний глагола "су-д-ить" слово "суд" отождествиться не может.
Особенности реализации
Морфологический анализатор реализован в виде динамической библиотеки с экспортируемыми функциями в стиле "C". Размер библиотеки со словарем - немногим более двух Mb. Двоичный словарь включен в виде данных, что позволяет операционным системам оптимальным образом подгружать и выгружать его страницы по мере надобности. Последнее (вкупе со способом организации словаря - см. выше) обеспечивает высокую производительность анализатора - более двадцати тысяч слов в секунду в режиме лемматизации с построением текстов нормальных форм слов и грамматических описаний отождествлений.Генерация словаря происходит полностью автоматически, процесс этот занимает не более трех минут.
Процесс отождествления последовательности символов идет слева направо - то есть сначала сканируется словарь основ, затем происходит отождествление остатка слова по отсортированным лексикографически таблицам окончаний, что позволяет обрывать сканирование, не проходя по всей таблице.
Основы в пределах страницы словаря разложены в таблицу переходов конечного автомата.
"Классический" программный интерфейс
Структуры данных и терминология
Морфологический анализатор использует метафору аддитивности грамматической информации о форме слова. Полное грамматическое описание формы слова занимает 16 бит и разбито на следующие области:- временнáя характеристика глагольной формы - 3 бита;
- лицо глагольной формы - 2 бита (1-е, 2-е и 3-е);
- признак и тип причастия - 2 бита (действительное, страдательное, деепричастие и "не причастие");
- признак сравнительной степени - 1 бит;
- признак краткой формы - 1 бит;
- род - 2 бита (нет, м., ж., с.);
- признак множественного числа - 1 бит;
- падеж - 3 бита (8 значений);
- признак возвратности - 1 бит.
Константы, позволяющие конструировать грамматические описания простым сложением, приведены в заголовочном файле mlma1049.h.
Для полного грамматического описания формы слова используется структура
Также в заголовочном файле mlma1049.h декларированы коды ошибок, возвращаемые функциями морфологического анализатора, и флаги его настройки.
Код ошибки | Значение | Толкование |
---|---|---|
LEMMBUFF_FAILED | -1 | Недостаточно места в массиве нормальных форм |
LIDSBUFF_FAILED | -2 | Недостаточно места в массиве лексем |
GRAMBUFF_FAILED | -3 | Недостаточно места для грамматических описаний |
WORDBUFF_FAILED | -4 | Слишком длинное слово или плохой указатель |
Флаг настройки | Значение | Толкование |
---|---|---|
sfStopAfterFirst | 0x0001 | Сканировать словарь до первого отождествления |
sfIgnoreCapitals | 0x0002 | Игнорировать неправильные схемы капитализации |
sfHardForms | 0x0004 | Разрешать затрудненные формы слов |
nfAdjVerbs | 0x0100 | Нормализовать причастия, как прилагательные |
Часть речи | Значение |
---|---|
1 | Глагол несовершенного вида |
2 | Непереходный глагол несовершенного вида |
3 | Глагол совершенного вида |
4 | Непереходный глагол совершенного вида |
5 | Двувидовой глагол |
6 | Непереходный двувидовой глагол |
7 | Неодуш. существительное мужского рода |
8 | Одуш. существительное мужского рода |
9 | Одуш.-неодуш. существительное мужского рода |
10 | Неодуш. существительное мужского рода, склоняющееся по схеме среднего |
11 | Одуш. существительное мужского рода, склоняющееся по схеме женского |
12 | Одуш. существительное мужского рода, склоняющееся по схеме среднего |
13 | Неодуш. существительное женского рода |
14 | Одуш. существительное женского рода |
15 | Одуш.-неодуш. существительное женского рода |
16 | Неодуш. существительное среднего рода |
17 | Одуш. существительное среднего рода |
18 | Одуш.-неодуш. существительное среднего рода |
19 | Неодуш. существительное общего рода |
20 | Одуш. существительное общего рода |
21 | Неодуш. существительное мужского/среднего рода |
22 | Одуш. существительное мужского/среднего рода |
23 | Неодуш. существительное женского/среднего рода |
24 | Неодуш. существительное множественного числа |
25 | Прилагательное |
26 | Прилагательное, образованное от географического названия |
27 | Притяжательное местоимение |
28 | Местоименное прилагательное |
29 | Местоимение множественного числа |
30 | Местоимение мужского рода |
31 | Местоимение женского рода |
32 | Местоимение среднего рода |
33 | Числительное |
34 | Числительное "два" |
35 | Собирательное числительное |
36 | Порядковое числительное |
37 | Имя собственное |
38 | Имя мужского рода |
39 | Имя женского рода |
40 | Отчество мужского рода |
41 | Отчество женского рода |
42 | Фамилия |
43 | Неизменяемое географическое название |
44 | Географическое название мужского рожа |
45 | Географическое название женского рода |
46 | Географическое название среднего рода |
47 | Географическое название множественного числа |
48 | Вводное слово |
49 | Междометье |
50 | Предикатив |
51 | Предлог |
52 | Союз |
53 | Частица |
54 | Наречие |
59 | Аббревиатура, пишущаяся прописными буквами |
60 | Аббревиатура, пишущаяся строчными буквами |
Проверка правописания
- 1, если слово опознано;
- 0, если слово не опознано;
- значение меньше нуля в случае ошибки (коды ошибок см. выше).
- lpWord - указатель на строку в кодировке 1251 Windows Cyrillic;
- options - настройки морфологического анализатора (см. выше).
Лемматизация
- количество лексем, с формами которых произошло отождествление;
- 0, если слово не опознано;
- значение меньше нуля в случае ошибки (коды ошибок см. выше).
- lpWord - указатель на строку в кодировке 1251 Windows Cyrillic;
- dwSets - настройки морфологического анализатора (см. выше);
- lpLemm - указатель на массив, в который анализатор помещает разделенные нулевым символом нормальные формы слов, с которыми произошло отождествление (если передано нулевое значение, нормальные формы не строятся);
- lpLids - указатель на массив, в который анализатор кладет идентификаторы лексем, соответствующие нормальным формам слов (если передано нулевое значение, идентификаторы лексем не выдаются);
- lpGram - указатель на массив, в который анализатор выдает грамматические описания (SGramInfo) тех форм, с которыми произошло отождествление (если передано нулевое значение, грамматические описания не строятся);
- ccLemm - размер массива lpLemm или 0, если lpLemm == NULL;
- cdwLid - размерность массива lpLids или 0, если lpLids == NULL;
- ccGram - размер массива lpGram или 0, если lpGram == NULL.
- Первым байтом лежит количество грамматических описаний отождествившихся форм для очередной лексемы.
- Следом за ним лежит указанное количество структур SGramInfo, каждая из которых описывает отождествление с конкретной грамматической формой. Всего же в lpGram восстанавливается столько блоков описанной структуры, с формами скольких лексем произошло отождествление.
Построение словоформы по ее идентификатору
- количество построенных форм (значение больше нуля);
- 0, если такого слова нет в словаре или у слова нет такой формы;
- значение меньше нуля в случае ошибки (коды ошибок см. выше).
- lpWord - указатель на строку в кодировке 1251 Windows Cyrillic (может быть 0, в этом случае обязательно должен быть задан идентификатор лексемы);
- dwLxID - идентификатор лексемы (если задана строка, то его можно не указывать, однако желательно указать, чтобы не были построены шумовые формы, возникающие при отождествлении переданной строки с формами нескольких лексем);
- dwSets - настройки морфологического анализатора (см. выше);
- idForm - идентификатор грамматической формы слова;
- lpDest - указатель на массив, в который анализатор помещает разделенные нулевым символом формы слова;
- ccDest - размер массива lpDest
Построение словоформы по ее грамматическому описанию
- количество построенных форм (значение больше нуля);
- 0, если такого слова нет в словаре или у слова нет такой формы;
- значение меньше нуля в случае ошибки (коды ошибок см. выше).
- lpWord - указатель на строку в кодировке 1251 Windows Cyrillic (может быть 0, в этом случае обязательно должен быть задан идентификатор лексемы);
- dwLxID - идентификатор лексемы (если задана строка, то его можно не указывать, однако желательно указать, чтобы не были построены шумовые формы, возникающие при отождествлении lpWord с формами нескольких лексем);
- dwSets - настройки морфологического анализатора (см. выше);
- grInfo - аддитивное грамматическое описание формы слова (см. выше);
- bFlags - флаги одушевленности/неодушевленности;
- lpDest - указатель на массив, в который анализатор помещает разделенные нулевым символом формы слова;
- ccDest - размер массива lpDest.
Итератор по идентификаторам лексем
- 1 в случае успешного завершения перебора;
- 0 в случае прерывания пользователем;
- значение меньше нуля в случае ошибки (коды ошибок см. выше).
- enumproc - указатель на функцию - callback, вызываемую для каждой лексемы;
- lpv - внешний параметр, передаваемый enumproc без изменений.
Низкоуровневая подсказка
|
- количество построенных символов в случае успешного завершения перебора;
- 0 в случае, если данному шаблону не соответствует ни одна словоформа;
- значение меньше нуля в случае ошибки (коды ошибок см. выше).
- lpWord - указатель на строку-шаблон в кодировке 1251 Windows Cyrillic;
- lpList - адрес массива размером не менее 35 символов, в который будут помещены символы-заместители.
Извлечение информации о лексеме
|
- положительное значение в случае успеха;
- 0 в случае, если такая лексема в словаре отсутствует;
- значение меньше нуля в случае ошибки (коды ошибок см. выше).
- dwLxId - идентификатор лексемы;
- lpInfo - указатель на байт, куда следует поместить описание лексемы.
CXX-интерфейс
В настоящее время в рамках развития модуля реализован также расширенный интерфейс доступа к модулю, более удобный в использовании и реализованный в духе стандарта COM. Он НЕ является истинным COM-интерфейсом, к нему нет и не может быть type library, однако доступ и обращения к нему выполняются практически так же.Реально доступны два интерфейса взаимодействия - multibyte, использующий кодировку 1251 Windows Cyrillic, и widechar, опирающийся на unicode.
Структуры данных и терминология
В дополнение к структуреSGramInfo
, описанной выше, используются
еще две структуры, похожих одна на другую:
В этих структурах:
nlexid
- идентификатор лексемы;plemma
- указатель на строку словарной формы слова или NULL, если построение словарных форм не требуется;pgrams
- указатель на массив грамматических описаний отождествлений с формами данной лексемы или NULL, если грамматические описания не требуются;ngrams
- количество грамматических описаний отождествлений для данной лексемы или 0, если грамматические описания не требуеются.
Для большей читаемости и наглядности здесь они приводятся так, как если бы они были декларированы явно в программном коде C++.
Доступ к интерфейсам
Для доступа к интерфейсам библиотека экспортирует два метода:Проверка правописания
- 1, если слово опознано;
- 0, если слово не опознано;
- значение меньше нуля в случае ошибки (коды ошибок см. выше).
pszstr
- указатель на строку, которую требуется проанализировать;cchstr
- длина строки в символах или (unsigned)-1, если строка заканчивается нулевым символом;dwsets
- настройки морфологического анализатора (см. выше).
Лемматизация
- количество лексем, с формами которых произошло отождествление;
- 0, если слово не опознано;
- значение меньше нуля в случае ошибки (коды ошибок см. выше).
pszstr
- указатель на строку, которую требуется проанализировать;cchstr
- длина строки в символах или (unsigned)-1, если строка заканчивается нулевым символом;plexid
- указатель на массив структурSLemmInfoA
илиSLemmInfoW
, в зависимости от используемого интерфейса, куда будут восстановлены описания отождествившихся лексем;clexid
- размерность этого массива;plemma
- указатель на массив, куда анализатор восстановит словарные формы слов, или NULL, если этого не требуется;clemma
- размерность этого массива;pgrams
- указатель на массив, куда анализатор восстановит грамматические описания (SGramInfo
) отождествившихся форм, или NULL, если этого не требуется;cgrams
- размерность этого массива;dwsets
- настройки морфологического анализатора (см. выше).
Построение формы слова
- количество построенных вариантов начертания формы слова;
- 0, если слово не опознано;
- значение меньше нуля в случае ошибки (коды ошибок см. выше).
output
- указатель на массив, куда анализатор восстановит построенные варианты формы слова;cchout
- размерность этого массива;nlexid
- идентификатор лексемы;idform
- идентификатор формы слова.
Построение форм возможных лексем
- количество построенных вариантов начертания формы слова;
- 0, если слово не опознано;
- значение меньше нуля в случае ошибки (коды ошибок см. выше).
output
- указатель на массив, куда анализатор восстановит построенные варианты формы слова;cchout
- размерность этого массива;pszstr
- указатель на строку ключевой словоформы;cchstr
- длина строки в символах или (unsigned)-1, если строка заканчивается нулевым символом;idform
- идентификатор формы слова.
Орфографическая подсказка
- количество построенных символов;
- значение меньше нуля в случае ошибки (коды ошибок см. выше).
output
- указатель на массив, куда анализатор восстановит построенный список символов;cchout
- размерность этого массива;pszstr
- указатель на строку шаблона;cchstr
- длина строки в символах или (unsigned)-1, если строка заканчивается нулевым символом.
Интерфейс вероятностного морфологического анализатора
Вероятностный морфологический анализатор предназначен для использования в связке со словарным анализатором, использует практически такой же программный интерфейс и оперирует теми же категориями, что и словарный анализатор. Отличие состоит лишь в том, что в структурах и параметрах используется длина графической основы слова и идентификатор грамматического класса вместо идентификатора лексемы. В остальном структуры данных интерфейса аналогичны описанным выше.Стандартная схема использования вероятностного анализатора - вызов его для тех слов, которые не были опознаны словарным морфологическим анализатором. Исходя из такой постановки задачи, при построении словарной базы экзотические модели словоизменения, свойственные древним словам языка и не использующиеся при образовании неологизмов, были исключены. Поэтому не следует ожидать корректных результатов анализа слов типа идти или быть.
Структуры данных и терминология
В этих структурах:
ccstem
- длина графической основы слова в символах;nclass
- идентификатор грамматического класса;plemma
- указатель на строку словарной формы слова или NULL, если построение словарных форм не требуется;pgrams
- указатель на массив грамматических описаний отождествлений с формами данной лексемы;ngrams
- количество грамматических описаний отождествлений для данной лексемы или 0, если грамматические описания не требуеются;frange
- вероятность соответствия данной модели словоизменения поданной форме слова.
Для большей читаемости и наглядности здесь они приводятся так, как если бы они были декларированы явно в программном коде C++.
Версия интерфейса для работы с unicode:
Доступ к интерфейсам
Для доступа к интерфейсам библиотека доступны два метода:Оба метода ожидают указатель на указатель на интерфейс в качестве параметра и возвращают либо 0, либо код ошибки в случае некорректного параметра. Никаких иных причин отказа в инициализации не предусмотрено, так как резервирование памяти или иные операции, которые могут быть неуспешными, при этом не производятся.
Лемматизация
- количество моделей словоизменения, допускающих образование такой формы слова;
- 0, если слово не опознано;
- значение меньше нуля в случае ошибки (коды ошибок см. выше).
pszstr
- указатель на строку, которую требуется проанализировать;cchstr
- длина строки в символах или (unsigned)-1, если строка заканчивается нулевым символом;plexid
- указатель на массив структурSStemInfoA
илиSStemInfoW
, в зависимости от используемого интерфейса, куда будут восстановлены описания отождествившихся лексем;clexid
- размерность этого массива;plemma
- указатель на массив, куда анализатор восстановит словарные формы слов, или NULL, если этого не требуется;clemma
- размерность этого массива;pgrams
- указатель на массив, куда анализатор восстановит грамматические описания (SGramInfo
) отождествившихся форм, или NULL, если этого не требуется;cgrams
- размерность этого массива;dwsets
- настройки морфологического анализатора (см. выше).
Построение формы слова
- количество построенных вариантов начертания формы слова;
- 0, если ни одной формы построить не удалось;
- значение меньше нуля в случае ошибки (коды ошибок см. выше).
output
- указатель на массив, куда анализатор восстановит построенные варианты формы слова;cchout
- размерность этого массива;lpstem
- указатель на строку основы слова;ccstem
- длина графической основы;nclass
- идентификатор грамматического класса;idform
- идентификатор формы слова.
PHP-интерфейс
Версия библиотеки, собранная в виде PHP-расширения, позволяет использовать морфологический анализатор русского языка непосредственно из PHP-скриптов.Библиотека расширения
Чтобы начать использование его в PHP-приложениях, следует либо упомянуть библиотеку в списке загружаемых расширений, либо явным образом указать на необходимость её загрузки в начале скрипта:Проверка правописания
boolean
Аргументы:
$string
- строка в кодировке 1251 Windows Cyrillic;$dwsets
- настройки морфологического анализатора.
Лемматизация
$string
- строка в кодировке 1251 Windows Cyrillic;$dwSets
- настройки морфологического анализатора.
Построение словоформы по ее идентификатору
$string
- строка в кодировке 1251 Windows Cyrillic;$lexeme
- идентификатор лексемы;$formid
- идентификатор грамматической формы слова.