С.Г.Сикорский

Использование логических методов
для морфологического и синтаксического
анализа русского языка


Цель морфологического и синтаксического анализа русского языка

Морфологический и синтаксический анализ русского языка представляют интерес в рамках взаимодействия человека с ЭВМ и естественно-языковых систем (ЕЯ-систем) [Преображенский, 1990]. При создании ЕЯ-систем одним из этапов является реализация компонентов понимания высказываний. Понимание высказываний включает анализ и интерпретацию. В методах анализа обычно выделяют анализ слов, предложений и текстов.

Анализ слов сводится к морфологическому анализу, обнаружению и исправлению орфографических ошибок. Цель морфологического анализа состоит в получении основ (под основой понимается словоформа с отсеченным окончанием) со значением грамматической категории (например, часть речи, род, число, падеж) для каждой из словоформ высказывания, поступивших на вход ЕЯ-системы. Теоретические методы морфологического анализа рассмотрены в работах И.А.Мельчука [Мельчук, 1995] и Ю.Д.Апресяна [Апресян, 1995]. Примерами ЕЯ-систем с достаточно полной для практических потребностей реализацией морфологического анализа могут служить системы ПОЭТ, TULIPS, АИСТ и современные коммерческие модули фирм “АГАМА” и “Информатик”. Эти методы используют для своей работы специализированные словари и, соответственно, бессильны в случае отсутствия слова в словаре.

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


Известные методы синтаксического анализа естественных языков

По типу используемых стратегий выделяют следующие типы анализаторов.

Традиционные анализаторы

Это анализаторы, использующие восходящие и нисходящие методы анализа и фиксированные грамматики. Типичной областью применения этих методов являются формальные языки, в том числе и языки программирования. К сожалению, эти методы дают плохие результаты при попытке их применения для анализа естественных языков. Для улучшения результатов применяют так называемые “расширенные сети переходов”.

Концептуальные анализаторы

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

Анализаторы, использующие сопоставление по образцам

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

Анализаторы, использующие разнообразные методы

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


Средства логических методов

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

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

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


Этапы анализа естественно-языкового текста

Анализ происходит в несколько этапов. На каждом из этих этапов имеются входные данные в виде таблиц или структур и выходные данные. Они описаны ниже. Выходные данные предыдущего этапа являются входными для следующего. Эти этапы можно представить следующим образом.

  1. Исходные морфологические таблицы, представленные в виде, удобном для человека, трансформируются в форму, пригодную для машинного поиска. (Эта операция производится только один раз.)
  2. Проводится лексический анализ текста, в результате которого текст разбивается на отдельные слова.
  3. Для каждого отдельного слова выполняется морфологический анализ и находится множество грамматических гипотез.
  4. Множество слов, прошедших морфологический анализ и составляющих предложение или именную фразу, подвергается синтаксическому анализу.


Предварительный обзор результатов

Неоднозначный морфологический анализ

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

Синтаксический анализ предложения в условиях неоднозначности

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


Метод морфологического анализа, не основанный на использовании словаря

Содержание (сущность) метода

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

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

Исходные данные для морфологического анализа

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

Эти таблицы имеют следующую структуру:

Пример:

resttalk(1,'йцами', [(114, [['ец',322]])]).
resttalk(2,'ьками', [(69, [['ька'],['ька',513]]),(114, [['ька',331]])]).
resttalk(3,'аете', [(140, [['ать']])]).
resttalk(4,'аешь', [(138, [['ать']])]).
resttalk(5,'аями', [(113, [['ай']])]).
resttalk(6,'еями', [(69, [['ея']]),(114, [['ей']])]).
resttalk(7,'иями', [(32, [['ие',73],['ий'],['ия'],['ия',61]])]).

И т.д.

resttalk (201, 'а', [(72, [[''], ['а'], ['а',34]]), (46, [['а'], ['а',44], ['а',45], ['а',51]]), (77, [[''], ['',21], ['',24], ['',31], ['',36]]), (91, [[''], ['',21], ['',24], ['',31], ['',36]]), (98, [['']]), (128, [['е',74], ['о'], ['о',70]]), (131, [['е',74], ['о'], ['о',70], ['я']]), (133, [['е',74], ['о'], ['о',70], ['я']])]).

И т.д.

Структура таблицы окончаний: resttalk (“Индекс окончания”, “Само окончание в виде строки”, “Список групп слов, которые могут иметь это окончание”).

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

