From cfed0cb2c95a4d1e6886498f041b4c27bff26953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cauthierj=E2=80=9D?= <“jules.authier@unit8.co”> Date: Mon, 27 Jan 2025 17:45:25 +0100 Subject: [PATCH 1/4] if clause modified to correct bug --- darts/models/forecasting/regression_model.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/darts/models/forecasting/regression_model.py b/darts/models/forecasting/regression_model.py index b5c76a0f0e..b8f30962de 100644 --- a/darts/models/forecasting/regression_model.py +++ b/darts/models/forecasting/regression_model.py @@ -393,7 +393,9 @@ def _generate_lags( processed_lags[lags_abbrev] = [ lag_ + output_chunk_shift for lag_ in processed_lags[lags_abbrev] ] - if processed_component_lags: + if processed_component_lags and list(tmp_components_lags.keys()) != [ + "default_lags" + ]: processed_component_lags[lags_abbrev] = { comp_: [lag_ + output_chunk_shift for lag_ in lags_] for comp_, lags_ in processed_component_lags[ From fb2931f3f4e3ab2873f92a06bd5f913d19dd44c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cauthierj=E2=80=9D?= <“jules.authier@unit8.co”> Date: Mon, 27 Jan 2025 18:01:25 +0100 Subject: [PATCH 2/4] contribution added to changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d0c316ec0..a6033700a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ but cannot always guarantee backwards compatibility. Changes that may **break co **Improved** +- Fixed a bug when initiating a `RegressionModel` with `lags_past_covariates` as dict and `lags_future_covariates` as some other type (not dict) and `output_chunk_shift>0`, [#2652 +](https://github.com/unit8co/darts/issues/2652) by [Jules Authier](https://github.com/authierj). - New model: `StatsForecastAutoTBATS`. This model offers the [AutoTBATS](https://nixtlaverse.nixtla.io/statsforecast/src/core/models.html#autotbats) model from Nixtla's `statsforecasts` library. [#2611](https://github.com/unit8co/darts/pull/2611) by [He Weilin](https://github.com/cnhwl). - Added the `title` attribute to `TimeSeries.plot()`. This allows to set a title for the plot. [#2639](https://github.com/unit8co/darts/pull/2639) by [Jonathan Koch](https://github.com/jonathankoch99). - Added parameter `component_wise` to `show_anomalies()` to separately plot each component in multivariate series. [#2544](https://github.com/unit8co/darts/pull/2544) by [He Weilin](https://github.com/cnhwl). From 4beaf24c2f19a2e450a1f4eb4b4e92b0bc2897a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cauthierj=E2=80=9D?= <“jules.authier@unit8.co”> Date: Tue, 28 Jan 2025 14:44:43 +0100 Subject: [PATCH 3/4] implemented modifications from reviewer --- CHANGELOG.md | 3 +-- darts/models/forecasting/regression_model.py | 9 +++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85ba7d11ba..62267cbd32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,6 @@ but cannot always guarantee backwards compatibility. Changes that may **break co **Improved** -- Fixed a bug when initiating a `RegressionModel` with `lags_past_covariates` as dict and `lags_future_covariates` as some other type (not dict) and `output_chunk_shift>0`, [#2652 -](https://github.com/unit8co/darts/issues/2652) by [Jules Authier](https://github.com/authierj). - New model: `StatsForecastAutoTBATS`. This model offers the [AutoTBATS](https://nixtlaverse.nixtla.io/statsforecast/src/core/models.html#autotbats) model from Nixtla's `statsforecasts` library. [#2611](https://github.com/unit8co/darts/pull/2611) by [He Weilin](https://github.com/cnhwl). - Added the `title` attribute to `TimeSeries.plot()`. This allows to set a title for the plot. [#2639](https://github.com/unit8co/darts/pull/2639) by [Jonathan Koch](https://github.com/jonathankoch99). - Added parameter `component_wise` to `show_anomalies()` to separately plot each component in multivariate series. [#2544](https://github.com/unit8co/darts/pull/2544) by [He Weilin](https://github.com/cnhwl). @@ -60,6 +58,7 @@ but cannot always guarantee backwards compatibility. Changes that may **break co **Fixed** +- Fixed a bug when initiating a `RegressionModel` with `lags_past_covariates` as dict and `lags_future_covariates` as some other type (not dict) and `output_chunk_shift>0`, [#2652](https://github.com/unit8co/darts/issues/2652) by [Jules Authier](https://github.com/authierj). - Fixed a bug which raised an error when computing residuals (or backtest with "per time step" metrics) on multiple series with corresponding historical forecasts of different lengths. [#2604](https://github.com/unit8co/darts/pull/2604) by [Dennis Bader](https://github.com/dennisbader). - Fixed a bug when using `darts.utils.data.tabularization.create_lagged_component_names()` with target `lags=None`, that did not return any lagged target label component names. [#2576](https://github.com/unit8co/darts/pull/2576) by [Dennis Bader](https://github.com/dennisbader). - Fixed a bug when using `num_samples > 1` with a deterministic regression model and the optimized `historical_forecasts()` method, which did not raise an exception. [#2576](https://github.com/unit8co/darts/pull/2588) by [Antoine Madrona](https://github.com/madtoinou). diff --git a/darts/models/forecasting/regression_model.py b/darts/models/forecasting/regression_model.py index b8f30962de..3f6b3efd96 100644 --- a/darts/models/forecasting/regression_model.py +++ b/darts/models/forecasting/regression_model.py @@ -381,8 +381,11 @@ def _generate_lags( else: max_lags = max(max_lags, tmp_components_lags[comp_name][-1]) + # Check if only default lags are provided + has_default_lags = list(tmp_components_lags.keys()) == ["default_lags"] + # revert to shared lags logic when applicable - if list(tmp_components_lags.keys()) == ["default_lags"]: + if has_default_lags: processed_lags[lags_abbrev] = tmp_components_lags["default_lags"] else: processed_lags[lags_abbrev] = [min_lags, max_lags] @@ -393,9 +396,7 @@ def _generate_lags( processed_lags[lags_abbrev] = [ lag_ + output_chunk_shift for lag_ in processed_lags[lags_abbrev] ] - if processed_component_lags and list(tmp_components_lags.keys()) != [ - "default_lags" - ]: + if processed_component_lags and not has_default_lags: processed_component_lags[lags_abbrev] = { comp_: [lag_ + output_chunk_shift for lag_ in lags_] for comp_, lags_ in processed_component_lags[ From 83d1d592b7005e335f04e9fd8f4a204acc08a04c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cauthierj=E2=80=9D?= <“jules.authier@unit8.co”> Date: Wed, 29 Jan 2025 13:03:14 +0100 Subject: [PATCH 4/4] unit tests added --- .../forecasting/test_regression_models.py | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/darts/tests/models/forecasting/test_regression_models.py b/darts/tests/models/forecasting/test_regression_models.py index 9aed20f431..2633dac92b 100644 --- a/darts/tests/models/forecasting/test_regression_models.py +++ b/darts/tests/models/forecasting/test_regression_models.py @@ -2390,6 +2390,20 @@ def test_component_specific_lags(self, config): "lags_past_covariates": 4, "lags_future_covariates": [-3, 1], }, + # check that component-specific lags with output_chunk_shift works + { + "lags_past_covariates": {"lin_past": [-3, -1]}, + "lags_future_covariates": [1, 2], + }, + { + "lags_past_covariates": [-3, -1], + "lags_future_covariates": {"lin_future": [1, 2]}, + }, + { + "lags": {"gaussian": 5}, + "lags_past_covariates": [-3, -1], + "lags_future_covariates": [1, 2], + }, ], [True, False], [3, 5], @@ -2431,11 +2445,19 @@ def test_same_result_output_chunk_shift(self, config): ) # adjusting the future lags should give identical models to non-shifted list_lags_adj = deepcopy(list_lags) + # this loop works for both component-specific and non-component-specific future lags if "lags_future_covariates" in list_lags_adj: - list_lags_adj["lags_future_covariates"] = [ - lag_ - output_chunk_shift - for lag_ in list_lags_adj["lags_future_covariates"] - ] + if isinstance(list_lags_adj["lags_future_covariates"], dict): + for key in list_lags_adj["lags_future_covariates"]: + list_lags_adj["lags_future_covariates"][key] = [ + lag_ - output_chunk_shift + for lag_ in list_lags_adj["lags_future_covariates"][key] + ] + else: + list_lags_adj["lags_future_covariates"] = [ + lag_ - output_chunk_shift + for lag_ in list_lags_adj["lags_future_covariates"] + ] model_shift_adj = LinearRegressionModel( **list_lags_adj, output_chunk_shift=output_chunk_shift,