Автор: Илья Воронцов, аналитик данных и ML-специалист

Привет! Я Илья Воронцов. За годы в Data Science я видел, как команды тратят недели на модели, которые в итоге не работают. Почему? Базовые ошибки при обучении моделей машинного обучения — это не про сложную математику, а про простые промахи: от данных до валидации. В этой статье разберём 10 ключевых ловушек, которые встречаются у новичков и даже опытных специалистов. Для каждой — причина, последствия и чёткий план действий. Всё с примерами из реальных проектов, чтобы вы могли сразу применить.

Если вы строите первую модель или отлаживаете пайплайн в бизнес-задаче (предсказание оттока клиентов, сегментация или рекомендационная система), эти советы сэкономят часы. Давайте разберём по шагам.

Почему ошибки в обучении моделей — это проблема №1 для ML-проектов

В 80% случаев модели проваливаются не из-за слабого алгоритма, а из-за ошибок на этапе подготовки и обучения. По моему опыту в проектах для e-commerce и финансов, игнорирование базовых вещей приводит к переобучению, низкой точности и моделям, которые не работают на проде.

Ключевые последствия:

  • Трата времени: неделя на «идеальную» модель, которая даёт 50% accuracy.
  • Бизнес-риски: неверные предсказания оттока приводят к потере клиентов.
  • Разочарование в ML: «Мы попробовали, не сработало».

Решение — системный подход. Ниже таблица с топ-ошибками и быстрыми фиксами для сканирования.

Ошибка Частота (по моему опыту) Быстрый фикс
Недостаток данных 40% Аугментация + синтетика
Неправильный split 25% Stratified K-Fold
Игнор feature engineering 15% Корреляция + SHAP
Переобучение 10% Early stopping + dropout

Теперь по порядку.

Ошибка 1: Недостаточно данных для обучения модели

Почему происходит: Новички берут 100–500 строк и ждут чуда. Модели типа Random Forest или нейросетей требуют тысяч примеров, чтобы уловить паттерны. На практике даже для простой логистической регрессии на десяти фичах 500 объектов — это почти гарантированная нестабильность коэффициентов.

Последствия: Модель «запоминает» данные, но на новых — полный провал (accuracy падает на 20–30%). В задаче предсказания цен на жильё с 300 объектами модель дала RMSE 50k рублей на train, но 200k на test. Разрыв в четыре раза — типичный признак, что данных катастрофически мало.

Как исправить:

  1. Проверьте объём: для табличных данных — минимум 1k строк на класс, но если зависимость сложная, может потребоваться в разы больше. Ориентируйтесь не на абсолютное число, а на стабильность метрик при кросс-валидации.
  2. Аугментируйте: для изображений — повороты, зеркала (библиотека Albumentations). Для текстов можно использовать обратный перевод или замену синонимов.
  3. Генерируйте синтетику: SMOTE для несбалансированных классов, но помните — он создаёт линейные комбинации, что может внести шум, если данные не очень разделимы. Для сложных случаев лучше GAN или вариационные автоэнкодеры.
  4. Практика: В Python: from imblearn.over_sampling import SMOTE; smote = SMOTE(); X_res, y_res = smote.fit_resample(X, y).

Проверка: Train/test gap < 5%. Инструмент: scikit-learn train_test_split(test_size=0.2). Если gap больше, модель не обобщает — либо данных мало, либо переобучение.

Ошибка 2: Неправильный разбиение данных (data leakage и bias)

Почему: Берут случайный split, не учитывая временные ряды или стратификацию. Leakage — когда future данные просачиваются в train. Например, при прогнозировании продаж случайное перемешивание позволяет модели «увидеть» будущие цены через идентификаторы или косвенные признаки.

Последствия: Модель показывает 95% accuracy на валидации, но 60% на проде. В реальном проекте по оттоку клиентов мы случайно включили в train данные о пост-оттоковых действиях (жалобы после ухода) — модель идеально предсказывала отток, но на новых клиентах была бесполезна.

Как исправить:

  • Временные данные: train = df[df['date'] < '2025-01-01']. Всегда делайте split по времени, а не случайно. Если данных мало, используйте скользящий кросс-валидационный сплит (TimeSeriesSplit).
  • Несбалансированные классы: StratifiedKFold (n_splits=5). Он сохраняет пропорции классов в каждом фолде, что критично для редких событий.
  • Leakage чек: Удалите target из features, проверьте корреляцию признаков с target. Если какой-то признак имеет подозрительно высокую корреляцию (например, 0.9), возможно, он содержит информацию о будущем.