Окончания разбиты на группы по длине. Сначала идут группы с наибольшей длиной. Это необходимо для того, чтобы выделить в слове окончание с наибольшей длиной.

Рассмотрим один из элементов таблицы окончаний, например: resttalk (4,'аешь', [(138, [['ать']])]). Из структуры таблицы ясно, что окончание 'аешь' имеет индекс 4, это окончание может иметь морфологическая группа номер 138, а окончание нормальной формы слова — 'ать'.

Пример:

sufnew('',$<из><иров><ав>$, [(5, [['']])]).
sufnew('',$<ист><иче><ск>$, [(10, [['ий']]),(4, [['и']])]).
sufnew('',$<ат><ич><еск>$, [(10, [['ий']]),(4, [['и']])]).
sufnew('',$<атель><ск>$, [(10, [['ий']]),(4, [['и']])]).
sufnew('',<етель><ск>$, [(10, [['ий']]),(4, [['и']])]).

И т.д.

sufnew('',$<ущ>$, [(12, [['ий']])]).
sufnew('',<ющ>$, [(10, [['ий']])]).
sufnew($(ль)$,'', [(15, [['ен']]),(4, [['но']])]).
sufnew($(а)$,'', [(71, [['ец',322]])]).

И т.д.

Структура таблицы суффиксов: sufnew (“Часть слова, относящаяся к корню”, “Суффикс”, “Список групп слов, которые могут иметь этот суффикс”).

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

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

Рассмотрим один из элементов таблицы суффиксов, например: sufnew ('',$<из><иров><ав>$, [(5, [['']])]). Из структуры таблицы ясно, что суффикс 'изировав' (угловые скобки введены для наглядности) не имеет части, которая бы относилась к корню, этот суффикс может иметь морфологическая группа номер 5, а окончание нормальной формы слова отсутствует (деепричастие не приводится к инфинитиву глагола).


Морфологические таблицы

Описанные выше структуры строятся автоматически на основе морфологических таблиц.
Пример морфологической таблицы:

form([''], 'сущ.м.рода неодуш. ед.ч.', 001, 'телефон', '', 'а', 'у', '', 'ом', 'е').
form([''], 'сущ.м.рода неодуш. ед.ч.', 002, 'тираж', '', 'а', 'у', '', 'ом', 'е').
form(['ь'],'сущ.м.рода неодуш. ед.ч.', 003, 'огонь', 'ь', 'я', 'ю', 'ь', 'ем', 'е').
form(['ой'],'сущ.м.рода неодуш. ед.ч.', 004, 'перебой', 'ой', 'оя', 'ою', 'ой', 'оем', 'ое').
form(['ий'],'сущ.м.рода неодуш. ед.ч.', 005, 'санаторий','ий', 'ия', 'ию', 'ий', 'ием', 'ие').

И т.д.

Структура: form (“Окончание нормальной формы”, “Описание грамматических атрибутов в виде строки”, “Номер морфологической группы”, “Пример слова из этой морфологической группы”, “Перечисление окончаний всех словоформ слова”).

Рассмотрим один из элементов морфологической таблицы, например: form([''], 'сущ.м.рода неодуш. ед.ч.', 001, 'телефон', '', 'а', 'у', '', 'ом', 'е'). Эта морфологическая группа представлена словом 'телефон', нормальная форма имеет нулевое окончание, грамматические атрибуты, соответствующие этой морфологической группе, — 'существительное мужского рода, неодушевленное, единственное число'. Эта группа имеет номер один.


Трансформация морфологических таблиц

При трансформации каждому окончанию ставится в соответствие грамматический атрибут со следующей структурой:

at (Лицо-Род,Число,Падеж,Время,Возвратность,Иерархия).

Где:

  1. Лицо-Род —> one | two | tre(Род);
  2. Род —> 'м.род'|'ж.род'|'с.род'|'';
  3. Число —> 'ед.число' | 'мн.число'|'';
  4. Падеж —> 'им.пад.'|'род.пад.'|'дат.пад.'|'вин.пад.'|'тв.пад.'|'пр.пад.'|'';
  5. Время —> 'Пр.вр.'|'НиБ вр.'|'';
  6. Возвратность —> 'возв.'|'невозв.'|'';
  7. Иерархия —> t(s('неодуш.'),_)|t(s('одуш.'),_)|t(a,_)|t(v,_).

