Share
Embed
Дмитрий Бровкин – Почему исправление опечаток сложнее, чем кажется, и как мы с этим српавляемся @ PythoNN
Sobolev Nikita
April 09, 2025
Transcript
63 slides
-
Почему исправление опечаток сложнее, чем кажется, и как мы с
этим справляемся Дмитрий Бровкин Спикер -
Привет, я Дмитрий Бровкин Backend разработчик, Занимаюсь бэкэнд разработкой с
2018 года. Начал со своих проектов, разработал игровой чат-бот на базе API популярной социальной сети, бесплатно получил трафик, пару месяцев держал 40к MAU, потом похоронил проект. Далее работал в документообороте, финтех и сейчас в Звуке. команда поиска HiFi-стриминг Звук -
Что такое Звук? ✦ Это музыка в HiFi-качестве, а также
подкасты, аудиокниги, эксклюзивные плейлисты и раздел для детей ✦ Слушайте Звук в приложении, на сайте zvuk.com, в автомобилях с поддержкой CarPlay и Android Auto ✦ А также в онлайн-кинотеатре Оkko и на колонках SberBoom -
Запустились в 2010 году 01 02 03 Звук развивается в
трех направлениях: HiFi-стриминг Звук, Звук СТУДИО и Звук Бизнес Пионеры высокого качества. Звук первым среди российских стримингов предоставил пользователям возможность слушать музыку в HiFi-качестве Звук Гиперперсонализация -
Зачем исправлять опечатки? Классификации ошибок: ✦ Набор в неправильной раскладке
✦ Ошибки в наборе сложных названий артистов и песен ✦ Ввод запросов в транслитерации ✦ Ввод запроса с лишними пробелами или без них Даже ошибка в 1 букве запроса может значительно поменять поисковую выдачу -
Высокоуровневое представление поиска SEARCH GATEWAY CLIENT SEARCH ENGINES ПРЕДОБРАБОТКА ЗАПРОСА
- очистка от спецсимволов - приведение к нижнему регистру - … - исправление опечаток ГОТОВКА ПОИСКОВОЙ ВЫДАЧИ - переранжирование - обогащение контентом - … - фильтрация контента -
Терминология Elasticsearch это распределенная система полнотекстового поиска Индекс коллекция документов,
хранящаяся в Elasticsearch -
Терминология Elasticsearch это распределенная система полнотекстового поиска Индекс коллекция документов,
хранящаяся в Elasticsearch Терм отдельное нормализованное слово из текста -
Терминология Elasticsearch это распределенная система полнотекстового поиска Индекс коллекция документов,
хранящаяся в Elasticsearch Терм отдельное нормализованное слово из текста Корпус совокупность текстовых данных -
Терминология Elasticsearch это распределенная система полнотекстового поиска Индекс коллекция документов,
хранящаяся в Elasticsearch Терм отдельное нормализованное слово из текста Корпус совокупность текстовых данных Расстояние Дамерау- Левенштейна это мера разницы двух строк символов, определяемая как минимальное количество операций вставки, удаления, замены и транспозиции (перестановки двух соседних символов), необходимых для перевода одной строки в другую. -
Терминология Elasticsearch это распределенная система полнотекстового поиска Индекс коллекция документов,
хранящаяся в Elasticsearch Терм отдельное нормализованное слово из текста Корпус совокупность текстовых данных Расстояние Дамерау- Левенштейна это мера разницы двух строк символов, определяемая как минимальное количество операций вставки, удаления, замены и транспозиции (перестановки двух соседних символов), необходимых для перевода одной строки в другую. TFIDF (term frequency, - inverse document frequency) статистическая мера, используемая для оценки важности слова в контексте документа), являющегося частью коллекции документов или корпуса). Вес некоторого слова пропорционален частоте употребления этого слова в документе и обратно пропорционален частоте употребления слова во всех документах коллекции. -
Требования к системе Должна работать за минимально возможное время 01
02 Должна учитывать корпус домена -
Требования к системе Должна работать за минимально возможное время 01
02 Должна учитывать корпус домена Должна легко масштабироваться, обеспечивать высокую пропускную способность 03 -
Требования к системе Должна работать за минимально возможное время 01
02 Должна учитывать корпус домена Должна легко масштабироваться, обеспечивать высокую пропускную способность Итеративное обновление справочника, коррекция исходя из “трендовˮ 03 04 -
Какие существуют инструменты? Elasticsearch suggest Предоставляет встроенный функционал исправления текста
запроса. Для генерация вариантов исправления ES использует TFIDF индекс для нахождения наиболее близкого терма. Плюсы: ✦ Функционал встроен в Elasticsearch, не требуется использовать дополнительные инструменты ✦ Упрощается актуализация данных т.к. уже выстроены процессы индексации нового контента Минусы: ✦ Сложно учитывать пользовательские сигналы (популярные опечатки, изменение трендов) ✦ Медленная работа - 100ms на датасете названий треков -
SymSpell SymSpell Это библиотека для исправления опечаток, основанная на подходе
с предварительно рассчитанными возможными исправлениями. Она использует словарь с частотностью слов и позволяет очень быстро находить исправления благодаря заранее построенной структуре данных. Плюсы: ✦ Самая быстрая генерация вариантов исправления из существующих инструментов 1ms при расстоянии Дамерау — Левенштейна = 1 ✦ Не зависит от языка текста запроса ✦ Есть возможность использовать свой датасет Минусы: ✦ Необходимо собирать и постоянно обновлять датасет для оптимальной работы алгоритма -
JamSpell JamSpell Это opensource библиотека, написанная на С, использующая свою
реализацию алгоритма SymSpell совместно с языковой моделью. Исправления учитывают контекст. Существуют биндинги к большинству популярных языков программирования. Плюсы: ✦ Высокое качество исправления с учетом лингвистических особенностей Минусы: ✦ Невозможно итеративное дообучение модели ✦ Для наиболее качественного исправления нужны модели для каждого языка отдельно -
Выбираем SymSpell как основу Согласованность с нашими требованиями: ✦ Быстрый
✦ Позволяет формировать справочник данными нашего домена ✦ Можем итеративно модифицировать справочник ✦ Высокая гибкость, можем применять любые инструменты “вокругˮ алгоритма Минусы: ✦ Не учитывает контекст предложения, надо что-то придумывать и достраивать ✦ Нет готовой библиотеки, которая поддерживает абстрактное хранилище для справочника -
Как работает SymSpell В основе лежит алгоритм симметричных удалений. Его
суть в том, что для каждого слова в корпусе вычисляются все варианты, полученные удалением до заданного количества символов (например, при одной или двух ошибках). А для быстрого поиска вариантов исправлений, используется HashMap. -
Как работает SymSpell Для оптимизации памяти можно поменять структуру данных,
например, хранить ссылки на слова вместо самих строковых последовательностей: -
Первая итерация системы и ее проблемы 01 Первоначальное заполнение справочника
слишком долгое — 3 дня -
Первая итерация системы и ее проблемы 01 Первоначальное заполнение справочника
слишком долгое — 3 дня 02 Справочник слишком большой: 110КК записей | 12 ГБ ОЗУ -
Первая итерация системы и ее проблемы 01 Первоначальное заполнение справочника
слишком долгое — 3 дня 02 Справочник слишком большой: 110КК записей | 12 ГБ ОЗУ 03 Сервис слишком медленный: 99P 200мс -
Первая итерация системы и ее проблемы 01 Первоначальное заполнение справочника
слишком долгое — 3 дня 02 Справочник слишком большой: 110КК записей | 12 ГБ ОЗУ 03 Сервис слишком медленный: 99P 200мс 04 Низкое качество: Точность - 30% Полнота - 60% -
Проблема: ✦ Теперь можем агрегировать одинаковые термы и отправлять сообщения
в кафку только по уникальным словам. ✦ Тем самым уменьшить объем сообщений в десятки раз. ✦ Получаем выигрыш c 3 дней до 7 часов долгое время первоначального заполнения справочника Тело запроса: Тело ответа: -
Проблема: ✦ Теперь можем агрегировать одинаковые термы и отправлять сообщения
в кафку только по уникальным словам. ✦ Тем самым уменьшить объем сообщений в десятки раз. ✦ Получаем выигрыш c 3 дней до 7 часов долгое время первоначального заполнения справочника Тело запроса: Тело ответа: -
✦ Оптимизируем структуры данных в редисе, убираем префикс названия сервиса
из ключа ✦ Делаем фильтрацию термов по frequency при добавлении новых слов в словарь, не добавляем редко встречаемые Проблема: слишком большой справочник -
✦ Оптимизируем структуры данных в редисе, убираем префикс названия сервиса
из ключа ✦ Делаем фильтрацию термов по frequency при добавлении новых слов в словарь, не добавляем редко встречаемые с 110кк → 33кк записей с 12 гб → 2.7 гб ОЗУ Результатом словарь “худеетˮ: Проблема: слишком большой справочник -
Было: Стало: Проблема: слишком медленный Делаем возможные вычисления и собираем
запросы в пачку, для получения данных из справочника: -
Было: Стало: Проблема: слишком медленный Делаем возможные вычисления и собираем
запросы в пачку, для получения данных из справочника: -
Было: Стало: Проблема: слишком медленный Делаем возможные вычисления и собираем
запросы в пачку, для получения данных из справочника: latency падает: 200мс → 35мс по 99P -
Проблема: низкое качество исправлений Очевидные проблемы: ✦ Вообще не учитываем
контекст. Одно слово исправляем нормально, предложения из 2+ слов - плохо ✦ Слишком много мусора в корпусе, есть слова с ошибками -
Проблема: низкое качество исправлений Очевидные проблемы: ✦ Вообще не учитываем
контекст. Одно слово исправляем нормально, предложения из 2+ слов - плохо ✦ Слишком много мусора в корпусе, есть слова с ошибками Решения ✦ Дешевый способ учета контекста — добавить биграммы в алгоритм ✦ Не учитывать низкочастотные термы при добавлении ✦ поменять алгоритм ранжирования, не просто сортировать по расстоянию и частоте, а ранжировать на основе формулы с нормализацией и весами -
Что такое биграммы? Н-граммы — это непрерывные последовательности из n
элементов (слов, символов или других единиц) в тексте. Биграммы, частный случай н-грамм, последовательности из двух подряд идущих слов - помогают уловить взаимосвязи между парами последовательных слов. Примеры биграмм для предожения “На улице идет дождьˮ: ✦ на улице ✦ улице идет ✦ идет дождь -
Добавляем поддержку биграмм Добавляем поле в индекс эластика и пересобираем
его: 01 Добавляем хешмап в редис для хранения биграмм 02 -
Добавляем поддержку биграмм Добавляем поле в индекс эластика и пересобираем
его: 01 03 Добавляем поддержку биграмм в алгоритм symspell Добавляем хешмап в редис для хранения биграмм 02 -
Меняем ранжирование вариантов исправлений Определения: ft(c) — показатель частотности терма
для кандидата c fb(c) — показатель частотности биграммы для кандидата c -
Меняем ранжирование вариантов исправлений Определения: ft(c) — показатель частотности терма
для кандидата c fb(c) — показатель частотности биграммы для кандидата c max(ft) — максимальная частотность терма среди всех кандидатов max(fb) — максимальная частотность биграммы среди всех кандидатов -
Меняем ранжирование вариантов исправлений Определения: ft(c) — показатель частотности терма
для кандидата c fb(c) — показатель частотности биграммы для кандидата c d(c)— редакционное расстояние между вводимым словом и кандидатом c max(ft) — максимальная частотность терма среди всех кандидатов max(fb) — максимальная частотность биграммы среди всех кандидатов dmax — максимальное допустимое расстояние -
Меняем ранжирование вариантов исправлений Определения: ft(c) — показатель частотности терма
для кандидата c fb(c) — показатель частотности биграммы для кандидата c d(c)— редакционное расстояние между вводимым словом и кандидатом c max(ft) — максимальная частотность терма среди всех кандидатов max(fb) — максимальная частотность биграммы среди всех кандидатов dmax — максимальное допустимое расстояние wt, wb, wd — веса для компонентов -
Проводим линейную нормализацию частоты: 01 02 Нормализуем дистанцию: 03 Считаем
итоговый скор кандидата по формуле: Меняем ранжирование вариантов исправлений -
Итоги качества после улучшений: Точность исправлений: 30% → ~ 68%
Полнота: 60% 88% Время ответа сервиса: 200 мс → 35 мс 99P Потребление ОЗУ 12ГБ 2.7 ГБ Первоначальное время заполнения: 3 дня → 7 часов -
Что дальше? Текущее качество исправлений нас не устраивает, нужно думать
над следующими вариантами улучшений и производить еще несколько итераций доработок. Возможные точки расширения: ✦ добавление компоненты популярность в ранжировании ✦ Сделать кастомную функцию расчета расстояния на базе расстояния между символами QWERTY клавиатур и/или фонетической близости (Soundex like) ✦ Полноценная ML для переранжирования (тут можно добавить учет дополнительных сигналов от пользователей), оставить symspell только для поднятия вариантов исправлений