← Назад к вопросам

Как определишь качество работы модели целевых контактов?

2.4 Senior🔥 141 комментариев
#Machine Learning#Статистика и математика

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Определение качества работы модели целевых контактов

Модель целевых контактов (targeting model, lead scoring) — это критическая система в CRM и маркетинге. Как Product Analyst, нужно уметь оценивать её эффективность.

Что такое "модель целевых контактов"

Это ML модель, которая предсказывает:

  • Какой лид наиболее вероятно совершит покупку
  • Какой клиент уйдёт (churn prediction)
  • На какого пользователя нужно потратить больше внимания sales team

Примеры:

  • B2B SaaS: скорить на каких компаниях лучше фокусироваться (высокий fit + budget)
  • E-commerce: какому пользователю предложить premium покупку
  • Банк: какому клиенту одобрить кредит

Проблема: как измерить качество

Часто companies смотрят на отвлечённые метрики:

  • Accuracy = 85%
  • Precision = 90%

Но это НЕ значит что модель хороша для бизнеса.

3 уровня оценки качества модели

Уровень 1: Статистические метрики (ML metrics)

Это базовые метрики качества предсказаний.

Матрица ошибок (Confusion Matrix):

                Модель предсказала: "Да"    Модель предсказала: "Нет"
Реально: "Да"   TP (True Positive)          FN (False Negative)
Реально: "Нет"  FP (False Positive)         TN (True Negative)

Основные метрики:

# Accuracy — общая точность (часто БЕСПОЛЕЗНА)
Accuracy = (TP + TN) / (TP + TN + FP + FN)

# Precision — из предсказанных как "Да" сколько реально "Да"
Precision = TP / (TP + FP)
# Если Precision = 80%, значит 80% рекомендаций = реальные лиды

# Recall (Sensitivity) — из реальных "Да" сколько мы поймали
Recall = TP / (TP + FN)
# Если Recall = 70%, значит упустили 30% лидов

# F1 Score — гармоническое среднее Precision + Recall
F1 = 2 * (Precision * Recall) / (Precision + Recall)

# ROC-AUC — площадь под кривой ROC (0.5 = случайная, 1.0 = идеально)
AUC = Area Under ROC Curve

Примеры интерпретации:

Model A: Precision=95%, Recall=40%, F1=0.56
→ Мало FP (хорошие рекомендации), но упускаем много лидов

Model B: Precision=70%, Recall=80%, F1=0.75
→ Сбалансирован, потеряем 20% лидов но 70% рекомендаций верны

Model C: Precision=50%, Recall=95%, F1=0.67
→ Ловим почти всех, но 50% рекомендаций неверны (много FP)

SQL для расчета:

WITH predictions AS (
    SELECT
        lead_id,
        actual_converted,
        predicted_score,
        CASE WHEN predicted_score > 0.5 THEN 1 ELSE 0 END as predicted_class
    FROM model_predictions
    WHERE evaluation_date >= DATE_SUB(TODAY(), INTERVAL 30 DAY)
)
SELECT
    SUM(CASE WHEN actual_converted = 1 AND predicted_class = 1 THEN 1 ELSE 0 END) as TP,
    SUM(CASE WHEN actual_converted = 1 AND predicted_class = 0 THEN 1 ELSE 0 END) as FN,
    SUM(CASE WHEN actual_converted = 0 AND predicted_class = 1 THEN 1 ELSE 0 END) as FP,
    SUM(CASE WHEN actual_converted = 0 AND predicted_class = 0 THEN 1 ELSE 0 END) as TN,
    
    ROUND(100.0 * TP / (TP + FP), 1) as precision_pct,
    ROUND(100.0 * TP / (TP + FN), 1) as recall_pct,
    ROUND(100.0 * (TP + TN) / (TP + TN + FP + FN), 1) as accuracy_pct
FROM predictions

Уровень 2: Бизнес-метрики (Quality of outcomes)

Статистика важна, но бизнес волнует результат.

Главная метрика: Lift

Lift = Conversion Rate (targeted) / Conversion Rate (baseline)

Пример:
- Random selection из всех лидов: 5% converts
- Model selection (top 20% scored): 12% converts
- Lift = 12% / 5% = 2.4x

Это значит модель дает 2.4x лучше результат чем случайный выбор

SQL для расчета:

WITH baseline AS (
    SELECT 
        COUNT(DISTINCT lead_id) as total_leads,
        COUNT(DISTINCT CASE WHEN converted = 1 THEN lead_id END) as converted,
        ROUND(100.0 * converted / total_leads, 1) as baseline_cr_pct
    FROM all_leads
    WHERE created_at >= DATE_SUB(TODAY(), INTERVAL 30 DAY)
),
targeted AS (
    SELECT 
        COUNT(DISTINCT lead_id) as targeted_leads,
        COUNT(DISTINCT CASE WHEN converted = 1 THEN lead_id END) as converted,
        ROUND(100.0 * converted / targeted_leads, 1) as targeted_cr_pct
    FROM model_predictions
    WHERE predicted_score > 0.7  -- только high confidence
      AND created_at >= DATE_SUB(TODAY(), INTERVAL 30 DAY)
)
SELECT
    baseline.baseline_cr_pct,
    targeted.targeted_cr_pct,
    ROUND(targeted.targeted_cr_pct / baseline.baseline_cr_pct, 2) as lift
FROM baseline CROSS JOIN targeted

Другие важные метрики:

