Предобработка данных

Коротко

Definition

Предобработка данных — это этап ML pipeline, на котором данные очищают, проверяют, преобразуют и кодируют так, чтобы модель могла корректно и устойчиво на них обучаться.

Предобработка нужна не для «косметики», а для качества модели.

Она помогает:

  • убрать технические ошибки;
  • обработать пропуски;
  • привести признаки к нужному формату;
  • избежать утечек данных;
  • сделать признаки пригодными для конкретного алгоритма;
  • улучшить устойчивость и интерпретируемость модели.

Предобработка особенно важна для табличных данных, где признаки часто имеют разные типы, масштабы, пропуски, выбросы и категориальные значения.

Интуиция

Модель учится не на «реальном мире», а на том представлении данных, которое мы ей дали.

Если в данных есть:

  • пропуски;
  • дубликаты;
  • разные масштабы признаков;
  • неверные типы данных;
  • редкие категории;
  • выбросы;
  • утечки из будущего;
  • признаки, недоступные на инференсе;

то модель может обучиться неправильно, даже если алгоритм выбран хорошо.

Предобработка — это способ сделать данные честными, понятными и пригодными для обучения.

Главная идея:

Сначала нужно построить корректное представление данных, и только потом оценивать качество модели.

Основные идеи

Главный риск: data leakage

Important

Все трансформации, которые используют статистики данных, должны обучаться только на train-части. Нельзя считать среднее, медиану, стандартное отклонение, категории, target encoding или отбор признаков на всём датасете до разбиения на train/validation/test.

Правильный порядок:

  1. Разделить данные на train/validation/test.
  2. Обучить preprocessing-трансформеры только на train.
  3. Применить обученные трансформеры к validation/test.
  4. Сохранить эти же трансформеры для инференса.

Неправильный порядок:

  1. Заполнить пропуски по всему датасету.
  2. Отмасштабировать признаки по всему датасету.
  3. Отобрать признаки по всему датасету.
  4. Потом разделить на train/test.

Так возникает утечка информации из validation/test в train. Модель получает слишком оптимистичную оценку качества и может провалиться на новых данных.

Типовой порядок предобработки

Примерный порядок:

  1. Проверить схему данных.
  2. Проверить типы столбцов.
  3. Удалить явные дубликаты и технические ошибки.
  4. Разделить данные на train/validation/test.
  5. Обработать пропуски.
  6. Обработать семантические ошибки.
  7. Обработать выбросы.
  8. Создать доменные признаки.
  9. Кодировать категориальные признаки.
  10. Трансформировать распределения при необходимости.
  11. Масштабировать численные признаки.
  12. Отобрать признаки.
  13. Собрать всё в воспроизводимый pipeline.

Этот порядок не абсолютный. Он зависит от задачи, модели и природы данных. Но принцип остаётся: всё, что «учится» по данным, должно fit-иться только на train.

Что анализировать в данных

АспектЧто проверятьРиск без проверки
СхемаОжидаемые столбцы, типы, названияКод ломается или признаки интерпретируются неверно
ПолнотаПропуски, пустые строки, дубликатыСмещение модели, потеря информации
СемантикаДопустимые диапазоны, логическая согласованностьМодель учится на невозможных значениях
ВыбросыЭкстремальные значения, ошибки измеренияНестабильность неробастных моделей
РаспределенияSkewness, хвосты, дисбаланс классовПлохая сходимость, неверный выбор метрик
МасштабыРазные порядки величинДоминирование одних признаков над другими
КатегорииРедкие категории, новые категории, порядокОшибки кодирования и переобучение
МультиколлинеарностьКорреляции, VIFНестабильные коэффициенты и интерпретация
Связь с targetКорреляция, mutual information, доменная логикаШумовые или бесполезные признаки

Пропуски

Цель обработки пропусков — сохранить полезную информацию и сделать данные пригодными для алгоритмов, которые не умеют работать с missing values.

Типы пропусков:

ТипРасшифровкаЧто означает
MCARMissing Completely At RandomПропуски не зависят от данных
MARMissing At RandomПропуск зависит от других признаков
MNARMissing Not At RandomПропуск зависит от самого скрытого значения

