Почему ML-модель падает в продакшене: утечки данных и time travel | AiManual
AiManual Logo Ai / Manual.
18 Янв 2026 Гайд

Модель на 99% в тестах, на 0% в продакшене: как время и данные ломают ML-системы

Глубокий разбор реальных проблем ML в production: time travel leakage, fraud detection кейсы, проектирование систем. Для инженеров и Data Scientists.

Тихий ужас каждого ML-инженера

Вы только что обучили модель. На тестовой выборке - 99.2% accuracy. На кросс-валидации - 98.7%. Вы чувствуете себя богом машинного обучения. Запускаете в продакшен. И через неделю получаете звонок: "Модель предсказывает хуже, чем монетка. Что случилось?"

Это не баг. Это закономерность. 87% ML-моделей в реальных системах работают хуже, чем в тестах. И 64% из них ломаются из-за проблем, которых нет в учебниках по ML.

Если ваша модель идеальна на тренировке - вы что-то упустили. Идеальных моделей не бывает. Бывают плохие тесты.

Time Travel Leakage: преступление, которое вы совершаете каждый день

Представьте: вы строите модель для предсказания мошеннических транзакций. У вас есть данные за 2020-2023 годы. Вы берете все данные, перемешиваете, делите на train/test. Обучаете. Получаете фантастические метрики.

А теперь вопрос: в реальной жизни 1 января 2021 года у вас были данные за 2022 год? Нет. Но ваша модель их видела.

💡
Time Travel Leakage - это когда модель во время обучения видит данные из будущего относительно момента предсказания. В реальности таких данных у нее быть не может. Это как дать студенту на экзамене ответы заранее, а потом удивляться, почему он такой умный.

Реальный кейс: как мы сломали fraud-систему на $2 млн

Был у меня проект в финтехе. Модель детектила мошеннические переводы. На исторических данных - 99.4% precision. В продакшене первые две недели - тоже хорошо. Потом начался ад.

Оказалось, в данных была фича "количество транзакций за последние 7 дней". В тренировочных данных она считалась по всей истории. В реальности на момент транзакции мы знали только прошлые транзакции. Модель училась на информации, которой у нее никогда не будет в production.

# КАК НЕ НАДО ДЕЛАТЬ
import pandas as pd

# Все данные в кучу
df = pd.read_csv('all_transactions_2020_2023.csv')
# Перемешиваем - это смерть
df = df.sample(frac=1, random_state=42)

# Делим на train/test
# Модель видит транзакции из 2023 года при предсказании 2021 года
# Это читерство
train = df.iloc[:int(0.8*len(df))]
test = df.iloc[int(0.8*len(df)):]

Как это исправить? Time-based split

Единственный правильный способ - разделять данные по времени. Если модель будет предсказывать транзакции 2023 года, она должна тренироваться только на данных до 2023 года.

# КАК НАДО ДЕЛАТЬ
import pandas as pd
from datetime import datetime

# Сортируем по времени
df = df.sort_values('transaction_timestamp')

# Разделяем по времени
# Train: 2020-01-01 до 2022-12-31
train_cutoff = datetime(2022, 12, 31)
train = df[df['transaction_timestamp'] <= train_cutoff]

# Test: 2023-01-01 и позже
test = df[df['transaction_timestamp'] > train_cutoff]

# Теперь модель не видит будущего
# Метрики будут реалистичными (и скорее всего хуже)

Дрейф данных: мир меняется, а ваша модель - нет

Ковид. Инфляция. Новые законы. Смена поведения пользователей. Ваши тренировочные данные устарели в момент запуска модели. Это concept drift и data drift.

Тип дрейфа Что происходит Пример
Concept Drift Связь между фичами и таргетом меняется До ковида люди редко заказывали еду на дом. После - постоянно
Data Drift Распределение фичей меняется Средний чек вырос в 2 раза из-за инфляции
Label Drift Распределение таргета меняется Доля мошеннических транзакций упала после внедрения 2FA

Как детектировать дрейф? Мониторинг

Без мониторинга вы слепы. Нужно отслеживать:

  • Распределение ключевых фичей (KS-тест, PSI)
  • Метрики модели в реальном времени
  • Сдвиги в предсказаниях
  • Качество ground truth (если есть)
# Простой мониторинг дрейфа
import numpy as np
from scipy import stats

