Как посчитать Hit Rate@k в SQL

Закрепи формулу hit rate at k в Карьернике
Запомнить надолго — 5 коротких сессий с задачами на эту тему. Бесплатно
Тренировать hit rate at k в Telegram

Зачем Hit Rate@k

Hit Rate@k = доля запросов, у которых хотя бы один релевантный документ оказался в top-k результатов. Самая простая «recall-like» метрика, не учитывает позицию. Если HitRate@10 = 80%, в 8 из 10 запросов юзер видит правильный ответ в первых 10.

Формула

HitRate@k = (1/N) × Σ I(any relevant in top-k for query i)

I — индикатор (0 или 1). Range: [0, 1].

Hit Rate в SQL

WITH query_hits AS (
    SELECT
        query_id,
        MAX(CASE WHEN is_relevant = TRUE AND rank <= 10 THEN 1 ELSE 0 END) AS has_hit_at_10
    FROM search_results
    WHERE query_date >= CURRENT_DATE - INTERVAL '30 days'
    GROUP BY query_id
)
SELECT
    SUM(has_hit_at_10)::NUMERIC * 100 / NULLIF(COUNT(*), 0) AS hit_rate_at_10_pct,
    COUNT(*) AS total_queries
FROM query_hits;

MAX(CASE WHEN ...) — флаг «есть ли хотя бы один».

Разные k

WITH query_results AS (
    SELECT
        query_id,
        rank,
        is_relevant
    FROM search_results
    WHERE query_date >= CURRENT_DATE - INTERVAL '30 days'
),
hits AS (
    SELECT
        query_id,
        MAX(CASE WHEN is_relevant AND rank <= 1  THEN 1 ELSE 0 END) AS hit_1,
        MAX(CASE WHEN is_relevant AND rank <= 5  THEN 1 ELSE 0 END) AS hit_5,
        MAX(CASE WHEN is_relevant AND rank <= 10 THEN 1 ELSE 0 END) AS hit_10,
        MAX(CASE WHEN is_relevant AND rank <= 20 THEN 1 ELSE 0 END) AS hit_20
    FROM query_results
    GROUP BY query_id
)
SELECT
    AVG(hit_1)  * 100 AS hr_at_1_pct,
    AVG(hit_5)  * 100 AS hr_at_5_pct,
    AVG(hit_10) * 100 AS hr_at_10_pct,
    AVG(hit_20) * 100 AS hr_at_20_pct
FROM hits;

HitRate@k монотонно растёт с k. Большая разница между k=5 и k=10 = модель хорошо находит, но плохо ранжирует на самый верх.

Закрепи формулу hit rate at k в Карьернике
Запомнить надолго — 5 коротких сессий с задачами на эту тему. Бесплатно
Тренировать hit rate at k в Telegram

По сегментам запросов

WITH per_query AS (
    SELECT
        query_category,
        query_id,
        MAX(CASE WHEN is_relevant AND rank <= 10 THEN 1 ELSE 0 END) AS has_hit
    FROM search_results
    WHERE query_date >= CURRENT_DATE - INTERVAL '30 days'
    GROUP BY query_category, query_id
)
SELECT
    query_category,
    AVG(has_hit) * 100 AS hr_at_10_pct,
    COUNT(*) AS queries
FROM per_query
GROUP BY query_category
HAVING COUNT(*) >= 5
ORDER BY hr_at_10_pct DESC;

Категории с low HR — где модель плохо работает: либо мало данных, либо специфические запросы.

Частые ошибки

Ошибка 1. Hit Rate vs precision. HR говорит «есть ли релевантный в top-k». Precision — «какая доля top-k релевантны». Разные.

Ошибка 2. Multiple-relevant queries. Если в каждом запросе много релевантных, HR раскрывает мало — все ≈ 100%. NDCG / MAP полезнее.

Ошибка 3. Игнорировать sample size. HR на 100 запросах — широкий CI. Минимум 1000+ для значимости.

Ошибка 4. Считать только клики как «relevant». Click-through ≠ relevance. Юзер мог кликнуть и быстро уйти. Используйте dwell time или explicit feedback.

Ошибка 5. HR@k одинаков для разных моделей при разных k. Модель А лучше при k=10, модель B при k=5. Сравните по нескольким k.

Связанные темы

FAQ

Hit Rate vs Recall?

Hit Rate — есть ли хоть один в top-k. Recall — доля всех релевантных в top-k. Эквивалентны при 1 relevant per query.

Какой k?

@5, @10, @20 — стандарт. @1 для top-1 интерфейсов.

HR @k для long-tail запросов?

Часто < 50%. Нормально для редких запросов.

Сравнить HR между датасетами?

Сложно. HR зависит от prevalence и сложности запросов.

Hit Rate в production?

Часто заменяется на CTR (click-through) — proxy без ground truth.