Прямой ответ
Поиск аномалий нужен, когда редкие события нельзя разметить заранее: мошенничество нового типа, сбой оборудования, всплеск ошибок, необычное поведение пользователя. Главная сложность — оценка качества: истинных меток нет или их очень мало.
Методы и когда их применять:
- Статистические границы (z-score, IQR). Быстро и объяснимо. Подходят для одномерных метрик с устойчивым распределением. Не работают при сезонности и мультимодальности.
- Isolation Forest. Строит случайные деревья; аномалии изолируются за меньшее число разбиений, поэтому получают более высокий «score аномальности». Хорошо работает на табличных данных средней размерности и не требует предположений о распределении.
- One-Class SVM / Local Outlier Factor. Полезны, когда важна локальная плотность: объект аномален относительно своих соседей. Требуют аккуратной настройки и хуже масштабируются.
- Пороговые правила на перцентилях. Для метрик с известной сезонностью часто эффективнее моделей: аномалия — это выход за границы, построенные по истории. Как работать с перцентилями — в статье про гистограммы метрик.
from sklearn.ensemble import IsolationForest
import numpy as np
model = IsolationForest(n_estimators=300, contamination=0.01, random_state=42)
model.fit(X_train)
scores = model.score_samples(X_test) # чем меньше, тем аномальнее
labels = model.predict(X_test) # -1 для аномалий
Ключевые практические моменты:
contamination— это гипотеза, а не факт. Параметр задаёт ожидаемую долю аномалий и напрямую определяет порог. Ставить «0.01 по умолчанию» — значит подгонять результат под ожидание.- Обучение на «чистых» данных. Если в обучающей выборке много аномалий, границы размываются. Практика: обучать на периоде без известных инцидентов либо итеративно исключать найденные выбросы.
- Масштабирование и пропуски. Для SVM и LOF масштаб признаков критичен; Isolation Forest к масштабу устойчив, но пропуски нужно обработать явно.
- Сезонность. Без её учёта модель будет считать аномалиями регулярные пики. Решение — сравнивать с соответствующим периодом истории или предварительно вычитать сезонную компоненту.
Практика: от модели к полезному сигналу
1. Выбирайте рабочие точки по последствиям. Аномалии почти всегда идут на ручную проверку, поэтому главное ограничение — пропускная способность команды. Порог выбирают так, чтобы в день попадало разумное число случаев.
2. Оценивайте качество без полной разметки.
- Precision@K. Сколько из K самых аномальных случаев действительно требуют внимания. Проверяется экспертом на небольшой выборке.
- Обогащение. Во сколько раз доля реальных инцидентов среди flagged выше, чем в среднем по данным.
- Ручная валидация выборки. 50–100 случаев, размеченных экспертом, дают больше информации, чем любые автоматические метрики.
3. Логируйте решения. Для каждого flagged-случая фиксируйте скор, признаки и вердикт эксперта. Накопленная разметка со временем позволяет перейти к обучению с учителем — см. метрики при дисбалансе.
4. Разделяйте типы аномалий. Точечный выброс, сдвиг уровня и изменение формы распределения требуют разных методов. Одна модель на всё обычно посредственна во всех трёх случаях.
Пример пороговой проверки для метрик:
def flag_anomaly(value: float, history: list[float], window: int = 28) -> bool:
hist = history[-window:]
lo, hi = np.quantile(hist, [0.01, 0.99])
iqr = np.subtract(*np.quantile(hist, [0.75, 0.25]))
return value < lo - 1.5 * iqr or value > hi + 1.5 * iqr
Рекомендации:
- Начинайте с простого. Для одномерных метрик перцентильные границы часто работают не хуже Isolation Forest и объясняются одной фразой.
- Не алертите на каждую аномалию. Поток ложных срабатываний приводит к тому, что алерты игнорируют; правила и маршрутизацию настраивают через Alertmanager.
- Следите за дрейфом базовой линии. То, что было аномалией полгода назад, может стать нормой; границы нужно пересчитывать — подходы описаны в статье про мониторинг моделей.
- Фиксируйте версию модели и периода обучения. Без этого невозможно объяснить, почему вчера случай попадал в аномалии, а сегодня нет.
Практический сценарий: поток ложных срабатываний после обновления
Контекст: детектор аномалий в метриках оплаты; после релиза число алертов выросло с 3 до 60 в день.
- Диагностика. Распределение времени ответа сместилось: новый код добавил этап валидации, p50 вырос с 120 до 190 мс. Границы аномалий были построены на старой истории, поэтому обычный трафик стал «аномальным».
- Проверка модели. Isolation Forest обучен на периоде до релиза и не учитывает новые признаки запроса; часть случаев попадала в аномалии из-за отсутствующего поля.
- Исправление. (а) Пересобрали базовую линию на данных после релиза; (б) добавили обработку отсутствующих признаков; (в) разделили детекцию на два контура: сдвиг уровня (перцентили) и точечные выбросы (Isolation Forest).
- Результат. Число алертов вернулось к 2–4 в день, доля подтверждённых инцидентов среди flagged выросла с 8 % до 45 %.
- Профилактика. Переобучение детектора привязали к релизам: при изменении поведения сервиса базовая линия пересчитывается автоматически, а до пересчёта детектор работает в режиме предупреждений.
Вывод: детектор аномалий ломается не из-за алгоритма, а из-за устаревшей базовой линии. Пересчёт границ после изменений обязателен.
FAQ
Можно ли оценить качество детектора без разметки? Косвенно: через precision@K на проверенной экспертом выборке и через обогащение. Полноценная оценка появляется только после накопления разметки по результатам ручного разбора.
Почему Isolation Forest работает? Аномалии немногочисленны и отличаются от основной массы, поэтому случайные разбиения изолируют их быстрее. Средняя длина пути до изоляции становится мерой аномальности, и это не требует предположений о форме распределения.
Что лучше для временных рядов: модель или перцентили? Для метрик с выраженной сезонностью перцентильные границы по истории того же периода обычно надёжнее и объяснимее. Модели оправданы, когда аномалия определяется сочетанием нескольких признаков, а не одним значением.
Как бороться с тем, что аномалий в обучающих данных слишком много? Итеративно: обучить на периоде без известных инцидентов, найти явные выбросы, исключить подтверждённые инциденты и переобучить. Дополнительно помогает робастное масштабирование и работа с логарифмами значений.
Источники: scikit-learn outlier detection, Isolation Forest paper, Prometheus histograms — ссылки в шапке.