@xebav10477

Как парсить очень сложный текст?

Как парсить очень сложный, нелогичный текст? К примеру на сайте службы доставки есть районы, где они работают:

город Москва: ул. Таллинская; улица Твардовского, Туркменский проспект (дома с 1 по 31). Серебряноборское лесничество


Здесь мы видим, что улицы разделяются как попало, нет определенного знака. Еще вклиниваются всякие примечания типа "с дома 1 по 31", могут и в скобках, а могут после запятой, как будто это уже новая улица. Еще может включаться всякий шум: "на берегу Москвы-реки..." и т. д.

Задача - скопировать эти улицы, вместе с примечаниями, игнорируя всякие шумы.

Как я понимаю, регулярками тут очень трудно обойтись? Тогда копать в сторону нейросетей и ML? Я пробовал NER (Named Entity Recognition) у Azure но кажется там нельзя обучать ее, она ищет только так как ее обучали разработчики. Обучать тогда самому? Или есть какие-то решения?
  • Вопрос задан
  • 451 просмотр
Решения вопроса 1
trapwalker
@trapwalker
Программист, энтузиаст
Если вы хотите что-то парсить, это значит, что этого "чего-то" очень-очень много. Тем более, если хотите применять ML. В этом случае нужна еще и обучающая выборка, где есть много-премного примеров входных данных в размеченном виде.
К примеру на сайте службы доставки есть районы, где они работают

Из вопроса не ясно сколько "грязных" данных есть. Неужели на одном единственном сайте службы доставки НАСТОЛЬКО много адресов в таким виде? Или таких сайтов миллион?
Паресеры и ML превосходят возможности человеческой обработки только на больших, очень больших масштабах.

Из вашего вопроса складывается впечатление, что вы спрашиваете как сделать некий парсер, который будет парсить ЛЮБЫЕ грязные данные произвольного вида и типа в любых количествах.
Детализируйте свой вопрос, Показывайте больше примеров.

Сильного ИИ ещё не существует (а когда появится, он будет не менее ленив, чем те, кому призван помогать).

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

Постройте пайп-лайн так, чтобы изменения, внесённые каждым шагом можно было анализировать в виде диффа. Сделайте отдельный аналитический "вью", где будут видны только затронутые правкой ступени данные. Сразу видно будет косяки и калечащие изменения.
Считайте статистику правок каждой ступенью, реагируйте на крайней случаи.
Важно, что на каждом этапе энтропия датасета должна уменьшаться. Любая потеря данных вредна, поскольку заметить, скажем, что у вас "г." обозначает не только город, но и, к примеру, "гражданский" в большом количестве топонимов в конце обработки -- это фатально. Вы запутаетесь. Нужно выносить удаляемые данные в отдельные поля и оставлять возможность делать по ним анализ на более поздних этапах.
В целом исходный датасет у вас всегда созранён и всегда можно быстро повторить шаги.
Сохраняйте этапы написания парсера в системе контроля версий, делайте чаще коммиты с внятными описнаиями.
И да хранит вас Кнут и Страуструп.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
alternativshik
@alternativshik
Проще и быстрее нанять 10 школьников, которые руками скопируют и разделят текст на нужные улицы-дома.
Ответ написан
Комментировать
mmmaaak
@mmmaaak
Можно воспользоваться сервисами, типа dadata, краем глаза видел в одном проекте, что они умеют парсить такие адреса на составляющие, потом из объекта просто выцепляешь нужные тебе поля, нужно только изучить насколько это финансово подходит, мб у них есть бесплатные лимит запросов, если это критично, ну или искать их аналоги
Ответ написан
Комментировать
solotony
@solotony
покоряю пик Балмера
это называется NLP или NLU

я сейчас решаю аналогичную задачу, вижу следующий подход (если есть гуру - покритикуйте)

город Москва: ул. Таллинская; улица Твардовского, Туркменский проспект (дома с 1 по 31). Серебряноборское лесничество

1) предварительная обработка текста фильтрами
город [имя] [.] ул [имя] [.] улица [имя] [.] [имя] [.] проспект дома с 1 по 31 [имя] [.] лесничество

2) вытаскивание значений
город [имя] ул [имя] [.] улица [имя] [.] [имя] [.] проспект дома [диапазон] [.] [имя] лесничество

3) нормализация
город [имя] [.] улица [имя] [.] улица [имя] [.] [имя] проспект дом [диапазон] [.] [имя] лесничество

если у вас тематика фиксирована, то можно выделить какие-то маркерные слова, в вашем случае это виды гео-объектов

[геообъект] [имя] [.] [геообъект][имя] [.] [геообъект] [имя] [.] [имя] [геообъект] [геообъект] [диапазон] [.] [имя] [геообъект]

4) обработка на предмет выделения смысловых токенов
город [имя]
улица [имя]
улица [имя]
[имя] проспект дом [диапазон]
[имя] лесничество

последний пункт может решаться как алгоритмически, так и при помощи НС. это уже надо смотреть насколько регулярный сам текст. поскольку у вас есть разделители в конкретном примере все тривиально решается
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы