Source code for syne_tune.optimizer.schedulers.searchers.conformal.surrogate.conformalized_quantile_regression_model

from dataclasses import dataclass
from typing import Union, List, Dict

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from tqdm import tqdm

from syne_tune.optimizer.schedulers.searchers.conformal.surrogate.quantile_regression_model import (
    GradientBoostingQuantileRegressor,
    QuantileRegressorPredictions,
)


[docs] @dataclass class ConformalQuantileCorrection: alpha: float sign: float = None correction: float = None def __post_init__(self): if self.alpha == 0.5: self.sign = 0.0 elif self.alpha < 0.5: self.sign = 1.0 elif self.alpha > 0.5: self.sign = -1.0 else: raise RuntimeError( "Incorrect alpha provided to ConformalizedGradientBoostingQuantileRegressor" )
[docs] class ConformalizedGradientBoostingQuantileRegressor(GradientBoostingQuantileRegressor): conformal_correction: Dict[float, ConformalQuantileCorrection] = None def __init__( self, quantiles: Union[int, List[float]] = 9, valid_fraction: float = 0.10, verbose: bool = False, **kwargs ): super().__init__(quantiles, verbose, **kwargs) self.valid_fraction = valid_fraction self.conformal_correction = { alpha: ConformalQuantileCorrection(alpha) for alpha in self.quantiles }
[docs] def fit(self, df_features: np.ndarray, y: np.array, **kwargs): x_training, x_validation, y_training, y_validation = train_test_split( df_features, y, test_size=self.valid_fraction ) for quantile in tqdm( self.quantile_regressors, desc="Training Quantile Regression", disable=not self.verbose, ): self.quantile_regressors[quantile].fit(x_training, np.ravel(y_training)) for alpha, cq in self.conformal_correction.items(): residuals = cq.sign * ( self.quantile_regressors[alpha].predict(x_validation).ravel() - y_validation.ravel() ) if alpha < 0.5: target_quantile = 1 - alpha else: target_quantile = alpha cq.correction = np.quantile(residuals, q=target_quantile)
[docs] def predict(self, df_test: pd.DataFrame) -> QuantileRegressorPredictions: quantile_res = { quantile: regressor.predict(df_test) - self.conformal_correction[quantile].correction for quantile, regressor in self.quantile_regressors.items() } return QuantileRegressorPredictions.from_quantile_results( quantiles=self.quantiles, results=quantile_res, )