Skip to content

fix: LagsAdder.features_added() over-reports lags outside the horizon window#1023

Open
Valyrian-Code wants to merge 1 commit into
OpenSTEF:mainfrom
Valyrian-Code:fix/lags-adder-features-added
Open

fix: LagsAdder.features_added() over-reports lags outside the horizon window#1023
Valyrian-Code wants to merge 1 commit into
OpenSTEF:mainfrom
Valyrian-Code:fix/lags-adder-features-added

Conversation

@Valyrian-Code

Copy link
Copy Markdown
Contributor

What

LagsAdder.transform() only materializes lags that fall within a horizon's valid window (>= the horizon and <= history_available) — a configured lag below the shortest horizon, or beyond the available history, is never added. But features_added() returned a name for every configured lag (self._lags), so it advertised columns that transform() never creates.

That is a contract mismatch: any consumer relying on features_added() (feature selection, column validation) is told about columns that never materialize. Same defect shape as the recently merged #965 (RollingAggregatesAdder) and #980 (DatetimeFeaturesAdder).

Concretely, with history_available=10d, horizons=[2D], custom_lags=[1D, 3D, 30D], add_trivial_lags=False:

  • transform() adds only load_lag_P3D (1D is below the 2D horizon, 30D exceeds the 10D history);
  • features_added() previously returned load_lag_P30D, load_lag_P3D, load_lag_P1D.

Fix

Return only the lags transform() actually produces — the union of the per-horizon valid lags (self._horizon_lags), which mirrors the columns built in _transform_single_horizon / _transform_versioned:

materialized_lags = sorted({lag for lags in self._horizon_lags.values() for lag in lags}, reverse=True)
return [self._lag_feature(lag) for lag in materialized_lags]

No change to transform(), the lags/horizon_lags properties, or any public field.

Tests

Added regression tests (both fail on the previous code, pass with the fix):

  • single-horizon: features_added() equals the columns transform() adds, with the out-of-window custom_lags dropped;
  • multi-horizon: features_added() equals the union of columns created across horizons.

ruff check, ruff format --check, and ty check are clean on the changed files. The openstef-models time-domain transforms suite (64) and the openstef-meta presets suite (29 — the one internal consumer, forecasting_workflow.py, uses this as an exclude set where the change is behaviour-preserving) both pass.

… window

## What

LagsAdder.transform() only materializes lags that fall within a horizon's
valid window (>= the horizon and <= history_available); a configured lag
below the shortest horizon or beyond history_available is never added. But
features_added() returned a name for every configured lag, so it advertised
columns that transform() never creates -- a contract mismatch that can
mislead any consumer relying on it (feature selection / column validation).

## Fix

Return only the lags transform() actually produces: the union of the
per-horizon valid lags (self._horizon_lags), matching the columns built in
_transform_single_horizon / _transform_versioned. Same shape of fix as the
merged OpenSTEF#965 (RollingAggregatesAdder) and OpenSTEF#980 (DatetimeFeaturesAdder).

## Tests

Added regression tests (fail on the previous code, pass with the fix):
single-horizon and multi-horizon cases assert features_added() equals the
columns transform() actually adds, with out-of-window custom_lags dropped.
ruff, format, ty clean; models transforms (64) and meta presets (29) pass.

Signed-off-by: RAJVEER42 <irajveer.bishnoi2310@gmail.com>
@Valyrian-Code Valyrian-Code requested review from a team and Copilot July 4, 2026 04:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants