Pipelines
The Pipeline class in scikit-learn glues multiple processing steps into a single estimator.
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?
Reveal 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
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.
- 1The pipeline receives X_train and
y_trainfrom the single fit call. - 2The first step, the scaler, is fitted on X_train. It then transforms X_train, producing a new set of numbers.
- 3The transformed training data is passed forward to the next step. The original X_train values are no longer what the model sees.
- 4The final supervised model, the classifier, is fitted on the transformed data together with
y_train. - 5When 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.
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.
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.
- 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
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?
- 1Create the pipeline
The pipeline stores the scaler and the classifier in the order given. No data has been processed yet.
- 2Call 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. - 3Call 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_testand returns a score.
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.
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 failsThe classifier is fitted on whatever the preprocessing step hands it, which here is the scaled version of X_train.
Do this insteadReason 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 failsThe 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 insteadCall 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 failsThe score then reflects data the model has already learned from, so it does not measure performance on unseen data.
Do this insteadFit 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
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.