Морфологический разбор предложения и снятие омонимии (part-of-speech tagging)

Для определения грамматических признаков слов, составляющих предложение, API словаря предоставляет функцию:

C/C++:

HGREN_RESPACK sol_MorphologyAnalysis( HGREN hEngine, const wchar_t * Sentence, int Flags, int UnusedFlags, int Constraints, int LanguageID )

HGREN_RESPACK sol_MorphologyAnalysis8( HGREN hEngine, const char * SentenceUtf8, int Flags, int UnusedFlags, int Constraints, int LanguageID )

HGREN_RESPACK sol_MorphologyAnalysisA( HGREN hEngine, const char * Sentence, int Flags, int UnusedFlags, int Constraints, int LanguageID )

C#:

IntPtr sol_MorphologyAnalysis( IntPtr hEngine, string Sentence, int Flags, int UnusedFlags, int Constraints, int LanguageID )

Delphi:

function sol_MorphologyAnalysis( hEngine: PInteger; Sentence: PWideChar; Flags: Integer; UnusedFlags: Integer; Constraints: Integer; LanguageID: Integer ): PInteger;

Аргументы:

hEngine - дескриптор экземпляра грамматического словаря.

Sentence - указатель на строку из широких символов, из которой будет извлечен список лексем. Для функций с суффиксом 8 и A строка должна быть в кодировке utf-8 или текущей системной однобайтовой соответственно. Обратите внимание, что данная функция предназначена для работы с одним предложением за вызов.

Flags - флаги, управляющие работой морфоанализатора. Может иметь значение 0 для базового алгоритма анализа или быть побитовым объединением следующих значений:

SOL_GREN_ALLOW_FUZZY

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

SOL_GREN_COMPLETE_ONLY

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

SOL_GREN_MODEL

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

SOL_GREN_MODEL_ONLY

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

SOL_GREN_PRETOKENIZED

вместо использования внутреннего токенизатора использовать символ с кодом 0x1F как указатель границ слов. Это позволяет разбить предложений по своим правилам, если имеющиеся в словаре не устраивают.

SOL_GREN_TOKENIZE_ONLY

выполняется только токенизация; этот флаг предназначен для автоматизированного тестирования движка.

SOL_GREN_DISABLE_FILTERS

отключить правила, снимающие омонимию; в основном этот флаг предназначен для тестирования парсера по эталонному корпусу, а также для утилиты генерации правил снятия омонимии.

SOL_GREN_ENABLE_RECONSTRUCTION

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

Constraints - параметры для управления потребляемыми при разборе текста ресурсами. Значение 0 отключает все ограничения. Старшие 10 битов этого 32-битового аргумента задают максимальное значение одновременно проверяемых альтернативных путей разбора в нисходящем анализаторе. Младшие 22 бита задают максимальное время в миллисекундах, отведенное на выполнение анализа.

LanguageID - ID языка, правила которого нужно применять для токенизации, либо -1 для автоматического определения языка. По возможности следует указывать конкретный язык, тогда анализатор не будет тратить время на дополнительный анализ текста и избежит проблемы с ошибочным определением языка для предложений с латиницей и диакритическими значками.

Возвращает:

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

Примечания

Функция выполняет несколько этапов обработки исходного предложения. Прежде всего, выполняется разбивка на отдельные слова с учетом правил и исключений для выбранного языка, то есть токенизация. Затем происходит объединение устойчивых сочетаний слов, представляющих обособленные лексические единицы, то есть chunking. Затем для каждого слова определяется его часть речи и грамматические признаки, в том числе падеж, род, число, время, степень и так далее. Этот этап обычно называется part-of-speech tagging. В случае неоднозначного определения этих признаков у слова анализатор примеряет правила, учитывающие контекст, то есть соседние слова и законы согласования в языке. Таким образом, выполняется disambiguation. Если неоднозначность таким способом не удается устранить, например из-за свободного порядка слов в русском языке, то используются разнообразные эвристики. Например, часто существительное-подлежащее в именительном падеже идет перед сказуемым-глаголом, а прямое дополнение в винительном падеже - после.

Пример реализации part-of-speech tagging

В составе SDK грамматического словаря есть исходный текст утилиты POSTagger.

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

Благодаря ограниченности задаваемых настроек, исходный код программы достаточно прост и может использоваться для ознакомления с порядком использования функции sol_MorphologyAnalysis и некоторых других функций.

Программный доступ к результатам разбора

Для работы с результатами морфоанализа следует использовать функции sol_CountGrafs, sol_CountRoots, sol_GetRoot, sol_GetNodeIEntry, sol_GetNodeVerIEntry, sol_GetNodePosition, sol_GetNodeContents, sol_GetNodeCoordState, sol_GetNodeVersionCount, sol_GetNodeCoordPair, sol_GetNodeVerCoordPair, sol_GetNodePairsCount, sol_GetNodeVerPairsCount, sol_GetNodePairCoord, sol_GetNodeVerPairCoord, sol_GetNodePairState, sol_GetNodeVerPairState.

Если нужно определить связи слов в предложении, то следует использовать функцию sol_SyntaxAnalysis.

Что происходит внутри функции

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

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

… потому что …

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

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

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

Учет контекста просиходит на следующих стадиях анализа.

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

После этого этапа остается в среднем 6-9% слов с неоднозначным распознаванием. Эта неоднозначность может доставлять некоторое неудобство при работе с текстом, так как в число омонимов попадают такие частотные формы, как были, надо и так далее.

Чтобы еще сильнее уменьшить энтропию распознанного текста, движок применяет последовательно еще два приема.

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

