. Yargy-парсер и библиотека Natasha. Извлечения структурированной информации из текстов на русском языке
Yargy-парсер и библиотека Natasha. Извлечения структурированной информации из текстов на русском языке

Yargy-парсер и библиотека Natasha. Извлечения структурированной информации из текстов на русском языке

В 2020 году библиотека Natasha значительно обновилась, на Хабре опубликована статья про актуальную версию. Чтобы использовать инструменты, описанные в этом тексте, установите старую версию библиотеки pip install natasha<1 yargy<0.13 .

Раздел про Yargy-парсер актуален и сейчас.

Есть стандартная задача извлечения именованных сущностей из текста (NER). На входе текст, на выходе структурированные, нормализованные объекты, например, с именами, адресами, датами:

Задача старая и хорошо изученная, для английского языка существует масса коммерческих и открытых решений: Spacy, Stanford NER, OpenNLP, NLTK, MITIE, Google Natural Language API, ParallelDots, Aylien, Rosette, TextRazor. Для русского тоже есть хорошие решения, но они в основном закрытые: DaData, Pullenti, Abbyy Infoextractor, Dictum, Eureka, Promt, RCO, AOT, Ahunter. Из открытого мне известен только Томита-парсер и свежий Deepmipt NER.

Я занимаюсь анализом данных, задача обработки текстов одна из самых частых. На практике оказывается, что, например, извлечь имена из русского текста совсем непросто. Есть готовое решение в Томита-парсере, но там неудобная интеграция с Python. Недавно появилось решение от ребят из iPavlov, но там имена не приводятся к нормальной форме. Для извлечения, например, адресов («ул. 8 Марта, д.4», «Ленинский проезд, 15») открытых решений мне не известно, есть pypostal, но он чтобы парсить адреса, а не искать их в тексте. C нестандартными задачами типа извлечения ссылок на нормативные акты («ст. 11 ГК РФ», «п. 1 ст. 6 Закона № 122-ФЗ») вообще непонятно, что делать.

Год назад Дима Веселов начал проект Natasha. С тех пор код был значительно доработан. Natasha была использована в нескольких крупных проектах. Сейчас мы готовы рассказать о ней пользователям Хабра.

В статье показано, как использовать готовые правила из Natasha и, самое главное, как добавлять свои с помощью Yargy-парсера.

Готовые правила

Сейчас в Natasha есть правила для извлечения имён, адресов, дат и сумм денег. Есть ещё правила для названий организаций и географических объектов, но у них не очень высокое качество.

Имена

Воспользоваться готовыми правилами просто:

В 2016 году проходило соревнование factRuEval-2016 по извлечению именованных сущностей. Среди участников были крупные компании: ABBYY, RCO. У топовых решений F1-мера для имён была 0.9+. У Natasha результат хуже — 0.78. Проблема в основном c иностранными именами и сложными фамилиями, например: «Харуки Мураками», "… главой Афганистана Хамидом Карзаем", «Остап Бендер встречается с Кисой Воробьяниновым . ». Для текстов с русскими именами качество получается

0.95. Можно, например, извлекать имена учителей с сайтов школ, агрегировать отзывы:

Адреса

Интерфейс такой же как для имён, только NamesExtractor меняется на AddressExtractor :

В factRuEval-2016 участникам предлагалось извлекать имена, названия организаций и географические объекты. Независимых тестовых данных для оценки качества работы с адресами, на сколько я знаю, не существует. За несколько лет работы у нас накопились сотни тысяч строк вида «Адрес: 443041 г. Самара ул. Ленинская, д.168», «Адрес г. Иркутск, ул. Байкальская, д. 133, офис 1 (вход со двора).». Для оценки качества сделана случайная выборка из 1000 адресов, результаты проверены вручную,

90% строк обработались корректно. Проблемы возникают, в основном, с названиями улиц, например: «г. Волжск, 2-ая промышленная, стр. 2», «111674, г. Москва, Дмитриевского, д. 17».

В 2017 году параллельно с историей про реконструкцию в Москве обсуждались новые Правила землепользования и застройки (ПЗЗ). Был проведён опрос населения. Более 100 000 комментариев были выложены в открытый доступ в виде огромного pdf-файла. Никита Кузнецов с помощью Natasha извлёк упомянутые адреса и посмотрел в каких районах закон поддерживают, а в каких нет:

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

Другие правила

