-
-
Notifications
You must be signed in to change notification settings - Fork 25.9k
ENH Adds multimetric support to check_scoring #28360
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ENH Adds multimetric support to check_scoring #28360
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. One place that also seems to do something similiar to create multiple scorers is BaseSearchCV
scikit-learn/sklearn/model_selection/_search.py
Lines 784 to 815 in bb87768
def _get_scorers(self, convert_multimetric): | |
"""Get the scorer(s) to be used. | |
This is used in ``fit`` and ``get_metadata_routing``. | |
Parameters | |
---------- | |
convert_multimetric : bool | |
Whether to convert a dict of scorers to a _MultimetricScorer. This | |
is used in ``get_metadata_routing`` to include the routing info for | |
multiple scorers. | |
Returns | |
------- | |
scorers, refit_metric | |
""" | |
refit_metric = "score" | |
if callable(self.scoring): | |
scorers = self.scoring | |
elif self.scoring is None or isinstance(self.scoring, str): | |
scorers = check_scoring(self.estimator, self.scoring) | |
else: | |
scorers = _check_multimetric_scoring(self.estimator, self.scoring) | |
self._check_refit_for_multimetric(scorers) | |
refit_metric = self.refit | |
if convert_multimetric and isinstance(scorers, dict): | |
scorers = _MultimetricScorer( | |
scorers=scorers, raise_exc=(self.error_score == "raise") | |
) | |
return scorers, refit_metric |
@@ -942,6 +959,9 @@ def check_scoring(estimator, scoring=None, *, allow_none=False): | |||
"to a scorer." % scoring | |||
) | |||
return get_scorer(scoring) | |||
if isinstance(scoring, (list, tuple, set, dict)): | |||
scorers = _check_multimetric_scoring(estimator, scoring=scoring) | |||
return _MultimetricScorer(scorers=scorers) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing that is occluded is the raise_exc: bool = True
argument of _MultimetricScorer
. I have personally never used it so I do not mind. Is the decision not to support passing it in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not want to increase the scope of this PR. Usually increasing the scope makes it harder to merge.
If we want to add raise_exc
, then it can be done in a follow up PR.
sklearn/metrics/_scorer.py
Outdated
|
||
- a list or tuple of unique strings; | ||
- a callable returning a dictionary where the keys are the metric | ||
names and the values are the metric scores; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
names and the values are the metric scores; | |
names and the values are the metric scorers; |
Changing that part would increase the scope of this PR. #28359 is a step toward in refactoring Once #28359 is merged, then we can have a follow up PR to refactor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should make _MultimetricScorer
public when we're returning it in a public function. Otheriwise lgtm.
For the public API, |
I agree with this statement. However, I would implement two additional things. First, having a nicer In [5]: check_scoring(estimator=LogisticRegression(), scoring=scoring)
Out[5]: <sklearn.metrics._scorer._MultimetricScorer at 0x11c316830>
In [6]: check_scoring(estimator=LogisticRegression(), scoring=scoring["accuracy"])
Out[6]: make_scorer(accuracy_score, response_method='predict') Then, I think that we should have an entry point in the user guide: https://scikit-learn.org/dev/modules/model_evaluation.html#using-multiple-metric-evaluation. We could have a call to |
@glemaitre side question, is there any scope to make multimetric scorers publicly available through the |
Yep I think that we need to make sure that we can pass multiple scorer in the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks @thomasjpfan
Reference Issues/PRs
Fixes #28299
What does this implement/fix? Explain your changes.
This PR adds multi-metric support to
check_scoring
. This gives a public inference for returning a multiple metric scoring that uses the caching fromscoring
. With this PR, one can write the following to get a multi-metric scorer:Any other comments?
There are more places that can use this, but it requires #28359 to be merged in first.