Разбор естественного языка: грамматическая нотация
Я уже довольно давно интересуюсь ИИ, особенно областью, связанной с пониманием машиной текстов, написанных на естественном языке. Как известно, классическая теория анализа текста разделяет этот процесс на три этапа:
Морфологический — анализ словоформ и их характеристик (число, падеж, и т.д.); Синтаксический — выделение структуры предложения (отношения между словами); Семантический — выделение смысла исходя из «модели мира»; Первый этап в целом решён. Мы имеем подробные морфологические словари, покрывающие львиную долю слов, встречающихся в большинстве текстов. Кроме того, для распространённых языков существуют правила, позволяющие с достаточной точностью классифицировать неизвестные словоформы.Ситуация с синтаксическим разбором куда более сложная. Существующие анализаторы не могут претендовать на правильность и точность разбора в сложных случаях. Большая часть качественных продуктов выпущены под проприетарной лицензией (в большей мере это касается русского языка; с английским проблема, кажется, не стоит столь остро). Поэтому для прогресса в понимании машиной текстов, написанных на естественном языке, мы нуждаемся в качественных и доступных синтаксических анализаторах.
Из-за отсутствия у меня глубоких знаний в области нейронных сетей я решил следовать более проторенной тропой, а именно разработать BNF-подобную грамматическую нотацию и реализовать анализатор, использующий грамматические правила, описанные с её помощью. С этой точки зрения при разработке практически полезного анализатора основная работа заключается именно в построении достаточной системы правил (что у меня далеко до завершения). В следующем посте я опишу устройство реализованного анализатора, а пока хочу сфокусироваться на разработанной грамматической нотации.
Основы грамматической нотацииЯ решил начать свои изыскания, рассматривая конкретный текст. Я выбрал «Палату №6» — известную повесть А.С. Чехова, написанную им в 1892 году. Как оказалось, уже начиная с первого предложения я столкнулся с весьма существенными трудностями, связанными со сложностью чеховских предложений. Перед тем, как рассматривать конкретные примеры синтаксического разбора должен предупредить, что я не являюсь профессиональным лингвистом или филологом, и поэтому мой анализ может оказаться неверным с академической точки зрения. Моей целью будет выявить общую структуру предложения, а не подготовить разбор, соответствующий школьной программе. В больничном дворе стоит небольшой флигель, окруженный целым лесом репейника, крапивы и дикой конопли. Это простое предложение, состоящее из подлежащего (флигель), относящихся к нему определения (небольшой) и причастного оборота (окруженный целым лесом репейника, крапивы и дикой конопли), а также сказуемого (стоит) и относящегося к нему обстоятельства места (в больничном дворе).Давайте разделим это предложение на две большие части:
Первую назовём «predicate_group». В неё войдёт сказуемое и относящееся к нему обстоятельство. Вторую назовём «subject_group». В неё войдёт подлежащее и относящиеся к нему определение и причастный оборот. Теперь мы уже можем набросать несколько правил грамматики, успешно разбирающей первое предложение: sentence: — »{predicate_group} {subject_group}.»
predicate_group: — »{adverbial_modifier} {predicate}»
subject_group: — »{attribute} {subject}, {participial_phrase}» Грамматика описана в формате YAML. Этот формат удобен для редактирования правил и используется в моём анализаторе. Определения нетерминалов начинаются с названия, завершающегося двоеточием. Далее следуют одно или несколько правил, соответствующих данному нетерминалу. Правило представляет собой последовательность терминалов и нетерминалов. Нетерминал внутри правила обозначается как »{имя-нетерминала}». К примеру, единственное правило нетерминала «sentence» состоит из последовательности: нетерминал «predical_group», терминал » », нетерминал «subject_group» и терминал ».».Наша грамматика кроме того, что не определяет многие используемые нетерминалы, ещё и не учитывает важнейшие синтаксические ограничения. Вот, к примеру, совершенно некорректное предложение, не противоречащее данной грамматике:
В больничном дворе стояла небольшие флигелю, окруженный целым лесом репейника, крапивы и дикой конопли. Дело в том, что эта грамматика не учитывает ограничения на важнейшие характеристики, в частности, на падеж, число и род. Давайте модифицируем правила, добавив необходимые ограничения. sentence: — »{predicate_group number=@1 gender=@2} {subject_group number=@1 gender=@2}.»
predicate_group: — »{adverbial_modifier} {predicate! number! gender! tense}»
subject_group: — »{attribute} {subject case=nomn! number=@1! gender=@2}, {participial_phrase number=@1 gender=@2}» В приведённой нотации некоторые нетерминалы имеют атрибуты. Атрибут может иметь непосредственно заданное значение, как, например, атрибут «case» (падеж) нетерминала «predicate_group» в правиле «sentence» должен быть «nomn» (nominative, именительный).Название атрибута может начинаться с восклицательного знака. Значение такого атрибута экспортируется из соответствующего нетерминала во внешний нетерминал, правило которого мы рассматриваем. Например, «predicate_group» должен экспортировать атрибуты «number» (число), «gender» (род) и «tense» (время) для правила из «sentence», но их значения не могут быть определены на этом уровне, поэтому он импортирует их значения из нетерминала «predicate».
Иногда необходимо, чтобы атрибуты в разных нетерминалах правила имели одинаковые значения вне зависимости от самих этих значений (которые часто не могут быть определены на данном уровне). В этих случаях используется специальные значения, предваряемые символом »@». Например, в правиле «sentence» нетерминалы «predicate_group» и «subject_group» должны иметь одинаковое число и род. Кроме того, атрибут со специальным значением может ещё и экспортироваться (имя предваряется восклицательным знаком).
Нестрогость ограничения атрибутов В русском языке форма глагола зависит от рода соответствующего ему существительного, будучи в прошедшем времени («кот ел», «кошка ела»), но не зависит, будучи в настоящем или будущем времени («кот ест», «кошка ест»). Мы могли бы описать этот закон, создавая под каждое время отдельное правило, однако проще воспользоваться нестрогостью ограничения атрибутов: ограничение на атрибут игнорируется в случае, когда этот атрибут не определён в одном из соответствующих нетерминалов.Приведу пример, демонстрирующий это правило. Для разбора фраз типа «кот ел», «кошка ела», «кот ест», «кошка ест» будем использовать следующее правило:
— »{noun case=nomn number=@1 gender=@2} {verb number=@1 gender=@2}» В случае настоящего времени глагольная форма («ест») не будет иметь атрибута рода, поэтому из-за нестрогости ограничения атрибутов ограничение по роду будет проигнорировано. Этот приём также поможет и с атрибутом числа: нам не нужно добавлять отдельное правило для множественного числа (род глагола не определён для множественного числа, поэтому соответсвующее ограничение будет проигнорировано). На практике такой подход позволяет существенно уменьшить размер и сложность грамматики.Присвоение значений атрибутам Иногда требуется присвоить значения для атрибутов, которые дальше могут быть использованы в ограничениях. Например: — »@{number=plur}{noun} и {noun}» Данное правило устанавливает множественное число (plural) для перечисления двух существительных («слон и моська»). Присвоение значений атрибутов находится в самом начале правила, предваряется символом »@» и содержит перечисление атрибутов с соответствующими непосредственными значениями.Лексические терминалы Нетерминалы самого нижнего уровня могли бы определяться следующим образом: predicate: … — »@{number=sing gender=femin tense=past}ела» — »@{number=sing gender=masc tense=past}ел» — »@{number=plur tense=past}ели» … Однако данный подход не особо реалистичный, учитывая огромное число словоформ. Терминалы словоформ должны извлекаться из морфологического словаря. Поэтому такие словоформы не перечисляются в правилах, а обозначаются набором значений атрибутов: predicate: — »{pos=verb! number! gender! tense}» Как видно, такая нотация похожа на присвоение значений атрибутам, только в отличие от последнего не начинается с символа »@» и может быть в любой части правила. Вышеприведённое правило соответствует лексическому терминалу (словоформе) у которого атрибут «pos» (part of speech, часть речи) имеет значение «verb» (глагол).