Introduce yourself
My understanding is that if prefitis true, one could, in principle call transform() without calling fit() first.
While this is true if we don't set the output to pandas, it fails when we do so:
Minimal reproduction:
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.feature_selection import SelectFromModel
X, y = load_iris(as_frame=True, return_X_y=True)
clf = LogisticRegression(max_iter=1000).fit(X, y)
# prefit=True -- docs say we don't need to call .fit() on sel
sel = SelectFromModel(clf, prefit=True).set_output(transform="pandas")
sel.transform(X)
NotFittedError: This SelectFromModel instance is not fitted yet. Call 'fit' with appropriate arguments before using this estimator.
Without .set_output(transform="pandas"), the identical prefit=True selector transforms X just fine with no .fit() call.
The error only appears once pandas output is requested, because set_output internally calls get_feature_names_out(), which checks whether the wrapper itself has been fitted (via check_is_fitted(self), not check_is_fitted(self.estimator)).
According to Claude, that check was intentionally added in #25308 to standardize get_feature_names_out() behavior across SelectorMixin estimators.
So my question is: is this expected behaviour? or is it an unintended bug?
From a user perspective, if I use fitagain, even though prefit is True, I get the impression that my estimator would be re-fitted, so if this is intended, it might be worth adding a line in the docs.
sel.fit(X, y) # with prefit=True, does NOT retrain clf -- just
# deep-copies it and records feature_names_in_
sel.transform(X) # now works
Describe the issue linked to the documentation
SelectFromModel's prefit parameter is documented as:
prefit : bool, default=False
Whether a prefit model is expected to be passed into the constructor directly or not. If True, estimator must be a fitted estimator. If False, estimator is fitted and updated by calling fit and partial_fit, respectively.
Maybe it's just me, but I sort of read this as, if the estimator is prefit, I could avoid calling fit and it would be just fine.
Suggest a potential alternative/fix
Add a note to the prefit parameter docstring, e.g.:
Note: even with prefit=True, .fit() must still be called before using get_feature_names_out() or set_output(transform="pandas"), since these check whether the selector itself (not the underlying estimator) has been fitted. Calling .fit() in this case does not refit estimator; it only records bookkeeping metadata (estimator_, feature_names_in_).
Warning
This issue is not yet ready for a PR. If you are interested in contributing to scikit-learn, please have a look at our contributing guidelines, and in particular the sections for new contributors and the "Needs triage" label.
Introduce yourself
My understanding is that if
prefitis true, one could, in principle calltransform()without callingfit()first.While this is true if we don't set the output to pandas, it fails when we do so:
Minimal reproduction:
Without
.set_output(transform="pandas"), the identicalprefit=Trueselector transformsXjust fine with no.fit()call.The error only appears once pandas output is requested, because
set_outputinternally callsget_feature_names_out(), which checks whether the wrapper itself has been fitted (viacheck_is_fitted(self), notcheck_is_fitted(self.estimator)).According to Claude, that check was intentionally added in #25308 to standardize
get_feature_names_out()behavior acrossSelectorMixinestimators.So my question is: is this expected behaviour? or is it an unintended bug?
From a user perspective, if I use
fitagain, even though prefit is True, I get the impression that my estimator would be re-fitted, so if this is intended, it might be worth adding a line in the docs.Describe the issue linked to the documentation
SelectFromModel's prefit parameter is documented as:
prefit : bool, default=False
Whether a prefit model is expected to be passed into the constructor directly or not. If True, estimator must be a fitted estimator. If False, estimator is fitted and updated by calling fit and partial_fit, respectively.
Maybe it's just me, but I sort of read this as, if the estimator is prefit, I could avoid calling fit and it would be just fine.
Suggest a potential alternative/fix
Add a note to the prefit parameter docstring, e.g.:
Note: even with prefit=True, .fit() must still be called before using get_feature_names_out() or set_output(transform="pandas"), since these check whether the selector itself (not the underlying estimator) has been fitted. Calling .fit() in this case does not refit estimator; it only records bookkeeping metadata (estimator_, feature_names_in_).