Код-пример:

from sklearn.model_selection import StratifiedKFold
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
for train_idx, val_idx in skf.split(X, y):
    X_train, X_val = X[train_idx], X[val_idx]
    y_train, y_val = y[train_idx], y[val_idx]

Ошибка 3: Игнорирование feature engineering

Почему: «Сырые» данные кидают в модель без обработки. Фичи коррелированы, пропуски не заполнены. Часто новички считают, что градиентный бустинг «сам разберётся», но даже XGBoost может запутаться в мультиколлинеарности, если признаки дублируют информацию.

Последствия: Модель путает сигналы, accuracy на 10–15% ниже. В задаче оттока клиентов возраст и стаж коррелированы — модель «сходит с ума», приписывая важность то одному, то другому, и интерпретация становится ненадёжной.

Шаги по фиксу:

  1. Заполнение пропусков: Median для числовых, mode для категориальных (df.fillna(df.median())). Но лучше анализировать природу пропуска: если он не случаен, создайте отдельный бинарный признак «был ли пропуск».
  2. Кодирование: OneHot для номинальных, Target Encoding для высококардинальных — но осторожно, с регуляризацией (smoothing), чтобы избежать переобучения на редких категориях.
  3. Новые фичи: Взаимодействия (age * income), биннинг, полиномы. В одном проекте добавление признака «средний чек за последние 30 дней» подняло ROC-AUC на 0.05.
  4. Отбор: SHAP values или SelectKBest. SHAP хорош для интерпретации, но требует обученной модели; SelectKBest быстрее для отсеивания шума на старте.

Таблица топ-инструментов:

Задача Инструмент Пример
Корреляция df.corr() Удалить >0.9
Важность фич SHAP shap.summary_plot()
Масштабирование StandardScaler Перед градиентным бустингом

Ошибка 4: Переобучение (overfitting) — модель зубрит train

Почему: Слишком сложная модель (глубокий RF, большая NN) на малых данных. Деревья без ограничения глубины могут идеально запомнить обучающую выборку, включая шум.

Симптомы: Train accuracy 98%, val 75%. Разрыв >5% уже повод насторожиться. В одном проекте по кредитному скорингу мы получили AUC 0.99 на train и 0.72 на test — модель выучила идентификаторы клиентов, а не закономерности.

Фиксы:

  • Регуляризация: L1/L2 в логистике, dropout (0.2–0.5) в NN. L1 также помогает отбирать признаки, зануляя коэффициенты.
  • Early stopping: В Keras: callbacks=[EarlyStopping(patience=10)]. Терпение в 10 эпох — стандарт, но если loss на валидации скачет, лучше уменьшить до 5.
  • Ансамбли: Bagging (RF) вместо одной модели. Случайный лес сам по себе менее склонен к переобучению, чем одно глубокое дерево.
  • Кросс-валидация: Всегда 5-fold. Она не лечит переобучение, но позволяет его вовремя заметить.

Практика: Мониторьте с TensorBoard или MLflow. В MLflow удобно логировать кривые обучения и сравнивать эксперименты.

Ошибка 5: Подбор гиперпараметров наугад

Почему: «По умолчанию» из sklearn — редко оптимально. Например, n_estimators=100 в Random Forest может быть избыточно для простой задачи и недостаточно для сложной.

Как делать правильно:

  • GridSearchCV для малого поиска — когда пространство параметров невелико, и вы можете позволить полный перебор.
  • Optuna или Hyperopt для байесовского поиска. Optuna удобнее благодаря встроенной визуализации и возможности прерывать и возобновлять поиск.
  • Пример для XGBoost: optuna.create_study(direction='maximize'). Определите разумные диапазоны: learning_rate от 0.01 до 0.3, max_depth от 3 до 10.

Время экономия: 2–3 часа vs неделя ручного тюнинга. Но помните: даже байесовский поиск не спасёт, если не настроена функция потерь или неправильно выбрана метрика.

Ошибка 6: Неправильный выбор метрики

Почему: Accuracy для несбалансированных данных — обман. Если положительный класс составляет 1%, модель, предсказывающая всегда отрицательный, получит accuracy 99%, но не найдёт ни одного нужного случая.

Выбор по задаче:

Задача Метрика Почему
Бинарная классификация F1-score, ROC-AUC Учёт классов
Регрессия RMSE, MAE Разный вес ошибок
Несбалансированные Precision@K Бизнес-цена

На практике лучше согласовать метрику с бизнес-заказчиком. Например, в задаче оттока важнее recall (не пропустить уходящих), а в задаче фрод-мониторинга — precision (чтобы не блокировать честные транзакции).

