Skip to content
Machine Learning
ML Foundations 8 min read

scikit-learn Pipelines & Workflow

The estimator API, data leakage, and how Pipeline, ColumnTransformer, and GridSearchCV turn your workflow into one tunable, leak-proof object.

Download notebook Open Google ColabIn Colab: File → Upload notebook → pick the downloaded file.

You now know the workflow (split → fit → predict → evaluate) and you've seen that preprocessing like scaling must be fit on training data only. Doing that by hand gets error-prone fast — real datasets need imputation and scaling and encoding, each with its own fit-on-train rule. scikit-learn's answer is the Pipeline: bundle every step into a single object that behaves like one model. This lesson is the glue that holds the rest of the course together.

One interface: fit, predict, transform

Everything in scikit-learn is an estimator sharing a tiny, consistent API:

  • est.fit(X_train, y_train) — learn from data. Models learn parameters; preprocessors learn statistics (a scaler learns means, an encoder learns categories).
  • est.predict(X) — for models (predictors): output labels or numbers.
  • est.transform(X) — for transformers (preprocessors): output a modified copy of the data.
  • est.fit_transform(X) — fit then transform in one call (train data only!).

Because every scaler, encoder, imputer, and model speaks this same language, you can swap a KNN for a random forest — or a MinMax scaler for a standard one — without changing the surrounding code. That uniformity is what makes pipelines possible.

Leakage: the silent score inflator

Data leakage is when information from the test set sneaks into training. The model's scores look great, then reality disappoints. The most common leaks are mundane:

  • Scaling with statistics from all rows — the test set's mean has leaked into training.
  • Imputing missing values using the full dataset — same problem.
  • Tuning hyperparameters against the test set — after enough peeks, the test set is effectively memorized.

The rule that prevents leakage

Fit anything that learns from data — scalers, imputers, encoders, models — on the training split only. Then apply (transform) it, unchanged, to the test split. Never call fit, or fit_transform, on test data.

Pipeline: preprocessing and model as one estimator

A Pipeline chains transformers and ends with a model. When you call fit, it fit-transforms each step on training data in sequence; when you call predict or score, it only transforms — the fit-on-train rule is enforced automatically:

Python — runs in your browser

The cross_val_score call is doing something subtle and important. A single train/test split can be lucky or unlucky; k-fold cross-validation splits the training data into k parts, trains on k−1 and validates on the remaining one, rotating k times — like judging a student on both a midterm and a final instead of one exam. The mean of the k scores is a far more robust estimate. And because we passed the pipeline, the scaler is refit inside every fold — zero leakage, zero manual bookkeeping.

Mixed columns: ColumnTransformer

Real tables mix numeric columns (scale them, impute with the median) and categorical columns (impute with the most frequent value, one-hot encode them). ColumnTransformer routes each group of columns through its own mini-pipeline:

Python — runs in your browser

Four messy columns in; seven clean numeric columns out — missing values filled, numerics standardized, categories expanded into one-hot indicator columns. handle_unknown="ignore" keeps predictions from crashing if a category appears at test time that training never saw.

Tuning the whole pipeline: GridSearchCV

Hyperparameters (like KNN's n_neighbors) shouldn't be tuned against the test set. GridSearchCV tries every parameter combination using cross-validation inside the training data, then refits the best one. Name pipeline steps and address their parameters with a double underscore, as in knn__n_neighbors:

Python — runs in your browser

That's 4 × 2 = 8 combinations, each cross-validated 3 times — 24 fits, all leak-free because scaling happens inside each fold. On real projects the grid is bigger and you'd add n_jobs=-1 to parallelize across CPU cores (and consider RandomizedSearchCV when the grid explodes).

The complete modern workflow, then, in one breath: split → build preprocessor + model into a pipeline → grid-search with CV on the training set → evaluate once on the test set. This skeleton carries you through nearly every tabular ML problem.

Check your understanding

5 questions · free
  1. Q1.Which method does a transformer (like StandardScaler) use to modify data after fitting?

  2. Q2.You call scaler.fit_transform on the ENTIRE dataset before splitting. What went wrong?

  3. Q3.Why is cross_val_score(pipeline, ...) safer than scaling manually and then cross-validating the bare model?

  4. Q4.In a pipeline with a step named "knn", how do you refer to its n_neighbors in a GridSearchCV param grid?

  5. Q5.What does ColumnTransformer add on top of Pipeline?

Exercise: Build a leak-proof pipeline for messy data

Create a synthetic 200-row DataFrame with two numeric columns (income, age — make the label depend on income), one categorical column (city), and about 15% missing values in income. Build a full pipeline — ColumnTransformer preprocessing plus a KNeighborsClassifier — and tune n_neighbors and weights with a small GridSearchCV. Report the best CV score and the final test accuracy.

Next up: before any pipeline runs, you have to understand your data — EDA and feature engineering, where most real-world accuracy is won.