Перейти к содержанию

Ранжирование поиска: определение задачи

~4 минуты чтения

Предварительно: Подготовка к интервью по системному дизайну

Google обрабатывает 8.5 млрд поисковых запросов в день, а улучшение NDCG@10 всего на 0.5% приносит компании порядка $1.4 млрд дополнительной выручки в год. В e-commerce (Amazon, Ozon) 35% выручки генерируется через внутренний поиск. Search Ranking -- ML-система, которая определяет, в каком порядке показывать результаты, и от её качества напрямую зависит CTR, конверсия и revenue платформы.

Бизнес-контекст

Search Ranking -- ML-система для ранжирования результатов поиска по релевантности запросу пользователя. Ключевой компонент поисковых систем, e-commerce, контент-платформ.

Примеры применения

Компания Что ищут Ключевая метрика
Google Веб-страницы CTR, Query Success Rate
Amazon Товары Conversion, GMV
LinkedIn Люди, вакансии Application Rate, Connections
Spotify Песни, плейлисты Play Rate, Session Duration
Airbnb Жильё Booking Rate

Постановка задачи

Функциональные требования

  1. Relevance Ranking: Результаты отсортированы по релевантности
  2. Query Understanding: Понимание intent пользователя
  3. Personalization: Учёт предпочтений пользователя
  4. Real-time: Обновление индекса в реальном времени
  5. Spell Correction: Исправление опечаток
  6. Autocomplete: Подсказки при вводе

Нефункциональные требования

Метрика Требование Обоснование
Latency (p99) < 200ms UX критичен
Throughput 100K QPS Высокая нагрузка
Availability 99.99% Критичный сервис
Index Freshness < 1 min Новые items быстро ищутся

Этапы поискового пайплайна

graph TD
    Q["Query: красные кроссовки nike 42"] --> QP["1. Query Processing<br/>Tokenization, Spell check, Expansion"]
    QP --> QU["2. Query Understanding<br/>Intent: Product search<br/>Entities: brand=nike, size=42"]
    QU --> RET["3. Retrieval (Recall)<br/>BM25 + Semantic search<br/>10M -> 1000 candidates"]
    RET --> RANK["4. Ranking (Precision)<br/>ML model scoring<br/>1000 -> 100 ranked"]
    RANK --> RERANK["5. Re-ranking (Business)<br/>Diversity, freshness, ads"]
    RERANK --> RES["Results: Nike Air Max 42, Nike Zoom 42, ..."]

    style Q fill:#e8eaf6,stroke:#3f51b5
    style QP fill:#e8eaf6,stroke:#3f51b5
    style QU fill:#e8eaf6,stroke:#3f51b5
    style RET fill:#e8f5e9,stroke:#4caf50
    style RANK fill:#fff3e0,stroke:#ef6c00
    style RERANK fill:#f3e5f5,stroke:#9c27b0
    style RES fill:#e8f5e9,stroke:#4caf50

Типы поисковых задач

1. Web Search (Google-style)

  • Цель: Найти самую релевантную страницу
  • Сигналы: PageRank, content quality, user engagement
  • Challenges: Spam, SEO manipulation, freshness

2. E-commerce Search (Amazon-style)

  • Цель: Показать товары, которые купят
  • Сигналы: Conversion, reviews, inventory
  • Challenges: Long-tail queries, inventory changes

3. People Search (LinkedIn-style)

  • Цель: Найти подходящего человека/вакансию
  • Сигналы: Skills match, location, connections
  • Challenges: Двусторонняя релевантность

4. Content Search (Spotify/YouTube-style)

  • Цель: Найти контент для потребления
  • Сигналы: Popularity, freshness, personalization
  • Challenges: Cold start, diversity

Метрики успеха

Offline метрики

# NDCG (Normalized Discounted Cumulative Gain)
# Учитывает позицию в ранжировании
def ndcg_at_k(relevance_scores, k):
    dcg = sum(rel / log2(i + 2) for i, rel in enumerate(relevance_scores[:k]))
    ideal_dcg = sum(rel / log2(i + 2) for i, rel in enumerate(sorted(relevance_scores, reverse=True)[:k]))
    return dcg / ideal_dcg if ideal_dcg > 0 else 0

# MRR (Mean Reciprocal Rank)
# Позиция первого релевантного результата
def mrr(rankings):
    return np.mean([1 / rank for rank in rankings if rank > 0])