Здесь символ “ | ”— означает “или”.

Пункт “иерархия” обозначает следующие категории:

  1. t(s('неодуш.'),_) — неодушевленное существительное;
  2. t(s('одуш.'),_) — одушевленное существительное;
  3. t(a,_) — прилагательное;
  4. t(v,_) — глагол.

Категория “время” имеет всего два значения: 'Пр.вр.' — прошедшее и 'НиБ вр.' — настоящее и будущее, что связано с особенностями словообразования глагола. Категория “Лицо-Род” объединена в одну группу постольку, поскольку род существует только в третьем лице. Каждый атрибут может быть неизвестен, что в Прологе записывается как “_” и это значение может быть унифицировано впоследствии, либо вообще отсутствовать, что записывается как “’’”, то есть обозначает пустую строку и не позволяет этому атрибуту больше ни с чем унифицироваться.

Этот набор грамматических атрибутов является общим для всех частей речи. Естественно, некоторые комбинации являются взаимоисключающими, например, возвратность и род. По наличию или отсутствию того или иного признака можно определять отношение слова к той или иной части речи. Например: предикат “isa” по комбинации грамматических атрибутов определяет часть речи.

isa('деепричастие.', at('','','',_,_,t(a,_))).
isa('краткое прил. или прич.',at(tre(_),_,'','','',t(a,_))).
isa('прилагательное', at(tre(_),_,_,'','',t(a,_))).
isa('причастие', at(tre(_),_,_,_,_,t(a,(v,_)))).
isa('инфинитив', at('','','','',_,t(v,_))).
isa('глагол', at(_,_,'',_,_,t(v,_))).
isa('наречие', at('','','','','',t(adv,_))).
isa('сущ.', at(tre(_),_,_,'','',t(s(_),_))).

И т.д.

Программа трансформации имеет следующую структуру.

  1. Предикат, расшифровывающий грамматические атрибуты для каждого окончания.
  2. Предикат, формирующий грамматические атрибуты в виде структуры, описанной выше.

Функции, которые выполняют эти модули:

  1. Объединение двух множеств без повторения.
  2. Минимизация множества окончаний.
  3. Сбор множества атрибутов для одного окончания в общий список.
n:- not((

form(NormR, Str, Num, _, N1, N2, N3, N4, N5, N6),

NormRest = [NormR],
(
%%substantive(Падеж,Число,Род,Одушевленность,Абстрактное-конкретное)
Str = 'сущ.м.рода неодуш. ед.ч.',
make(N1,(at(tre('м.род'),'ед.число','им.пад.','','',t(s('неодуш.'),_)),NormRest)),
make(N2,(at(tre('м.род'),'ед.число','род.пад.','','',t(s('неодуш.'),_)),NormRest)),
make(N3,(at(tre('м.род'),'ед.число','дат.пад.','','',t(s('неодуш.'),_)),NormRest)),
make(N4,(at(tre('м.род'),'ед.число','вин.пад.','','',t(s('неодуш.'),_)),NormRest)),
make(N5,(at(tre('м.род'),'ед.число','тв.пад.','','',t(s('неодуш.'),_)),NormRest)),
make(N6,(at(tre('м.род'),'ед.число','пр.пад.','','',t(s('неодуш.'),_)),NormRest))
% Далее эта секция повторяется для других грамматических категорий
)
)).

Здесь предикат form производит унификацию с записью в морфологической таблице, конструкция “Str = 'сущ.м.рода неодуш. ед.ч.'” осуществляет проверку того, совпадает ли строка с грамматическими атрибутами из записи в морфологической таблице с контрольной строкой или нет. Серия предикатов make производит расшифровку грамматических атрибутов (трансформацию грамматических атрибутов) для каждого отдельно взятого окончания N1, N2, N3, N4, N5 или N6.

%%Параметры: (строка окончания, грамматический атрибут этого окончания)
make(N1, Val1):-
makekey(N1, Key),
(
retrieveb(dicdos,Key,resttalk(RestNum,N1,List1)),!,
change([Val1|List1],Val1,Out1),
ToIns = resttalk(RestNum,N1,Out1),
replaceb(dicdos,Key,resttalk(RestNum,N1,List1),ToIns),!
recordb(dicdos, Key, resttalk(0,N1,[Val1]))
),
!.

