Как ответить
Сначала — не паниковать и не менять модель вслепую. Классическая причина такого расхождения — data drift (смещение распределения признаков) или concept drift (изменение зависимости между признаками и целевой переменной). Валидация была честной, но продакшн-данные отличаются. Мой план действий:
- Шаг 1. Собрать логи и ground truth. Нужны предсказания модели и реальные значения (если доступны с задержкой). Если лейблов нет — работаем только с фичами.
- Шаг 2. Сравнить распределения фич. Беру выборку из продакшна (последние N записей) и сравниваю с валидационной. Использую Population Stability Index (PSI) или KS-тест. PSI > 0.1 — повод копать глубже. Пример кода для расчёта PSI:
import numpy as np
def psi(expected, actual, bins=10):
# expected — валидация, actual — продакшн
breaks = np.percentile(expected, np.linspace(0, 100, bins+1))
expected_bins = np.histogram(expected, breaks)[0] / len(expected)
actual_bins = np.histogram(actual, breaks)[0] / len(actual)
psi = sum((actual_bins - expected_bins) * np.log(actual_bins / expected_bins))
return psi- Шаг 3. Проверить target shift. Если ground truth приходит, смотрю распределение таргета. Если среднее значение сместилось — модель могла перестать быть калиброванной.
- Шаг 4. Оценить метрики на продакшн-данных. Если есть лейблы, считаю те же метрики, что на валидации (AUC, F1, MAE). Если метрика упала — дрейф подтверждён.
- Шаг 5. Проверить качество данных. Часто проблема в пайплайне: пропуски, новые категории, сбой feature engineering. Смотрю на долю missing values, уникальные значения категориальных фич.
- Шаг 6. Улучшение модели. Если дрейф обнаружен — переобучаю модель на свежих данных (ретрайн). Если данных мало — добавляю регуляризацию, упрощаю модель. Для concept drift — окна обучения (скользящее окно или детектор дрейфа типа ADWIN).
- Шаг 7. Внедрить мониторинг. Ставлю алерты по PSI и метрикам. Фиксирую версию данных и модели. Периодический ретрайн по расписанию.
Пример из практики: на одном проекте модель регрессии показывала MAE=2.3 на валидации, а в продакшне — 5.1. PSI по фиче «возраст» был 0.35 — оказалось, что изменился источник данных (стали приходить клиенты из другого региона). После ретрайна на новых данных MAE вернулась к 2.5.