Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Дмитрий Бровкин – Почему исправление опечаток с...

Дмитрий Бровкин – Почему исправление опечаток сложнее, чем кажется, и как мы с этим српавляемся @ PythoNN

Avatar for Sobolev Nikita

Sobolev Nikita

April 09, 2025
Tweet

More Decks by Sobolev Nikita

Other Decks in Technology

Transcript

  1. Почему исправление опечаток сложнее, чем кажется, и как мы с

    этим справляемся Дмитрий Бровкин Спикер
  2. Привет, я Дмитрий Бровкин Backend разработчик, Занимаюсь бэкэнд разработкой с

    2018 года. Начал со своих проектов, разработал игровой чат-бот на базе API популярной социальной сети, бесплатно получил трафик, пару месяцев держал 40к MAU, потом похоронил проект. Далее работал в документообороте, финтех и сейчас в Звуке. команда поиска HiFi-стриминг Звук
  3. Что такое Звук? ✦ Это музыка в HiFi-качестве, а также

    подкасты, аудиокниги, эксклюзивные плейлисты и раздел для детей ✦ Слушайте Звук в приложении, на сайте zvuk.com, в автомобилях с поддержкой CarPlay и Android Auto ✦ А также в онлайн-кинотеатре Оkko и на колонках SberBoom
  4. Запустились в 2010 году 01 02 03 Звук развивается в

    трех направлениях: HiFi-стриминг Звук, Звук СТУДИО и Звук Бизнес Пионеры высокого качества. Звук первым среди российских стримингов предоставил пользователям возможность слушать музыку в HiFi-качестве Звук Гиперперсонализация
  5. Зачем исправлять опечатки? Классификации ошибок: ✦ Набор в неправильной раскладке

    ✦ Ошибки в наборе сложных названий артистов и песен ✦ Ввод запросов в транслитерации ✦ Ввод запроса с лишними пробелами или без них Даже ошибка в 1 букве запроса может значительно поменять поисковую выдачу
  6. Высокоуровневое представление поиска SEARCH GATEWAY CLIENT SEARCH ENGINES ПРЕДОБРАБОТКА ЗАПРОСА

    - очистка от спецсимволов - приведение к нижнему регистру - … - исправление опечаток ГОТОВКА ПОИСКОВОЙ ВЫДАЧИ - переранжирование - обогащение контентом - … - фильтрация контента
  7. Терминология Elasticsearch это распределенная система полнотекстового поиска Индекс коллекция документов,

    хранящаяся в Elasticsearch Терм отдельное нормализованное слово из текста
  8. Терминология Elasticsearch это распределенная система полнотекстового поиска Индекс коллекция документов,

    хранящаяся в Elasticsearch Терм отдельное нормализованное слово из текста Корпус совокупность текстовых данных
  9. Терминология Elasticsearch это распределенная система полнотекстового поиска Индекс коллекция документов,

    хранящаяся в Elasticsearch Терм отдельное нормализованное слово из текста Корпус совокупность текстовых данных Расстояние Дамерау- Левенштейна это мера разницы двух строк символов, определяемая как минимальное количество операций вставки, удаления, замены и транспозиции (перестановки двух соседних символов), необходимых для перевода одной строки в другую.
  10. Терминология Elasticsearch это распределенная система полнотекстового поиска Индекс коллекция документов,

    хранящаяся в Elasticsearch Терм отдельное нормализованное слово из текста Корпус совокупность текстовых данных Расстояние Дамерау- Левенштейна это мера разницы двух строк символов, определяемая как минимальное количество операций вставки, удаления, замены и транспозиции (перестановки двух соседних символов), необходимых для перевода одной строки в другую. TFIDF (term frequency, - inverse document frequency) статистическая мера, используемая для оценки важности слова в контексте документа), являющегося частью коллекции документов или корпуса). Вес некоторого слова пропорционален частоте употребления этого слова в документе и обратно пропорционален частоте употребления слова во всех документах коллекции.
  11. Требования к системе Должна работать за минимально возможное время 01

    02 Должна учитывать корпус домена Должна легко масштабироваться, обеспечивать высокую пропускную способность 03
  12. Требования к системе Должна работать за минимально возможное время 01

    02 Должна учитывать корпус домена Должна легко масштабироваться, обеспечивать высокую пропускную способность Итеративное обновление справочника, коррекция исходя из “трендовˮ 03 04
  13. Какие существуют инструменты? Elasticsearch suggest Предоставляет встроенный функционал исправления текста

    запроса. Для генерация вариантов исправления ES использует TFIDF индекс для нахождения наиболее близкого терма. Плюсы: ✦ Функционал встроен в Elasticsearch, не требуется использовать дополнительные инструменты ✦ Упрощается актуализация данных т.к. уже выстроены процессы индексации нового контента Минусы: ✦ Сложно учитывать пользовательские сигналы (популярные опечатки, изменение трендов) ✦ Медленная работа - 100ms на датасете названий треков
  14. SymSpell SymSpell Это библиотека для исправления опечаток, основанная на подходе

    с предварительно рассчитанными возможными исправлениями. Она использует словарь с частотностью слов и позволяет очень быстро находить исправления благодаря заранее построенной структуре данных. Плюсы: ✦ Самая быстрая генерация вариантов исправления из существующих инструментов 1ms при расстоянии Дамерау — Левенштейна = 1 ✦ Не зависит от языка текста запроса ✦ Есть возможность использовать свой датасет Минусы: ✦ Необходимо собирать и постоянно обновлять датасет для оптимальной работы алгоритма
  15. JamSpell JamSpell Это opensource библиотека, написанная на С, использующая свою

    реализацию алгоритма SymSpell совместно с языковой моделью. Исправления учитывают контекст. Существуют биндинги к большинству популярных языков программирования. Плюсы: ✦ Высокое качество исправления с учетом лингвистических особенностей Минусы: ✦ Невозможно итеративное дообучение модели ✦ Для наиболее качественного исправления нужны модели для каждого языка отдельно
  16. Выбираем SymSpell как основу Согласованность с нашими требованиями: ✦ Быстрый

    ✦ Позволяет формировать справочник данными нашего домена ✦ Можем итеративно модифицировать справочник ✦ Высокая гибкость, можем применять любые инструменты “вокругˮ алгоритма Минусы: ✦ Не учитывает контекст предложения, надо что-то придумывать и достраивать ✦ Нет готовой библиотеки, которая поддерживает абстрактное хранилище для справочника
  17. Как работает SymSpell В основе лежит алгоритм симметричных удалений. Его

    суть в том, что для каждого слова в корпусе вычисляются все варианты, полученные удалением до заданного количества символов (например, при одной или двух ошибках). А для быстрого поиска вариантов исправлений, используется HashMap.
  18. Как работает SymSpell Для оптимизации памяти можно поменять структуру данных,

    например, хранить ссылки на слова вместо самих строковых последовательностей:
  19. Первая итерация системы и ее проблемы 01 Первоначальное заполнение справочника

    слишком долгое — 3 дня 02 Справочник слишком большой: 110КК записей | 12 ГБ ОЗУ
  20. Первая итерация системы и ее проблемы 01 Первоначальное заполнение справочника

    слишком долгое — 3 дня 02 Справочник слишком большой: 110КК записей | 12 ГБ ОЗУ 03 Сервис слишком медленный: 99P  200мс
  21. Первая итерация системы и ее проблемы 01 Первоначальное заполнение справочника

    слишком долгое — 3 дня 02 Справочник слишком большой: 110КК записей | 12 ГБ ОЗУ 03 Сервис слишком медленный: 99P  200мс 04 Низкое качество: Точность - 30% Полнота - 60%
  22. Проблема: ✦ Теперь можем агрегировать одинаковые термы и отправлять сообщения

    в кафку только по уникальным словам. ✦ Тем самым уменьшить объем сообщений в десятки раз. ✦ Получаем выигрыш c 3 дней до 7 часов долгое время первоначального заполнения справочника Тело запроса: Тело ответа:
  23. Проблема: ✦ Теперь можем агрегировать одинаковые термы и отправлять сообщения

    в кафку только по уникальным словам. ✦ Тем самым уменьшить объем сообщений в десятки раз. ✦ Получаем выигрыш c 3 дней до 7 часов долгое время первоначального заполнения справочника Тело запроса: Тело ответа:
  24. ✦ Оптимизируем структуры данных в редисе, убираем префикс названия сервиса

    из ключа ✦ Делаем фильтрацию термов по frequency при добавлении новых слов в словарь, не добавляем редко встречаемые Проблема: слишком большой справочник
  25. ✦ Оптимизируем структуры данных в редисе, убираем префикс названия сервиса

    из ключа ✦ Делаем фильтрацию термов по frequency при добавлении новых слов в словарь, не добавляем редко встречаемые с 110кк → 33кк записей с 12 гб → 2.7 гб ОЗУ Результатом словарь “худеетˮ: Проблема: слишком большой справочник
  26. Было: Стало: Проблема: слишком медленный Делаем возможные вычисления и собираем

    запросы в пачку, для получения данных из справочника:
  27. Было: Стало: Проблема: слишком медленный Делаем возможные вычисления и собираем

    запросы в пачку, для получения данных из справочника:
  28. Было: Стало: Проблема: слишком медленный Делаем возможные вычисления и собираем

    запросы в пачку, для получения данных из справочника: latency падает: 200мс → 35мс по 99P
  29. Проблема: низкое качество исправлений Очевидные проблемы: ✦ Вообще не учитываем

    контекст. Одно слово исправляем нормально, предложения из 2+ слов - плохо ✦ Слишком много мусора в корпусе, есть слова с ошибками
  30. Проблема: низкое качество исправлений Очевидные проблемы: ✦ Вообще не учитываем

    контекст. Одно слово исправляем нормально, предложения из 2+ слов - плохо ✦ Слишком много мусора в корпусе, есть слова с ошибками Решения ✦ Дешевый способ учета контекста — добавить биграммы в алгоритм ✦ Не учитывать низкочастотные термы при добавлении ✦ поменять алгоритм ранжирования, не просто сортировать по расстоянию и частоте, а ранжировать на основе формулы с нормализацией и весами
  31. Что такое биграммы? Н-граммы — это непрерывные последовательности из n

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

    его: 01 Добавляем хешмап в редис для хранения биграмм 02
  33. Добавляем поддержку биграмм Добавляем поле в индекс эластика и пересобираем

    его: 01 03 Добавляем поддержку биграмм в алгоритм symspell Добавляем хешмап в редис для хранения биграмм 02
  34. Меняем ранжирование вариантов исправлений Определения: ft(c) — показатель частотности терма

    для кандидата c fb(c) — показатель частотности биграммы для кандидата c
  35. Меняем ранжирование вариантов исправлений Определения: ft(c) — показатель частотности терма

    для кандидата c fb(c) — показатель частотности биграммы для кандидата c max(ft) — максимальная частотность терма среди всех кандидатов max(fb) — максимальная частотность биграммы среди всех кандидатов
  36. Меняем ранжирование вариантов исправлений Определения: ft(c) — показатель частотности терма

    для кандидата c fb(c) — показатель частотности биграммы для кандидата c d(c)— редакционное расстояние между вводимым словом и кандидатом c max(ft) — максимальная частотность терма среди всех кандидатов max(fb) — максимальная частотность биграммы среди всех кандидатов dmax — максимальное допустимое расстояние
  37. Меняем ранжирование вариантов исправлений Определения: ft(c) — показатель частотности терма

    для кандидата c fb(c) — показатель частотности биграммы для кандидата c d(c)— редакционное расстояние между вводимым словом и кандидатом c max(ft) — максимальная частотность терма среди всех кандидатов max(fb) — максимальная частотность биграммы среди всех кандидатов dmax — максимальное допустимое расстояние wt, wb, wd — веса для компонентов
  38. Проводим линейную нормализацию частоты: 01 02 Нормализуем дистанцию: 03 Считаем

    итоговый скор кандидата по формуле: Меняем ранжирование вариантов исправлений
  39. Итоги качества после улучшений: Точность исправлений: 30% → ~ 68%

    Полнота: 60%  88% Время ответа сервиса: 200 мс → 35 мс 99P Потребление ОЗУ 12ГБ  2.7 ГБ Первоначальное время заполнения: 3 дня → 7 часов
  40. Что дальше? Текущее качество исправлений нас не устраивает, нужно думать

    над следующими вариантами улучшений и производить еще несколько итераций доработок. Возможные точки расширения: ✦ добавление компоненты популярность в ранжировании ✦ Сделать кастомную функцию расчета расстояния на базе расстояния между символами QWERTY клавиатур и/или фонетической близости (Soundex like) ✦ Полноценная ML для переранжирования (тут можно добавить учет дополнительных сигналов от пользователей), оставить symspell только для поднятия вариантов исправлений