Что за страшный зверь этот фасетный поиск и почему он пока не заменит полнотекстовый
Как сделать так, чтобы голосовой помощник меньше переспрашивал адрес у пользователей? Можно внедрить фасетный поиск, который разбивает адрес на части и позволяет доспрашивать только недостающую информацию! Вот только при тестировании качество распознавания упало на 16%. С какими неожиданными сложностями мы столкнулись и как их решили — рассказываем в статье.
Замечали ли вы, что на некоторых сайтах нужно заполнять каждое поле адреса по отдельности, выбирая значение из выпадающего окошка? Мы подумали: что если использовать этот подход в нашем адаптере ГАР?
Что такое адаптер ГАР и зачем ему апгрейд
ГАР или Государственный адресный реестр — это база адресов России, на основе которой определяется уникальный код (ID) адреса для доставки или вызова врача на дом. ID можно получить для разных уровней адреса — от просто области до квартиры или даже комнаты в коммуналке. Всего есть 13 уровней элементов адреса.
Адаптер ГАР помогает найти в этой базе нужный адрес, произнесенный человеком в свободной форме. То есть абоненту не обязательно произносить все части адреса: если вы скажете «Тула, Горького 10, квартира 13», адаптер поймет, что это «Тульская область, городской округ город Тула, город Тула, улица М. Горького, дом 10, квартира 13».
В первых двух версиях адаптера мы использовали полнотекстовый поиск: система искала в базе строку, которая больше всего похожа на ту, что произнес пользователь.
Недостатки полнотекстового поиска
- Если система не смогла найти адрес из-за того, что пользователь дал неполную информацию — нельзя узнать, чего именно не хватило для корректного определения.
- Если пользователь сообщает слишком много информации, очень сложно отыскать максимально похожую строку в базе.
- Любая опечатка или ошибка распознавания резко снижает шансы найти адрес в базе.
Поэтому, если система не находила адрес, приходилось просить пользователя назвать свой адрес еще раз полностью. Не так уж «user friendly», да?
Во второй версии адаптера мы снизили процент ошибок из-за опечаток и неверного распознавания с помощью нормализации текста через модель NLP. Появился словарь, куда можно добавить синонимы для названий, которые система распознает плохо.
Тем не менее точность работы адаптера во второй версии составила около 85%, а две из трех проблем так и остались нерешенными. Поэтому коллеги из R&D предложили перейти на фасетный поиск.
Как фасетный поиск решает проблемы неполной и лишней информации
Фасетный поиск работает так: сначала адрес раскладывается на элементы (фасеты) — город, улица, дом, квартира — а затем система ищет в базе распознанную комбинацию.
Например, вот как раскладывается по фасетам «Тула, Горького 10, квартира 13»:
Фасет — Значение
Город — Тула
Улица — Горького
Дом — 10
Квартира — 13
Если по комбинации найдено несколько адресов, то адаптер запрашивает элементы, которых не хватает для точного ответа. Например, запрос «Тула, Горького 10» вернет несколько адресов, поскольку в нем отсутствует номер квартиры, поэтому адаптер попросит его уточнить.
На первый взгляд, этот вариант покрывает сразу все три проблемы:
- не хватает информации — система запрашивает только то, чего не хватает
- есть опечатки — не страшно, для фасетов можно дописать синонимы
- лишняя информация — не проблема, она просто не будет восприниматься моделью.
Но на практике все оказалось куда сложнее…
Качество упало до 69%: неожиданные сложности фасетного поиска
На тестовом наборе качество вдруг резко упало на 16%. Начали искать причины и нашли несколько интересных моментов.
1. Литера в адресе — это часть номера дома или номер корпуса?
Есть дома с литерами: например, 132А. Загвоздка в том, что иногда литера является частью номера дома, а иногда она вынесена в корпус — отдельный уровень по ГАР.
К тому же, пользователи иногда говорят не «дом 137 А», а «дом 137 корпус А», ошибочно выделяя «А» в корпус и вводя в заблуждение модель.
2. Микрорайон — это пригород, а не микрорайон?😱😱😱😱😱
Звучит немного сюрреалистично: как микрорайон может быть не микрорайоном?
У адаптера есть отдельный уровень под названием «микрорайон». Однако есть, например, «микрорайон Центральный», который может обозначать другой уровень — «пригород».
Мы с коллегами из R&D были знатно удивлены таким приколом от базы. Причем пользователи скорее всего сами не знают, что этот микрорайон — на самом деле пригород. Эта проблема сильно заставила поломать голову в поисках приемлемого решения.
3. Советский, 25 — поселок, переулок, улица? Кто ты?
При совсем короткой фразе — например, «Советский, 25» — сложно выделить, какой именно это фасет. Такие примеры сложно обработать и придется просить пользователя назвать адрес еще раз, только более полный.
4. Решили повторить название два раза, а зря…
Например, пользователь говорит «Донской, донской». Что это?
Он хотел сказать «поселок Донской, переулок Донской»? Или это ошибочный повтор, и запрос был на «поселок Донской» или «переулок Донской»?
Это напоминает предыдущий пункт, но тут грамотной работе фасетного поиска мешают уже излишки информации.
К какому решению мы пришли
Как можно заметить, все сложности фасетного поиска связаны с несовершенством устройства базы или особенностями того, как пользователи называют свой адрес.
Получается, ни полнотекстовый, ни фасетный поиск по отдельности не справляются со всеми сценариями работы с адресами. Поэтому мы решили использовать гибридный подход.
В третьей версии адаптера система сначала будет, как и раньше, искать максимально похожую строку в базе данных. Так можно избежать неоднозначных моментов в структуре адреса. А если так найти не получится, система перейдет уже к фасетному поиску — разобьет запрос на части и проанализирует, какой информации недостает, чтобы запросить нужное.
Мы уже начали тестировать этот вариант и обязательно вернемся к вам с результатами, так что stay tuned!
Ну а пока что вывод простой: теоретически идеальные решения всегда сталкиваются с реальностью данных и пользовательского поведения. Так что результат зачастую дает комбинация методов и постоянная их адаптация под реальные сценарии.