Во всевозможных заявлениях, анкетах и обращениях пользователи вводят свои ФИО, адреса и прочие персональные данные в настолько разном формате, что даже человеку бывает сложно понять, где ошибки, а где правильное написание. Например, Саша Петрович — это имя с отчеством или фамилия с именем? А может, это сокращенная форма имени? И кто перед нами — мужчина или женщина?

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

Занимается разбором «Фактор» — наше собственное ПО для обработки контактных данных в «промышленных» объемах, — это когда имеются миллионы или даже сотни миллионов анкет или записей. «Фактор» умеет приводить адреса к формату ГАР/ФИАС, исправлять опечатки в ФИО и определять пол, находить оператора связи по номеру телефона, выявлять одноразовые адреса электронной почты, проверять поля документов физических лиц на корректность в связке с датой рождения.

10 лет я проработал в команде «Фактора», а сейчас силами своего R&D помогаю его развивать. Дальнейший рассказ о сложностях и особенностях подхода к подобного рода задачам я готовил вместе с программистом Дмитрием Серёгиным.

Что не так с пользовательскими данными

Ошибки в данных появляются повсюду: пользователи путают буквы, операторы торопятся, а программы для распознавания документов добавляют свои погрешности. И если вы думаете, что корректность данных легко определить, просто взглянув на них, вспомните кавээновский номер с Гадей Петрович. Это имя, отчество или фамилия? А может, псевдоним? С такими загадками мы сталкиваемся ежедневно.

Сценка с Гадей Петрович из КВН — яркий пример сложности стандартизации имен
Сценка с Гадей Петрович из КВН — яркий пример сложности стандартизации имен

В банках обычно ситуация лучше: они тщательно проверяют данные. А вот страховые компании, где данные поступают от агентов, или онлайн-сервисы, где пользователи заполняют все сами, не могут похвастаться идеальной чистотой. И конечно, особый шарм добавляют иностранные имена или редкие фамилии, которые могут выглядеть как что угодно. Например, Александр Сергеевич — это имя-фамилия или имя-отчество? Галина Сергеев — ошибка в ФИО или просто частая опечатка в отчестве Сергеевна?

Галина Иванов может быть записано в паспорте, если женщина взяла фамилию мужа «Иванов» в другом государстве. Но это также частая опечатка, когда не дописывают окончание фамилии.

Ащьф Лштшфум, он же — Foma Kiniaev, по версии режиссера фильма «Идентификация Борна», 2002 г.
Ащьф Лштшфум, он же — Foma Kiniaev, по версии режиссера фильма «Идентификация Борна», 2002 г.

Еще пара примеров: Галина Марина — где здесь имя, а где фамилия? А если Галина Галина — это имя-фамилия или дублирование? Строго говоря, Валентин Валентин Валентин — может быть корректным ФИО: фамилия на -ин, частое имя, недописанное отчество. А если добавить к этому, что в других странах структура имен может быть совсем иной, задача становится еще сложнее.

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

А еще есть справочник адресов от налоговой службы, который периодически меняет формат: когда-то был КЛАДР, затем ФИАС, а сейчас ГАР БД. Это добавляет нам задачек по поддержке новых форматов. Кстати. Для тех, кто использует в своих системах ФИАС, мы все еще выкладываем актуальные данные в формате «ФИАС на базе ГАР» в открытый доступ.

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

В конечном итоге стандартизация данных — это всегда поиск баланса. С одной стороны, формальные правила и алгоритмы помогают наводить порядок. С другой — реальная жизнь полна исключений и «особых случаев». Фильтр данных (так мы в «Факторе» называем каждый отвечающий за обработку того или иного типа данных алгоритм) должен быть достаточно умным, чтобы отличить ошибку от реальной уникальной записи, закрепленной в документах. А нам остается тюнинговать правила, чтобы они решали эти задачи быстро и точно.

Нюансы подготовки данных для алгоритмов стандартизации имен

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

Подготовка данных начинается с устранения лишних или дублирующихся элементов, исправления форматов и приведения структуры к единому виду. Например, может потребоваться изменить порядок компонентов ФИО или убрать лишние символы. Мы также учитываем особенности конкретных источников данных — от внутренних баз до файлов, предоставленных клиентами.