Во-вторых, снять неоднозначность распознавания может синтаксический анализатор и входящий в него семантический процессор. Синтаксический анализ умеет учитывать “далекий” контекст, вплоть до слов, находящихся на разных концах предложения. Поэтому этот алгоритм характиризуется очень большой аккуратностью. Его основной недостаток - резко растущее время выполнения при удлинении предложения. В лучшем случае получается O(n3). Кроме того, набор синтаксических правил описывает только некоторое подмножество языковых конструкций. В случае отклонения структуры анализируемого предложения от распознаваемого правилами подмножества анализатор обычно не способен снять избыточность распознавания.

Что получается на выходе sol_MorphologyAnalysis?

В идеальном случае, пользователь получит одну цепочку токенов, в каждом будет по одному варианту распознавания грамматических атрибутов слова. В начале и конце этой цепочки будут два специальных токена, обозначающих границы предложения. Для данного идеального случая вызов sol_CountGrafs вернет 1, а каждый токен, получаемый вызовом sol_GetRoot, при вызове функции sol_GetNodeVersionCount тоже вернет 1.

В более сложных случаях прикладному коду придется разбираться с последствиями неоднозначностей.

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

А если некоторые слова даже после применения правил и модели остаются неоднозначно распознанными, то sol_GetNodeVersionCount для них вернет число больше 1.

Примеры выполнения морфологического анализа из прикладного кода

В составе SDK в каталоге ...\demo\ai\solarix\argon\POSTagger\ находится исходный код утилиты POSTagger, которая может служить достаточно полным и простым способом ознакомления с этой частью грамматического движка.

C++:

int Flags = SOL_GREN_ALLOW_FUZZY;

HGREN_RESPACK hs = sol_MorphologyAnalysisW( hEngine, L"Девчонки и мальчишки валяли дурака весь день", Flags, 0, 300000, id_language );

const int nroot = sol_CountRoots(hs,0);

for( int i=1; i<nroot-1; ++i )
 {
  HGREN_TREENODE hNode = sol_GetRoot( hs, 0, i );
  // ...
 }

sol_DeleteResPack(hs);

C#:

int Flags=0;
Flags |= GrammarEngine.SOL_GREN_ALLOW_FUZZY;
Flags |= GrammarEngine.SOL_GREN_ENABLE_RECONSTRUCTION;

IntPtr hPack1 = GrammarEngine.sol_MorphologyAnalysis( hEngine, "Девчонки и мальчишки валяли дурака весь день", Flags, 0, 60000, GrammarEngineAPI.RUSSIAN_LANGUAGE );

int nroot1 = GrammarEngine.sol_CountRoots( hPack1, 0 );

for( int i = 1; i < nroot1 - 1; ++i )
 {
  IntPtr hRoot0 = GrammarEngine.sol_GetRoot( hPack1, 0, i );
  // ...
 }

GrammarEngine.sol_DeleteResPack( hPack1 );

Навигация по API грамматического словаря

Приобретение SDK грамматического словаря

API layer C++ source code: grammar_engine_api.cpp

Вернуться к списку функций API

  © Elijah Koziev 2010
прикладные проекты на основе грамматического словаря API грамматической машины компоненты для доступа к грамматическому словарю условия получения SDK токенизатор и сегментатор морфологический анализ и синтез лемматизатор база N-грамм синтаксический анализатор словоформы морфология и синтаксис русского языка падеж число род совершенный и несовершенный вид экспорт в SQL формат экспорт в XML формат скрипт SQL словаря структура SQL словаря структура XML словаря компоненты для доступа к грамматическому словарю ORM Persistent Dictionary Library лемматизация стемминг примеры использования грамматического словаря склонение существительных в русском языке склонение русских прилагательных спряжение глаголов в русском языке поиск текста с учетом морфологии OCR подсистема расширенные регулярные выражения генератор текста генератор случайного текста и имитатор рандомизатор синонимизатор перефразировщик Статистика буквенных паттернов

Грамматический словарь русского языка



Грамматический словарь
склонение и спряжение глаголов, существительных, прилагательных

В состав входит русский и английский словарь.

платформа:  Windows 2000 ... Windows 7
требования: 512 Mb свободной памяти, 300 Мб на диске
размер:         34 Мб

  скачать грамматический словарь купить грамматический словарь SDK грамматического словаря
грамматический словарь русского языка



SDK Грамматического словаря



SDK Грамматического Словаря
склонение и спряжение глаголов, существительных, прилагательных

В состав входит русский и английский словарь.

платформа:  Windows 2000 ... Windows 7
размер:         13 Мб

SQL словарь (демо):
sqlite mysql oracle firebird mssql

скачать демо-версию SDK купить SDK API грамматического словаря



Поисковая система



Integra
настольная и сетевая поисковая система 

платформа:  Windows XP ... Windows 7
требования: 512 Mb свободной памяти
размер:         21 Мб

Дополнительные компоненты:
MySQL поисковый сервер 13.5 Мб
Integra.Premium MySQL 3.9 Мб

скачать поисковую систему SDK поисковой системыописание поисковой системы



SDK Поисковой системы



SDK Поискового движка
API для настольной и сетевой поисковая система 

платформа:  Windows XP ... Windows 7
размер:         17 Мб

Дополнительные компоненты:

MySQL поисковый сервер 13.5 Мб
Integra.Premium MySQL 3.9 Мб

скачать SDK SDK поисковой системы



Экранный переводчик



Translator
экранный переводчик

платформа:  Windows XP ... Windows 7
требования: 256 Mb свободной памяти
размер:         4.4 Мб

Дополнительные компоненты:
расширенный англо-русский словарь 6.4 Мб


скачать экранный переводчикописание экранного переводчика



изменено 11-Sep-13