Ранее мы писали об анализе отзывов о ресторанах, с целью извлечения упоминаний разных аспектов (еды, обстановки, и подобного). Недавно в комментариях возник вопрос о извлечении из текста фактической информации, т.е. можно ли, например, из отзывов об автомобилях извлечь факты, например «быстро ломается коробка передач» => ломается(коробка передач, быстро), чтобы с этими фактами можно было потом работать. В этой статье мы опишем один из подходов к решению такой проблемы.
Метод, о котором мы расскажем, опирается на ряд упрощений, он не самый точный, но зато легок в реализации и позволяет быстро создать прототип приложения, в котором он должен использоваться. В ряде случаев его будет и вполне достаточно, а для других можно ввести усовершенствования, не отступая от основного принципа.
Рассмотрим, например, такое предложение в отзыве о кронштейне для телевизора:
Все отверстия с телевизором совпадают, шайбы не вываливаются.
Мы хотим извлечь из него соотношения, например, вот в таком виде:
предикат => совпадают
субъект => отверстия
объект => c телевизором
предикат => не вываливаются
субъект => шайбы
Эта задача часто называется выделением семантический ролей (Semantic Role Labeling). Есть некоторый глагол (совпадает, вываливается и т. п.) и есть его аргументы. Что такое аргументы глагола и какие они бывают, есть предмет спора среди лингвистов. На практике они бывают такие, какие нужны для конкретной задачи. Поэтому, чтобы не погружаться глубоко в философские проблемы, определим, что будут нужны субъект, объект, обстоятельство/условия при котором происходило действие. К объекту, или субъекту также может быть привязано описание, например в словосочетании хороший телевизор эту роль выполняет слово хороший. Если же описание является не характеристикой качества объекта, а его составляющей (плазменный телевизор), то такое мы выделим в отдельный класс. Для начала этого будет достаточно, а чуть ниже мы к этому вопросу еще вернемся.
Теперь мы попробуем свести проблему извлечения соотношений к задаче аннотации последовательности, о решении которой мы рассказывали ранее.
Поставим напротив каждого слова соответствующую категорию и разметим таким образом обучающую выборку достаточных размеров. Далее мы можем обучить любой классификатор, который может работать с последовательностями, например CRF, после чего подав на вход новое предложение мы сможем получить предсказание категории для каждого слова. Мы, конечно, использовали для опытов наш API, доступ к которому могут бесплатно получить все желающие, зарегистрировавшись на нашем сайте. О том, как его использовать, мы подробно писали здесь, поэтому повторяться здесь не будем, чтобы не потерять главную мысль.
Мы вручную разметили около 100 предложений, что вообще-то очень маленькая выборка для такой задачи. Далее мы подали на вход модели несколько новых предложений и вот что получилось:
Первое предложение:
Второе предложение:
На этом этапе мы заметили, что потерялись связи между глаголом и соответствующим ему объектом (на самом деле мы это знали сразу, но для простоты изложения не говорили).
Существуют разные способы решения этой задачи. В узкоспециализированных системах, вид аргумента может сам по себе говорить о том, к какому глаголу его надо отнести:
Поезд приезжает на станцию в 16-00, а отбывает в 15-20
Ясно, что тут мы можем сразу отметить 16-00 как время_прибытия, а 15-20 как время_отбытия, при этом глагол тоже будет иметь тип, например, будет относится к типу «прибытие», а отбывает к типу «отбытие». Таким образом, вопрос правильного сопоставления переложен на систему аннотации последовательности, а справится она с этим или нет, будет зависеть от используемого алгоритма.
Такой подход хорошо подойдет для анализа команд («разбуди меня завтра в 10 утра => разбуди(меня, завтра в 10 утра, «заказать пиццу на 10 человек” => заказать(пиццу, 10 человек) и т. п.)
В нашем случае, мы могли бы определить типы аргументов точнее. Скажем, во фразе, «все отверстия с телевизором совпадают», у нас был бы тип отношения «совпадение», и два аргумента «что_совпадает» и «с_чем_совпадает». И это отлично работает, когда число соотношений ограничено, и строго определено.
Мы же вначале выбрали более общую схему, когда виды аргументов очень неопределенные, в надежде, что они подойдут к любому глаголу. Вследствие этого, нам потребуется вторая фаза анализа — определение какие аргументы к какому глаголу соответствуют.
Поскольку мы делаем простой метод извлечения фактов, то предположим, что все объекты относятся к ближайшим к ним глаголам. Это не всегда так, но часто бывает правдой. Таким же методом можно соотнести объекты их описания.
Приняв это упрощение, мы написали программу, которая сначала ищет все определенные глаголы, а потом разносит к ним соответствующие объекты, считая расстояние до глагола в словах. С помощью этой программы из приведенных выше предложений удалось выделить вот такие соотношения:
первое предложение:
предикат => поменял
объект1 => шило
объект2 => мыло
предикат => купился
объект => название
второе предложение:
предикат => есть
объект1 => насечки
описание => пунктирной
объект2 => ножа
описание => обычного
объект3 => комплекте
Получилась довольно интересная вещь, при этом на всю работу, включая ручное аннотирование обучающей выборки, у нас ушло 4 часа времени. Чтобы улучшить качество, можно на втором этапе анализа собрать все выделенные факты вместе, и попробовать отбросить неверно определенные соотношения на основании анализа результатов.
В целом, как мы видим, задача извлечения соотношений из текстов может решаться разными путями. Мы рассмотрели лишь некоторые, стараясь акцентировать внимание на доступных методах, и, как видно, на сегодняшний день, построить такой анализатор не так уж сложно.
Метод, о котором мы расскажем, опирается на ряд упрощений, он не самый точный, но зато легок в реализации и позволяет быстро создать прототип приложения, в котором он должен использоваться. В ряде случаев его будет и вполне достаточно, а для других можно ввести усовершенствования, не отступая от основного принципа.
Рассмотрим, например, такое предложение в отзыве о кронштейне для телевизора:
Все отверстия с телевизором совпадают, шайбы не вываливаются.
Мы хотим извлечь из него соотношения, например, вот в таком виде:
предикат => совпадают
субъект => отверстия
объект => c телевизором
предикат => не вываливаются
субъект => шайбы
Эта задача часто называется выделением семантический ролей (Semantic Role Labeling). Есть некоторый глагол (совпадает, вываливается и т. п.) и есть его аргументы. Что такое аргументы глагола и какие они бывают, есть предмет спора среди лингвистов. На практике они бывают такие, какие нужны для конкретной задачи. Поэтому, чтобы не погружаться глубоко в философские проблемы, определим, что будут нужны субъект, объект, обстоятельство/условия при котором происходило действие. К объекту, или субъекту также может быть привязано описание, например в словосочетании хороший телевизор эту роль выполняет слово хороший. Если же описание является не характеристикой качества объекта, а его составляющей (плазменный телевизор), то такое мы выделим в отдельный класс. Для начала этого будет достаточно, а чуть ниже мы к этому вопросу еще вернемся.
Теперь мы попробуем свести проблему извлечения соотношений к задаче аннотации последовательности, о решении которой мы рассказывали ранее.
Все | |
отверстия | субъект |
с | |
телевизором | объект |
совпадают | предикат |
, | |
шайбы | объект |
не | предикат |
вываливаются | предикат |
Поставим напротив каждого слова соответствующую категорию и разметим таким образом обучающую выборку достаточных размеров. Далее мы можем обучить любой классификатор, который может работать с последовательностями, например CRF, после чего подав на вход новое предложение мы сможем получить предсказание категории для каждого слова. Мы, конечно, использовали для опытов наш API, доступ к которому могут бесплатно получить все желающие, зарегистрировавшись на нашем сайте. О том, как его использовать, мы подробно писали здесь, поэтому повторяться здесь не будем, чтобы не потерять главную мысль.
Мы вручную разметили около 100 предложений, что вообще-то очень маленькая выборка для такой задачи. Далее мы подали на вход модели несколько новых предложений и вот что получилось:
Первое предложение:
Поменял | предикат |
шило | объект |
на | |
мыло | объект |
за | |
такие | |
деньги | объект |
, | |
купился | предикат |
на | |
название | объект |
Второе предложение:
В | |
комплекте | объект |
помимо | |
обычного | |
ножа | объект |
есть | предикат |
для | |
пунктирной | описание |
насечки | объект |
На этом этапе мы заметили, что потерялись связи между глаголом и соответствующим ему объектом (на самом деле мы это знали сразу, но для простоты изложения не говорили).
Существуют разные способы решения этой задачи. В узкоспециализированных системах, вид аргумента может сам по себе говорить о том, к какому глаголу его надо отнести:
Поезд приезжает на станцию в 16-00, а отбывает в 15-20
Ясно, что тут мы можем сразу отметить 16-00 как время_прибытия, а 15-20 как время_отбытия, при этом глагол тоже будет иметь тип, например, будет относится к типу «прибытие», а отбывает к типу «отбытие». Таким образом, вопрос правильного сопоставления переложен на систему аннотации последовательности, а справится она с этим или нет, будет зависеть от используемого алгоритма.
Такой подход хорошо подойдет для анализа команд («разбуди меня завтра в 10 утра => разбуди(меня, завтра в 10 утра, «заказать пиццу на 10 человек” => заказать(пиццу, 10 человек) и т. п.)
В нашем случае, мы могли бы определить типы аргументов точнее. Скажем, во фразе, «все отверстия с телевизором совпадают», у нас был бы тип отношения «совпадение», и два аргумента «что_совпадает» и «с_чем_совпадает». И это отлично работает, когда число соотношений ограничено, и строго определено.
Мы же вначале выбрали более общую схему, когда виды аргументов очень неопределенные, в надежде, что они подойдут к любому глаголу. Вследствие этого, нам потребуется вторая фаза анализа — определение какие аргументы к какому глаголу соответствуют.
Поскольку мы делаем простой метод извлечения фактов, то предположим, что все объекты относятся к ближайшим к ним глаголам. Это не всегда так, но часто бывает правдой. Таким же методом можно соотнести объекты их описания.
Приняв это упрощение, мы написали программу, которая сначала ищет все определенные глаголы, а потом разносит к ним соответствующие объекты, считая расстояние до глагола в словах. С помощью этой программы из приведенных выше предложений удалось выделить вот такие соотношения:
первое предложение:
предикат => поменял
объект1 => шило
объект2 => мыло
предикат => купился
объект => название
второе предложение:
предикат => есть
объект1 => насечки
описание => пунктирной
объект2 => ножа
описание => обычного
объект3 => комплекте
Получилась довольно интересная вещь, при этом на всю работу, включая ручное аннотирование обучающей выборки, у нас ушло 4 часа времени. Чтобы улучшить качество, можно на втором этапе анализа собрать все выделенные факты вместе, и попробовать отбросить неверно определенные соотношения на основании анализа результатов.
В целом, как мы видим, задача извлечения соотношений из текстов может решаться разными путями. Мы рассмотрели лишь некоторые, стараясь акцентировать внимание на доступных методах, и, как видно, на сегодняшний день, построить такой анализатор не так уж сложно.
Комментарии (7)
DKey
12.07.2015 10:56Стало интересно посмотреть, как наш синтаксический анализатор разбирает предложения. Получилось, например:
В комплекте помимо обычного ножа есть для пунктирной насечки.
По идее, Ваш метод будет точнее, если скрестить его с анализатором, натренировав CRF на авто-разметке.Durham Автор
12.07.2015 11:28К сожалению, картинка мне не видна
DKey
12.07.2015 12:21Ссылка ведёт на наш сервис, видимо, не всегда что-то срабатывает. Скопировал на внешний ресурс:
http://pasteboard.co/1TPnkJqt.png
elingur
Идея не нова, и, я считаю, перспективна в соотношении скорость/качество. Вопрос: какой объем выборки использовали для обучения? Каковы результаты точности и полноты? Кстати, почему у вас частица «не» стала предикатом?
Durham Автор
О новизне речи и не идет, мы просто рассказываем о полезном методе и показываем, что можно получить результаты быстро, с примером, исключительно в демонстрационных и учебных целях. Объем обучающей выборки указан в тексте статьи (100 предложений), тестовой 35 предложений. По причине столь малого объема данных точность и полноту в плане извлеченных фактов не считали. В плане аннотации последовательности, F1 для извлечения объектов получается где-то 59.7, но опять таки неопределенность в связи с маленькой выборкой велика. Задачей было убедится, что приводимый пример вообще работоспособен, и результаты имеют смысл. Что касается частицы не, мы решили объединить не_вываливается, не_совпадает и т.п. в одну сущность, поскольку других средств для учета отрицания в описанном методе не предусмотрено, и если их вводить, то придется добавлять еще усложнения.
elingur
Могу поделиться своим опытом. На CRF реализовано большинство лингвистических моделей: PoS-tagger (точность по F1 около 96%), NER — по трем типам сущностей — 92%, сентимент анализ (object-based) — 86%, и поверхностный синтаксис или разметка синтаксических ролей (то что у вас называется разметкой семантических ролей — это все-таки не семантические роли, ибо не несут смысла, а только определяют роль слова в предложении) — 98%. Обучение не выборке около 50 тыс.предложений, сентимент анализ — около 16 тыс. (все русский язык). Правда использовать только один параметр в CRF не выгодно, т.к. получается почти как SVM, можно и нужно варьировать сразу нескольким, чтобы добиться наилучшей точности.
Durham Автор
За информацию спасибо. Вообще на 50 тыс. предложений можно много чего сделать, это не новость, и мы в курсе общего положения дел. Тут мы писали для тех, у кого нет 50 тыс. размеченных предложений для своей задачи, о том как быть, и на что можно рассчитывать. Ну и кстати говоря, все это довольно чувствительно к области применения — NER на новостных текстах может показывать 92%, а на, скажем постах в форумах цифры сильно упадут. Также и с другими задачами.