Polynomial Features and Regression
The scaler and the polynomial expander are transformers, because they change the input values.
The Scattered Workflow Problem
A typical machine learning workflow is a chain of operations. Raw numbers are transformed, then transformed again, and only at the end is a model fitted and used to make predictions. Each link in that chain can be handled as a separate object, but then the code that runs the chain gets scattered across many lines. That spread makes it easy to apply the steps in the wrong order or to forget one of them.
A scikit-learn pipeline solves this by wrapping the whole chain in a single object. Instead of managing a scaler, a polynomial expander, and a regressor as three separate things, you treat them as one estimator. You give that one estimator the training data, and it passes the data through each step in turn. This article follows one concrete case from the source: earlier work computed polynomial features from the Boston dataset and passed them to a ridge regressor, and the same work can be modeled as one pipeline.
Three Steps Held in One Object
A scikit-learn pipeline encapsulates several processing steps in a single estimator, so a whole workflow can be handled as one object.
The case in the source has three steps: scaling the data, computing polynomial features, and applying ridge regression. Each step is either a transformer or an estimator. The scaler and the polynomial expander are transformers, because they change the input values. The ridge regressor is an estimator, because it is fitted to the target and makes predictions. The pipeline keeps all three in a fixed order.
The source builds this pipeline with the make_pipeline() function. You pass the steps as arguments, in the order they should run. The pipeline does not reorder them. The diagram below shows the chain for this case, read from left to right.
Building the Pipeline in Code
The source fragment does not show its imports, so the example below includes them. It also uses a small generated dataset in place of the Boston data, so the code runs on its own. The structure of the pipeline is the same either way. Read the code and notice how many objects the single pipeline variable is holding.
make_pipelinereceives the steps as arguments in the order they should run- fit is called once on the whole pipeline, not on each step
- steps lists the (name, step) pairs stored inside the pipeline
named_stepsgives access to the same steps by name
The pipeline holds three steps even though you wrote only one assignment. The stored steps can be inspected through pipe.steps or pipe.named_steps. The names are assigned from the class names, so each step can be found by the name the pipeline gave it.
Tracing What Happens During fit
When fit is called on the pipeline, the training data is handled one step at a time. The scaler learns what it needs from the data and transforms it. The polynomial step then expands the transformed values into polynomial terms. The ridge regressor is fitted on those expanded values together with the target. You do not write any of this sequencing yourself. The pipeline's fit method carries it out in the stored order.
Following one fit call through the chain
Trace what the pipeline does when pipe.fit(X, y) is called with the code from the previous section.
- 1Receive the data
The pipeline receives X, the raw input, and y, the target.
- 2Scale X
The scaler learns what it needs from X and returns transformed values.
- 3Expand the scaled values
The polynomial step turns the transformed values into polynomial terms.
- 4Fit the regressor
The ridge regressor is fitted on the expanded terms together with y.
After one call, every step in the pipeline has been fitted in order, and the ridge regressor is ready for predict.
Tuning Preprocessing With the Outcome
The source describes a second, more important benefit of wrapping the steps together. Because the preprocessing and the model live in one object, the parameters of the preprocessing can be adjusted using the outcome of a supervised task, such as a regression or a classification. The number of polynomial terms is one such preprocessing parameter. Its value is judged by how well the final model predicts the target.
Without a pipeline, a learner might choose the number of polynomial terms by hand, fit the model, and then repeat the process. Nothing in the code ties those choices together, so the link between the preprocessing decision and the target is easy to lose. With a pipeline, the preprocessing steps are part of what gets evaluated against the target. The comparison below sets the two ways of working side by side.
Where Behavior Differs From Step-by-Step Code
The main difference is not in the arithmetic. Each step computes the same thing whether it is called inside a pipeline or manually. The difference lies in who sequences the work and who keeps the choices connected. When you apply the steps one at a time, you decide the order, you call each fit and transform yourself, and you carry the results forward. When you use the pipeline, the stored order is enforced for you, and fit and predict on the whole object run through every step.
Common Mistakes With Pipelines
Common mistake Thinking the pipeline is three separate objects that must be called one by one
Why it failsThe source treats the scaler, the polynomial expander, and the regressor as one estimator. You give the whole pipeline the training data, and it passes the data through each step in turn.
Do this insteadCall fit and predict on the pipeline object, and let it run the steps in order.
Common mistake Assuming the order of steps can be changed freely
Why it failsmake_pipelinetakes the steps in the order they should run, and each step receives the output of the step before it. The regressor sees only the expanded features produced by the polynomial step.Do this insteadPlace the steps in the order the data should flow: preprocessing first, the model last.
Common mistake Choosing the polynomial degree by hand and treating it as unrelated to the model's score
Why it failsThe source's benefit of the pipeline is that preprocessing parameters can be adjusted using the outcome of a supervised task. Choices made outside the pipeline are not tied to the target.
Do this insteadKeep the preprocessing inside the pipeline so that it is evaluated together with the model against the target.
Common mistake Forgetting that the step names come from the class names when you access pipe.named_steps
Reading a Pipeline Yourself
Suppose a pipeline is built with make_pipeline(StandardScaler(), PolynomialFeatures(degree=2), Ridge(alpha=1.0)). Without running the code, name the three steps in the order they run, state which step sees only the raw input, and say which step receives the target y during fit.
Hints
- The steps run in the order they were passed to
make_pipeline. - Only the first step receives the raw input directly.
- The regressor is the estimator, so it is the step that is fitted with y.
Explain in two or three sentences why a pipeline makes it possible for the choice of polynomial terms to be judged by the model's performance on the target, while a manual sequence of steps does not automatically do so.
Hints
- Think about where the preprocessing parameter lives relative to the model.
- The source ties this benefit to both living in one object.
Key Takeaways
- A scikit-learn pipeline wraps several processing steps into a single estimator, so a workflow can be handled as one object.
make_pipeline()takes the steps in the order they should run, and each step receives the output of the step before it.- Calling fit on the pipeline passes the training data through each step in stored order, and the regressor is fitted on the expanded features together with the target.
- Because preprocessing and the model share one object, preprocessing parameters such as polynomial degree can be judged using the outcome of a supervised task.
- The main difference from step-by-step code is who sequences the work and keeps the choices connected, not the arithmetic inside each step.