ConfidenceIntervalApplicator#

class openstef_models.transforms.postprocessing.ConfidenceIntervalApplicator(**data: Any) None[source]

Bases: BaseModel, Transform[ForecastDataset, ForecastDataset]

Add quantile predictions to forecasts based on learned uncertainty patterns.

This transform learns hour-specific uncertainty from validation errors and applies it to new predictions to generate probabilistic forecasts.

How it works:

  1. Learning phase (fit()):

    • Computes validation errors for each hour of day (0-23)

    • Calculates standard deviation for each hour

    • For multi-horizon data, stores separate std for each horizon

  2. Prediction phase (transform()):

    • Looks up appropriate std based on prediction hour

    • For multi-horizon: interpolates std using exponential decay

    • Converts std to quantiles assuming a normal distribution (e.g., P10 = median - 1.28*std, P90 = median + 1.28*std)

The exponential decay interpolation (for multi-horizon) uses sigma(t) = a * (1 - exp(-t/tau)) + b, where t is hours ahead and tau = far_horizon / 4. This reflects the pattern of uncertainty growing quickly at first then leveling off.

Parameters:

quantiles (list[Quantile] | None) – Quantiles to generate (e.g., [0.1, 0.5, 0.9]). If None, returns predictions unchanged.

Invariants

  • Validation data must span multiple days for reliable hourly statistics

  • Generated quantiles satisfy ordering: P10 <= P50 <= P90 (for typical quantiles)

Example

>>> from openstef_core.types import LeadTime, Quantile
>>> from datetime import timedelta
>>> applicator = ConfidenceIntervalApplicator(
...     quantiles=[Quantile(0.1), Quantile(0.5), Quantile(0.9)]
... )
>>> applicator.fit((validation_data, validation_predictions))
>>> result = applicator.transform((new_input_data, new_predictions))
>>> list(result.data.columns)
['quantile_P10', 'quantile_P50', 'quantile_P90']

Note

Assumes forecast errors follow a normal distribution. This works well for energy forecasting but may not suit all domains.

Parameters:

data (Any)

quantiles: list[Quantile] | None
add_quantiles_from_std: bool
property standard_deviation: DataFrame

Hour-specific standard deviations learned during fit.

Raises:

NotFittedError – If fit() has not been called.

property is_fitted: bool

Check if the transform has been fitted.

fit(data: ForecastDataset) None[source]

Fit the transform to the input data.

This method should be called before applying the transform to the data. It allows the transform to learn any necessary parameters from the data.

Parameters:
Return type:

None

transform(data: ForecastDataset) ForecastDataset[source]

Transform the input data.

This method should apply a transformation to the input data and return a new instance.

Parameters:
Returns:

A new instance of the transformed data.

Raises:

NotFittedError – If the transform has not been fitted yet.

Return type:

ForecastDataset

model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Parameters:
  • self (BaseModel) – The BaseModel instance.

  • context (Any) – The context.

  • self

  • context

Return type:

None