Здесь предикат makekey рассчитывает для строки окончания уникальный ключ, основанный на длине строки, предикат retrieveb извлекает запись об окончании из внутренней базы данных dicdos, предикат replaceb заменяет старую запись в базе данных новой, модифицированной, а предикат recordb заносит первую запись в базу данных, если записи для данного окончания во внутренней базе данных dicdos найдено не было.


Лексический анализ текста

Входные строки для анализа трансформируются в списки букв и поступают на анализ предикатом analysis
Программа, читающая входной поток и производящая лексический анализ, имеет следующий вид:

analysis(Expression, Words):-
lex(Expression,Tokens),
tokens2words(Tokens, Words).
lex(Expression,Tokens):-
lexemes(Tokens,Expression,[]),!
;
write('Морфологический анализ прерван'),nl,!,fail.
lexemes(X)- ->space,lexemes(X).
lexemes([X|Y])- ->lexeme(X),lexemes(Y).
lexemes([ ])- ->[ ].
lexeme(Out)--141t;word(WordList),!,
{
name(WordText, WordList),
Out = w(WordText)
}.
space- ->[L],{ not(
(L = 45; /* '-' */
L>=128,L=<143; /* А-П */
L>=144,L=<159; /* Р-Я */
L>=160,L=<175; /* а-п */
L>=224,L=<239 /* р-я */
))}.
word([L|Ls]) - ->letter(L),lords(Ls).
letter(L1)- ->[L],{/* в коде ASCII а-я, А-Я */
(L = 45, L1=L; /* '-' */
L>=128,L=<143, L1 is L + 32; /* А-П */
L>=144,L=<159, L1 is L + 80; /* Р-Я */
L>=160,L=<175, L1=L; /* а-п */
L>=224,L=<239, L1=L /* р-я */
)}.
lords([L|Ls])- ->letter(L),lords(Ls).
lords([ ])- ->[ ].

Эта часть программы представляет собой классический пример DC-грамматики.


Этапы морфологического анализа слова

Морфологический анализ слова выполняется за несколько этапов, начиная с конца слова.

  1. Проверяем на 'сь' или 'ся', выставляем для глаголов, причастий и деепричастий возвратность.
  2. Находим окончание.
  3. Проверяем на наличие суффикса.
  4. Производим пересечение множеств атрибутов.

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


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

%% Key — входной параметр, представляющий собой слово в виде инвертированного списка букв, составляющих это слово,
%% Line — выходная структура, которая показана в следующих примерах:
make_analyse(Key, Line):-
%% Проверяем на 'сь' или 'ся'
begin(Num1,BeginStr,BeginSuf,RevBeginSuf,AtrBegin),
prefix(Key,RevBeginSuf, Rest1),
%% Находим окончание
recorded_tro(restnew, resttalk(Num2,Str,RevSuf,AtrRest), _),
prefix(Rest1, RevSuf, Rest2),
AtrBegin = [TermBegin],
apply(TermBegin,AtrRest,Atr_2_Suff1),
%% выставляем для глаголов возвратность
apply((at(_,_,'',_,'невозв.',t(v,_)), _), Atr_2_Suff1, Atr_2_Suff),
%% Проверяем на суффиксы
%% Берем суффикс из группы
retrieveb(match, _, sufnew(Osnowa,SuffixStr1, RevSuffix1, AtrSuff)),
prefix(Rest2, RevSuffix1, Rest3),
concat(Osnowa,SuffixStr1,CheckStr),
string_length(CheckStr,CheckStr_Length),
%% Производим усечение атрибутов
restore_compr(Atr_2_Suff,Atr_2_SuffRestor),
restore_compr(AtrSuff,AtrSuffRestor),
intersection(CheckStr_Length,Atr_2_SuffRestor,AtrSuffRestor,Atr_2_Root),
Atr_2_Root \= [],
list_text(OsnowaList,Osnowa),
reverse(OsnowaList, RevOsnowaList),
append(RevOsnowaList, Rest3, Rest4),
reverse(Rest4, RevRest4),
list_text(Rest4,RestStr4),
list_text(RevRest4,RevRestStr4),
string_term(StrFound, Atr_2_Root),
reverse(Key, RevKey),
list_text(RevKey,StrRevKey),
concat([RevRestStr4, SuffixStr1],MostAll),
Line = wd((StrRevKey,MostAll),Atr_2_Root
).