Фрагмент конфигурационного файла, где мы отключаем часть автозамен
Фрагмент конфигурационного файла, где мы отключаем часть автозамен

На этапе настройки важно определить, какие ошибки можно исправлять автоматически, а какие нужно оставлять в исходном виде. Например, если ошибка закреплена в официальных документах (как в случае с фамилией «Бекмомбетов» вместо «Бекмамбетова»), данные остаются неизменными. Для таких случаев мы добавили функцию, которая предлагает варианты исправлений без автоматического вмешательства. Оператор принимает финальное решение, сверяя данные с оригинальными документами.

Разбор и стандартизация имен

Для обработки мы используем собственные справочники, основанные на открытых данных. Но даже при их наличии часто неясно, где имя, где фамилия, а где отчество и в каком они порядке. Бывают сложные случаи с двойными фамилиями или длинными комбинациями компонентов. Например, в нашей практике встречались ФИО из восьми слов: Бдур Самир Реда Мансур Камаль Эль Хафи Давуд. Однако такие случаи редки — порядка одного на 30 000 записей. В то же время в базе, где 100 миллионов ФИО, наберется несколько тысяч подобных имен. Все они требуют особого внимания, и алгоритм должен их корректно обрабатывать. К тому же среди иностранцев бывает много VIP-клиентов, которыми заказчики дорожат.

Алгоритм подбирает наиболее подходящий формат для ФИО, будь то стандартная схема «фамилия — имя — отчество» или более сложные варианты. Например, для тюркских ФИО используются специфические правила, учитывающие такие компоненты, как Кызы, Углу, Заде или Баласы. В среднем около 1% записей относятся к этому типу ФИО, но точное распределение зависит от региона.

Уменьшительные формы, такие как «Саша», тоже добавляют сложности. «Саша» может быть краткой формой имени «Александр», а может быть полноценным именем, особенно на Западе (например, у известных личностей). Унисекс-имена, такие как «Саша Николенко», требуют дополнительной информации для определения пола. Здесь нам помогают отчества или данные из других полей.

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

Как работает алгоритм разбора имен

Алгоритм принимает на вход строку с фамилией, именем и отчеством (ФИО) либо отдельные компоненты. Формат данных может быть произвольным, что часто усложняет их стандартизацию.

1. Разделение на токены

Сначала строка разбивается на токены — слова, разделенные пробелами, слешами или точками. Например, строка «Иванов Валентин Иванович» будет разделена на три токена: «Иванов», «Валентин» и «Иванович».

2. Поиск в справочниках

Каждый токен проверяется в справочниках для фамилий, имен и отчеств. Если найдено точное совпадение, процесс не заканчивается: алгоритм продолжает поиск, проверяя варианты с учетом опечаток, замен и других возможных отклонений.

Например, токен «Валентин» сначала находится как мужское имя. Алгоритм дополнительно проверяет, не является ли это опечаткой, и находит женский вариант — «Валентина». Аналогично с фамилиями: если в строке «Валентин Иванов» фамилия «Иванов» найдена в справочнике, но отчество отсутствует, алгоритм предполагает возможность его восстановления как «Иванович». На финальном этапе наименее вероятные варианты отбрасываются.

Чтобы алгоритм не сбивался, используются так называемые справочники мусора. Они помогают отсеивать лишние или нерелевантные токены — например, служебные слова, некорректные символы или очевидные ошибки, которые не относятся к компонентам ФИО.

Список используемых справочников. На момент написания статьи в них суммарно 1 480 000 записей
Список используемых справочников. На момент написания статьи в них суммарно 1 480 000 записей

В итоге для каждого токена будет список вариантов, чем он может являться на самом деле.

Для токена «Валентин» подберет:

  • Валентин, имя, мужское, справочное, без опечаток

  • Валентина, имя, женское, справочное, с опечаткой

  • Валентин, фамилия, мужская, НЕсправочная (по окончанию ИН)

  • Валентинович, отчество, мужское, справочное, по замене

  • Валентиновна, отчество, женское, справочное, по замене

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

3. Перебор комбинаций

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