Примеры обработки:

СитуацияВозможное решение
Очень мало случайных пропусковУдалить строки
Числовой признак без сильного skewЗаполнить средним
Числовой признак со skew или выбросамиЗаполнить медианой
Категориальный признакЗаполнить модой или отдельной категорией
Пропуск сам информативенДобавить флаг is_missing
Много пропусков в неважном признакеУдалить признак
Сложная структура пропусковKNN/MICE/модельная импутация

Важно: импьютер обучается только на train, а затем применяется к validation/test.

Выбросы

Выброс — это значение, которое сильно отличается от основной массы данных.

Но не каждый выброс нужно удалять.

Сначала нужно понять тип выброса:

ТипПримерЧто делать
Техническая ошибкаВозраст = 999Исправить или удалить
Семантически невозможное значениеОтрицательная массаИсправить или удалить
Редкое, но реальное значениеОчень дорогая квартираЧасто оставить
Шум измеренияОшибка сенсораОбработать
Важный экстремальный случайАномалия, fraud, дефектНе удалять без анализа

Способы обработки:

  • удалить некорректные строки;
  • winsorization;
  • clipping;
  • log-transform;
  • robust scaling;
  • использовать робастную модель;
  • оставить как есть, если выбросы важны для задачи.

Деревья решений, случайный лес и градиентный бустинг обычно менее чувствительны к масштабу и умеренным выбросам, чем линейные модели, SVM, k-means и нейросети.

Трансформация распределений

Некоторые признаки имеют сильный skew или тяжёлые хвосты. Это может мешать линейным моделям, градиентной оптимизации и расстояниевым методам.

Примеры трансформаций:

УсловиеМетодИдея
log1p(x)Сжать правый хвост
Box-CoxПодобрать степенную трансформацию
Любые значенияYeo-JohnsonУниверсальная степенная трансформация
Сильные выбросыQuantile transformПривести к заданному распределению

Ориентиры по skewness:

  • — трансформация обычно не нужна;
  • — можно рассмотреть;
  • — трансформация часто полезна.

Но трансформация должна быть осмысленной. Нельзя автоматически логарифмировать всё подряд без проверки доменного смысла.

Масштабирование

Масштабирование приводит численные признаки к сопоставимому масштабу.

Оно особенно важно для моделей, которые зависят от расстояний или градиентов:

  • SVM;
  • k-means;
  • KNN;
  • PCA;
  • линейные модели с регуляризацией;
  • нейросети.

Деревья решений, случайный лес и градиентный бустинг обычно не требуют масштабирования.

Основные scaler-ы:

МетодФормула / идеяКогда использовать
StandardScalerБез сильных выбросов, линейные модели, SVM, нейросети
MinMaxScalerПриведение к Ограниченный диапазон, некоторые neural network pipeline
RobustScalerЕсть выбросы или тяжёлые хвосты
NormalizerНормирует объект как векторТекстовые/векторные признаки, cosine similarity

Важно: scaler fit-ится только на train.

Кодирование категориальных признаков

Модели обычно требуют численные признаки, поэтому категории нужно кодировать.

Перед кодированием полезно проверить:

  • редкие категории;
  • опечатки;
  • разные варианты одной категории;
  • новые категории, которые могут появиться на инференсе;
  • есть ли естественный порядок.

Основные методы:

МетодКогда использоватьРиск
One-hot encodingНебольшое число категорий без порядкаРост размерности
Ordinal encodingЕсть естественный порядокЛожный порядок, если порядка нет
Frequency encodingМного категорий, важна частотностьМожет потерять смысл категории
Target encodingМного категорий, сильная связь с targetВысокий риск leakage
EmbeddingsНейросети, много категорийНужно больше данных

Important

Target encoding нельзя считать по всему датасету. Его нужно делать через K-Fold/OOF-схему, smoothing и только внутри train, иначе модель напрямую получает информацию о target.

Редкие категории часто объединяют в Other, особенно если их слишком мало для устойчивого обучения.

Конструирование признаков

Конструирование признаков — создание новых признаков на основе исходных данных и предметной логики.

Примеры:

ТипПример
Датыгод, месяц, день недели, час
Отношенияцена за квадратный метр, плотность, отношение масс
Разностиразница температур, изменение во времени
Агрегациисреднее значение по группе, количество событий
Полиномы,
Циклические признакиsin(hour), cos(hour)
Доменная физикаформулы, размерности, нормировки

Feature engineering особенно важен для табличных данных. Часто хороший доменный признак даёт больше пользы, чем более сложный алгоритм.

Дисбаланс классов

В классификации нужно проверять распределение классов.

Если positive-класс редкий, accuracy может быть бесполезной. Модель может почти всегда предсказывать majority class и выглядеть хорошо по accuracy.

Способы работы:

  • class weights;
  • oversampling;
  • undersampling;
  • SMOTE;
  • threshold tuning;
  • stratified split;
  • правильные метрики: precision, recall, F1, PR-AUC.

Подробнее: Метрики качества классификаторов.

Отбор признаков

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

Методы:

ТипПримеры
Filter methodsкорреляция, mutual information, chi-square, ANOVA
Wrapper methodsforward selection, backward selection, recursive feature elimination
Embedded methodsL1-регуляризация, feature importance в деревьях
Доменный отборудаление признаков, невозможных на инференсе

Что проверять:

  • константные признаки;
  • почти константные признаки;
  • сильную корреляцию между признаками;
  • признаки с утечкой target;
  • признаки, недоступные в момент предсказания;
  • признаки, которые слишком дороги или нестабильны.

Ориентиры:

  • корреляция — признаки почти дублируют друг друга;
  • VIF или — возможная мультиколлинеарность;
  • доля одного значения — почти константный признак.

Когда использовать

Предобработка нужна почти всегда, когда данные идут в ML-модель.

Особенно важна, если:

  • данные табличные;
  • есть пропуски;
  • есть категориальные признаки;
  • признаки имеют разные масштабы;
  • используется SVM, k-means, KNN или нейросеть;
  • есть риск data leakage;
  • данные собираются из разных источников;
  • модель будет использоваться на новых данных;
  • нужно воспроизводимое обучение и инференс.

Для production-подхода preprocessing должен быть частью pipeline, а не набором разрозненных ручных действий.

Когда не использовать

Предобработку нельзя делать механически.

Не стоит:

  • удалять все выбросы без доменного анализа;
  • масштабировать признаки для деревьев просто «по привычке»;
  • делать target encoding без защиты от leakage;
  • считать статистики на всём датасете до split;
  • трансформировать признаки так, что они теряют предметный смысл;
  • применять train-only признаки, которых не будет на инференсе.

Плохая предобработка может навредить сильнее, чем её отсутствие.

Минимальный пример

import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.linear_model import LogisticRegression
 
df = pd.DataFrame({
    "age": [20, 35, None, 50],
    "city": ["A", "B", "A", None],
    "target": [0, 1, 0, 1],
})
 
X = df.drop(columns=["target"])
y = df["target"]
 
X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.25,
    random_state=42,
)
 
numeric_features = ["age"]
categorical_features = ["city"]
 
numeric_pipeline = Pipeline([
    ("imputer", SimpleImputer(strategy="median")),
    ("scaler", StandardScaler()),
])
 
categorical_pipeline = Pipeline([
    ("imputer", SimpleImputer(strategy="most_frequent")),
    ("encoder", OneHotEncoder(handle_unknown="ignore")),
])
 
preprocess = ColumnTransformer([
    ("num", numeric_pipeline, numeric_features),
    ("cat", categorical_pipeline, categorical_features),
])
 
model = Pipeline([
    ("preprocess", preprocess),
    ("classifier", LogisticRegression()),
])
 
model.fit(X_train, y_train)
print(model.predict(X_test))

В этом примере preprocessing входит внутрь Pipeline, поэтому импьютеры, scaler и encoder обучаются только на train-части.

Связанные понятия

Что знать перед этим

Связанные заметки