From cf4a536665e9f5e96b8b818a355bf804be80b25f Mon Sep 17 00:00:00 2001 From: jawadhussein462 <41950044+jawadhussein462@users.noreply.github.com> Date: Mon, 2 Dec 2024 14:52:05 +0100 Subject: [PATCH] REFACTOR & ENH: Split .fit into .fit_single_estimator and fit_multi_estimator in MapieRegressor and EnsembleRegressor, implement (wip) CrossConformalRegressor (#545) --- mapie_v1/conformity_scores/utils.py | 22 +++++++++++++++- mapie_v1/regression.py | 39 ++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/mapie_v1/conformity_scores/utils.py b/mapie_v1/conformity_scores/utils.py index 20e12719c..7de179246 100644 --- a/mapie_v1/conformity_scores/utils.py +++ b/mapie_v1/conformity_scores/utils.py @@ -1,4 +1,4 @@ -from typing import Union +from typing import Union, List from mapie.conformity_scores import BaseRegressionScore from . import REGRESSION_CONFORMITY_SCORES_STRING_MAP @@ -12,3 +12,23 @@ def check_and_select_split_conformity_score( return REGRESSION_CONFORMITY_SCORES_STRING_MAP[conformity_score]() else: raise ValueError("Invalid conformity_score type") + + +def process_confidence_level( + self, confidence_level: Union[float, List[float]] +) -> List[float]: + """ + Ensure confidence_level is always a list of floats. + """ + if isinstance(confidence_level, float): + return [confidence_level] + return confidence_level + + +def compute_alpha( + self, confidence_levels: List[float] +) -> List[float]: + """ + Compute alpha values from confidence levels. + """ + return [1 - level for level in confidence_levels] diff --git a/mapie_v1/regression.py b/mapie_v1/regression.py index a049ec4c4..5d89fcbb2 100644 --- a/mapie_v1/regression.py +++ b/mapie_v1/regression.py @@ -10,8 +10,11 @@ from mapie.conformity_scores import BaseRegressionScore from mapie.regression import MapieRegressor from mapie.utils import check_estimator_fit_predict -from mapie_v1.conformity_scores.utils import \ - check_and_select_split_conformity_score +from mapie_v1.conformity_scores.utils import ( + check_and_select_split_conformity_score, + process_confidence_level, + compute_alpha, +) class SplitConformalRegressor: @@ -101,10 +104,8 @@ def __init__( random_state=random_state, ) - if isinstance(confidence_level, float): - confidence_level = [confidence_level] - - self.alpha = [1 - level for level in confidence_level] + self.confidence_level = process_confidence_level(confidence_level) + self.alpha = compute_alpha(self.confidence_level) def fit( self, @@ -322,7 +323,19 @@ def __init__( verbose: int = 0, random_state: Optional[Union[int, np.random.RandomState]] = None ) -> None: - pass + + self.mapie_regressor = MapieRegressor( + estimator=self.estimator, + method=method, + cv=cv, + n_jobs=n_jobs, + verbose=verbose, + conformity_score=self.conformity_score, + random_state=random_state, + ) + + self.confidence_level = process_confidence_level(confidence_level) + self.alpha = compute_alpha(self.confidence_level) def fit( self, @@ -350,7 +363,10 @@ def fit( Self The fitted CrossConformalRegressor instance. """ - pass + X, y, sample_weight, groups = self.init_fit( + X, y, fit_params=fit_params + ) + self.mapie_regressor.fit_estimator(X, y, sample_weight, groups) def conformalize( self, @@ -387,7 +403,12 @@ def conformalize( Self The conformalized SplitConformalRegressor instance. """ - pass + self.mapie_regressor.conformalize( + X, + y, + groups=groups, + predict_params=predict_params + ) def predict_set( self,