Как подойти к препроцессингу датасета
Что проверяют
Понимаете ли вы, что препроцессинг зависит от данных и модели, а не проходит по одному шаблону. Главное, что ищут: знаете ли вы про утечку данных. Следом почти всегда спрашивают, в какой момент делить выборку и на чём обучать скейлер.
Как отвечать
Начните с разбиения, а не с чистки: всё, что учится на данных (медиана для заполнения, параметры масштаба, словарь категорий), обучается только на train. В scikit-learn это решают Pipeline и ColumnTransformer: тогда fit вызывается внутри кросс-валидации на каждом фолде отдельно.
Дальше по шагам:
- разбиение: случайное подходит для независимых строк. Для временных данных нужен сплит по времени (
TimeSeriesSplit), для нескольких записей одного клиента групповой (GroupKFold), для редкого класса стратифицированный; - пропуски: сначала выяснить причину.
SimpleImputerс медианой плюс флаг пропуска часто лучше удаления строк, а LightGBM и CatBoost умеют работать сNaNсами; - категории: для линейных моделей и сетей one-hot через
OneHotEncoder(handle_unknown="ignore"), для высокой кардинальности target encoding с кросс-валидацией,OrdinalEncoderдля деревьев или реально упорядоченных значений; - масштаб:
StandardScaler, а при выбросахRobustScalerнужны линейным моделям, kNN, SVM и сетям. Деревьям масштаб безразличен; - выбросы: отличить ошибку ввода от редкого, но реального значения. Ошибки чинить, реальные значения оставлять или логарифмировать;
- признаки: отбор по важности или
RFEтоже живёт внутри пайплайна.
Хорошо звучит мысль про воспроизводимость: один и тот же пайплайн сериализуется и применяется в проде к новым данным без ручных шагов.
Где спотыкаются
Нормализуют весь датасет до разбиения. Метрика на тесте получается завышенной, потому что статистики теста уже просочились в обучение.
Отвечают, что деление на train и test «защищает от переобучения». Оно только позволяет его заметить.
Кодируют номинальные признаки числами 0, 1, 2 для линейной модели и получают порядок там, где его нет.