{"id":14276,"url":"\/distributions\/14276\/click?bit=1&hash=721b78297d313f451e61a17537482715c74771bae8c8ce438ed30c5ac3bb4196","title":"\u0418\u043d\u0432\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043b\u044e\u0431\u043e\u0439 \u0442\u043e\u0432\u0430\u0440 \u0438\u043b\u0438 \u0443\u0441\u043b\u0443\u0433\u0443 \u0431\u0435\u0437 \u0431\u0438\u0440\u0436\u0438","buttonText":"","imageUuid":""}

Точный адрес, пожалуйста

Многие аналитики данных сталкиваются с задачей распознавания адресов, напечатанных на документах.

Для решения этой задачи я обратился к инструментам выявления сущностей в тексте с помощью NLP: NLTK, Spacy, Flair, DeepPavlov, Polyglot, AdaptNLP, Stanza, AllenNLP, HanLP, PullEnti, Natasha и т. д. Глаза начали разбегаться. И что же делать? Конечно, выбрать самое лучшее. Я выбрал несколько самых популярных библиотек, поддерживающих русский язык, и сравнил, какую же из них использовать — Natasha, Stanza и Pullenti. Далее пойдет речь именно об этих библиотеках.

  1. Stanza

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

Использование:

#Импорт Stanza import stanza # Скачивание требуемой модели stanza.download('ru') # инициализация нейронной модели nlp = stanza.Pipeline('ru') #Текст, содержащий адреса text = "текст текст текст Россия, Воронежская обл., г. Воронеж, Ленинский р-н, ул. 9 Января, д. 88к текст текст текст" #Извлечение адреса из текста doc = nlp(text) #Цикл для вывода адреса в удобной форме for el in doc.sentences: for ent in el.entities: if (ent.type in ('LOC')): print (ent.text,' ',ent.type)

Результат:

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

2. Natasha

Natasha решает основные задачи NLP для русского языка: токенизация, сегментация предложений, встраивание слов, разметка морфологии, лемматизация, нормализация фраз, разбор синтаксиса, разметка NER, извлечение фактов.

Использование:

#Импортируем необходимые модули из Natasha и объявляем переменные from natasha import ( Segmenter, MorphVocab, LOC, AddrExtractor ) segmenter = Segmenter() morph_vocab = MorphVocab() addr_extractor = AddrExtractor(morph_vocab) #Текст, содержащий адреса text = "текст текст текст Россия, Воронежская область, г. Воронеж, район Ленинский, ул. 9 Января, д. 88к текст текст текст" #Извлечение адреса из текста matches = addr_extractor(text) facts = [i.fact.as_json for i in matches] #Цикл для вывода адреса в удобной форме for i in range(len(facts)): tmp = list(facts[i].values()) print(tmp[1], tmp[0])

Результат:

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

3. Pullenti

Pullenti предназначено для разработчиков информационных систем, имеющих дело с неструктурированными данными — текстами на естественном языке. Это программное обеспечение с открытым исходным кодом представлено на языках программирования C#, Java, Python и JavaScript.SDK состоит из трёх независимых друг от друга частей:

  • Lingvo — лингвистический анализ текстов,
  • Unitext — выделение текстов из файлов,
  • Address — выделение из текста адресов и их привязка к ГАР ФИАС.

Использование:

#Импортируем необходимые модули из Pullenti и объявляем переменные from pullenti_wrapper.langs import ( set_langs, RU ) set_langs([RU]) from pullenti_wrapper.processor import ( Processor, GEO, ADDRESS ) from pullenti_wrapper.referent import Referent processor = Processor([GEO, ADDRESS]) #Текст, содержащий адреса text = "текст текст текст Россия, Воронежская область, г. Воронеж, Ленинский р-н, л. 9 Января, д. 88к текст текст текст" #Функция формирования словаря с адресами def display_shortcuts(referent, level=0): tmp = {} a = "" b = "" for key in referent.__shortcuts__: value = getattr(referent, key) if value in (None, 0, -1): continue if isinstance(value, Referent): display_shortcuts(value, level + 1) else: if key == 'type': a = value if key == 'name': b = value # print('ok', value) if key == 'house': a = "дом" b = value tmp[a] = b if key == 'flat': a = "квартира" b = value # print('ok', value) tmp[a] = b if key == 'corpus': a = "корпус" b = value tmp[a] = b tmp[a] = b addr.append(tmp) #Использование функции display_shortcuts и вывод результатов addr = [] result = processor(text) referent = result.matches[0].referent display_shortcuts(referent) print(addr)

Результат:

Pullenti имеет более лучшие показатели в задаче распознавания адресов при сравнении с конкурентами. Одним из плюсов является то, что в тексте осуществляется поиск адреса и привязка к объектам из ГАР ФИАС. То есть если адрес распознался, то значит он точно существует. Но Pullenti все-таки не лишен зависимости от расположения ключевых слов и их сокращений. В качестве приятного бонуса Pullenti имеет демонстрацию возможностей библиотеки, которую вы можете увидеть, перейдя по ссылке.

Для реализации всех примеров использования библиотек пришлось расширить программный код и обогатить исходный словарь новыми элементами.

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

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

0
Комментарии
-3 комментариев
Раскрывать всегда