33from typing_extensions import Self
44
55import numpy as np
6- from sklearn .linear_model import LinearRegression , QuantileRegressor
6+ from sklearn .linear_model import LinearRegression
77from sklearn .base import RegressorMixin , clone
88from sklearn .model_selection import BaseCrossValidator
9+ from sklearn .pipeline import Pipeline
910
1011from mapie .subsample import Subsample
1112from mapie ._typing import ArrayLike , NDArray
1213from mapie .conformity_scores import BaseRegressionScore
13- from mapie .regression import MapieRegressor
14+ from mapie .regression import MapieRegressor , MapieQuantileRegressor
1415from mapie .utils import check_estimator_fit_predict
1516from mapie_v1 .conformity_scores ._utils import (
1617 check_and_select_regression_conformity_score ,
@@ -904,12 +905,29 @@ class ConformalizedQuantileRegressor:
904905
905906 def __init__ (
906907 self ,
907- estimator : RegressorMixin = QuantileRegressor (),
908- confidence_level : Union [float , List [float ]] = 0.9 ,
909- conformity_score : Union [str , BaseRegressionScore ] = "absolute" ,
910- random_state : Optional [Union [int , np .random .RandomState ]] = None ,
908+ estimator : Optional [
909+ Union [
910+ RegressorMixin ,
911+ Pipeline ,
912+ List [Union [RegressorMixin , Pipeline ]]
913+ ]
914+ ] = None ,
915+ confidence_level : float = 0.9 ,
916+ prefit : bool = False ,
911917 ) -> None :
912- pass
918+
919+ self ._alpha = 1 - confidence_level
920+ self .prefit = prefit
921+
922+ cv : str = "prefit" if prefit else "split"
923+ self ._mapie_quantile_regressor = MapieQuantileRegressor (
924+ estimator = estimator ,
925+ method = "quantile" ,
926+ cv = cv ,
927+ alpha = self ._alpha ,
928+ )
929+
930+ self ._sample_weight : Optional [NDArray ] = None
913931
914932 def fit (
915933 self ,
@@ -937,6 +955,27 @@ def fit(
937955 Self
938956 The fitted ConformalizedQuantileRegressor instance.
939957 """
958+
959+ if self .prefit :
960+ raise ValueError (
961+ "The estimators are already fitted, the .fit() method should"
962+ " not be called with prefit=True."
963+ )
964+
965+ if fit_params :
966+ fit_params_ = copy .deepcopy (fit_params )
967+ self ._sample_weight = fit_params_ .pop ("sample_weight" , None )
968+ else :
969+ fit_params_ = {}
970+
971+ self ._mapie_quantile_regressor ._initialize_fit_conformalize ()
972+ self ._mapie_quantile_regressor ._fit_estimators (
973+ X = X_train ,
974+ y = y_train ,
975+ sample_weight = self ._sample_weight ,
976+ ** fit_params_ ,
977+ )
978+
940979 return self
941980
942981 def conformalize (
@@ -969,6 +1008,14 @@ def conformalize(
9691008 The ConformalizedQuantileRegressor instance with calibrated
9701009 prediction intervals.
9711010 """
1011+ self .predict_params = predict_params if predict_params else {}
1012+
1013+ self ._mapie_quantile_regressor .conformalize (
1014+ X_conf ,
1015+ y_conf ,
1016+ ** self .predict_params
1017+ )
1018+
9721019 return self
9731020
9741021 def predict_set (
@@ -1007,7 +1054,18 @@ def predict_set(
10071054 Prediction intervals with shape `(n_samples, 2)`, with lower
10081055 and upper bounds for each sample.
10091056 """
1010- return np .ndarray (0 )
1057+ _ , intervals = self ._mapie_quantile_regressor .predict (
1058+ X ,
1059+ optimize_beta = minimize_interval_width ,
1060+ allow_infinite_bounds = allow_infinite_bounds ,
1061+ symmetry = symmetric_intervals ,
1062+ ** self .predict_params
1063+ )
1064+
1065+ return make_intervals_single_if_single_alpha (
1066+ intervals ,
1067+ self ._alpha
1068+ )
10111069
10121070 def predict (
10131071 self ,
@@ -1026,7 +1084,9 @@ def predict(
10261084 NDArray
10271085 Array of point predictions with shape `(n_samples,)`.
10281086 """
1029- return np .ndarray (0 )
1087+ estimator = self ._mapie_quantile_regressor
1088+ predictions , _ = estimator .predict (X , ** self .predict_params )
1089+ return predictions
10301090
10311091
10321092class GibbsConformalRegressor :
0 commit comments