def detect_drift(train_data, prod_data, feature):
    """Детектим дрейф с помощью KS-теста"""
    stat, p_value = stats.ks_2samp(
        train_data[feature], 
        prod_data[feature]
    )
    
    # p-value < 0.05 значит дрейф есть
    return p_value < 0.05, p_value

# Пример использования
has_drift, p_val = detect_drift(
    train_df, 
    last_week_prod_df, 
    'transaction_amount'
)

if has_drift:
    print(f"ВНИМАНИЕ: Дрейф в transaction_amount! p-value: {p_val:.4f}")
    # Пора переобучать модель или исследовать причину

Проблемы с фичами: что знает модель в реальном времени?

Самая частая ошибка: использовать фичи, которые в реальности недоступны в момент инференса.

Кейс: предсказание оттока клиентов

Модель предсказывает, уйдет ли клиент в этом месяце. В фичах:

  • Количество обращений в поддержку за месяц (ок)
  • Сумма покупок за месяц (ок)
  • Был ли отказ от подписки в этом месяце (СТОП!)

Если клиент уже отказался от подписки - он уже ушел. Модель учится на тавтологии. В реальности в момент предсказания мы не знаем, откажется ли клиент.

Правило: каждая фича должна быть доступна в момент предсказания. Если для расчета фичи нужны данные из будущего - выбросьте ее.

Архитектурные проблемы: ML-система ≠ модель

Модель - это 10% ML-системы. Остальное - инфраструктура. И она ломается чаще.

Проблема 1: разная предобработка

На тренировке вы нормализовали данные одним способом. В продакшене другой сервис делает это по-другому. Результат - мусор на входе модели.

# Тренировка
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)

# Сохраняем scaler для продакшена
import joblib
joblib.dump(scaler, 'scaler.pkl')

# В продакшене
# ВСЕГДА используем тот же scaler
scaler = joblib.load('scaler.pkl')
X_prod_scaled = scaler.transform(X_prod)  # НЕ fit_transform!

Проблема 2: задержки данных

В тренировочных данных все чисто и синхронизировано. В продакшене:

  • Данные из Kafka приходят с задержкой 5 минут
  • База данных реплицируется с лагом
  • Кэш не инвалидируется вовремя

Модель получает устаревшие фичи. Предсказывает на основе вчерашних данных.

Пошаговый план: как не сломать продакшен

1 Проверка временных утечек

Перед любым split спросите: "В реальности в этот момент времени у модели были бы эти данные?" Если нет - перестраивайте split.

2 Аудит фичей

Для каждой фичи создайте документацию:

  • Источник данных
  • Время доступности
  • Задержка обновления
  • Может ли содержать информацию из будущего

3 Симуляция продакшена

Запустите модель на исторических данных, имитируя реальные условия:

  • Только те данные, которые были доступны на каждую дату
  • С теми же задержками, что в production
  • С реальными ошибками и пропусками данных

4 Мониторинг с первого дня

Не ждите, пока что-то сломается. Настройте алерты на:

  • Дрейф распределений (PSI > 0.1)
  • Падение метрик
  • Аномалии во входных данных
  • Задержки в пайплайнах

5 План отката

Что делать, если модель сломалась?

  • Вернуться к предыдущей версии
  • Включить fallback-правила
  • Увеличить пороги для консервативных предсказаний

Инструменты, которые спасут вашу карьеру

Не изобретайте велосипед. Используйте:

Проблема Инструмент За что отвечает
Временные утечки Temporal Validation в sklearn Правильное разделение по времени
Мониторинг дрейфа Evidently AI, WhyLabs Детектирование сдвигов в данных
Версионирование MLflow, DVC Слежка за моделями, данными, кодами
Продакшен пайплайны Kubeflow, Metaflow Оркестрация обучения и инференса

Что почитать дальше

Если вы дочитали до сюда - вы серьезный человек. Вот что поможет глубже погрузиться в тему:

Главный секрет: лучшие ML-инженеры - не те, кто строит модели с 99.9% accuracy. Это те, чьи модели стабильно работают на 85% accuracy, но НИКОГДА не падают ниже 80%. Надежность важнее идеальности.

Следующий раз, когда ваша модель покажет 99% на тестах - насторожитесь. Скорее всего, вы что-то упустили. Проверьте временные утечки. Проанализируйте фичи. Запустите симуляцию продакшена. И только потом запускайте в реальный мир.

P.S. Если после прочтения вы проверили свои модели и нашли time travel leakage - поздравляю. Вы только что сэкономили компании кучу денег и себе - бессонную ночь на разборе полетов.