Сопоставления «фраза-фильтр»: семантический поиск для фильтров товаров

В этой статье объясняется, как мы создаём и расширяем сопоставления «фраза-фильтр», которые обеспечивают работу нашей системы извлечения фильтров. Эти сопоставления связывают фразы на естественном языке из поисковых запросов со структурированными фильтрами товаров.

Проблема: извлечение фильтров из естественного языка

Когда пользователи ищут «mini pc with 16gb ram», нам нужно извлечь:

  • Форм-фактор: Mini PC

  • Основная память: 16

Но пользователи выражают ту же цель разными способами:

  • "16gb ram mini pc"

  • "mini computer 16 gb memory"

  • "small pc 16gb"

  • "compact desktop with 16 gigs"

Нам нужна система, которая сопоставляет все эти варианты фраз с правильными значениями фильтров.

Двухэтапный процесс

Мы создаём сопоставления фраз в два этапа:

  1. Шаг 3a: создание базовых фраз из характеристик товаров с помощью перестановок и правил, специфичных для характеристик
  2. Шаг 4: расширение с помощью семантической близости на основе эмбеддингов

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

Шаг 3a: генерация базовых фраз

Метаданные характеристик

Каждая характеристика товара имеет метаданные в последовательности характеристик:

  • Заголовок: название категории (например, "Processing" для характеристик процессора)

  • Единица измерения: единица измерения (например, "GB" для памяти, "GHz" для частоты)

Эти метаданные управляют генерацией фраз.

Генерация на основе перестановок

Для каждого значения характеристики мы генерируем все перестановки:

  • Заголовок: "processor"

  • Ключ характеристики: "series"

  • Значение: "i5"

  • Единица измерения: (нет для series)

Это даёт:

  • "processor series i5"

  • "series processor i5"

  • "i5 processor series"

  • "i5 series processor"

  • "processor i5"

  • "series i5"

  • "i5"

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

Комбинации «значение + единица измерения»

Для характеристик с единицами измерения (память, хранилище, частота) мы генерируем варианты с пробелом и без пробела:

  • "16 gb" (с пробелом)

  • "16gb" (без пробела)

Они комбинируются с другими компонентами:

  • "16gb ram"

  • "ram 16gb"

  • "processor 16gb"

Правила добавления суффикса «порт»

Для характеристик подключения (USB, HDMI, DisplayPort) мы добавляем суффиксы, связанные с портами:

  • "usb port"

  • "usb ports"

  • "2 usb ports"

  • "hdmi port"

Это позволяет сопоставлять запросы вида "mini pc with 2 hdmi ports".

Правила для конкретных характеристик

Для каждого типа характеристик есть свои правила генерации фраз:

Серия процессора (i3, i5, N-series):

  • Обозначения процессоров Core порождают варианты: название производителя, бренд ядра, комбинированные формы

  • Процессоры N-series (N100 и т.д.) создают аналогичные комбинации шаблонов

  • Каждый вариант генерирует несколько перестановок со словом "processor"

Основная память:

  • Числовые значения генерируют варианты с "GB" с пробелом и без пробела ("16gb", "16 gb")

  • Автоматически добавляются уточнители "ram" и "memory" ("16gb memory", "16 gb ram")

SSD-хранилище:

  • Числовые значения генерируют варианты с "GB" ("512gb", "512 gb")

  • Значения ≥ 1024 автоматически генерируют варианты с "TB" (например, 1024GB → 1TB)

  • Автоматически добавляются уточнители "ssd" и "storage" ("512gb ssd", "512 gb storage")

Форм-фактор:

  • Mini PC → несколько вариантов, включая форму без пробела

  • All-in-One → "all in one", "aio", сокращённые формы

  • Thin Client → варианты с пробелом и без пробела

  • Industrial PC → сокращённая и полная формы

Поколение:

  • Числовые значения поколений превращаются в: "12th gen", "12th generation", "gen 12"

Ядра:

  • 2 → "dual core"

  • 4 → "quad core"

  • 6 → "hexa core"

  • 8 → "octa core"

  • Все генерируют варианты "[n] core processor"

Ethernet:

  • "1000" → ["gigabit ethernet", "gbe", "1gbps"]

  • "2500" → ["2.5gbe", "2.5 gigabit", "2.5gbps"]

Операционная система:

  • "Windows 11" → ["windows", "windows 11", "win 11"]

  • "Ubuntu" → ["linux", "ubuntu"]

  • "FreeDOS" → ["freedos", "no os", "without os"]

Белый список для самостоятельных значений

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

  • Серия: "i3", "i5", "N100" (но не отдельные буквы)

  • Модель процессора: "N100", "1335U"

  • Операционная система: "Windows", "Linux", "Ubuntu"

  • Поколение: "12th", "13th", "14th"

  • Бренд процессора: "Intel", "ARM"

Например, "2" не должно соответствовать "2 cores", если запрос — "2 hdmi ports". Проверка длины предотвращает сопоставление отдельных букв или очень коротких неоднозначных значений в качестве самостоятельных. Характеристики с явными единицами измерения, такие как Ethernet или порты, генерируют самостоятельные комбинации только при указании единицы измерения.

Предотвращение коллизий

Значения памяти и хранилища пересекаются (обе имеют 64, 128, 256 и т.д.). На шаге 4 применяются правила диапазонов значений для устранения неоднозначности:

  • ≤ 64 ГБ: основная память (RAM)

  • ≥ 128 ГБ: SSD-хранилище

  • Диапазон 65-127 ГБ: пропускается (неоднозначно)

Фразы с явными уточнителями ("ram"/"memory" или "ssd"/"storage") переопределяют это правило и могут соответствовать любому значению.

Кроме того, на этапе разрешения коллизий с помощью постобработки исключаются неопределённые общие термины, которые соответствуют слишком многим несвязанным фильтрам: такие термины, как "connectivity", "audio", "display", "processor" и "physical", создают слишком много неоднозначности между различными аспектами.

Шаг 4: семантическое расширение

Извлечение N-грамм

Мы извлекаем частотные фразы из реальных поисковых запросов — от отдельных слов (1-граммы, например "mini") до более длинных последовательностей (до 6-грамм, например "mini pc with 16gb ram ssd"). Сохраняются только фразы, встречающиеся не менее 3 раз. Такой подход к фильтрации снижает уровень шума, сохраняя при этом реальные языковые паттерны пользователей.

Генерация поисковых текстов для фильтров

Для каждого значения фильтра мы генерируем поисковые тексты:

Основная память: 16:

  • "16gb ram memory"

  • "16 main memory"

  • "main memory 16"

SSD-хранилище: 512:

  • "512gb storage ssd"

  • "512 ssd storage"

  • "ssd storage 512"

Эти поисковые тексты представляют фильтр в пространстве эмбеддингов.

Эмбеддинги и сопоставление

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

Ручные стартовые фразы

Перед расширением мы добавляем высоконадёжные ручные стартовые фразы:

"Series:i5": [
    "i5",
    "core i5",
    "intel i5",
    "intel core i5",
    "i5 processor",
    "cpu i5",
]

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

Инкрементальные эмбеддинги

Мы кэшируем эмбеддинги и для фраз, и для поисковых текстов фильтров. Когда поступают новые запросы:

  1. Загружаем существующие эмбеддинги
  2. Создаём эмбеддинги только для новых фраз
  3. Добавляем их в кэш

Это позволяет избежать повторного создания эмбеддингов для неизменённых данных. Подробнее см. Стратегия эмбеддингов.

Разрешение коллизий

После завершения сопоставления по близости мы разрешаем коллизии между фильтрами памяти и хранилища:

Разрешение на основе чисел:

  • Для неоднозначных фраз, содержащих числа: если значение фразы ≤ 64, сохраняем только для памяти; если > 64 — только для хранилища

  • Это предотвращает соответствие "16gb" фильтрам SSD-хранилища и "512gb" фильтрам памяти

Явные уточнители переопределяют правила:

  • Фразы с ключевыми словами "ram", "memory", "cpu", "processor" → только память

  • Фразы с ключевыми словами "ssd", "storage", "disk", "nvme", "drive" → только хранилище

  • Пример: "processor 8gb" соответствует памяти, несмотря на числовое значение

Неопределённые термины:

  • Удаляем фразы типа "connectivity", "audio", "display", которые соответствуют нескольким несвязанным фильтрам

Формат вывода

Итоговые сопоставления сортируются по близости (сначала наибольшие), затем по длине (сначала самые короткие):

