Метрики системы детекции спама¶
~3 минуты чтения
Предварительно: Определение задачи, Компоненты
Gmail блокирует 15 млрд спам-писем в день с precision > 99.9% (1 false positive на 1000 blocked). Dummy-классификатор с "всё нормально" даёт accuracy 55%, но пропускает весь спам. Ключевая сложность: цена FP (легитимное письмо в спам) и FN (спам во входящих) асимметричны -- FP в 10-100 раз дороже FN с точки зрения пользователя.
Иерархия метрик¶
| Уровень | Метрики | Цели |
|---|---|---|
| Business | User complaints, unsubscribe rate, trust score | Complaints < 0.01% |
| Operational | Manual review queue, false positive reports | FP reports < 0.1% |
| Model | Precision, Recall, AUC-PR, F1 | Precision > 99.9%, Recall > 95% |
| System | Latency, throughput, availability | p99 < 50ms, 99.99% uptime |
Business Metrics¶
User-Facing Impact¶
| Метрика | Формула | Цель | Почему важно |
|---|---|---|---|
| Spam reach rate | spam_in_inbox / total_inbox | < 1% | Прямая UX-метрика |
| False positive rate (user-facing) | legit_in_spam / total_legit | < 0.01% | Потеря важных писем |
| User complaint rate | spam_reports / total_delivered | < 0.05% | Сигнал деградации |
| Unsubscribe rate delta | unsub_after - unsub_before | < +0.5% | Косвенный индикатор FP |
Cost Analysis¶
def compute_spam_cost(
daily_emails: int = 300_000_000_000,
spam_ratio: float = 0.45,
fp_cost_per_email: float = 0.50, # lost business, support ticket
fn_cost_per_email: float = 0.001, # user annoyance
infra_cost_monthly: float = 500_000,
) -> dict:
spam_volume = daily_emails * spam_ratio
legit_volume = daily_emails * (1 - spam_ratio)
# At 99.9% precision, 95% recall
fp_daily = legit_volume * 0.001 # 165M FP/day
fn_daily = spam_volume * 0.05 # 6.75B missed spam/day
return {
"fp_cost_daily": fp_daily * fp_cost_per_email, # $82.5M
"fn_cost_daily": fn_daily * fn_cost_per_email, # $6.75M
"infra_cost_daily": infra_cost_monthly / 30,
"key_insight": "FP cost >> FN cost, optimize precision first",
}
Model Metrics¶
Classification Metrics¶
| Метрика | Цель | Почему именно эта |
|---|---|---|
| Precision | > 99.9% | FP = потеря важного письма |
| Recall | > 95% | FN = спам в inbox, терпимо |
| AUC-PR | > 0.95 | Корректна для imbalanced (45% spam) |
| F2-score | > 0.97 | Weighted F-score, recall-biased |
Per-Category Metrics¶
def compute_per_category_metrics(y_true, y_pred, categories):
"""Spam не монолитен -- phishing vs commercial vs malware"""
results = {}
for cat in categories.unique():
mask = categories == cat
tp = ((y_pred[mask] == 1) & (y_true[mask] == 1)).sum()
fp = ((y_pred[mask] == 1) & (y_true[mask] == 0)).sum()
fn = ((y_pred[mask] == 0) & (y_true[mask] == 1)).sum()
results[cat] = {
"precision": tp / (tp + fp) if (tp + fp) > 0 else 0,
"recall": tp / (tp + fn) if (tp + fn) > 0 else 0,
"volume": mask.sum(),
}
return results
# Целевые значения по типам:
# Phishing: recall > 99% (опасно для пользователя)
# Malware: recall > 99.5% (критически опасно)
# Commercial: recall > 90% (менее критично)
# Bot spam: recall > 95%
Adversarial Metrics¶
| Метрика | Описание | Цель |
|---|---|---|
| Evasion rate | % новых спам-паттернов, обходящих модель | < 5% в первые 24h |
| Adaptation time | Время до обнаружения нового паттерна | < 4 часа |
| Model staleness | Деградация precision за неделю без retrain | < 2% drop |
System Metrics¶
Latency Budget¶
Total: 50ms (p99)
+----------------------+--------+---------+
| Stage | Budget | p99 |
+----------------------+--------+---------+
| Header analysis | 5ms | 3ms |
| Content features | 15ms | 12ms |
| ML inference | 15ms | 10ms |
| Reputation lookup | 10ms | 8ms |
| Decision engine | 5ms | 3ms |
+----------------------+--------+---------+
| TOTAL | 50ms | 36ms |
+----------------------+--------+---------+
Throughput & SLA¶
| Метрика | Цель |
|---|---|
| Throughput | 3.5M emails/sec (300B/day) |
| p50 latency | < 20ms |
| p99 latency | < 50ms |
| Availability | 99.99% |
| Error rate | < 0.01% |
Заблуждение: accuracy -- хорошая метрика для спам-детекции
При 45% spam ratio accuracy не так плоха как при 0.1% fraud, но всё равно маскирует проблемы. Модель с recall 80% и precision 99.99% имеет accuracy 91%, выглядит отлично -- но 20% спама проходит в inbox. Правильные метрики: precision (> 99.9%) как primary, recall (> 95%) как secondary, с разбивкой по типам спама (phishing recall > 99%).
Заблуждение: одна модель для всех типов спама
Email spam, SMS smishing, fake reviews и bot accounts -- разные задачи с разными features и метриками. Email: header + body + reputation, latency 50ms. SMS: short text only, latency 10ms. Reviews: user behavior + text + purchase history, batch OK. Метрики тоже разные: для email precision > 99.9%, для reviews precision > 95% достаточно (есть fallback на модерацию).
Секция для интервью¶
Вопрос: "Какие метрики для спам-детекции?"
Слабый ответ: "Precision и recall."
Сильный ответ: "Четыре уровня. Business: spam reach rate (< 1%), user complaint rate (< 0.05%), false positive reports (< 0.1%). Model: precision > 99.9% (FP = потерянное важное письмо), recall > 95% с разбивкой по типам (phishing recall > 99%, commercial > 90%). Adversarial: evasion rate < 5% в первые 24h после нового паттерна. System: p99 < 50ms, 3.5M emails/sec. Ключевой insight: FP в 10-100x дороже FN -- пользователь простит спам во входящих, но не простит потерю важного письма."