machine learning
Python
sklearn
GridSearchCV
fit_transform

Python sklearn fit_transform does not work for GridSearchCV

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

fit_transform() is not something you should run on the full dataset before GridSearchCV. Doing that lets the transformer learn from validation folds in advance, which creates data leakage and makes cross-validation scores look better than they really are.

Why fit_transform Before the Search Is Wrong

Suppose you scale features before running grid search:

python
1from sklearn.model_selection import GridSearchCV
2from sklearn.preprocessing import StandardScaler
3from sklearn.svm import SVC
4
5scaler = StandardScaler()
6X_scaled = scaler.fit_transform(X)
7
8grid = GridSearchCV(
9    SVC(),
10    param_grid={"C": [0.1, 1, 10], "kernel": ["linear", "rbf"]},
11    cv=5,
12)
13grid.fit(X_scaled, y)

The code runs, but the evaluation is flawed. StandardScaler was fit on the entire dataset, including examples that later belong to validation folds. That means information from validation data influenced the transformation used during training.

The model has effectively seen a summary of the validation set ahead of time. Even if the leakage seems small, it is enough to bias model selection and score reporting.

The Correct Pattern: Put Preprocessing in a Pipeline

The fix is to place preprocessing and the estimator in a Pipeline. Then GridSearchCV refits the pipeline separately inside each cross-validation split.

python
1from sklearn.model_selection import GridSearchCV
2from sklearn.pipeline import Pipeline
3from sklearn.preprocessing import StandardScaler
4from sklearn.svm import SVC
5
6pipe = Pipeline([
7    ("scaler", StandardScaler()),
8    ("svc", SVC()),
9])
10
11param_grid = {
12    "svc__C": [0.1, 1, 10],
13    "svc__kernel": ["linear", "rbf"],
14}
15
16grid = GridSearchCV(pipe, param_grid=param_grid, cv=5, scoring="accuracy")
17grid.fit(X, y)
18
19print(grid.best_params_)
20print(grid.best_score_)

Now the scaler is fit only on the training fold for each split, and the validation fold is transformed using that fold-specific fitted scaler. That is the behavior you want.

What Happens Internally

GridSearchCV does not need you to call fit_transform manually. It clones the estimator for each parameter combination and each fold. When that estimator is a pipeline, the pipeline handles the sequence:

  1. fit the first transformer on the training fold
  2. transform the training fold
  3. fit the next step if needed
  4. fit the final estimator
  5. transform the validation fold using the already-fitted transformers
  6. score the model on the validation fold

That is why pipeline-based preprocessing is the standard scikit-learn pattern. The library can only protect the train-validation boundary if preprocessing is inside the estimator object passed to cross-validation.

Tuning Preprocessing Parameters Too

The pipeline approach also lets you tune preprocessing parameters along with model hyperparameters.

python
1from sklearn.decomposition import PCA
2from sklearn.model_selection import GridSearchCV
3from sklearn.pipeline import Pipeline
4from sklearn.preprocessing import StandardScaler
5from sklearn.svm import SVC
6
7pipe = Pipeline([
8    ("scaler", StandardScaler()),
9    ("pca", PCA()),
10    ("svc", SVC()),
11])
12
13param_grid = {
14    "pca__n_components": [5, 10, 20],
15    "svc__C": [0.1, 1, 10],
16    "svc__kernel": ["linear", "rbf"],
17}
18
19grid = GridSearchCV(pipe, param_grid=param_grid, cv=5, n_jobs=-1)
20grid.fit(X, y)

The double underscore syntax means "parameter of a named pipeline step." This is how you search across the entire preprocessing-and-model stack.

Mixed Data with ColumnTransformer

Real datasets often have numeric and categorical columns that need different preprocessing. The same rule still applies: put everything inside the cross-validated pipeline.

python
1from sklearn.compose import ColumnTransformer
2from sklearn.model_selection import GridSearchCV
3from sklearn.pipeline import Pipeline
4from sklearn.preprocessing import OneHotEncoder, StandardScaler
5from sklearn.ensemble import RandomForestClassifier
6
7preprocessor = ColumnTransformer([
8    ("num", StandardScaler(), ["age", "salary"]),
9    ("cat", OneHotEncoder(handle_unknown="ignore"), ["city", "department"]),
10])
11
12pipe = Pipeline([
13    ("prep", preprocessor),
14    ("clf", RandomForestClassifier(random_state=42)),
15])
16
17param_grid = {
18    "clf__n_estimators": [100, 200],
19    "clf__max_depth": [None, 10],
20}
21
22grid = GridSearchCV(pipe, param_grid=param_grid, cv=5)
23grid.fit(X, y)

This keeps the preprocessing logic honest for every fold, no matter how many transformations are involved.

Common Pitfalls

  • Calling fit_transform on the entire dataset before GridSearchCV, which leaks validation information.
  • Forgetting that pipeline parameters use step_name__parameter_name.
  • Preprocessing X_train correctly but then transforming X_test with a separately fitted transformer.
  • Assuming leakage only matters for scaling when it also matters for encoding, imputation, feature selection, and dimensionality reduction.
  • Using a pipeline for training but bypassing it at prediction time instead of calling best_estimator_.predict(...).

Summary

  • Do not call fit_transform on the full dataset before GridSearchCV.
  • Put preprocessing steps and the model inside a Pipeline.
  • 'GridSearchCV will then fit transformers on training folds and apply them correctly to validation folds.'
  • Use step__param names to tune preprocessing and estimator settings together.
  • The safest prediction path is the fitted best_estimator_, which includes the full preprocessing pipeline.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.