Skip to content

Commit 2186f9a

Browse files
orauschglemaitre
authored andcommitted
BUG: allow None as final estimator in Pipeline (#554)
1 parent dff4670 commit 2186f9a

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

doc/whats_new/v0.5.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,7 @@ Bug
4141
- Fix bug which converting to COO format sparse when stacking the matrices in
4242
:class:`imblearn.over_sampling.SMOTENC`. This bug was only old scipy version.
4343
:issue:`539` by :user:`Guillaume Lemaitre <glemaitre>`.
44+
45+
- Fix bug in :class:`imblearn.pipeline.Pipeline` where None could be the final
46+
estimator.
47+
:issue:`554` by :user:`Oliver Rausch <orausch>`.

imblearn/pipeline.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,6 @@ def fit_transform(self, X, y=None, **fit_params):
276276
else:
277277
return last_step.fit(Xt, yt, **fit_params).transform(Xt)
278278

279-
@if_delegate_has_method(delegate='_final_estimator')
280279
def fit_resample(self, X, y=None, **fit_params):
281280
"""Fit the model and sample with the final estimator
282281
@@ -525,6 +524,13 @@ def _inverse_transform(self, X):
525524
Xt = transform.inverse_transform(Xt)
526525
return Xt
527526

527+
# need to overwrite sklearn's _final_estimator since sklearn supports
528+
# 'passthrough', but imblearn does not.
529+
@property
530+
def _final_estimator(self):
531+
estimator = self.steps[-1][1]
532+
return estimator
533+
528534
@if_delegate_has_method(delegate='_final_estimator')
529535
def score(self, X, y=None, sample_weight=None):
530536
"""Apply transformers/samplers, and score with the final estimator

imblearn/tests/test_pipeline.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,3 +1104,22 @@ def test_predict_with_predict_params():
11041104
pipe.fit(None, None)
11051105
pipe.predict(X=None, got_attribute=True)
11061106
assert pipe.named_steps['clf'].got_attribute
1107+
1108+
1109+
def test_resampler_last_stage_passthrough():
1110+
1111+
X, y = make_classification(
1112+
n_classes=2,
1113+
class_sep=2,
1114+
weights=[0.1, 0.9],
1115+
n_informative=3,
1116+
n_redundant=1,
1117+
flip_y=0,
1118+
n_features=20,
1119+
n_clusters_per_class=1,
1120+
n_samples=50000,
1121+
random_state=0)
1122+
1123+
rus = RandomUnderSampler(random_state=42)
1124+
pipe = make_pipeline(rus, None)
1125+
pipe.fit_resample(X, y)

0 commit comments

Comments
 (0)