Concepts / Pipelines

Pipelines

The Pipeline class in scikit-learn glues multiple processing steps into a single estimator.

  • Programming

Why Separate Steps Cause Trouble

When you build a machine learning model, the raw data you start with is rarely the data the model should see. Values may sit on very different scales, and a preprocessing step has to transform them before a classifier can learn from them. Keeping track of those steps by hand, in the right order, every time you train or test a model is tedious and easy to get wrong. The Pipeline class in scikit-learn lets you package several processing steps into one object, so the whole sequence can be handled as a single unit.

What do you think happens?

A pipeline has a scaler and a classifier, and you make only one fit call on the pipeline. Which component gets trained first?

  • The classifier, because it is the final model

  • The scaler, because it is the first step in the pipeline

Reveal answer
Answer:

The scaler is fitted first, and the classifier is fitted afterward on the scaled data rather than on the original training values.

Calling fit on the pipeline runs through the steps in a fixed order. The first processing step learns from the training data and passes transformed data forward, and the final model learns from whatever arrives at the end.

Keep one question in mind as you read: when you call a single method on a Pipeline, what happens to the data before the final model sees it? The rest of this article works through that question step by step.

One Object for a Chain of Steps

Definition

A Pipeline is a scikit-learn object that glues multiple processing steps into a single estimator. It holds an ordered list of steps internally, so you can treat the whole sequence as one unit.

The key word is single. Without a pipeline, a scaler lives in one variable, a classifier lives in another, and you must remember to apply them in sequence every time. With a pipeline, you hold one object, and that object already knows its ordered list of steps. The source introduces the Pipeline class in the context of tools such as cross_val_score and GridSearchCV, where it provides a way to combine processing steps with the model being evaluated.

Think of a Pipeline as an ordered chain. Data enters at the first step. That step's output becomes the input to the next step, and so on, until the final element, which is the supervised model. The most common arrangement described in the source is a preprocessing step such as scaling, followed by a classifier. In that arrangement the classifier never receives the raw features directly. It receives whatever the preprocessing step hands it. The preprocessing is part of the pipeline's definition, not a separate action you must remember to perform first.

Because the result is a single estimator, it can be passed to the same tools you would use with any other scikit-learn model. The Pipeline class itself has fit, predict, and score methods and behaves like any other model in scikit-learn. Once you know how to train and evaluate one estimator, you already know how to use a Pipeline, because the interface matches. The chaining happens behind that familiar interface.

What pipe.fit Does, Step by Step

The single line pipe.fit(X_train, y_train) stands in for several operations. The arguments are the training inputs and their labels, and both are given to the pipeline, which decides how each component uses them. The program never calls fit on the scaler or on the SVM directly. The pipeline object takes care of that.

  1. 1
    The pipeline receives X_train and y_train from the single fit call.
  2. 2
    The first step, the scaler, is fitted on X_train. It then transforms X_train, producing a new set of numbers.
  3. 3
    The transformed training data is passed forward to the next step. The original X_train values are no longer what the model sees.
  4. 4
    The final supervised model, the classifier, is fitted on the transformed data together with y_train.
  5. 5
    When fit returns, every step in the pipeline has been trained in the order it appears.

The sequence is easier to follow as a set of calls over time. The pipeline is the caller, and it hands work to each component in turn.

PipelineScalerClassifier1. fit, then transform X_train2. returns scaled X_train3. fit on scaled X_train and y_train
Which component the pipeline calls first during fit, and what each component hands back to the pipeline.

The diagram shows the calls in order, but the important question is what the data looks like at each stage. The scaler's output is a different set of numbers from the data you started with, and the classifier is trained on that second version. Keeping the two versions distinct in your head is the key to tracing a fit correctly.

X_train (raw)original feature valuesScalerfit, then transformX_train (scaled)values the classifierreceivesClassifierfit on scaled dataFitted pipelinepassed in during fittransform outputfit with y_traintrained steps
How the raw training values become scaled values, and how only the scaled values reach the classifier during fit.

Building a Scale-Then-Classify Pipeline

The following example is an original illustration for this article. It assumes that X_train, y_train, X_test, and y_test already exist as the feature and label splits of a dataset. It chains a scaling step with a logistic regression classifier. Each step is given a name, so you can refer to it later.