4. Выбор наилучшего варианта

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

  • пол каждого компонента;

  • точность совпадения: определили тип компонента по справочникам, по алгоритму Левенштейна с разницей в одну букву или по окончанию, 

  • вероятность комбинации «фамилия — имя — отчество» самое вероятное, а «отчество — фамилия — имя» — наименее;

  • наличие специфических элементов, таких как префиксы и суффиксы иностранных ФИО.

5. Форматирование и окончательная стандартизация

После выбора структуры данные форматируются. Система может исправлять опечатки или сохранять оригинальные значения в зависимости от настроек. На этом этапе также производится попытка определить пол клиента.

6. Маркеры для оценки качества

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

Например, маркеры UNLIST (данные не найдены в справочнике) и VERY_FEW_UNIQUE_LETTERS (слишком много одинаковых букв) по отдельности еще не указывают на проблему. Однако их сочетание часто сигнализирует, что разбор может быть некорректным, и данные лучше показать оператору.

Новые маркеры, которые мы применяем в разборе имен. Например, ABBR_MISPRINT ставится, когда сокращенное отчество было дополнено; GEN_EXCEPT — ФИО встретилось в основном справочнике исключений; CUST_EXCEPT — ФИО нашлось в справочнике исключений заказчика
Новые маркеры, которые мы применяем в разборе имен. Например, ABBR_MISPRINT ставится, когда сокращенное отчество было дополнено; GEN_EXCEPT — ФИО встретилось в основном справочнике исключений; CUST_EXCEPT — ФИО нашлось в справочнике исключений заказчика

Эта система позволяет не только минимизировать ошибки, но и автоматизировать этапы анализа, оставляя операторам только действительно проблемные случаи.

Как эволюционировала система разбора имен

Мы тюним этот алгоритм уже ~20 лет. Первая версия из тех, код которых остался в истории коммитов, появилась в 2007 году. Сегодня это уже четвертая реинкарнация модуля обработки ФИО и пола. Начинали мы с простых решений, которые со временем становились все сложнее и умнее.

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

В какой-то момент у нас появилась локальная шутка, сопровождающая релизы: «1000 и 1 способ ничего не менять в ФИО».

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

Каждая новая версия фильтра все меньше «исправляла» ошибки, но одновременно становилась точнее. Полностью отказаться от функционала исправлений никто не хочет — корректные данные по-прежнему важны, но теперь мы больше внимания уделяем сохранению оригинальных записей, особенно если они закреплены в официальных документах.

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

Плюсы

Минусы

Программист больше не нужен: достаточно было добавить новые кейсы в обучающую выборку и запустить генерацию.

Генерация занимала слишком много времени: иногда час, а иногда всю ночь.

На обучающих кейсах все работало идеально, но с новыми данными алгоритм был настолько нестабилен, что стал проигрывать ручным правкам программистов.

Третья версия. От алгоритмов в привычном понимании пришлось отказаться. Вместо них начали использовать атрибуты для каждого токена. Например, токен может быть мужским именем, женским именем, отчеством, фамилией, тюркским суффиксом или инициалом. Все данные превращались в векторы атрибутов. На основе обучающей выборки определялся шаблон ФИО, например: LLFM (первые два слова — фамилия, третье — имя, четвертое — отчество).

Плюсы

Минусы

Полностью избавились от вмешательства программиста.

Исправления стали локальными и не нарушали остальные кейсы.

Обучающая выборка стала огромной.

Если возникал контрпример, требующий нового атрибута, это увеличивало объем выборки в разы.

Постоянно возникал вопрос: можно ли это вообще назвать «обучением», если процесс обучения как таковой отсутствует?

Четвертая версия. Современная версия объединила сильные стороны предыдущих подходов:

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

  • Сложные кейсы разбираются на основе обучающей выборки, которая анализирует векторы атрибутов и подбирает для них шаблоны.

  • Для специфических случаев, таких как азиатские имена, добавлены отдельные ветки алгоритма, которые учитывают культурные и этнические особенности.

Такой гибридный подход позволяет эффективно обрабатывать данные, избегать нестабильности, характерной для первых версий, и минимизировать ошибки, делая систему устойчивой и гибкой.

Разбор и стандартизация адресов