# MAP (Mean Average Precision)
def mean_average_precision(predictions, labels):
    aps = []
    for pred, label in zip(predictions, labels):
        ap = average_precision_score(label, pred)
        aps.append(ap)
    return np.mean(aps)

Online метрики

Метрика Описание Target
CTR@1 Click на первый результат > 30%
CTR@10 Click на любой из топ-10 > 60%
Zero-result Rate Запросы без результатов < 1%
Reformulation Rate Повторные запросы < 20%
Session Success Rate Успешные сессии > 80%
Time to Click Время до клика < 5s

E-commerce специфичные

Метрика Описание
Add-to-Cart Rate Добавление в корзину
Conversion Rate Покупка после поиска
Revenue per Search Выручка на запрос
Average Position of Purchased Item Позиция купленного товара

Ключевые challenges

1. Query-Document Mismatch

Query: "ноутбук для работы"
Document: "MacBook Pro M3 с 16GB RAM..."

Проблема: Нет слова "ноутбук" в описании
Решение: Semantic search, query expansion

2. Vocabulary Mismatch

Query: "кроссы" vs "кроссовки" vs "sneakers"
Решение: Synonyms, stemming, embeddings

3. Intent Ambiguity

Query: "apple"
Intent: Фрукт? Компания? Музыка?
Решение: Personalization, diversification

4. Position Bias

Проблема: Пользователи чаще кликают на топ позиции
Влияние: Training data biased
Решение: Position debiasing, randomization

Trade-offs

Аспект Вариант A Вариант B
Recall vs Latency Больше кандидатов Быстрее
Relevance vs Diversity Точно по запросу Разнообразие
Personalization vs Privacy Лучший опыт Меньше данных
Fresh vs Quality Новые результаты Проверенные
Semantic vs Lexical Понимание смысла Точное совпадение

Ключевые вопросы для интервью

  1. Какой тип поиска? (web, e-commerce, people)
  2. Размер индекса? (1M vs 1B documents)
  3. QPS и latency requirements?
  4. Персонализация нужна?
  5. Какие сигналы доступны? (clicks, purchases, ratings)
  6. Freshness requirements? (real-time vs daily)
  7. Multilingual support?

Заблуждение: NDCG и CTR измеряют одно и то же

NDCG оценивает качество ранжирования всего списка (учитывая позицию каждого результата), а CTR -- только долю кликов. Система с высоким CTR@1 (>30%) может иметь низкий NDCG@10 (<0.6), если релевантные результаты разбросаны по списку. На интервью важно показать понимание обеих метрик.

Заблуждение: семантический поиск полностью заменяет BM25

На практике гибридный retrieval (BM25 + vector search) дает на 15-20% лучший recall, чем любой из методов отдельно. BM25 точно находит exact-match запросы ("iPhone 15 Pro Max"), а semantic search ловит синонимы ("кроссы" -> "кроссовки"). Google, Amazon и LinkedIn используют гибридный подход.

Заблуждение: position bias -- незначительная проблема

Позиция 1 получает в 5-10 раз больше кликов, чем позиция 5, независимо от релевантности. Без position debiasing (inverse propensity weighting, рандомизация 1% трафика) модель обучается на смещённых данных и усиливает bias, создавая порочный круг.

На интервью

Типичные ошибки:

❌ "Я бы использовал только BERT для поиска" -- игнорирует latency (BERT cross-encoder на 10M документов = минуты, не миллисекунды)

❌ "Давайте обучим модель на кликах как есть" -- не упоминает position bias, который делает training data некорректными

❌ "BM25 достаточно, семантика не нужна" -- query "ноутбук для работы" не найдёт "MacBook Pro M3", потому что нет лексического совпадения

Сильные ответы:

✅ "Я бы построил pipeline из 4 стадий: query processing -> retrieval (hybrid BM25 + ANN, 10M -> 1000) -> ranking (LambdaMART, 1000 -> 100) -> re-ranking (diversity + business rules). Бюджет latency: 200ms total."

✅ "Для training data использую graded relevance (purchase=4, cart=3, long dwell=2, click=1, impression=0) с inverse propensity weighting для коррекции position bias."

✅ "Ключевая метрика -- NDCG@10 офлайн, а онлайн -- CTR@10, zero-result rate (<1%), reformulation rate (<20%). A/B тест через interleaving, не split traffic."