Skip to content

Commit

Permalink
[MRG + 2] ENH add sample_weight support to Pipeline.score (scikit-lea…
Browse files Browse the repository at this point in the history
…rn#7723)

* add sample_weight support to Pipeline.score

* TST check that pipe.score raises TypeError for unsorrported arguments

* TST check error message for invalid score_params in pipeline.score

* TST check that pipe.fit raises TypeError when argument is not supported

* only support sample_weight argument

* whats_new: mention sample_weight in Pipeline.score
  • Loading branch information
kmike authored and jnothman committed Oct 29, 2016
1 parent 4c8f12d commit 10323f5
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 3 deletions.
6 changes: 5 additions & 1 deletion doc/whats_new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ Enhancements
- Added ``norm_order`` parameter to :class:`feature_selection.SelectFromModel`
to enable selection of the norm order when ``coef_`` is more than 1D

- Added ``sample_weight`` parameter to :meth:`pipeline.Pipeline.score`.
(`#7723 <https://github.com/scikit-learn/scikit-learn/pull/7723>`_)
by `Mikhail Korobov`_.

Bug fixes
.........

Expand Down Expand Up @@ -4675,7 +4679,7 @@ David Huard, Dave Morrill, Ed Schofield, Travis Oliphant, Pearu Peterson.

.. _Yannick Schwartz: https://team.inria.fr/parietal/schwarty/

.. _Mikhail Korobov: http:https://kmike.ru/pages/about/
.. _Mikhail Korobov: https:https://github.com/kmike

.. _Kyle Kastner: http:https://kastnerkyle.github.io

Expand Down
11 changes: 9 additions & 2 deletions sklearn/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ def _inverse_transform(self, X):
return Xt

@if_delegate_has_method(delegate='_final_estimator')
def score(self, X, y=None):
def score(self, X, y=None, sample_weight=None):
"""Apply transforms, and score with the final estimator
Parameters
Expand All @@ -494,6 +494,10 @@ def score(self, X, y=None):
Targets used for scoring. Must fulfill label requirements for all
steps of the pipeline.
sample_weight : array-like, default=None
If not None, this argument is passed as ``sample_weight`` keyword
argument to the ``score`` method of the final estimator.
Returns
-------
score : float
Expand All @@ -502,7 +506,10 @@ def score(self, X, y=None):
for name, transform in self.steps[:-1]:
if transform is not None:
Xt = transform.transform(Xt)
return self.steps[-1][-1].score(Xt, y)
score_params = {}
if sample_weight is not None:
score_params['sample_weight'] = sample_weight
return self.steps[-1][-1].score(Xt, y, **score_params)

@property
def classes_(self):
Expand Down
36 changes: 36 additions & 0 deletions sklearn/tests/test_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ def fit_predict(self, X, y, should_succeed=False):
self.fit(X, y, should_succeed=should_succeed)
return self.predict(X)

def score(self, X, y=None, sample_weight=None):
if sample_weight is not None:
X = X * sample_weight
return np.sum(X)


def test_pipeline_init():
# Test the various init parameters of the pipeline.
Expand Down Expand Up @@ -212,6 +217,37 @@ def test_pipeline_fit_params():
# and transformer params should not be changed
assert_true(pipe.named_steps['transf'].a is None)
assert_true(pipe.named_steps['transf'].b is None)
# invalid parameters should raise an error message
assert_raise_message(
TypeError,
"fit() got an unexpected keyword argument 'bad'",
pipe.fit, None, None, clf__bad=True
)


def test_pipeline_sample_weight_supported():
# Pipeline should pass sample_weight
X = np.array([[1, 2]])
pipe = Pipeline([('transf', Transf()), ('clf', FitParamT())])
pipe.fit(X, y=None)
assert_equal(pipe.score(X), 3)
assert_equal(pipe.score(X, y=None), 3)
assert_equal(pipe.score(X, y=None, sample_weight=None), 3)
assert_equal(pipe.score(X, sample_weight=np.array([2, 3])), 8)


def test_pipeline_sample_weight_unsupported():
# When sample_weight is None it shouldn't be passed
X = np.array([[1, 2]])
pipe = Pipeline([('transf', Transf()), ('clf', Mult())])
pipe.fit(X, y=None)
assert_equal(pipe.score(X), 3)
assert_equal(pipe.score(X, sample_weight=None), 3)
assert_raise_message(
TypeError,
"score() got an unexpected keyword argument 'sample_weight'",
pipe.score, X, sample_weight=np.array([2, 3])
)


def test_pipeline_raise_set_params_error():
Expand Down

0 comments on commit 10323f5

Please sign in to comment.