Ранжирование поиска: определение задачи¶
~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, контент-платформ.
Примеры применения¶
| Компания | Что ищут | Ключевая метрика |
|---|---|---|
| Веб-страницы | CTR, Query Success Rate | |
| Amazon | Товары | Conversion, GMV |
| Люди, вакансии | Application Rate, Connections | |
| Spotify | Песни, плейлисты | Play Rate, Session Duration |
| Airbnb | Жильё | Booking Rate |
Постановка задачи¶
Функциональные требования¶
- Relevance Ranking: Результаты отсортированы по релевантности
- Query Understanding: Понимание intent пользователя
- Personalization: Учёт предпочтений пользователя
- Real-time: Обновление индекса в реальном времени
- Spell Correction: Исправление опечаток
- 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¶
3. Intent Ambiguity¶
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 | Понимание смысла | Точное совпадение |
Ключевые вопросы для интервью¶
- Какой тип поиска? (web, e-commerce, people)
- Размер индекса? (1M vs 1B documents)
- QPS и latency requirements?
- Персонализация нужна?
- Какие сигналы доступны? (clicks, purchases, ratings)
- Freshness requirements? (real-time vs daily)
- 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."