Если в случае ФИО нужно разложить 3–7 слов по трем категориям — фамилия, имя, отчество, то с адресами задача масштабируется: нужно правильно распределить 5–15 слов по 20+ позициям.

Добавим сюда пользовательские ошибки, где встречаются устаревшие значения или пропуски фрагментов — и вот вам адрес вроде «мск ул тполева 9,4,23, позвонить от турникета», который на деле должен стать «город Москва, набережная академика Туполева, дом 9 строение 4 квартира 23».

Какие проблемы встречаются:

  • Опечатки: вместо «Никольская» — «Николькая». А варианты написания Космодамианской набережной мы уже коллекционируем.

  • Переименования: например, Калининград Московской области — это уже Королёв. А Ростов скоро станет Ростовом Великим. 

  • Синонимы и сокращения: «Москва» пишут как «МСК», а «Большая» сокращают до «Б.».

  • Пропуски и лишние слова: «улица Челомея» или «улица Ивана Ремизова».

  • Ошибки в типах: вместо «Гоголевский бульвар» пишут «Гоголевский проспект».

  • Транслитерация: «Ставропольская» превращается в «Stavropolskaya».

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

Кроме исправления ошибок важна и скорость. В оригинале справочники весят больше 40 гигабайт, но ключевые части мы держим в оперативной памяти, что позволяет обрабатывать тысячи запросов в секунду. Один адрес разбирается за миллисекунды, что критично для крупных систем.

Адреса — это всегда поиск баланса между автоматизацией и реальной хаотичностью данных. Мы учитываем региональные особенности, автоматически подхватываем новые версии справочников, которые обновляются два раза в неделю, и добавляем маркеры, помогающие понять, где данные требуют уточнений. Все это позволяет адаптироваться к реальным сценариям и делать работу с адресами не только точной, но и быстрой.

Кроме разбора и стандартизации может возникнуть задача в преобразовании формата — например, в формат Почты России, где адрес делится на три строки: 

POST_STREET_OTHER — тип улицы, улица, дом, расширение дома;

POST_CITY_SETTLEMENT_DISTRICT — тип города, город, тип НП, НП, район, тип района;

POST_SUBJECT — субъект, тип субъекта.

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

Основные принципы валидации результатов

Создать алгоритм, который просто парсит адреса с точностью 50–60%, — это задача на несколько чашек кофе. Опытный разработчик за неделю или месяц может настроить базовую систему, которая справится с большинством тривиальных случаев. Но вот довести точность до 90% — гораздо сложнее. Тут начинаются месяцы, а иногда годы доработок.

Однако и 90% точности в реальных условиях бизнеса, например в банке, никого не устроят. Миллионы записей все равно придется перепроверять вручную, так как каждая ошибка в данных может обернуться убытками. Вот тут-то и появляется необходимость валидации результата разбора. Это не просто проверка, правильно ли алгоритм обработал данные, а создание системы, которая разделяет результаты на две категории: гарантированно корректные и сомнительные.

  1. Гарантированные данные: эти адреса можно сразу использовать в бизнес-процессах, не привлекая операторов.

  2. Сомнительные данные: требуют дополнительной проверки.

Два типа ошибок, которые отслеживает валидация:

  1. Ошибка первого рода: корректно разобранный адрес помечается как сомнительный. Это увеличивает объем работы операторов, но никак не влияет на качество данных.

  2. Ошибка второго рода: некорректно разобранный адрес принимается за корректный. Это куда критичнее, ведь такие данные могут уйти в продакшен, где уже никто их не проверяет.

Для нас важно минимизировать именно второй тип ошибок. Мы гарантируем, что вероятность таких ситуаций — не чаще одной на 10 тысяч записей. А вот ошибки первого рода, хотя и менее критичны, стараемся свести к минимуму, чтобы не перегружать операторов.

Как работает система валидации
Алгоритм разбора адресов дополнен системой статусов, которая оценивает качество результатов:

  • «Неразобранные части»: если в строке остались элементы, которые алгоритм не смог сопоставить с известными шаблонами.

  • «Неоднозначные адреса»: если система не может однозначно выбрать между несколькими вариантами разбора.