Поясним предикаты, используемые при проведении анализа.

Предикат recorded_tro является недетерминированным системным предикатом и извлекает из внутренней базы данных другие предикаты. Restnew извлекает из базы данных предикат resttalk, который, как мы знаем, содержит информацию об окончаниях, из базы данных match — предикат sufnew с информацией о суффиксах.

Предикат begin возвращает грамматические атрибуты для 'сь', 'ся' для глаголов:

%% ['возв.','невозв.']
begin(1,'сь',[225,236],[236,225],[(at(_,_,'',_,'возв.',_), _)]).
begin(2,'ся',[225,239],[239,225],[(at(_,_,_,_,'возв.',_), _)]).
begin(3,'',[ ],[ ],[(at(_,_,_,_,_,_), _)]).

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

%% prefix(+Text,+Prefix,-Rest)
prefix(Text,[ ],Text):- !.
prefix([H|T1],[H|T2],Rest):-
prefix(T1,T2,Rest).

Предикат apply служит для унификации первого своего аргумента с каждым элементом списка, который является вторым аргументом, а результат возвращается как третий аргумент. Таким образом, на выходе получается “уточненный” список, где входной список не урезается, но каждый его элемент унифицируется с первым аргументом. Это необходимо для того, чтобы “уточнить” неизвестные грамматические атрибуты для слова, вернее было бы сказать “список грамматических атрибутов”.

%% apply(H,R1,R2).
apply((At, At7), [(At, At_Old)|R1], [(At, At_Old)|R2]):-!,
apply((At, At7),R1,R2).
apply(H,[H1|R1],[H1|R2]):-!,
apply(H,R1,R2).
apply(_ ,[ ] ,[ ] ).

Предикат intersection находит пересечение двух списков с учетом списков нормальных окончаний:

%% первый список — ограничиваемый
%% второй список — ограничивающий
intersection(_ , [ ] , _ , [ ] ):- !.
intersection(CheckStr_Len, [(At, At7)|L1], L2, [(At, At_Found)|L3]):-
not((
retract(found(_)),
fail
)),
assert(found(L2)),
member((At, At_New), L2),
%% Нахожу пересечение списков нормальных окончаний
intersection_old(CheckStr_Len, At7, At_New, At_Found),
At_Found \= [ ] , ! ,
retract(found(L2_Old)),
intersection(CheckStr_Len, L1,L2_Old,L3),
! .
intersection(CheckStr_Len, [_|L1],L2,L3):-
intersection(CheckStr_Len, L1,L2,L3).

Он использует классический предикат intersection_old, находящий декартово произведение для множеств (в данном случае для списков).

intersection_old(_ , [ ] , _ , [ ]):- !.
intersection_old(CheckStr_Len, [H|L1], L2, [H|L3]):-
ifthen(CheckStr_Len=0,H=[_]),
member(H, L2),
intersection_old(CheckStr_Len, L1,L2,L3),
!.
intersection_old(CheckStr_Len, [_|L1],L2,L3):-
intersection_old(CheckStr_Len, L1,L2,L3).

Аналогично функционирует классический предикат member, который либо проверяет наличие своего первого элемента в списке, заданном вторым элементом, либо вставляет его туда, либо извлекает в зависимости от логики программы.

member(H,[H|_]).
member(H,[_|R]):-
member(H,R).

Предикат list_text трансформирует список букв в строку и является системным.

Предикат reverse производит инверсию списка:

reverse(List, Rev):-
rev(List, [], Rev).
rev([ ], Rev, Rev):- !.
rev([H|T], WorkList, Rev):-
rev(T, [H|WorkList], Rev).

Предикат concat производит конкатенацию двух списков и является системным.

Предикат append добавляет список (являющийся вторым аргументом) к концу списка, являющегося первым аргументом:

append([ ],L , L).
append([H|T], L, [H|R]):-
append(T, L, R).

Результат анализа, представленный как терм пролога, выглядит следующим образом:


Пример 1.

Результат морфологического анализа словосочетания 'веселая жизнь':

test([
wd(('веселая','весел'), [
(at(tre('ж.род'),'ед.число','им.пад.','','',t(a,('',_))), [['ий'],['ой'],['ый']]),
(at(tre('м.род'),'ед.число','род.пад.','','',t(s('неодуш.'),('',_))), [['ай']]),
(at(tre('м.род'),'мн.число','вин.пад.','','',t(s('неодуш.'),('',_))), [['ай']]),
(at(tre('м.род'),'мн.число','им.пад.','','',t(s('неодуш.'),('',_))), [['ай']])
]),
wd(('жизнь','жизн'),[
(at(tre('ж.род'),_,'вин.пад.','','',t(s('одуш.'),('',_))), [['ь']]),
(at(tre('ж.род'),'ед.число','им.пад.','','',t(s(_),('',_))), [['ь']]),
(at(tre('ж.род'),'мн.число','род.пад.','','',t(s(_),('',_))), [['я']]),
(at(tre('м.род'),'ед.число','вин.пад.','','',t(s('неодуш.'),('',_))), [['ь']]),
(at(tre('м.род'),'ед.число','им.пад.','','',t(s(_),('',_))), [['ь']])
])
]).

Здесь анализатор понял слово “веселая” как прилагательное (a,('',_)) либо неодушевленное существительное (s('неодуш.')) с различными значениями грамматических категорий. Слово “жизнь” понято как существительное женского или мужского рода, единственного или множественного числа, именительного, родительного или винительного падежа.


Пример 2.

Результат морфологического анализа предложения 'смелый командир пошел на войну':

test([
wd(('смелый', 'смел'),
[(at(tre('м.род'),'ед.число','им.пад.','','',t(a,('',_))), [['ый']])
]),
wd(('командир', 'команд(ир)'),
[(at(tre('м.род'),'ед.число','им.пад.','','',t(s(_),('',_))),[['',21]])
]),
wd(('пошел', 'пой'),
[(at(tre('м.род'),'ед.число','','пр.вр.',_,t(v,('',_))),[['еть'],['ти']]),
(at(one,'ед.число','','пр.вр.',_,t(v,('',_))), [['еть'],['ти']]),
(at(two,'ед.число','','пр.вр.',_,t(v,('',_))), [['еть'],['ти']])
]),
wd(('на', 'на'),
[(at('','','вин.пад.','','',t(p,('',_))), [['на']]),
(at('','','пр.пад.','','',t(p,('',_))), [['на']])
]),
wd(('войну', 'войн'),
[(at(tre('с.род'),'ед.число','дат.пад.','','',t(s(_),('',_))), [['о']]),
(at(one,'ед.число','','НиБ вр.',_,t(v,('',_))),[['ать'],['еть'],['ти']]),
(at(tre('ж.род'),'ед.число','вин.пад.','','',t(s(_),('',_))), [['а']]),
(at(tre('м.род'),'ед.число','вин.пад.','','',t(s('одуш.'),('',_))), [['а']]),
(at(tre('м.род'),'ед.число','дат.пад.','','',t(s(_),('',_))), [['']])
])
]).




Пример 3.

Результат морфологического анализа предложения ‘юный бизнесмен сидел за столом хозяина фирмы с соседней улицы’:

