Python
machine learning
sklearn
feature selection
data science

How to get feature names selected by feature elimination in sklearn pipeline?

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

When Recursive Feature Elimination sits inside a scikit-learn pipeline, the selected features are not exposed automatically as a friendly list of names. The usual solution is to get the transformed feature names from the preprocessing step, then apply the selector's boolean support mask to those names.

The Core Idea

An RFE-style selector stores which features survived in support_. That array is boolean and matches the feature matrix seen by the selector. So the workflow is:

  1. fit the pipeline
  2. get the feature names entering the selector
  3. apply support_ to those names

That works whether the selector is RFE, RFECV, or another transformer exposing the same mask semantics.

Example with a Simple Pipeline

python
1import pandas as pd
2from sklearn.feature_selection import RFE
3from sklearn.linear_model import LogisticRegression
4from sklearn.pipeline import Pipeline
5from sklearn.preprocessing import StandardScaler
6
7X = pd.DataFrame(
8    {
9        "age": [25, 32, 47, 51, 62],
10        "income": [40, 55, 80, 90, 120],
11        "score": [500, 620, 680, 710, 790],
12        "visits": [1, 3, 5, 4, 8],
13    }
14)
15y = [0, 0, 1, 1, 1]
16
17pipeline = Pipeline(
18    [
19        ("scale", StandardScaler()),
20        ("select", RFE(LogisticRegression(max_iter=1000), n_features_to_select=2)),
21    ]
22)
23
24pipeline.fit(X, y)
25
26feature_names = X.columns.to_numpy()
27mask = pipeline.named_steps["select"].support_
28selected_features = feature_names[mask]
29
30print(selected_features)

In this simple case, the input feature names are just the original DataFrame column names because the scaler keeps the same feature count and order.

When the Pipeline Changes Feature Names

Real pipelines often include transformations such as one-hot encoding. In that case, the names entering RFE are not the original column names anymore. You need the transformed names from the preprocessing stage.

python
1import pandas as pd
2from sklearn.compose import ColumnTransformer
3from sklearn.feature_selection import RFE
4from sklearn.linear_model import LogisticRegression
5from sklearn.pipeline import Pipeline
6from sklearn.preprocessing import OneHotEncoder, StandardScaler
7
8X = pd.DataFrame(
9    {
10        "age": [25, 32, 47, 51, 62],
11        "income": [40, 55, 80, 90, 120],
12        "city": ["A", "B", "A", "C", "B"],
13    }
14)
15y = [0, 0, 1, 1, 1]
16
17preprocess = ColumnTransformer(
18    [
19        ("num", StandardScaler(), ["age", "income"]),
20        ("cat", OneHotEncoder(handle_unknown="ignore"), ["city"]),
21    ]
22)
23
24pipeline = Pipeline(
25    [
26        ("prep", preprocess),
27        ("select", RFE(LogisticRegression(max_iter=1000), n_features_to_select=3)),
28    ]
29)
30
31pipeline.fit(X, y)
32
33feature_names = pipeline.named_steps["prep"].get_feature_names_out()
34mask = pipeline.named_steps["select"].support_
35selected_features = feature_names[mask]
36
37print(selected_features)

This is the general pattern you want in modern scikit-learn pipelines.

Why the Support Mask Is the Right Tool

RFE recursively removes features until only the requested number remains. The final result is stored in:

  • 'support_ for selected-versus-dropped'
  • 'ranking_ for relative importance order'

If you only want the chosen feature names, support_ is the direct answer.

If you want a fuller diagnostic view, ranking_ can be paired with the transformed feature names too.

A Reusable Helper

python
1def selected_feature_names(pipeline, selector_step, feature_source):
2    names = feature_source.get_feature_names_out() if hasattr(feature_source, "get_feature_names_out") else feature_source
3    mask = pipeline.named_steps[selector_step].support_
4    return names[mask]

The exact helper shape is up to you, but packaging the pattern once makes repeated model inspection easier.

Common Pitfalls

The biggest pitfall is applying support_ to the original DataFrame columns when the preprocessing step changed the feature space. After one-hot encoding or similar transforms, the selector is no longer working on the raw column list.

Another common mistake is reading support_ before fitting the pipeline. The selector mask does not exist until the estimator has been trained.

People also confuse ranking_ with the final selected mask. ranking_ == 1 usually means selected, but support_ is the clearer and safer attribute for this purpose.

Summary

  • Fit the pipeline first, then read the selector's support_ mask.
  • Apply that mask to the feature names that actually enter the selector.
  • If preprocessing changes the feature space, use get_feature_names_out() from the preprocessing step.
  • Use support_ for selected features and ranking_ when you want broader elimination diagnostics.
  • The general solution is "transformed feature names plus selector mask."

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.