Код: from sklearn.metrics import classification_report — он даёт полную картину по каждому классу.

Ошибка 7: Игнор outliers и аномалий

Почему: Не чистят данные — модель учится на шуме. Одиночный выброс в регрессии может сильно сместить линию, особенно если используется MSE.

Фикс:

  1. Визуализация: boxplot. Быстро показывает экстремальные значения.
  2. Z-score >3 — удалить или winsorize. Winsorizing (замена на пороговые значения) предпочтительнее, когда данных мало и жалко терять наблюдения.
  3. Isolation Forest для авто-детекта. Хорош для многомерных выбросов, которые не видны в одномерных распределениях.

Пример: В ценах на товары outliers от «1 рубль» искажают регрессию. В одном проекте после удаления таких записей RMSE снизился на 30%.

Ошибка 8: Забытые категориальные переменные

Почему: OrdinalEncoder вместо OneHot — модель видит порядок, которого нет. Для номинальных категорий (страна, цвет) порядковое кодирование вносит ложную иерархию.

Правильно: pd.get_dummies() или CategoryEncoders. Если категорий много, используйте Target Encoding с регуляризацией или Count Encoding. А ещё лучше — CatBoost, который умеет обрабатывать категории на лету, но всё равно стоит проверять, не появилось ли смещения.

Ошибка 9: Нет валидации на hold-out

Почему: Только train/test — не видно стабильности. Одна случайная разбивка может дать оптимистичную оценку, особенно на малых данных.

Фикс: 70/15/15 split + K-Fold. Отложенный hold-out (15%) не участвует ни в обучении, ни в подборе гиперпараметров — это финальный экзамен. Если модель хорошо работает на кросс-валидации, но проваливается на hold-out, значит, вы переоптимизировали под валидационные фолды.

Ошибка 10: Модель не деплоится (игнор MLOps)

Почему: Jupyter-ноутбук не превращается в API. Модель, которая работает в ноутбуке, часто не воспроизводится из-за несохранённых зависимостей, путей к данным и версий библиотек.

Шаги: Docker + FastAPI + MLflow для трекинга. Заверните модель в контейнер с фиксированными версиями пакетов, сделайте простой REST API. MLflow сохранит параметры, метрики и артефакты, чтобы можно было откатиться к удачной версии.

Чек-лист: как обучать модель без ошибок

  • Собрал >1k данных?
  • Stratified split?
  • Features: scale, encode, engineer?
  • CV score > threshold?
  • No overfitting (gap <5%)?
  • Метрика под бизнес?
  • Тест на hold-out?

Скопируйте в Notion — используйте перед каждым обучением.

FAQ: Ответы на частые вопросы об ошибках в обучении моделей

Что делать, если данных мало для машинного обучения?

Начните с аугментации (SMOTE) или transfer learning (HuggingFace). Если <500 строк — рассмотрите rule-based подход. В некоторых случаях помогает генерация синтетических данных с помощью GAN, но это требует аккуратной проверки на реалистичность. Иногда лучше собрать больше данных, чем пытаться выжать невозможное из крошечной выборки.

Как быстро проверить переобучение?

Plot learning curves: train vs val loss. Если расходятся — добавьте регуляризацию. Ещё один быстрый тест: сравните качество на train и test; если разница больше 5–10%, модель переобучена. Для нейросетей полезно смотреть на динамику весов: резкие скачки могут указывать на нестабильность.

Лучший фреймворк для новичков?

Scikit-learn для старта, XGBoost для бустинга, PyTorch для кастомных NN. Scikit-learn даёт единообразный API и отличную документацию. XGBoost часто выигрывает «из коробки» на табличных данных. PyTorch более гибкий, но требует понимания автоматического дифференцирования.

Сколько времени на feature engineering?

30–50% всего времени проекта. Это даёт +15–20% к accuracy. В реальных проектах генерация осмысленных признаков часто важнее выбора модели. Не жалейте времени на анализ предметной области и создание признаков, отражающих бизнес-логику.

Как измерить качество модели в продакшене?

A/B-тест с baseline + мониторинг drift (Alibi Detect). Сравните новую модель с текущим решением на реальном трафике. Отслеживайте дрейф данных и концепций: если распределение признаков изменилось, модель может деградировать незаметно для стандартных метрик.

Эта статья — ваш щит от типичных фейлов. Примените на следующем проекте и увидите разницу. Если есть кейсы — пишите в комментариях, разберём вместе!