@@ -214,7 +214,7 @@ def get_quantile(
214214 conformity_scores : NDArray ,
215215 alpha_np : NDArray ,
216216 axis : int ,
217- method : str
217+ reversed : bool = False
218218 ) -> NDArray :
219219 """
220220 Compute the alpha quantile of the conformity scores or the conformity
@@ -235,25 +235,32 @@ def get_quantile(
235235 axis: int
236236 The axis from which to compute the quantile.
237237
238- method: str
239- ``"higher"`` or ``"lower"`` the method to compute the quantile.
238+ reversed: bool
239+ Boolean specifying whether we take the upper or lower quantile,
240+ if False, the alpha quantile, otherwise the (1-alpha) quantile.
240241
241242 Returns
242243 -------
243244 NDArray of shape (1, n_alpha) or (n_samples, n_alpha)
244245 The quantile of the conformity scores.
245246 """
246- n_ref = conformity_scores .shape [- 1 ]
247- quantile = np .column_stack ([
247+ n_ref = conformity_scores .shape [1 - axis ]
248+ n_calib = np .min (np .sum (~ np .isnan (conformity_scores ), axis = axis ))
249+ signed = 1 - 2 * reversed
250+
251+ # Adapt alpha w.r.t upper/lower : alpha vs. 1-alpha
252+ alpha_ref = (1 - 2 * alpha_np )* reversed + alpha_np
253+
254+ # Adjust alpha w.r.t quantile correction
255+ alpha_ref = np .ceil (alpha_ref * (n_calib + 1 ))/ n_calib
256+
257+ # Compute the target quantiles
258+ quantile = signed * np .column_stack ([
248259 np_nanquantile (
249- conformity_scores .astype (float ),
250- _alpha ,
251- axis = axis ,
252- method = method
260+ signed * conformity_scores , _alpha , axis = axis , method = "lower"
253261 ) if 0 < _alpha < 1
254- else np .inf * np .ones (n_ref ) if method == "higher"
255- else - np .inf * np .ones (n_ref )
256- for _alpha in alpha_np
262+ else np .inf * np .ones (n_ref )
263+ for _alpha in alpha_ref
257264 ])
258265 return quantile
259266
@@ -281,7 +288,7 @@ def _beta_optimize(
281288 -------
282289 NDArray
283290 Array of betas minimizing the differences
284- ``(1-alpa +beta)-quantile - beta-quantile``.
291+ ``(1-alpha +beta)-quantile - beta-quantile``.
285292 """
286293 beta_np = np .full (
287294 shape = (len (lower_bounds ), len (alpha_np )),
@@ -405,26 +412,34 @@ def get_bounds(
405412 X , y_pred_up , conformity_scores
406413 )
407414 bound_low = self .get_quantile (
408- conformity_scores_low , alpha_low , axis = 1 , method = "lower"
415+ conformity_scores_low , alpha_low , axis = 1 , reversed = True
409416 )
410417 bound_up = self .get_quantile (
411- conformity_scores_up , alpha_up , axis = 1 , method = "higher"
418+ conformity_scores_up , alpha_up , axis = 1
412419 )
420+
413421 else :
414- quantile_search = "higher" if self .sym else "lower"
415- alpha_low = 1 - alpha_np if self .sym else beta_np
416- alpha_up = 1 - alpha_np if self .sym else 1 - alpha_np + beta_np
422+ if self .sym :
423+ alpha_ref = 1 - alpha_np
424+ quantile_ref = self .get_quantile (
425+ conformity_scores [..., np .newaxis ], alpha_ref , axis = 0
426+ )
427+ quantile_low , quantile_up = - quantile_ref , quantile_ref
428+
429+ else :
430+ alpha_low , alpha_up = beta_np , 1 - alpha_np + beta_np
431+
432+ quantile_low = self .get_quantile (
433+ conformity_scores [..., np .newaxis ],
434+ alpha_low , axis = 0 , reversed = True
435+ )
436+ quantile_up = self .get_quantile (
437+ conformity_scores [..., np .newaxis ],
438+ alpha_up , axis = 0
439+ )
417440
418- quantile_low = self .get_quantile (
419- conformity_scores [..., np .newaxis ],
420- alpha_low , axis = 0 , method = quantile_search
421- )
422- quantile_up = self .get_quantile (
423- conformity_scores [..., np .newaxis ],
424- alpha_up , axis = 0 , method = "higher"
425- )
426441 bound_low = self .get_estimation_distribution (
427- X , y_pred_low , signed * quantile_low
442+ X , y_pred_low , quantile_low
428443 )
429444 bound_up = self .get_estimation_distribution (
430445 X , y_pred_up , quantile_up
0 commit comments