Skip to content

RepresentationSearchCV lacks predict_proba, classes_ and classifier tags, so nested roc_auc CV returns NaN #92

Open

Description

@ChrisW09

Description

RepresentationSearchCV wrapping a classifier does not behave like one. It is a plain BaseEstimator with only predict and score:

  • no classes_, predict_proba, predict_log_proba or decision_function;
  • its estimator type is unset, so sklearn.base.is_classifier(search) is False.

As a result, cross_val_score(search, X, y, scoring="roc_auc") returns all-NaN scores, with only a UserWarning ("Scoring failed"). Outer cross-validation with an integer cv also uses plain KFold instead of StratifiedKFold. scikit-learn's search meta-estimators (GridSearchCV, RandomizedSearchCV) delegate all of these to the refitted best estimator.

Affected code

Reproduction

import warnings
import numpy as np, pandas as pd
from sklearn.base import is_classifier
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV, cross_val_score
from pretab import RepresentationSearchCV

rng = np.random.default_rng(0)
X = pd.DataFrame({"x": rng.uniform(-3, 3, 300)})
y = (np.sin(X["x"]) + rng.normal(0, 0.3, 300) > 0).astype(int)
search = RepresentationSearchCV(LogisticRegression(), ["minmax", "ple"], cv=3).fit(X, y)
grid = GridSearchCV(LogisticRegression(), {"C": [0.1, 1.0]}, cv=3).fit(X, y)
for name, est in (("GridSearchCV", grid), ("RepresentationSearchCV", search)):
    print(f"{name:23s} is_classifier={is_classifier(est)}, predict_proba={hasattr(est, 'predict_proba')}, "
          f"classes_={getattr(est, 'classes_', None)}")
with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    print("nested CV roc_auc:", cross_val_score(RepresentationSearchCV(LogisticRegression(), ["minmax", "ple"], cv=3),
                                                 X, y, scoring="roc_auc", cv=3))

Output (PreTab 1.0.0 (6bacaba), Python 3.12, numpy 2.5.3, pandas 2.3.3, scikit-learn 1.9.1, scipy 1.18.1):

GridSearchCV            is_classifier=True, predict_proba=True, classes_=[0 1]
RepresentationSearchCV  is_classifier=False, predict_proba=False, classes_=None
nested CV roc_auc: [nan nan nan]

Expected behavior

The same surface as GridSearchCV: predict_proba / predict_log_proba / decision_function / classes_ delegated to best_estimator_ when the wrapped estimator has them, and the estimator type taken from the wrapped estimator.

Actual behavior

The attributes are missing, is_classifier is False, and probability-based scorers fail on every fold.

Impact

Nested evaluation of a representation search, a natural next step after using it, silently produces NaN scores for any probability-based metric. Probability predictions of the selected model are only reachable by transforming with best_preprocessor_ and calling best_estimator_.predict_proba by hand.

Root cause

The class does not delegate the classifier API and does not take its estimator type from the wrapped estimator.

Suggested fix direction

  • Delegate with sklearn.utils.metaestimators.available_if, as BaseSearchCV does.
  • Expose classes_ after fit.
  • Derive the estimator type in __sklearn_tags__ from self.estimator.

Related issues

Activity

  1. changed the title [-]RepresentationSearchCV around a classifier exposes no predict_proba / classes_ and is not a classifier, so nested CV with roc_auc returns NaN[/-] [+]RepresentationSearchCV lacks predict_proba, classes_ and classifier tags, so nested roc_auc CV returns NaN[/+] on Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions