Skip to content

Model configuration

How to set hyperparameters and choose features for a forecasting experiment.


Config files

Each model family has a base YAML in conf/model/. The only one today is conf/model/xgboost.yaml. The file has two required top-level keys:

# Identifies the BaseForecaster subclass to instantiate (Hydra _target_).
_target_: xgboost_forecaster.forecaster.XGBoostForecaster

model_params:
  # Identifies the companion config class.
  _target_: xgboost_forecaster.forecaster.XGBoostConfig

  selected_features:
    - "power_lag_24h"
    - "temperature_2m"
    - ...

  # Model-specific hyperparameters:
  n_estimators: 500
  learning_rate: 0.05
  ...

_target_ values are fully-qualified Python class paths resolved by Hydra at registration time. You should not change them unless you are wiring up a new model family.


Features (selected_features)

selected_features is a list of strings. The feature engineering pipeline (ml_core.features._parsed_features.ParsedFeatures.from_strings) parses each string into a typed descriptor at registration time and raises ValueError immediately on any unrecognised or forbidden name.

Power lags

Pattern Example Notes
power_lag_{N}h power_lag_24h Observed power at valid_time − N hours. N must be a positive integer ≤ 17,520 (2 years).

Power lags shorter than or equal to the forecast lead time are automatically nullified at engineering time to prevent lookahead bias — see Lookahead-bias guardrails below.

Raw weather variables

These are the NWP variables available directly from ECMWF ENS at valid_time.

Feature name Variable
temperature_2m 2 m temperature (°C)
dew_point_temperature_2m 2 m dew point (°C)
wind_speed_10m Wind speed at 10 m (m/s)
wind_direction_10m Wind direction at 10 m (°)
wind_speed_100m Wind speed at 100 m (m/s)
wind_direction_100m Wind direction at 100 m (°)
pressure_surface Surface pressure (Pa)
pressure_reduced_to_mean_sea_level MSLP (Pa)
geopotential_height_500hpa 500 hPa geopotential height (m)
downward_long_wave_radiation_flux_surface Downward LW radiation (W/m²)
downward_short_wave_radiation_flux_surface Downward SW radiation (W/m²)
precipitation_surface Total precipitation (kg/m²)
categorical_precipitation_type_surface Precipitation type (categorical)

Weather lags and rolling means

Any raw weather variable can be lagged or smoothed:

Pattern Example Notes
{weather_var}_lag_{N}h temperature_2m_lag_6h NWP value at valid_time − N hours. Never leaky (NWP forecasts are available for future times).
{weather_var}_rolling_mean_{N}h temperature_2m_rolling_mean_6h Mean of the weather variable over the N-hour window ending at valid_time. Never leaky.

N must be a positive integer ≤ 17,520 (2 years).

Time features

Cyclical and calendar encodings computed from valid_time in local wall-clock time (respecting DST). Electricity demand follows human behaviour, which tracks local time not UTC.

Feature name Encoding
local_time_of_day_sin Sine of fraction of day (24 h period)
local_time_of_day_cos Cosine of fraction of day (24 h period)
local_time_of_year_sin Sine of fraction of year (365.25 day period)
local_time_of_year_cos Cosine of fraction of year (365.25 day period)
local_day_of_week_sin Sine of day-of-week (7 day period)
local_day_of_week_cos Cosine of day-of-week (7 day period)
local_day_of_week Integer day-of-week (0 = Monday)
local_utc_offset UTC offset in hours (e.g. 0 or 1 for GB)

Static derived features

Derived from weather variables via a fixed formula; no time-shifting.

Feature name Definition
windchill Wind-chill temperature from temperature_2m and wind_speed_10m (°C)

Pass-through base columns

These columns from the AllFeatures frame can be passed directly to the model as-is (e.g. to let the model learn horizon-dependent biases).

Feature name Description
nwp_lead_time_hours Hours between nwp_init_time and valid_time
ensemble_member ECMWF ensemble member index (0–50)
time_series_id Substation identifier (integer)
time_series_type Substation type (categorical string)
power_fcst_init_time When the forecast was issued
nwp_init_time When the NWP model ran

Lookahead-bias guardrails

Two feature names are forbidden and raise ValueError at parse time:

  • power — requesting the raw target variable as an input would let the model learn a trivial identity function, useless at inference time.
  • valid_time — an index column; use time features (e.g. local_time_of_day_sin) instead.

Power lags are automatically nullified by the feature engineering pipeline when the lag is shorter than or equal to the forecast lead time. For example, power_lag_2h would leak observed power into a 1-hour-ahead forecast, so its value is set to null for those rows. The model sees a null and treats it as a missing value (XGBoost handles nulls natively). This nullification happens per-row in _nullify_leaky_lags(), not at config time — the feature name is still valid; the pipeline just makes it safe.

Weather lags and rolling means are never nullified: NWP forecasts cover future valid_times, so a weather feature is always available at inference time regardless of lead time.


XGBoost hyperparameters

These fields live in XGBoostConfig (which inherits the universal fields from BaseForecasterConfig).

Universal fields (all model families)

Field Default Description
selected_features (required) List of feature name strings — see above.
weather_source "" Leaderboard tag, e.g. "ecmwf_control" or "ecmwf_ens".
training_strategy "" Leaderboard tag, e.g. "horizon_as_feature".
random_seed 0 Passed to XGBoost's seed param; makes re-training a fold reproduce the same model.

XGBoost-specific fields

Field Default Description
n_estimators 1000 Number of boosting rounds (num_boost_round).
learning_rate 0.05 Step size shrinkage (eta).
max_depth 6 Maximum tree depth.
min_child_weight 1 Minimum sum of instance weights in a child.
subsample 0.8 Fraction of rows sampled per tree.
colsample_bytree 0.8 Fraction of features sampled per tree.
device "cpu" "cpu" or "cuda".
objective "reg:squarederror" Loss function.

Tweaking a config for an experiment

You never edit a YAML file per experiment. Instead, pass config_overrides to register_experiment_job. Overrides are merged onto model_params by OmegaConf before instantiation, so any model_params key can be overridden.

Example — reduce tree depth and add a feature:

{
  "max_depth": 4,
  "selected_features": [
    "power_lag_24h",
    "power_lag_48h",
    "temperature_2m",
    "local_time_of_day_sin",
    "local_time_of_day_cos"
  ]
}

Note that selected_features is a whole-value replacement, not an extension. If you want to add one feature to the baseline set you must list all the features you want, not just the new one.

The resolved config (YAML defaults merged with your overrides) is frozen as a JSON tag on the MLflow experiment at registration time. That frozen record is what trained_cv_model reads back at train time — so changing the YAML after registering an experiment has no effect on it.