Skip to content

Fix get_feature_names_out raising AttributeError on fitted estimators - #246

Open
LukeTheoJohnson wants to merge 2 commits into
MaxHalford:masterfrom
LukeTheoJohnson:fix-get-feature-names-out
Open

Fix get_feature_names_out raising AttributeError on fitted estimators#246
LukeTheoJohnson wants to merge 2 commits into
MaxHalford:masterfrom
LukeTheoJohnson:fix-get-feature-names-out

Conversation

@LukeTheoJohnson

@LukeTheoJohnson LukeTheoJohnson commented Jul 11, 2026

Copy link
Copy Markdown

Problem

Calling get_feature_names_out() on a fitted PCA, MCA, or FAMD estimator raises:

AttributeError: 'PCA' object has no attribute 'n_components_'
import pandas as pd, numpy as np, prince

X = pd.DataFrame(np.arange(40, dtype=float).reshape(10, 4), columns=list("abcd"))
pca = prince.PCA(n_components=3).fit(X)
pca.get_feature_names_out()  # AttributeError

This also breaks Pipeline.get_feature_names_out() and ColumnTransformer, which delegates to this method, so a pipeline containing a prince estimator fails the same way.

Cause

get_feature_names_out returns np.arange(self.n_components_), but there's nothing in fit that assigns n_components_. It just exists as a class-level annotation, so the type checker stays green while the attribute is missing at runtime.

Fix

fit now sets self.n_components_ = len(self.svd_.s) in PCA.fit and MCA.fit (FAMD inherits). Works in the paths I traced (including the rank capped CA/MCA SVD where fewer components are kept than requested) and matches the width of the transform output. Happy to adjust if there's a case I've missed.

Tests

One regression test per estimator, asserting len(get_feature_names_out()) == transform(X).shape[1]. All three raise the AttributeError on master and pass with this change. ruff check, ruff format --check, and ty check prince are clean.

PCA.get_feature_names_out and MCA.get_feature_names_out return
np.arange(self.n_components_), but n_components_ was only declared as a
type annotation (added to make ty pass) and never assigned during fit.
Calling the method on any fitted PCA, MCA, or FAMD estimator raised
AttributeError: object has no attribute 'n_components_', breaking the
scikit-learn transformer contract that Pipeline.get_feature_names_out and
ColumnTransformer rely on.

fit now sets n_components_ to the effective number of fitted components
(len(svd_.s)). This equals the width of the transform output in every
path, including the rank-capped CA/MCA SVD where fewer components are kept
than requested.

Adds a regression test for PCA, MCA, and FAMD.
@LukeTheoJohnson
LukeTheoJohnson marked this pull request as ready for review July 11, 2026 00:23
@MaxHalford

Copy link
Copy Markdown
Owner

Cheers! I'll take a look in a couple of weeks after my holidays.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants