Combining preprocessing and modeling in a single pipeline
make_pipeline is a convenience function that builds a pipeline and names each step automatically from its estimator's class.
Two Ways to Write the Same Pipeline
A pipeline chains preprocessing and modeling into one object, so that the same sequence of steps can be applied to data in one call. This article compares two ways of building such a pipeline with the same two steps: a scaler that transforms the input values, followed by an SVC model that makes predictions from the scaled values. Both ways produce objects that do exactly the same work. What differs is how each step is labeled and how much typing you must do.
Before you read the explanation, try the code in your head. The standard syntax passes a list of (name, estimator) pairs, so you choose each name yourself. The abbreviated syntax passes only the estimators. The question to answer is what names the abbreviated version gives its two steps.
What do you think happens?
When you build a pipeline with make_pipeline(StandardScaler(), SVC(C=100)) and no names, what names does it give the two steps?
Reveal answer
standardscaler and svc. make_pipeline names each step from the class of its estimator, so the scaler becomes standardscaler and the SVC becomes svc.
The function has access to each estimator object, and that object's class is the information it uses. You can confirm this yourself by printing the steps attribute of the pipeline, which is covered later in this article.
Following Data Through the Steps
When you call fit or predict on a pipeline, the data enters the first step and that step's output becomes the input of the next step. In the two-step pipeline, the input enters the scaler first, and the scaled values then enter the SVC. The final estimator is the last link in the chain, and it is the one that produces the predictions. Because the steps are linked this way, the chain behaves like a sequence of links: a problem introduced at any link is carried forward to the final result.
Read the diagram from left to right as you would read the steps of a recipe. Each box receives only what the box before it produced. The scaler does not see the predictions, and the SVC does not see the raw input. That separation is what makes the pipeline a chain rather than a pile of unrelated objects.
What make_pipeline Changes
The standard Pipeline syntax asks you to write a name for every step. Those names are useful when you want labels that mean something to you. When default names are enough, that naming work is unnecessary. The make_pipeline function is a convenience function in scikit-learn that handles this case: it creates a pipeline for you and names each step automatically from the class of its estimator or transformer.
[('standardscaler', StandardScaler()), ('svc', SVC(C=100))]- The standard version passes a list of (name, estimator) pairs, so the names scaler and classifier are chosen by hand.
- The abbreviated version passes only the estimators; no names are written.
- The steps attribute of the abbreviated pipeline reveals the names that were generated.
| Feature | Pipeline (standard syntax) | make_pipeline (abbreviated syntax) |
|---|---|---|
| Step names | You write a name for every step | Names are generated from each estimator's class |
| Amount of typing | More, because each step needs a name | Less, because only the estimators are passed |
| Work performed | Same preprocessing and modeling | Same preprocessing and modeling |
| Best when | You want meaningful names of your own | Default names are enough |
The two constructors differ in labeling and typing, not in what the pipeline computes.
The two constructors produce objects that do exactly the same work. Only the step names and the amount of typing differ. Choose the form that matches how much you care about the names.
Mapping Estimator Classes to Step Names
Because make_pipeline generates the names, the names themselves tell you the class of each step. Each generated name is a key that refers to one estimator. The key-value map below shows the mapping the printed output reveals: each key is a string you can use to refer to the step, and each value is the estimator that the step runs. The printed output also displays parameter settings such as C=100 for the SVC, but the name-to-estimator mapping is the part that matters for finding steps.
Reading the steps Attribute
A pipeline, whether fitted or unfitted, keeps its list of steps in an attribute named steps. Each entry in that list is a pair: the step name first, then the estimator object. Because the names are stored there, the steps attribute is the place to look when you want to confirm which name belongs to which estimator. It is also the first place to check when a result is unexpected.
('standardscaler', StandardScaler())
standardscaler
SVC(C=100)- Indexing steps by position returns a (name, estimator) pair.
- A second index selects either the name (index 0) or the estimator (index 1) inside the pair.
- Printed output depends on the library version and the parameter settings you use.
A step can also be located by its name. Once you have confirmed the names, you can check each estimator object stored under them, which lets you verify that the pipeline contains the estimators you intended and in the order you intended.
Tracing an Unexpected Result
Checking a pipeline whose prediction looks wrong
A colleague says the predictions from abbreviated are wrong. How do you find where the problem starts?
- 1List the steps
Print abbreviated.steps. Confirm that there are two pairs, that the names are standardscaler and svc, and that the estimators are the ones you intended.
- 2Check the order
The data enters the first step and then the second. If the scaler appeared after the SVC, the chain would be wrong even though each estimator is correct.
- 3Check each estimator
Inspect the object stored under each name. A step may be the right class with unexpected settings, such as a different C value.
- 4Locate the first bad link
Because a mismatch at any step carries forward, the earliest step whose contents differ from what you intended is the most likely origin of the problem.
The problem is found by reading the named steps in order, starting with the first link, before blaming the final model.
Common mistake Assuming make_pipeline and Pipeline produce different computations
Why it failsBoth constructors produce objects that do exactly the same work. Only the step names and the typing required differ.
Do this insteadCompare the steps attribute or the outputs of the two versions if you doubt they match, rather than assuming the results differ.
Common mistake Expecting make_pipeline to give custom names
What it looks likemake_pipeline(StandardScaler(), SVC()) produces names like standardscaler and svc, not scaler and classifier.
Why it failsThe function names each step from its estimator's class, so custom names are not generated.
Do this insteadUse the standard Pipeline syntax with (name, estimator) pairs when you need names of your own.
Common mistake Debugging the final model before checking the steps
Why it failsA mismatch at any earlier step carries forward to the final result, so the final model may be innocent.
Do this insteadList the steps and check them in order, starting from the first step.
Practice Locating Steps
Build a pipeline with make_pipeline from a StandardScaler followed by an SVC with C=10. Without running the code, write down the step names you expect. Then print the steps attribute and compare your answer. Finally, retrieve the estimator in the second step by its position.
Hints
- Think about which information
make_pipelinehas when it names each step. - The steps attribute is a list of (name, estimator) pairs, so a position index returns a pair.
- The estimator is the second item inside the pair.
A pipeline printed its steps as [('svc', SVC(C=100)), ('standardscaler', StandardScaler())]. Its predictions look wrong. Explain which step you would check first and why.
Hints
- Compare the order of the steps with the order in which the data should flow.
- Data passes from the first step to the next, so the scaler should normally come before the SVC.
Key Takeaways
make_pipelinebuilds a pipeline without requiring names and generates each step name from its estimator's class; the work performed is the same as the standard Pipeline syntax.- Data flows through the steps in order: each transformer's output becomes the input of the next, and the final estimator produces the result.
- The steps attribute is a list of (name, estimator) pairs, and it is the first place to check when a pipeline result is unexpected.
- When a result looks wrong, list the named steps, confirm their order and estimators, and check the earliest step that differs from what you intended.