python
Notes on the code
  • Pipeline takes a list of (name, step) pairs; the order of the list is the order of processing
  • StandardScaler is the preprocessing step at the front of the chain
  • LogisticRegression is the final supervised model at the end of the chain
  • One fit call trains the scaler and then the classifier
  • score runs the test data through the same fitted steps
Worked example

Tracing one fit and one score

Given a pipeline with a scaler followed by a classifier, what does each of the two method calls do to the data?

  1. 1
    Create the pipeline

    The pipeline stores the scaler and the classifier in the order given. No data has been processed yet.

  2. 2
    Call pipe.fit(X_train, y_train)

    The scaler is fitted on X_train and transforms it. The classifier is then fitted on the scaled training values and y_train.

  3. 3
    Call pipe.score(X_test, y_test)

    The test inputs pass through the same fitted scaler and then into the same fitted classifier. The pipeline compares the classifier's predictions with y_test and returns a score.

Result

One fit call trained both components in order, and one score call evaluated the whole chain on data kept separate from training.

How pipe.score Uses Fitted Steps

Once the pipeline is fitted, you need a way to judge how well it works. The source describes pipe.score for this purpose: to evaluate the model on test data, you call pipe.score. Like fit, the call goes to the whole pipeline. The test data passes through the same scaler and then into the same classifier that were set up during training.

The important detail is that score does not retrain the steps. The scaling uses what the scaler learned from the training data during fit, and the classifier uses what it learned during fit. The test data is only transformed and predicted on. This is why test data should stay separate from the training call. If you fit the pipeline on the test data, the evaluation no longer tells you how the model handles data it has never seen.

Finding Where Results Go Wrong

When the pipeline's output is unexpected, you do not need to guess which step caused it. The source advises tracing the input to each stage in order to find where the result diverges from expectations. Start at the front of the chain and check each stage's output against what you anticipated. The first stage whose output looks wrong is the place to look.

Unexpected outputInspect raw inputInput as expected?Inspect scaled outputScaled values asexpected?Check classifieroutputProblem beforepipelineScaler is thedivergencestart tracingyesnoyesno
Checking the data at each stage in order to find the first point where it departs from what you expected.

The flowchart is a simple habit to adopt. Inspect the data before the scaler, then the data after it, then the classifier's predictions. Each check narrows the search, and you stop at the first stage where the data stops matching your expectation.

Common Mistakes With Pipelines

  • Common mistake

    Expecting the classifier to see the raw training values

    Why it fails

    The classifier is fitted on whatever the preprocessing step hands it, which here is the scaled version of X_train.

    Do this instead

    Reason about the classifier's input as the scaled data, and inspect the scaler's output when the classifier behaves unexpectedly.

  • Common mistake

    Calling fit on the scaler and the classifier separately and also calling fit on the pipeline

    Why it fails

    The pipeline's fit call already trains each component in order. Repeating the steps by hand makes the sequence easy to get out of order.

    Do this instead

    Call fit once on the pipeline and let it run the steps in their defined order.

  • Common mistake

    Fitting the pipeline on test data before scoring

    Why it fails

    The score then reflects data the model has already learned from, so it does not measure performance on unseen data.

    Do this instead

    Fit on the training split only, then pass the test split to score.

  • Common mistake

    Treating the pipeline as a black box when a result looks wrong, instead of checking the output of each stage

Building and Tracing Your Own Pipeline

MEDIUM

Write a pipeline with a scaling step followed by a classifier of your choice. Fit it on the training split, then score it on the test split. Before you run the code, predict which component is trained first and what data the classifier receives. After you run it, change one step and explain how the result would be traced if it looked wrong.

Hints
  • Give each step a name in the list of (name, step) pairs.
  • The first element of the list is the first processing step.
  • Score the pipeline on the test split, never on the training split.

Key Takeaways

  • The Pipeline class in scikit-learn glues multiple processing steps into a single estimator, so a sequence of steps can be handled as one object.
  • Calling pipe.fit runs the steps in order: the first step is fitted and transforms the training data, and the final model is fitted on the transformed data.
  • The final classifier never sees the raw training values; it learns from what the scaler passes forward.
  • pipe.score evaluates the fitted pipeline on test data kept separate from training, passing it through the same fitted steps.
  • When a pipeline's output looks wrong, trace the input to each stage in order to find the first point where the data departs from your expectations.

Related concepts

More concepts starting with P