Создание полноценного, "сильного" искусственного интеллекта — задача, далекая от завершения. Современная область ИИ, в том числе и обработка естественного языка, представляет, скорее, инструментарий со множеством подходов и методов.
В нашей прошлой статье [1], посвященной пониманию текстов, мы упоминали о существовании в NLP двух базовых подходов к анализу неструктурированной информации:
- Глубокие (deep) методы анализа стремятся сначала структурировать заданный текст целиком, привести его к нормальной форме, и только затем выявлять части (слова, словосочетания), подлежащие обработке.
- Поверхностные (shallow) методы ориентируются на анализ отдельных частей текста, а также статистических метриках.
В недавней статье на Хабрахабре [2] рассматривались технологии синтаксического анализа текстов (парсинга). Полноценный парсинг языка относится к глубоким методам обработки текстов, так как при этом строится дерево разбора, включающее взаимосвязи между вспомогательными словами. Применение таких тяжелых методов невыгодно для реальных бизнес-задач, так как любое приложение рано или поздно (а в ИИ — почти всегда рано) сталкивается с ограничениями производительности.
Как правило, объемы текстов в задачах извлечения информации (information extraction, IE) особенно большие. Это могут быть коллекции новостей, исторических записей, научных статей, собранных за десятилетия. Среди этих документов требуется найти имена, события, факты, даты, наименования организаций и т. д. Именно поэтому задача извлечения информации чаще всего решается с помощью поверхностных методов NLP. Далее мы рассмотрим эти методы от простых к сложным.
Регулярные выражения Пожалуй, самым простым подходом к задаче извлечения информации будет использование регулярных выражений. Предположим, что перед нами стоит задача разбора резюме, и в них фигурируют строки следующего вида:
IBM - Армонк, Нью-Йорк, США - Сентябрь 2003 - Ноябрь 2005
Microsoft Corp. | Редмонд, Вашингтон, США | с 04.2008 по 09.2009
Google Inc.<TAB>Маунтин-Вью, Калиф.<TAB> с сент. 2011 по янв. 2014
В этом случае даты мы можем извлечь даты начала и окончания работы на организацию с помощью регулярного выражения вида:
((\d{1,2}|\w{3,}).? ?(\d{2,4})) (-|по) ((\d{1,2}|\w{3,}).? ?(\d{2,4})) Этот подход будет эффективным в большинстве случаев, и вы даже сможете обойтись без сложных инструментов наподобие DateParser [4]. Кроме того, регулярные выражения могут применяться для предобработки текста. Например, зная, что даты обычно располагаются в первой строке описания каждого места работы кандидата, мы можем сегментировать исходный текст, а затем работать с каждой из частей по отдельности, что увеличит производительность.
Извлечение именованных сущностей
Более сложная проблема — извлечение имен и фамилий, городов, стран, а также названий организаций. Они начинаются с заглавной буквы, состоят из последовательности слов (между которыми часто встречаются запятые), каждое из которых может быть сколь угодно длинным. Перечисленные выше понятия в NLP принято называть именованными сущностями (
named entities), а соответствующие задачи обозначаются как извлечение именованных сущностей (
named entity recognition, NER) и связывание сущностей (
entity linking, NEL).
Базовым решением к проблеме NER служит газеттир. В узком смысле это словарь географических названий, а в широком — любой словарь часто встречающихся слов и словосочетаний. Зачастую именно от качества словарей зависит результат. Примером такого инструмента является пакет GeoText [5], предназначенный для выявления городов и соответствующих стран в тексте.
Немалую пользу в реальных приложениях приносит анализ слов текста на принадлежность к определенным частям речи (частеречная разметка,
part-of-speech tagging, POS-tagging). Современные инструменты NLP, такие как Stanford NLP, spaCy и NLTK умеют различать имена собственные (
proper nouns, тег "NNP") и нарицательные (
common nouns, тег "NN"). Например, объединив идущие подряд слова с тегом "NN" (см. рисунок) мы получим список всех именованных сущностей в тексте — останется только определить, что есть что.