Ещё в Natasha есть правила для дат и денег. Интерфейс такой же как у AddressExtractor и NamesExtractor .

Интерфейс Natasha очень простой: e = Extractor(); r = e(text); . . Пользователю недоступны никакие настройки. На практике обойтись только готовыми правилами получается редко. Например, Natasha не разберёт дату "«21» апреля 2017", потому что в правилах не предусмотрен номер дня в кавычках. Библиотека не разберёт адрес «Люберецкий район, деревня Мотяково, д. 61/2», потому что в нём нет названия улицы.

Часто приходится опускаться на уровень ниже, дополнять готовые правила и писать свои. Для этого использует Yargy-парсер. Все правила в Natasha написаны на нём. Yargy — сложная и интересная библиотека, в этой статье мы рассмотрим только простые примеры использования.

Yargy-парсер

Yargy-парсер — аналог яндексового Томита-парсера для Python. Правила для извлечения сущностей описываются с помощью контекстно-свободных грамматик и словарей.

Грамматики

Грамматики в Yargy записываются на специальном DSL-е. Так, например, будет выглядеть простое правило для извлечения дат в ISO-формате («2018-02-23», «2015-12-31»):

Пока не очень впечатляет, похожую функциональность можно получить регуляркой r'\d\d\d\d-\d\d-\d\d' , правда она будет метчить ерунду типа «1234-56-78».

Предикаты

gte и lte в примере выше — предикаты. В парсер встроено много готовых предикатов, есть возможность добавить свои. Для определения морфологии слов используется pymorphy2. Например, предикат, gram('NOUN') срабатывает на существительных, normalized('январь') метчит все формы слова «январь». Добавим правила для дат вида «8 января 2014», «15 июня 2001 г.»:

Интерпретация

Найти подстроку с фактом обычно недостаточно. Например, для текста «8 мая по поручению президента Владимира Путина» парсер должен вернуть не просто «8 мая», «Владимира Путина», а Date(month=5, day=8) , Name(first='Владимир', last='Путин') , для этого в Yargy предусмотрена процедура интерпретации. Результат работы парсера — это дерево разбора:

(R0, R1 — технические вершины, «R» сокращение от «Rule»)

Для интерпретации пользователь «развешивает» на узлы дерева пометки с помощью метода .interpretation(. ) :

Нормализация

В примере с датами нужно привести названия месяцев, дни и годы к числам, для этого в Yargy встроена процедура нормализации. Внутри .interpretation(. ) пользователь указывает, как нормировать поля:

Ура, мы повторили маленький кусочек функциональности библиотеки dateparser. Если нужно извлечь из текста, например, только даты, то стоит выбрать готовую специализированную библиотеку. Решение будет работать быстрее, качество будет выше. Yargy нужен для объёмных, нестандартных задач.

Согласование

Рассмотрим простое правило для извлечения имён. В словаре Opencorpora, который использует pymorphy2, для имён ставится метка Name , для фамилий — метка Surn . Будем считать именем пару слов Name Surn или Surn Name :

У такого решения есть две проблемы:

1. Правило метчит имя и фамилию в разных падежах («Иванова Лёша», «Петрову Ромой») 2. Женские фамилии после нормализации становятся мужскими

Чтобы решить эти проблемы в Yargy есть механизм согласования. С помощью метода .match(. ) пользователь указывает ограничения на правила:

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

Natasha предоставляет под лицензией MIT решения, которых раньше не было в открытом доступе (или я о них не знаю). Например, раньше нельзя было просто взять и извлечь структурированные имена и адреса из русскоязычного текста, а теперь можно. Раньше для Python не было чего-то вроде Томита-парсера, теперь есть.

  1. Вручную составленные правила. Natasha разбирает только те словосочетания, для которых заранее были составлены правила. Может показаться, что нереально написать правила, например, для имён в произвольном тексте, слишком они разные. На практике всё не так плохо:
    1. Если посидеть недельку, то всё-таки для 80% имён составить правила можно.
    2. Обычно нужно работать не с произвольными текстами, а с текстами на контролируемом естественном языке: резюме, решения судов, нормативные акты, раздел сайта с контактами.
    3. В правилах для Yargy-парсера можно использовать разметку, полученную методами машинного обучения.

    Ссылки

    Адрес проекта на Гитхабе простой — github.com/natasha.

    Установка — pip install natasha . Библиотека тестируется на Python 2.7, 3.3, 3.4, 3.5, 3.6, PyPy и РyPy3.