Concepts / Combining Grid Search and Pipelines for Model Selection

Combining Grid Search and Pipelines for Model Selection

A Pipeline is built from a list of (step name, estimator or transformer) tuples, and the list order defines the sequence of data processing.

  • Programming

A Single Line That Builds Two Steps

Model selection and preprocessing show up together so often that you will meet one line of Python again and again. That line builds a Pipeline out of two pieces: a scaler that prepares the data, and a classifier that learns from the prepared data. Before reading any explanation, look at the line and decide what it constructs. The rest of this article unpacks exactly what happens when Python runs it.

python

What do you think happens?

Before reading on, what do you think this line constructs, and which piece runs first when data is passed in?

Reveal answer
Answer:

It constructs one Pipeline with two ordered steps. The step named 'preprocessing' runs first and uses StandardScaler(), and the step named 'classifier' runs second and uses SVC().

The Pipeline is built from a list in which each element is a tuple of a step name and an estimator or transformer object. The list order defines the sequence of data processing, so the scaler comes before the classifier.

How a Pipeline Is Built From Named Steps

Definition

A Pipeline is built from a list of (step name, estimator or transformer) tuples. The step name is a string you choose, and the object is what performs that step. The list order defines the sequence of data processing.

In the line above, 'preprocessing' is the name of the first step and StandardScaler() is the object that performs it. 'classifier' is the name of the second step and SVC() is the object that performs it. The names are not decoration. They are how each part of the pipeline gets an identity you can use later.

Once a pipeline exists, you can read its structure back. The steps attribute holds the list of (name, object) pairs in the same order you supplied them. Because the order is preserved, the first element of that list is the first step the data passes through.

python
Output (expected)
[('preprocessing', StandardScaler()), ('classifier', SVC())]
Notes on the code
  • The list order matches the order you wrote the tuples in
  • Index 0 is the first step the data passes through
Raw featurespreprocessingStandardScaler()classifierSVC()Predictionsenters first stepprepared featureslearned output
What happens to the data as fit or predict moves it from the scaler to the classifier. The classifier never receives the raw features directly.

Read the diagram from left to right. The classifier's input is whatever the preprocessing step produces, not the raw features. That is the practical meaning of a sequence of data processing steps: each stage hands its output to the next stage.

Why Step Names Matter

Naming each step gives every part of the pipeline an identity you can refer to later. You do not need the name just to run the pipeline, but you need it the moment you want to point at one specific step, for example to change its settings during a search.

GridSearchCV can search over the parameters of the classifier inside a pipeline. The grid key is built from the step name, then a double underscore, then the parameter name. With the step named 'classifier', the regularization parameter C of the SVC becomes the key classifier__C.

python
preprocessingStandardScaler()classifierSVC()classifier__C0.1, 1, 10maps to objectmaps to objectprefix of keyvalues tried
The step name 'classifier' is the prefix of the grid key classifier__C, which points at the candidate values for that step's setting.

Deciding Whether Scaling Is Needed

The reason a pipeline has a preprocessing step at all comes from the estimator. The SVC may need its data scaled, so scaling becomes work that must happen before the classifier sees the data. Placing the scaler inside the pipeline keeps that work in one ordered chain rather than in a separate script you have to remember to run.

Different estimators may need different preprocessing. The comparison below uses the iris dataset, where the SVC is paired with a scaler and the RandomForestClassifier is not. The pipeline is the place where you express that difference.

EstimatorPreprocessing step in the pipelineReason given
SVC()StandardScaler() placed before the classifierThe SVC might need the data to be scaled
RandomForestClassifier()NoneNo preprocessing is necessary for it

Preprocessing decisions for two estimators on the iris dataset

Preprocessing is not always fixed in advance. GridSearchCV can also compare the preprocessing choice itself, for example StandardScaler against MinMaxScaler, or no preprocessing at all, alongside the classifier's own settings. This enlarges the search space considerably. Trying every possible combination is usually not a viable strategy, so choose the comparisons that answer a focused question.

Following Data Through Each Search Step

When GridSearchCV runs over a pipeline, each parameter combination is evaluated across the cross-validation folds. Within each fold, the whole pipeline is fitted on the training part, so the scaler learns its scaling from training data only and then transforms the validation part. The scaler therefore never sees the validation data while it is being fitted.

Worked example

Tracing one fold of a pipeline search

A grid search with five folds tests the value C = 1 for the classifier inside pipe. What happens to the scaler and the classifier during one fold?

  1. 1
    Split the data

    The fold separates the training rows from the validation rows.

  2. 2
    Fit the scaler

    The preprocessing step learns its scaling from the training rows only.

  3. 3
    Transform both parts

    The scaler applies that learned scaling to the training rows and to the validation rows.

  4. 4
    Fit the classifier

    The SVC with C = 1 learns from the scaled training rows, which are the output of the first step.

  5. 5
    Score the fold

    The classifier predicts on the scaled validation rows and that score is recorded.

Result

The scaler never learned anything from the validation rows, and the classifier only ever saw the output of the scaler.

Finding Where a Result Goes Wrong

When a pipeline gives a result you did not expect, the most useful habit is to find the step where the data stopped looking the way you intended. Because a pipeline is an ordered chain, you can walk it from the first step to the last. Start by printing the step names with pipe.steps. Then ask, for each step, whether it received the input you assumed.

Input featurescheck the raw valuespreprocessingwas the scaler applied?Scaled featuresdoes the scale look right?classifierdid it get the scaledinput?Predictionscompare with expectedlabelspasses intoproducesfeedsproduces
If the final predictions look wrong, inspect the data at each stage from left to right and find the first point where it differs from what you expected.

A missing scaler, a scaler you mentally placed after the classifier, or a step you forgot to name are all common places where the divergence starts. Each one changes what the classifier receives, so an error in an early step often appears to be a problem with the classifier itself.

Mistakes Beginners Make With Pipelines

  • Common mistake

    Leaving out the preprocessing step for an estimator that needs scaled data

    What it looks like
    pipe = Pipeline([('classifier', SVC())]) when the SVC needs its features scaled
    Why it fails

    The classifier then learns from the raw features, so its results can differ from the scaled version you intended.

    Do this instead

    Add the scaler as the first named step, such as ('preprocessing', StandardScaler()), so the classifier always receives prepared data.

  • Common mistake

    Thinking the scaler runs after the classifier

    What it looks like

    Reading the list ('classifier', SVC()), ('preprocessing', StandardScaler()) and assuming the data is scaled before prediction

    Why it fails

    The list order defines the sequence of data processing, so the first element is the first step the data passes through.

    Do this instead

    Read the steps list from the first element to the last, and confirm with pipe.steps that the preprocessing tuple comes first.

  • Common mistake

    Using a grid key that does not match the step name

    What it looks like

    Naming the step 'clf' but writing a grid key such as 'classifier__C'

    Why it fails

    The prefix of a grid key must be the name you chose for the step in the tuple.

    Do this instead

    Use the exact step name as the prefix, such as 'clf__C' when the step is named 'clf'.

  • Common mistake

    Ignoring how much a preprocessing comparison enlarges the search space

Practice Tracing a Pipeline

MEDIUM

A colleague builds pipe = Pipeline([('classifier', SVC()), ('preprocessing', StandardScaler())]) and reports that the predictions look unscaled. Without running anything, identify which step receives the raw features, and say what you would print to confirm the order.

Hints
  • Remember that the list order defines the sequence of data processing.
  • The steps attribute returns the (name, object) pairs in the same order you supplied them.
EASY

Write a param_grid for a pipeline whose classifier step is named 'model' and whose regularization parameter C should be tried at 0.5 and 5. Then state which name each grid key must start with.

Hints
  • The key is the step name, then a double underscore, then the parameter name.
  • The prefix must match the name you gave the step in the tuple.

Summary of Pipeline Model Selection

  1. 1
    A Pipeline is built from a list of (step name, estimator or transformer) tuples, and the list order defines the sequence of data processing.
  2. 2
    Step names give each part of the pipeline an identity, and they become the prefix of grid search keys such as classifier__C.
  3. 3
    Preprocessing such as StandardScaler is chosen according to the estimator: the SVC may need scaling, while the RandomForestClassifier needs none.
  4. 4
    GridSearchCV can compare preprocessing choices too, but this enlarges the search space and should be planned with a focused question in mind.
  5. 5
    When a result looks wrong, print pipe.steps and check each step in order to find where the data first stops looking as you intended.

At a glance

  • A Pipeline chains named steps from a list of (name, object) tuples, and the list order is the order the data is processed.
  • Step names matter because they let you refer to individual steps, including as grid search key prefixes such as classifier__C.
  • Scaling is decided by the estimator: the SVC may need it, while the RandomForestClassifier does not.
  • To debug an unexpected result, walk the steps in order and find the first step where the data differs from what you expected.

Related concepts

More concepts starting with C