FEA add temperature scaling to CalibratedClassifierCV#31068
FEA add temperature scaling to CalibratedClassifierCV#31068lorentzenchr merged 100 commits intoscikit-learn:mainfrom
CalibratedClassifierCV#31068Conversation
virchan
left a comment
There was a problem hiding this comment.
A follow-up to my comment on the Array API: I don't think we can support the Array API here, as scipy.optimize.minimize does not appear to support it.
If I missed anything, please let me know—I'd be happy to investigate further.
ogrisel
left a comment
There was a problem hiding this comment.
Thanks for the PR. Here is a first pass of feedback:
…enting_temperature_scaling
…fier`. Updated constructor of `_TemperatureScaling` class. Updated `test_temperature_scaling` in `test_calibration.py`. Added `__sklearn_tags__` to `_TemperatureScaling` class.
…enting_temperature_scaling
…enting_temperature_scaling
…enting_temperature_scaling
…enting_temperature_scaling
…enting_temperature_scaling
…Updated doc-strings of temperature scaling in `calibration.py`. Updated formatting.
virchan
left a comment
There was a problem hiding this comment.
I'm still working on addressing the feedback, but I also wanted to share some findings related to it and provide an update.
…enting_temperature_scaling
lorentzenchr
left a comment
There was a problem hiding this comment.
I few computational things seem off.
…enting_temperature_scaling
Update `minimize` in `_temperture_scaling` to `minimize.scalar`. Update `test_calibration.py` to check the optimised inverse temperature is between 0.1 and 10.
virchan
left a comment
There was a problem hiding this comment.
There are some CI failures—I'll fix those shortly.
Also considering adding a verbose parameter to CalibratedClassifierCV to optionally display convergence info when optimising the inverse temperature beta.
…enting_temperature_scaling
…id `method` parameter.
…ature_scaling' into issues/28574_implementing_temperature_scaling # Conflicts: # sklearn/calibration.py
…tedClassifier.predict_proba` only.
virchan
left a comment
There was a problem hiding this comment.
I've refactored the part for checking reponse_method_name:
if len(classes) == 2 and predictions.shape[-1] == 1:
response_method_name = _check_response_method(
clf,
["decision_function", "predict_proba"],
).__name__
if response_method_name == "predict_proba":
predictions = np.hstack([1 - predictions, predictions])I think this only needs to be applied in two places: : _fit_calibrator and _CalibratedClassifier.predict_proba. But please let me know if there's a better way to handle this.
I've also moved _temperature_scaling inside _TemperatureScaling.fit.
CI has passed, so it's ready for review!
… `_TemperatureScaling.fit` method directly.
…enting_temperature_scaling
There was a problem hiding this comment.
I updated _convert_to_logits to handle the conversion to a 2D array in _TemperatureScaling.fit and _TemperatureScaling.predict when the input is 1D.
_TemperatureScaling now has a new parameter, response_method_name ("decision_function" or "predict_proba"), which indicates whether it should fit or predict based on the output of decision_function or predict_proba, respectively. The default value is "decision_function".
In the CalibratedClassifierCV workflow, this value is computed in _fit_calibrator, then passed to _TemperatureScaling when the calibrator is initialised. If the input is 1D, _convert_to_logits will interpret it as either probabilities or decision values, accordingly.
This is to address an edge case where the output of predict_proba is 1D and was incorrectly converted to logits using [-x, x], which was first caught by the test_calibration_prefit function.
Previously, I attempted something similar in 2769eab, but I thought it was awkward for _TemperatureScaling to store response_method_name, so I didn't finalise it at the time. We'll see how this version goes.
Edit: Reverted.
|
Sorry for the back and forth: Could you revert the last changes with the response_method_name c4ec0e8. It seems cleaner after all. |
This reverts commit c4ec0e8.
…enting_temperature_scaling
virchan
left a comment
There was a problem hiding this comment.
The response_method_name commit has been reverted, and CI has passed.
|
Thank you everyone for your time! 🫡 |
…#31068) Co-authored-by: Christian Lorentzen <lorentzen.ch@gmail.com>
Reference Issues/PRs
Closes #28574
What does this implement/fix? Explain your changes.
This PR adds temperature scaling to scikit-learn's
CalibratedClassifierCV:Temperature scaling can be enabled by setting
method = "temperature"inCalibratedClassifierCV:This method supports both binary and multi-class classification.
Any other comments?
Cc @adrinjalali, @lorentzenchr in advance.