Прямой ответ
ML-модель деградирует молча: сервис отвечает без ошибок, метрики инфраструктуры в норме, а качество предсказаний падает, потому что изменились данные. Мониторинг моделей — набор сигналов, который замечает это до жалоб пользователей.
Что мониторить:
- Дрейф входных данных (data drift). Изменилось распределение признаков: появились новые категории, сместился средний чек, изменился состав клиентов.
- Дрейф концепции (concept drift). Изменилась связь «признаки → цель»: то же поведение клиента больше не означает отток.
- Дрейф предсказаний (prediction drift). Изменилось распределение выходов модели — самый быстрый и дешёвый сигнал, потому что не требует истинных значений.
- Качество с задержкой. Когда истинные метки становятся известны (через дни или недели), считают реальные precision/recall и сравнивают с офлайн-оценкой.
- Целостность входа. Доля пропусков, доля значений вне ожидаемого диапазона, доля запросов с отсутствующими признаками.
Метрики дрейфа:
- PSI (Population Stability Index). Сравнение распределений по корзинам:
< 0.1— стабильно,0.1–0.25— заметные изменения,> 0.25— сильное смещение. - KS-статистика. Максимальное расхождение кумулятивных распределений; удобен для числовых признаков.
- Доля категорий-новичков. Признак, что справочник или источник данных изменились.
import numpy as np
def psi(expected: np.ndarray, actual: np.ndarray, bins: int = 10) -> float:
qs = np.quantile(expected, np.linspace(0, 1, bins + 1))
qs[0], qs[-1] = -np.inf, np.inf
e = np.histogram(expected, qs)[0] / len(expected)
a = np.histogram(actual, qs)[0] / len(actual)
e, a = np.clip(e, 1e-6, None), np.clip(a, 1e-6, None)
return float(np.sum((a - e) * np.log(a / e)))
Практический принцип: дрейф входа — не инцидент сам по себе. Он означает, что нужно проверить качество. Алерт на «PSI > 0.25» без процедуры реакции создаёт шум.
Практика: минимальный контур мониторинга
1. Логируйте предсказания. Для каждого запроса: входные признаки (или их хеш), версия модели, предсказание и вероятность, временная метка. Без этих логов анализ невозможен.
2. Считайте распределение предсказаний ежедневно.
SELECT date_trunc('day', ts) AS d,
count(*) AS n,
avg(score) AS avg_score,
percentile_cont(0.5) WITHIN GROUP (ORDER BY score) AS p50,
avg((score > 0.5)::int) AS positive_rate
FROM model_predictions
GROUP BY 1 ORDER BY 1 DESC LIMIT 30;
Резкий сдвиг positive_rate — самый заметный симптом: либо изменились данные, либо сломалась подача признаков.
3. Проверяйте целостность входа. Доля пропусков по каждому ключевому признаку и доля значений вне диапазона. Рост пропусков часто объясняет «внезапную» деградацию лучше, чем сам дрейф. Связь с определением признаков — в статье про feature store.
4. Сравнивайте версии. Если в проде работают champion и challenger, сравнение их предсказаний на одном трафике даёт ранний сигнал — механика версий в статье про model registry.
5. Настройте алерты с процедурой. Каждый алерт должен вести к действию: проверить схему входа → сравнить распределения → при подтверждённой деградации откатить версию. Как оформлять правила и маршрутизацию — в статье про Alertmanager.
Рекомендации:
- Начните с трёх сигналов: распределение предсказаний, доля пропусков, качество с задержкой. Это покрывает большинство реальных инцидентов.
- Храните базовое распределение. PSI и KS требуют эталона — среза данных, на котором модель обучалась или была валидирована.
- Не алертите на каждый дрейф. Сезонность выглядит как дрейф; отличить её помогает сравнение с тем же периодом прошлого года.
- Фиксируйте переобучение как реакцию, а не как рутину. Автоматическое переобучение без проверки качества опасно: оно может закрепить деградацию.
Практический сценарий: качество упало, а ошибок в логах нет
Контекст: скоринг обращений; через месяц после выкатки доля «высокий приоритет» выросла с 12 % до 30 %, жалобы от операторов.
- Быстрая проверка. Ошибок в логах нет, латентность в норме. Смотрим распределение предсказаний: средний скор вырос, сдвиг начался три недели назад.
- Проверка входа. Доля пропусков признака
previous_resolution_hoursвыросла с 2 % до 41 %: изменилась схема источника, и поле перестало заполняться для новых типов обращений. - Подтверждение дрейфа. PSI по этому признаку 0.63; по остальным — в норме. То есть причина точечная, а не общее изменение поведения клиентов.
- Действия. Восстановили заполнение признака в источнике; на время починки включили консервативный порог, чтобы снизить поток ложных «высоких приоритетов».
- Профилактика. Добавили алерт на долю пропусков по ключевым признакам (>10 %) и на PSI (>0.25) с ежедневным расчётом; процедуру внесли в runbook.
Вывод: «модель испортилась» почти всегда означает изменение входных данных. Мониторинг входа находит причину быстрее, чем переобучение.
Как хранить историю для сравнения. Базовое распределение признаков удобно держать как снимок в отдельной таблице с меткой периода: на нём строятся PSI и KS. Снимок должен соответствовать данным, на которых модель была валидирована, иначе метрика дрейфа сравнивает несравнимое. При плановом переобучении базовый снимок обновляют вместе с версией модели, а старый сохраняют для истории.
FAQ
Можно ли обнаружить деградацию без истинных меток? Частично: дрейф входа и распределения предсказаний не требуют меток. Но подтвердить падение качества без них нельзя — только заподозрить. Поэтому истинные метки стоит собирать, даже если они приходят с задержкой.
Как часто считать метрики дрейфа? Для стабильных процессов достаточно ежедневного расчёта. При высокой нагрузке и быстрых изменениях (маркетинговые акции, сезонность) считают чаще, но сравнивают с соответствующим базовым периодом.
Стоит ли переобучать модель автоматически при дрейфе? Только если есть автоматическая проверка качества и возможность отката. Иначе автоматическое переобучение на изменившихся данных может закрепить ошибку, а не исправить её.
Как отличить дрейф от сбоя пайплайна признаков? Сбой обычно даёт резкий скачок доли пропусков или появление постоянного значения; дрейф — плавное смещение распределения. Проверка целостности входа разделяет эти два случая за минуты.
Источники: Wikipedia (concept drift), Prometheus docs (histograms), scikit-learn model evaluation — ссылки в шапке.