МетрикаФормулаЧто значит
CoverageTop_10%_conversions / Total_conversionsСколько из лучших лидов в top 10% модели
Cost per LeadTotal_Sales_Cost / Leads_ContactedЭффективность затрат
Sales EfficiencyRevenue / Sales_HoursПроизводительность sales
Lead QualityConversion Rate от modelКакой % лидов реально конвертятся

Уровень 3: Диагностический анализ (Debugging)

Когда модель работает хуже чем ожидалось, нужно понять почему.

Метод 1: Decile Analysis

Разделяем лиды на 10 групп по score и смотрим конверсию:

WITH scored_leads AS (
    SELECT
        lead_id,
        model_score,
        converted,
        NTILE(10) OVER (ORDER BY model_score DESC) as decile
    FROM model_predictions
)
SELECT
    decile,
    COUNT(*) as lead_count,
    ROUND(100.0 * SUM(converted) / COUNT(*), 1) as conversion_rate_pct,
    ROUND(AVG(model_score), 3) as avg_score
FROM scored_leads
GROUP BY decile
ORDER BY decile

Результат должен выглядеть так:

Decile  | Lead Count | Conversion Rate | Avg Score
--------|------------|-----------------|----------
1 (Top)    | 100    | 18%              | 0.95
2          | 100    | 16%              | 0.82
3          | 100    | 14%              | 0.71
4          | 100    | 12%              | 0.61
5          | 100    | 8%               | 0.52
6          | 100    | 6%               | 0.42
7          | 100    | 5%               | 0.33
8          | 100    | 3%               | 0.22
9          | 100    | 2%               | 0.12
10 (Bottom)| 100    | 1%               | 0.03

Хорошая модель — монотонное снижение conversion rate с топа вниз

Плохая модель — нет четкого паттерна или перекрёстки

Метод 2: Feature Importance

Проверяем какие факторы влияют на score:

# Какие features самые важные в модели?
import shap

explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X_test)

# Визуализировать какие features влияют на предсказание
shap.summary_plot(shap_values, X_test, plot_type="bar")

# Выводы:
# Если модель опирается на 1-2 фактора → переоверфиттинг
# Если использует много разумных факторов → хорошая генерализация

Метод 3: Calibration Check

Проверяем что predicted probabilities соответствуют реальным:

from sklearn.calibration import calibration_curve

# Модель предсказала 80% probability
# Сколько из этих лидов реально конвертились?

fpr, mpv = calibration_curve(y_true, y_pred_proba, n_bins=10)

# Если точки близко к diagonal → модель хорошо калибрована
# Если выше диагонали → модель overconfident
# Если ниже диагонали → модель underconfident

Пример: как я оцениваю модель в реальной работе

Шаг 1: Быстрая проверка (5 минут)

-- Работает ли вообще?
SELECT
    COUNT(*) as total,
    COUNT(CASE WHEN predicted_score > 0.7 THEN 1 END) as high_score_count,
    ROUND(100.0 * SUM(converted) / COUNT(*), 1) as overall_cr,
    ROUND(100.0 * SUM(CASE WHEN predicted_score > 0.7 AND converted = 1 THEN 1 END) 
          / COUNT(CASE WHEN predicted_score > 0.7 THEN 1 END), 1) as high_score_cr
FROM model_predictions
WHERE created_at >= DATE_SUB(TODAY(), INTERVAL 30 DAY)

Если high_score_cr > overall_cr в 2+ раза → модель работает.

Шаг 2: Детальная оценка (30 минут)

  • Decile analysis (видим ли тренд)
  • Precision, Recall, F1
  • Lift по сегментам
  • Feature importance

Шаг 3: Постоянный мониторинг (weekly)

-- Dashboard для weekly tracking

SELECT
    DATE(created_at) as date,
    COUNT(*) as leads,
    ROUND(100.0 * SUM(converted) / COUNT(*), 1) as cr_pct,
    ROUND(100.0 * SUM(CASE WHEN predicted_score > 0.7 THEN 1 END) / COUNT(*), 1) as high_score_pct,
    ROUND(100.0 * SUM(CASE WHEN predicted_score > 0.7 AND converted THEN 1 END) 
          / NULLIF(SUM(CASE WHEN predicted_score > 0.7 THEN 1 END), 0), 1) as high_score_cr_pct
FROM model_predictions
WHERE created_at >= DATE_SUB(TODAY(), INTERVAL 90 DAY)
GROUP BY DATE(created_at)
ORDER BY date DESC

Красные флаги: когда модель плохо работает

🚩 ФлагЧто проверить
Lift < 1.2xМодель не лучше random, нужна переподготовка
Decile analysis без трендаFeatures не релевантны
Recall < 50%Упускаем половину лидов, слишком консервативно
Precision < 60%40% рекомендаций неверны, отпугивает sales
Data driftРаспределение данных изменилось, нужна переподготовка
Feature importance: 1 feature > 50%Переоверфиттинг на одном факторе

Рекомендуемый процесс оценки

  1. Day 1: Быстрая проверка работает ли
  2. Week 1: Decile analysis + Lift на разных сегментах
  3. Month 1: Feature importance, calibration, drift check
  4. Every week: Dashboard с трендом Lift и CR
  5. Every month: Полный audit + рекомендации по улучшению

Качество модели = (Статистика × Бизнес-результаты) / Сложность модели

Простая модель с 2.0x Lift > сложная модель с 2.2x Lift и data drift problems.