Skip to content

Commit 820d98f

Browse files
committed
expose tags, classes_, _estimator_type in Learner classes
1 parent 0189e68 commit 820d98f

1 file changed

Lines changed: 46 additions & 40 deletions

File tree

skrub/_data_ops/_estimator.py

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,57 @@ def _copy_attr(source, target, attributes):
8282
pass
8383

8484

85-
class _CloudPickleDataOp(_CloudPickle):
85+
class _DataOpWrapperMixin(_CloudPickle):
8686
"""
87-
Mixin to serialize the `DataOp` attribute with cloudpickle when pickling a
88-
learner.
87+
Mixin for learners and estimators that wrap a DataOp.
88+
89+
It exposes some attributes (tags, classes_) needed by scikit-learn by
90+
inspecting the data_op attribute.
91+
92+
It also relies on the _CloudPickle mixin to serialize the DataOp with
93+
cloudpickle rather than the normal pickle protocol when the learner is
94+
pickled.
8995
"""
9096

9197
_cloudpickle_attributes = ["data_op"]
9298

99+
@property
100+
def _estimator_type(self):
101+
first = find_first_apply(self.data_op)
102+
if first is None:
103+
return "transformer"
104+
estimator = get_default(first._skrub_impl.estimator)
105+
if isinstance(estimator, DataOp):
106+
return "transformer"
107+
try:
108+
return estimator._estimator_type
109+
except AttributeError:
110+
return "transformer"
111+
112+
if hasattr(BaseEstimator, "__sklearn_tags__"):
113+
# scikit-learn >= 1.6
114+
115+
def __sklearn_tags__(self):
116+
first = find_first_apply(self.data_op)
117+
if first is None:
118+
return _default_sklearn_tags()
119+
estimator = get_default(first._skrub_impl.estimator)
120+
if isinstance(estimator, DataOp):
121+
return _default_sklearn_tags()
122+
try:
123+
return estimator.__sklearn_tags__()
124+
except AttributeError:
125+
return _default_sklearn_tags()
126+
127+
@property
128+
def classes_(self):
129+
try:
130+
return _get_classes(self.data_op)
131+
except AttributeError:
132+
attribute_error(self, "classes_")
133+
93134

94-
class SkrubLearner(_CloudPickleDataOp, BaseEstimator):
135+
class SkrubLearner(_DataOpWrapperMixin, BaseEstimator):
95136
"""Learner that evaluates a skrub DataOp.
96137
97138
This class is not meant to be instantiated manually, ``SkrubLearner``
@@ -482,41 +523,6 @@ def _get_env(self, X, y):
482523
xy_environment[Y_NAME] = y
483524
return {**self.environment, **xy_environment}
484525

485-
@property
486-
def _estimator_type(self):
487-
first = find_first_apply(self.data_op)
488-
if first is None:
489-
return "transformer"
490-
estimator = get_default(first._skrub_impl.estimator)
491-
if isinstance(estimator, DataOp):
492-
return "transformer"
493-
try:
494-
return estimator._estimator_type
495-
except AttributeError:
496-
return "transformer"
497-
498-
if hasattr(BaseEstimator, "__sklearn_tags__"):
499-
# scikit-learn >= 1.6
500-
501-
def __sklearn_tags__(self):
502-
first = find_first_apply(self.data_op)
503-
if first is None:
504-
return _default_sklearn_tags()
505-
estimator = get_default(first._skrub_impl.estimator)
506-
if isinstance(estimator, DataOp):
507-
return _default_sklearn_tags()
508-
try:
509-
return estimator.__sklearn_tags__()
510-
except AttributeError:
511-
return _default_sklearn_tags()
512-
513-
@property
514-
def classes_(self):
515-
try:
516-
return _get_classes(self.data_op)
517-
except AttributeError:
518-
attribute_error(self, "classes_")
519-
520526

521527
class _XyPipeline(_XyPipelineMixin, SkrubLearner):
522528
"""
@@ -763,7 +769,7 @@ def iter_cv_splits(data_op, environment, *, keep_subsampling=False, cv=KFOLD_5):
763769
yield split_info
764770

765771

766-
class _BaseParamSearch(_CloudPickleDataOp, BaseEstimator):
772+
class _BaseParamSearch(_DataOpWrapperMixin, BaseEstimator):
767773
"""Base class for hyperparameter search objects.
768774
769775
It defines some default implementations for getting results, plotting, and

0 commit comments

Comments
 (0)