Summary
CustomBinTransformer.get_feature_names_out() raises when called with no arguments and
returns a plain list rather than an ndarray. Both break the scikit-learn contract, and the
first makes Pipeline.get_feature_names_out() fail for any pipeline containing the
transformer.
The package already fixed exactly this for three sibling transformers — see the docstring of
tests/test_feature_names_out.py ("get_feature_names_out(None) defaults to generated
x0, x1, ... names instead of raising, for NoTransformer, ToFloatTransformer and
ContinuousOrdinalTransformer") — but CustomBinTransformer was left out.
Reproduction
import numpy as np
from sklearn.pipeline import Pipeline
from pretab.transformers import CustomBinTransformer, NoTransformer
X = np.linspace(0, 1, 20).reshape(-1, 1)
t = CustomBinTransformer(output_dim=4).fit(X)
t.get_feature_names_out()
InvalidParamError: input_features must be specified
print(type(t.get_feature_names_out(["f"])).__name__) # list
print(type(NoTransformer().fit(X).get_feature_names_out()).__name__) # ndarray
Pipeline([("bin", CustomBinTransformer(output_dim=4))]).fit(X).get_feature_names_out()
InvalidParamError: input_features must be specified
Expected
Consistent with every other transformer in the package and with scikit-learn:
get_feature_names_out() works with no arguments, generating x0, x1, ..., and always
returns an ndarray of strings.
Actual
Raises without arguments; returns a list with them.
Root cause
pretab/transformers/binning/binning.py:142-157:
def get_feature_names_out(self, input_features=None):
if input_features is None:
raise InvalidParamError("input_features must be specified")
return input_features
It also does not guard on being fitted, unlike the siblings which call check_is_fitted.
Suggested fix
Mirror NoTransformer.get_feature_names_out:
def get_feature_names_out(self, input_features=None):
check_is_fitted(self, "n_features_in_")
if input_features is None:
input_features = [f"x{i}" for i in range(self.n_features_in_)]
return np.asarray(input_features, dtype=object)
Note this changes two existing tests that pin the current behaviour:
test_custom_bin_transformer_feature_names_out_raises (asserts the no-argument call raises)
and test_custom_bin_transformer_feature_names_out (asserts a list is returned, via
names == ["feature1"]). Both encode the defect rather than a desired guarantee.
Environment
- pretab 0.1.0 (
main @ 51c3043)
- Python 3.11.15, numpy 2.4.6, pandas 2.3.3, scikit-learn 1.9.0, scipy 1.17.1
- macOS (darwin 25.5.0)
Summary
CustomBinTransformer.get_feature_names_out()raises when called with no arguments andreturns a plain
listrather than an ndarray. Both break the scikit-learn contract, and thefirst makes
Pipeline.get_feature_names_out()fail for any pipeline containing thetransformer.
The package already fixed exactly this for three sibling transformers — see the docstring of
tests/test_feature_names_out.py("get_feature_names_out(None)defaults to generatedx0, x1, ...names instead of raising, forNoTransformer,ToFloatTransformerandContinuousOrdinalTransformer") — butCustomBinTransformerwas left out.Reproduction
Expected
Consistent with every other transformer in the package and with scikit-learn:
get_feature_names_out()works with no arguments, generatingx0, x1, ..., and alwaysreturns an ndarray of strings.
Actual
Raises without arguments; returns a list with them.
Root cause
pretab/transformers/binning/binning.py:142-157:It also does not guard on being fitted, unlike the siblings which call
check_is_fitted.Suggested fix
Mirror
NoTransformer.get_feature_names_out:Note this changes two existing tests that pin the current behaviour:
test_custom_bin_transformer_feature_names_out_raises(asserts the no-argument call raises)and
test_custom_bin_transformer_feature_names_out(asserts a list is returned, vianames == ["feature1"]). Both encode the defect rather than a desired guarantee.Environment
main@ 51c3043)