%% ‘юный бизнесмен сидел за столом хозяина фирмы с соседней улицы’
test([
wd(($юный$, $ю< н >$),
[(at(tre('м.род'),'ед.число','им.пад.','','',t(a,('',A))), [['ый']])]),
wd(($бизнесмен$, $бизнесм$),
[(at(tre('ж.род'),'мн.число','род.пад.','','',t(s(B),('',C))), [['ня']]),
(at(tre('ж.род'),'мн.число','вин.пад.','','',t(s('одуш.'),('',D))), [['ня']]),
(at(tre('м.род'),'ед.число','им.пад.','','',t(s(_),('',E))), [[ 'ен'] ] )] ),
wd(($сидел$, $сид$),
[(at(tre('м.род'),'ед.число','','пр.вр.',F,t(v,('',G))), [['еть'],['ти']]),
(at(one,'ед.число','','пр.вр.',H,t(v,('',I))), [['еть'],['ти']]),
(at(two,'ед.число','','пр.вр.',J,t(v,('',K))), [['еть'],['ти']])]),
wd(($за$, $за$),
[(at('','','вин.пад.','','',t(p,('',L))), [[$за$]]),
(at('','','тв.пад.','','',t(p,('',M))), [[$за$]])]),
wd(($столом$, $стол$),
[(at(tre('с.род'),'ед.число','тв.пад.','','',t(s(N),('',O))), [['о']]),
(at(tre('м.род'),'ед.число','пр.пад.','','',t(a,('',P))), [['ий'],['ой'],['ый']]),
(at(tre('м.род'),'ед.число','тв.пад.','','',t(s(Q),('',R))), [['']]),
(at(tre('с.род'),'ед.число','пр.пад.','','',t(a,('',S))), [['ий'],['ой'],['ый']])]),
wd(($хозяина$, $хозяи$),
[(at(tre('ж.род'),'ед.число','род.пад.','','',t(s(_),('',T))), [['н']])]),
wd(($фирмы$, $фирм$),
[(at(tre('м.род'),'мн.число','им.пад.','','',t(s(U),('',V))), [['']]),
(at(tre('ж.род'),'ед.число','род.пад.','','',t(s(W),('',X))), [['а']]),
(at(tre('ж.род'),'мн.число','вин.пад.','','',t(s('неодуш.'),('',Y))), [['а']]),
(at(tre('ж.род'),'мн.число','им.пад.','','',t(s(Z),('',AA))), [['а']]),
(at(tre('м.род'),'мн.число','вин.пад.','','',t(s('неодуш.'),('',AB))), [['']])]),
wd(($с$, $с$),
[(at('','','род.пад.','','',t(p,('',AC))), [[$с$]]),
(at('','','тв.пад.','','',t(p,('',AD))), [[$с$]])]),
wd(($соседней$, $сосед$),
[(at(tre('ж.род'),'ед.число','род.пад.','','',t(a,('',AF))), [['ний']])]),
wd(($улицы$, $улиц$),
[(at(tre('м.род'),'мн.число','им.пад.','','',t(s(AG),('',AH))), [['']]),
(at(tre('ж.род'),'ед.число','род.пад.','','',t(s(AI),('',AJ))), [['а']]),
(at(tre('ж.род'),'мн.число','вин.пад.','','',t(s('неодуш.'),('',AK))), [['а']]),
(at(tre('ж.род'),'мн.число','им.пад.','','',t(s(AL),('',AM))), [['а']]),
(at(tre('м.род'),'мн.число','вин.пад.','','',t(s('неодуш.'),('',AN))), [['']])])

]).


Результат

Для одного слова мы можем найти несколько грамматических атрибутов. С чем это связано? У одного слова могут совпадать формы различных словоформ, например именительный и винительный падежи у существительных. Это также могут быть различные слова: функциональные омонимы (юноша, учащийся в техникуме —> учащийся), совпадающие словоформы различных слов (плавки стали, плавки пловца, стали большими), выделенное в слове окончание может относиться к нескольким морфологическим группам.

Достоинства метода

Данный метод хорошо проявляет себя в текстах, где есть неизвестные слова или слова содержат ошибки. Используя данный метод морфологического анализа можно даже производить синтаксический анализ известного “бессмысленного” предложения: “Дрякая куздра бряко бокрячит бокренка”.

Недостатки метода

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

Возможные усовершенствования

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

Вывод

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


Синтаксический анализ

Метод синтаксического анализа, основанный на использовании неоднозначной грамматической информации

Цель: построение синтаксического дерева или, говоря в терминах модели “Смысл <=> Текст”, построение поверхностной синтаксической структуры (ПСС). Уже следующим этапом может быть трансформация ПСС в глубинную синтаксическую структуру (ГСС), которая уже содержит в себе элементы семантики.

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

Замечание. В данной работе не описаны принципы работы и реализация самого метода. Методы синтаксического анализа изложены в работах И.А. Мельчука и Ю.Д.Апресяна. Мы будем рассматривать лишь полученные результаты. Данный метод необходимо здесь лишь для оценки результативности морфологического анализа.

Содержание (сущность) метода

В отличие от метода морфологического анализа, синтаксический анализ не порождает множество гипотез. Синтаксический анализ рассматривается как поиск доказательства (что, вообще говоря, является базовым понятием языка Prolog). Поиск доказательства понимается как поиск возможности построения ПСС для предложения или фразы и основывается на заданных грамматических правилах. Этот метод отвечает на вопрос: “существует ли ПСС для данного предложения или фразы?”, и если существует, то какова она. Предполагается, что предлагаемый для анализа текст является грамматически верным и не содержит грамматических ошибок, препятствующих пониманию этого текста человеком.

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

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


Результаты

Результаты синтаксического анализа получаются в виде терма языка Пролог, который трансформируется потом для наглядности в графическую форму (древовидную конструкцию).

Структура древовидной конструкции:

  1. Узел содержит информацию о слове (даются варианты построения нормальной формы), грамматических атрибутах слова (из множества гипотез алгоритм синтаксического анализа выбирает только одну) и примененном синтаксическом правиле. Информация о примененном синтаксическом правиле записывается в подчиненном узле, соответственно, самый верхний узел этой информации не содержит.
  2. Иерархия узлов задает отношение “главный — подчиненный”. “Главный” узел находится выше по иерархии.


Примеры работы

Пример 4: %% 'веселая жизнь'.
Результат морфологического анализа берем из примера 1.
Результат синтаксического анализа в структурной форме:

жизнь —> сущ ж.род ед.число им.пад.
веселий, веселой, веселый <Прил Сущ> —> прилагательное ж.род ед.число им.пад.

Где слово “жизнь” — это существительное женского рода, единственного числа, именительного падежа, а слово “веселий, веселой, веселый” — это прилагательное женского рода, единственного числа, именительного падежа и связано со своим “главным” словом связью типа “Прилагательное — Существительное”, т.е. — согласованием.


Пример 5: %% 'смелый командир пошел на войну'.
Результат морфологического анализа берем из примера 2.
Результат синтаксического анализа в структурной форме:

команд(ир) —> сущ м.род ед.число им.пад.
смелый <Прил — Сущ> —> прилагательное м.род ед.число им.пад.
пойтеть, пойти <Подлежащее — Сказуемое прямой порядок слов> —> глагол м.род ед.число пр.вр.
на <пред. с сущ.подч.глаг.>—> сущ. с предлогом вин.пад.
война <Предлог — Сущ> —>сущ ж.род ед.число вин.пад.


Пример 6: %% 'юный бизнесмен сидел за столом хозяина фирмы с соседней улицы'.
Результат морфологического анализа берем из примера 3.
Результат синтаксического анализа в структурной форме:

бизнесмен —> сущ м.род ед.число им.пад.
ю<н>й <Прил Сущ> —> прилагательное м.род ед.число им.пад.
сидеть, сидти <Подлежащее Сказуемое прямой порядок слов> —> глагол м.род ед.число пр.вр.
за < пред. с сущ.подч.глаг.> —> сущ. с предлогом тв.пад.
столо <Предлог Сущ> —> сущ с.род ед.число тв.пад.
хозяин <для сущ.стоит в род.пад.опред.или дополн.> —> сущ ж.род ед.число род.пад.
фирма <для сущ.стоит в род.пад.опред.или дополн.> —> сущ ж.род ед.число род.пад.
с <пред. с сущ.подч.глаг.> —> сущ. с предлогом род.пад.
улица <Предлог Сущ>—> сущ ж.род ед.число род.пад.
соседня <Прил Сущ> —>прилагательное ж.род ед.число род.пад.



Замечания

Пример 4 — это простейшее словосочетание с согласовательной связью. В таких конструкциях все неоднозначности разрешаются очень просто.

Пример 5 — это простое предложение, в котором уже есть управление. Неоднозначность морфологического анализа здесь так же устраняется.

Пример 6 — это уже достаточно сложное предложение с большим количеством управлений и нанизыванием групп. Здесь проявляются недостатки результатов неоднозначного морфологического анализа. Не смотря на то что синтаксический анализ произведен верно, слово “стол” понимается как имеющее средний род. В связи типа “примыкание” род старшего существительного не играет роли, что и привело к построению правильной ПСС.

Вообще говоря, Д.Э.Розенталь [Розенталь, 1994] такие конструкции использовать не рекомендует. Зачастую, их понимание вызывает затруднение не только у компьютера, но и у человека. Анализ нанизанных именных групп — это всегда сложная задача.


Достоинства

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

Основной интерес представляет тот факт, что использование ограниченного количества правил приводит к приемлемым практическим результатам. В сущности, мы производим анализ естественного языка, не обладая познаниями в этом языке, не опираясь на знание семантики окружающего мира. В обоих методах использовалась лишь небольшая часть морфологических и грамматических правил, описанных в работах И.А.Мельчука и Ю.Д.Апресяна. Развитие каждого метода в отдельности обладает большими перспективами именно в области анализа неграмматических конструкций и текстов с ошибками в словах.


Недостатки

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