Сложные случаи часто помечаются одним статусом — «эмби-адрес», указывая на неоднозначность данных. Для уточнения запускается 15 автоматических тестов, которые выявляют проблемы — например, путаницу между номером дома и улицы. Это помогает находить слабые места в разборе.

Валидация данных и алгоритмов
Важно понимать, что есть два уровня валидации:

  1. Валидация данных: например, проверка контрольных сумм ИНН или других цифровых атрибутов.

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

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

Валидация и проверка точности данных

Разделить данные на части и привести их к единому формату — это только полдела. Важно понять, насколько результат надежен, чтобы избежать неприятных сюрпризов.

Раньше в нашем адресном фильтре парсер и валидатор работали раздельно. Парсер разбирал строку, а валидатор проверял, насколько это разбиение было корректным, не заглядывая «внутрь». Это помогало оставаться объективными, но не всегда справлялось с хитрыми случаями.

Теперь мы используем более быстрый подход с эвристиками, которые подсказывают, где что-то пошло не так. Например:

  • Если в строке остались неиспользованные части, как в «САНКТ-ПЕТЕРБУРГ, ДИБУНЫ, ПИОНЕРСКАЯ, 11», это сигнал к проверке.

  • Когда система не может выбрать между вариантами, как в «гор. Москва, Курчатова, 12, 25» (улица или площадь?), — данные помечаются как неоднозначные.

  • Если в адресе пропущен город, как в «Шоссе Бабигонское», — это может создать проблемы, даже если разбор вроде бы правильный.

  • Или, скажем, подозрительно длинный номер дома, например «МОСКВА, ФЕСТИВАЛЬНАЯ, 4057», вызывает вопросы.

Эти проверки не просто выявляют слабые места, но и экономят время операторам. К тому же они помогают настроить алгоритм так, чтобы избегать повторения ошибок.

Для других типов данных, как ФИО или телефоны, мы используем аналогичный подход. Если что-то выглядит странно, данные помечаются статусом «на ручной разбор» — это лучше, чем автоматически вносить некорректные правки. Такой баланс между автоматизацией и контролем позволяет находить и исправлять сложные случаи без потери качества.

Пара слов про разбор телефонных номеров

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

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

Кроме того задействуются фильтры несуществующих или мусорных номеров типа «111111111», а также проверяется соответствие длины телефона системе нумерации населенного пункта.

ML и AI

Неверно полагать, что внедрение ML и AI решит все проблемы с обработкой данных. В реальности все сложнее.

Мы используем подходы с обучающими выборками, которые помогают алгоритмам принимать более точные решения. Однако это еще не полноценный ML: выборка обучает систему определять, какой вариант разбора предпочтительнее. Такой подход работает эффективно, без необходимости подключения мощных графических процессоров (GPU).

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

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

Итоги

Так случается, что простые с виду задачи по объективным причинам могут перерастать в длительные процессы шлифовки алгоритмов и подходов. Это происходит, например, там, где качество обработки многомиллионных баз должно быть на уровне 99,9% и более, в то время как базовые подходы дают лишь 60–70%, оставляя те же миллионы записей для ручной обработки и валидации, и ни один заказчик с таким качеством не согласится.

Что касается самого процесса разбора, то к справочникам и первичной стандартизации данных добавляется обязательный процесс валидации. Он позволяет определить, где нужны дополнительные проверки для минимизации ошибок. А прозрачность процессов достигается за счет маркеров и статусов, делая результаты понятными и управляемыми. И примерно по этой схеме находится баланс между автоматизацией и ручной проверкой.

Комментарии (2)


  1. Timosha_Kulikov
    23.12.2024 11:58

    Даже не читал еще статью, но с точки зрения маркетинга и качества превью - гениально.


  1. sshikov
    23.12.2024 11:58

    Если что-то выглядит странно, данные помечаются статусом «на ручной разбор»

    Не исключаю что я что-то невнимательно прочитал, но когда я реально пользовался Фактором для разбора миллионов адресов (несколько лет назад), именно вот эта часть была самой слабой. Потому что такого статуса недостаточно. Нужно максимально четкое пояснение, что именно пошло не так. Ну т.е. имеет место неоднозначность? Какая конкретно? Дублирование? Где? Ну т.е. на примере:

    Москва, Курчатова, 12, 25

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