{
  "Main Memory:16": [
    {"phrase": "16gb ram", "similarity": 1.0},
# ... (implementation details omitted)

Интеграция с извлечением фильтров

Эти сопоставления обеспечивают работу алгоритма извлечения фильтров:

  1. Поступает запрос: "mini pc with 16gb ram"
  2. Извлекаем фразы: ["mini pc", "16gb ram", "mini", "pc", "16gb", "ram"]
  3. Сопоставляем фразы с фильтрами с помощью сопоставлений
  4. Возвращаем фильтры: {"Form Factor": ["Mini PC"], "Main Memory": ["16"]}

Подробнее см. Алгоритм извлечения фильтров.

Хранение и распространение

Сопоставления фраз сохраняются в виде JSON-файлов и используются во всей системе:

  • Файл базовых сопоставлений: создаётся на шаге 3a, содержит фразы на основе правил

  • Файл расширенных сопоставлений: создаётся на шаге 4, содержит результаты семантического расширения

Расширенные сопоставления используются в:

  • Генерация страниц запросов: извлечение фильтров из текста запроса

  • Поисковый сервис: API извлечения фильтров в реальном времени

  • Сопоставление товаров: фильтрация товаров по извлечённым фильтрам

Характеристики производительности

Базовая генерация (шаг 3a):

  • Время обработки масштабируется в зависимости от количества значений фильтров

  • Генерируется большое количество базовых вариантов фраз

  • Потребление памяти остаётся умеренным во время генерации

Семантическое расширение (шаг 4):

  • Время обработки масштабируется в зависимости от объёма запросов и размера эмбеддингов

  • Выходные данные содержат значительно больше фраз, чем базовая генерация

  • Требования к памяти возрастают из-за хранения эмбеддингов

Расширение является вычислительно интенсивным (CPU-bound) из-за вычисления близости. Использование NumPy с ускорением BLAS значительно ускоряет матричные операции.

Интеграция с SEO-конвейером

Генерация сопоставлений фраз — это шаги 3a и 4 в SEO-конвейере:

  1. Шаг 0: Встраивание исходных данных — товары, детали, статьи
  2. Шаг 1: Получение запросов — GSC, Google Ads, live, Algolia
  3. Шаг 2: Объединение запросов — объединение всех источников
  4. Шаг 3a: Генерация базовых сопоставлений фраз ← Вы находитесь здесь
  5. Шаг 3b: Встраивание запросов — преобразование в векторы
  6. Шаг 4: Расширение сопоставлений фраз ← Вы находитесь здесь
  7. Шаг 5: Кластеризация запросов — группировка по страницам
  8. Шаг 6: Сопоставление товаров — сопоставление запросов и товаров
  9. Шаг 7: Создание страниц запросов — генерация HTML
  10. Шаг 8: Генерация связанных запросов — поиск связанных запросов
  11. Шаг 11: Миграция на Valkey — загрузка в поисковый сервис

Полное описание процесса см. в статье Обзор SEO-конвейера.

Зачем нужны два шага?

Базовая генерация (шаг 3a) обеспечивает:

  • Точность: фразы на основе правил соответствуют ровно тому, что мы ожидаем

  • Покрытие: перестановки обеспечивают учёт всех порядков слов

  • Контроль: правила для конкретных характеристик учитывают предметные знания

Семантическое расширение (шаг 4) обеспечивает:

  • Гибкость: обнаруживает фразы, которые мы не предвидели

  • Реальный язык пользователей: учится на фактических поисковых запросах

  • Синонимы: находит эквивалентные фразы ("16 gigs" для "16gb")

Вместе они обеспечивают баланс между точностью и полнотой.

Ссылки

Технические концепции

Документация по моделям

Связанные статьи

Итоги

Мы создаём сопоставления «фраза-фильтр» в два этапа:

Шаг 3a (базовая генерация):

  • Генерируем все перестановки заголовка, ключа, значения, единицы измерения

  • Применяем правила для конкретных характеристик (серия процессора, память, хранилище, форм-фактор)

  • Добавляем суффиксы портов для характеристик подключения

  • Используем белый список для самостоятельных значений отдельных характеристик

  • Выводим базовый набор фраз на основе правил

Шаг 4 (семантическое расширение):

  • Извлекаем n-граммы из реальных поисковых запросов

  • Создаём эмбеддинги фраз и поисковых текстов фильтров

  • Сопоставляем фразы с оценками близости выше порога

  • Добавляем ручные стартовые фразы для направления расширения

  • Разрешаем коллизии между памятью и хранилищем

  • Выводим расширенный и однозначный набор фраз

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


← Назад к индексу документации