-
-
Notifications
You must be signed in to change notification settings - Fork 25.8k
Warn in the main process when a fit fails during a cross-validation #20619
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
Conversation
Putting _warn_about_fit_failures before _insert_error_scores is enough.
The tests pass, the CI red only because I have not added a changelog yet. Comments about the points noted in my top post or anything else in this PR, let me know! |
@@ -2082,37 +2082,6 @@ def test_fit_and_score_failing(): | |||
y = np.ones(9) | |||
fit_and_score_args = [failing_clf, X, None, dict(), None, None, 0, None, None] | |||
# passing error score to trigger the warning message | |||
fit_and_score_kwargs = {"error_score": 0} |
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.
The check on the warnings were moved below to test_cross_validate_failing_fits_warnings
since _fit_and_score
does not warn anymore
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.
removing the per-split warning may affect BaseSearchCV derived classes outside scikit-learn.
The BaseSearchCV
"public API" consist calling evaluate_candidates
in _run_search
. The warning will still appear when calling evaluate_candidates
, just not as often. I think it is okay to change.
This is how it looks right now. I could potentially shorten it when some of the errors are exactly the same:
If error message is exactly the same, only show one of them?
quirk that for multimetric you get an error if all the test fails (but not for single metric)
With callable multimetric, at least one _fit_and_score
has to succeed so that *SearchCV
can create error_score
dictionaries for the failed cases. In the single metric case, *SearchCV
can still proceed because there are no keys to deal with.
To confirm this behaviour, I assume that we can try using |
Interesting. On the user side, you don't think that we should anyway raise an error when everything is Indeed, I would not be surprised to raise an error in both multimeric and single metric. I would be a bit more lenient if some of the metrics fail in the multimetric case. |
It does make sense to raise an error if everything failed. We can add this improvement in another PR. |
I summarised errors in the warnings showing each error only once. This is how the warning looks with 10 fit failures with 2 different failures:
test.py script usedimport numpy as np
from sklearn.base import BaseEstimator
class FailingClassifier(BaseEstimator):
"""Classifier that raises a ValueError on fit()"""
FAILING_PARAMETERS = [2, 3]
def __init__(self, parameter=None):
self.parameter = parameter
def fit(self, X, y=None):
if self.parameter in FailingClassifier.FAILING_PARAMETERS:
raise ValueError(f"Failing classifier failed for parameter {self.parameter}")
def predict(self, X):
return np.zeros(X.shape[0])
def score(self, X=None, Y=None):
return 0.0
from sklearn.datasets import make_classification
X, y = make_classification()
from sklearn.model_selection import GridSearchCV
gs = GridSearchCV(FailingClassifier(), {'parameter': [1, 2, 3, 4, 5]})
gs.fit(X, y) |
That looks great! |
Co-authored-by: Thomas J. Fan <thomasjpfan@gmail.com>
) | ||
|
||
some_fits_failed_message = ( | ||
f"\n{num_failed_fits} fits failed on the training sets over a total of" |
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 find this language a bit strange... Should "over" be "out of"? Is "on the training sets" helpful?
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.
Thanks for the comment, I updated the wording:
- now: "5 fits failed out of a total of 15"
- before it was: "5 fits failed on the training sets over a total of 15 fits"
Let me know if the language is still a bit strange!
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. I think this is a really nice usability improvement.
+1 for a follow-up PR to always raise an error if 100% of the fits fail (both in simple cross validation and in hyperparam search).
Co-authored-by: Guillaume Lemaitre <g.lemaitre58@gmail.com>
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.
Small nit, otherwise LGTM!
Co-authored-by: Thomas J. Fan <thomasjpfan@gmail.com>
Merged! Thank you very much for the improvement @lesteve! |
…cikit-learn#20619) Co-authored-by: Thomas J. Fan <thomasjpfan@gmail.com> Co-authored-by: Guillaume Lemaitre <g.lemaitre58@gmail.com> Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org>
Reference Issues/PRs
Fix #20475
What does this implement/fix? Explain your changes.
Removes a per-split warning and do a summary warning in the main process.
Any other comments?
Still polishing it for now, some test failures expected.
Some remaining things to discuss/do:
BaseSearchCV
derived classes outside scikit-learn. There will be no warnings when a fit fails. How acceptable is it?test_callable_multimetric_clf_all_fails
failure: quirk that for multimetric you get an error if all the test fails (but not for single metric). Is there a good reason for this behaviour? I changed my PR to make this test pass, basically the warnings on fit failures happens before the insertion of error scores for the multimetric case.