Machine Learning Best Practices

Chapter 2 · Practice 2 of 5

Put preprocessing and the model in one Pipeline

From Data splits and leakage

Why it matters

A Pipeline chains transforms with the estimator, so every fit learns preprocessing from the training part only, and every predict applies it consistently. scikit-learn's docs recommend it for two reasons:

  • it prevents inconsistent preprocessing, where a transform used in training is forgotten at test or production time;
  • it prevents leakage inside cross-validation and tuning, because each fold refits the transforms on that fold's training data.

Use a ColumnTransformer when numeric and categorical columns need different steps.

Example

Python
from sklearn.compose import ColumnTransformer
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.impute import SimpleImputer
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler

prep = ColumnTransformer([
    ("num", make_pipeline(SimpleImputer(strategy="median"), StandardScaler()), num_cols),
    ("cat", OneHotEncoder(handle_unknown="ignore"), cat_cols),
])
model = make_pipeline(prep, HistGradientBoostingClassifier(random_state=0))
model.fit(X_train, y_train)