From dc8f5657c856e0699763c40d0be84445a4a4cf64 Mon Sep 17 00:00:00 2001 From: authierj Date: Fri, 28 Feb 2025 19:50:31 +0100 Subject: [PATCH 01/13] notes --- darts/utils/data/tabularization.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/darts/utils/data/tabularization.py b/darts/utils/data/tabularization.py index 1742f7ccd1..9137e74f9c 100644 --- a/darts/utils/data/tabularization.py +++ b/darts/utils/data/tabularization.py @@ -341,6 +341,7 @@ def create_lagged_data( logger, ) if use_moving_windows and series_equal_freq: + # TODO look here X_i, y_i, times_i, weights_i = _create_lagged_data_by_moving_window( target_series=target_i, output_chunk_length=output_chunk_length, @@ -988,6 +989,7 @@ def _create_lagged_data_by_moving_window( Assumes that all the lags are sorted in ascending order. """ + # TODO look here feature_times, min_lags, max_lags = _get_feature_times( target_series=target_series, past_covariates=past_covariates, @@ -1672,6 +1674,7 @@ def _get_feature_times( # Append times to end of series - see Step 1b for extracting features # times from `future_covariates`, or Step 1 for extracting features # from `target_series`/`past_covariates` in `Notes`: + # TODO look at this line new_end = ( times_i[-1] + series_i.freq * (min_lag_i) if min_lag_i > 0 else None ) From c66597ae8b1ef63a31b86ddd834016556227ad53 Mon Sep 17 00:00:00 2001 From: authierj Date: Mon, 3 Mar 2025 11:02:26 +0100 Subject: [PATCH 02/13] dennis note --- .../optimized_historical_forecasts_regression.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/darts/utils/historical_forecasts/optimized_historical_forecasts_regression.py b/darts/utils/historical_forecasts/optimized_historical_forecasts_regression.py index a8a1444731..358f1ab94a 100644 --- a/darts/utils/historical_forecasts/optimized_historical_forecasts_regression.py +++ b/darts/utils/historical_forecasts/optimized_historical_forecasts_regression.py @@ -81,6 +81,8 @@ def _optimized_historical_forecasts_last_points_only( show_warnings=show_warnings, ) + # TODO get target lags and adjust hist_fct_tgt_end + # Additional shift, to account for the model output_chunk_length if model.output_chunk_length != forecast_horizon and not model.multi_models: # used to convert the shift into the appropriate unit From daee87c2355519132ecdd04a84b936a3c291b37c Mon Sep 17 00:00:00 2001 From: authierj Date: Mon, 3 Mar 2025 16:59:47 +0100 Subject: [PATCH 03/13] trying a few things --- darts/models/forecasting/regression_model.py | 8 ++- ...timized_historical_forecasts_regression.py | 3 + darts/utils/historical_forecasts/utils.py | 7 ++- testing2.py | 59 +++++++++++++++++++ 4 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 testing2.py diff --git a/darts/models/forecasting/regression_model.py b/darts/models/forecasting/regression_model.py index 6c69c48c3e..4d4892b3b2 100644 --- a/darts/models/forecasting/regression_model.py +++ b/darts/models/forecasting/regression_model.py @@ -457,7 +457,13 @@ def extreme_lags( Optional[int], ]: min_target_lag = self.lags["target"][0] if "target" in self.lags else None - max_target_lag = self.output_chunk_length - 1 + self.output_chunk_shift + # WHHHHHYYYYYYYY + # max_target_lag = self.output_chunk_length - 1 + self.output_chunk_shift + max_target_lag = ( + self.output_chunk_length + self.lags["target"][-1] + self.output_chunk_shift + if "target" in self.lags + else self.output_chunk_length - 1 + self.output_chunk_shift + ) min_past_cov_lag = self.lags["past"][0] if "past" in self.lags else None max_past_cov_lag = self.lags["past"][-1] if "past" in self.lags else None min_future_cov_lag = self.lags["future"][0] if "future" in self.lags else None diff --git a/darts/utils/historical_forecasts/optimized_historical_forecasts_regression.py b/darts/utils/historical_forecasts/optimized_historical_forecasts_regression.py index 358f1ab94a..8a6b09a773 100644 --- a/darts/utils/historical_forecasts/optimized_historical_forecasts_regression.py +++ b/darts/utils/historical_forecasts/optimized_historical_forecasts_regression.py @@ -82,6 +82,9 @@ def _optimized_historical_forecasts_last_points_only( ) # TODO get target lags and adjust hist_fct_tgt_end + # lags = model._get_lags("target") + # if lags is not None and lags[-1] < -1: + # hist_fct_tgt_end += (lags[-1] + 1) * freq # Additional shift, to account for the model output_chunk_length if model.output_chunk_length != forecast_horizon and not model.multi_models: diff --git a/darts/utils/historical_forecasts/utils.py b/darts/utils/historical_forecasts/utils.py index c8502cd7c4..8d3c7825e0 100644 --- a/darts/utils/historical_forecasts/utils.py +++ b/darts/utils/historical_forecasts/utils.py @@ -1007,7 +1007,7 @@ def _get_historical_forecast_boundaries( # `max_target_lag_train` is redundant, since optimized hist fc is running in predict mode only ( min_target_lag, - _, + max_target_lag, min_past_cov_lag, max_past_cov_lag, min_future_cov_lag, @@ -1020,7 +1020,10 @@ def _get_historical_forecast_boundaries( hist_fct_tgt_start, hist_fct_tgt_end = historical_forecasts_time_index if min_target_lag is not None: hist_fct_tgt_start += min_target_lag * freq - hist_fct_tgt_end -= 1 * freq + # BUGFIX this is strange, why not + hist_fct_tgt_end += 1 * freq * (max_target_lag - 1) + # hist_fct_tgt_end += 1 * freq * model._get_lags("target")[-1] + # hist_fct_tgt_end -= 1 * freq # past lags are <= 0 hist_fct_pc_start, hist_fct_pc_end = historical_forecasts_time_index if min_past_cov_lag is not None: diff --git a/testing2.py b/testing2.py new file mode 100644 index 0000000000..dc02f9da71 --- /dev/null +++ b/testing2.py @@ -0,0 +1,59 @@ +from itertools import product + +from sklearn.preprocessing import MaxAbsScaler + +from darts.dataprocessing.transformers import Scaler +from darts.models import LinearRegressionModel +from darts.tests.utils.historical_forecasts.test_historical_forecasts import ( + TestHistoricalforecast, +) +from darts.utils import timeseries_generation as tg + +tester = TestHistoricalforecast() + +sine_univariate1 = tg.sine_timeseries(length=50) * 2 + 1.5 +sine_univariate2 = tg.sine_timeseries(length=50, value_phase=1.5705) * 5 + 1.5 +sine_univariate3 = tg.sine_timeseries(length=50, value_phase=0.1963125) * -9 + 1.5 + +params = product( + [ + ( + { + "series": sine_univariate1 - 11, + }, + {"series": Scaler(scaler=MaxAbsScaler())}, + ), + ( + { + "series": sine_univariate3 + 2, + "past_covariates": sine_univariate1 * 3 + 3, + }, + {"past_covariates": Scaler()}, + ), + ( + { + "series": sine_univariate3 + 5, + "future_covariates": sine_univariate1 * (-4) + 3, + }, + {"future_covariates": Scaler(scaler=MaxAbsScaler())}, + ), + ( + { + "series": sine_univariate3 * 2 + 7, + "past_covariates": sine_univariate1 + 2, + "future_covariates": sine_univariate2 + 3, + }, + {"series": Scaler(), "past_covariates": Scaler()}, + ), + ], + [True, False], # retrain + [True, False], # last point only + [LinearRegressionModel], +) + +i = 0 + +for param in params: + if i == 2 or i == 3: + tester.test_historical_forecasts_with_scaler(params=param) + i += 1 From 85e83d3729c220e119ff3abc2c004230ac3eed81 Mon Sep 17 00:00:00 2001 From: authierj Date: Tue, 4 Mar 2025 14:38:53 +0100 Subject: [PATCH 04/13] seems to fix it --- darts/models/forecasting/regression_model.py | 12 ++++++------ darts/utils/historical_forecasts/utils.py | 8 +++++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/darts/models/forecasting/regression_model.py b/darts/models/forecasting/regression_model.py index 4d4892b3b2..86932ece69 100644 --- a/darts/models/forecasting/regression_model.py +++ b/darts/models/forecasting/regression_model.py @@ -458,12 +458,12 @@ def extreme_lags( ]: min_target_lag = self.lags["target"][0] if "target" in self.lags else None # WHHHHHYYYYYYYY - # max_target_lag = self.output_chunk_length - 1 + self.output_chunk_shift - max_target_lag = ( - self.output_chunk_length + self.lags["target"][-1] + self.output_chunk_shift - if "target" in self.lags - else self.output_chunk_length - 1 + self.output_chunk_shift - ) + max_target_lag = self.output_chunk_length - 1 + self.output_chunk_shift + # max_target_lag = ( + # self.output_chunk_length + self.lags["target"][-1] + self.output_chunk_shift + # if "target" in self.lags + # else self.output_chunk_length - 1 + self.output_chunk_shift + # ) min_past_cov_lag = self.lags["past"][0] if "past" in self.lags else None max_past_cov_lag = self.lags["past"][-1] if "past" in self.lags else None min_future_cov_lag = self.lags["future"][0] if "future" in self.lags else None diff --git a/darts/utils/historical_forecasts/utils.py b/darts/utils/historical_forecasts/utils.py index 8d3c7825e0..c65e3f2607 100644 --- a/darts/utils/historical_forecasts/utils.py +++ b/darts/utils/historical_forecasts/utils.py @@ -1021,9 +1021,11 @@ def _get_historical_forecast_boundaries( if min_target_lag is not None: hist_fct_tgt_start += min_target_lag * freq # BUGFIX this is strange, why not - hist_fct_tgt_end += 1 * freq * (max_target_lag - 1) - # hist_fct_tgt_end += 1 * freq * model._get_lags("target")[-1] - # hist_fct_tgt_end -= 1 * freq + # hist_fct_tgt_end += 1 * freq * (max_target_lag - 1) + if hasattr(model, "lags") and "target" in model.lags: + hist_fct_tgt_end += 1 * freq * model.lags["target"][-1] + else: + hist_fct_tgt_end -= 1 * freq # past lags are <= 0 hist_fct_pc_start, hist_fct_pc_end = historical_forecasts_time_index if min_past_cov_lag is not None: From 2500e418cd68141b7670dd4ea852d0d6822e227b Mon Sep 17 00:00:00 2001 From: authierj Date: Tue, 4 Mar 2025 17:59:36 +0100 Subject: [PATCH 05/13] fix and tests --- darts/models/forecasting/regression_model.py | 6 ------ .../historical_forecasts/test_historical_forecasts.py | 4 +++- darts/utils/data/tabularization.py | 3 --- darts/utils/historical_forecasts/utils.py | 11 ++++++----- 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/darts/models/forecasting/regression_model.py b/darts/models/forecasting/regression_model.py index 86932ece69..6c69c48c3e 100644 --- a/darts/models/forecasting/regression_model.py +++ b/darts/models/forecasting/regression_model.py @@ -457,13 +457,7 @@ def extreme_lags( Optional[int], ]: min_target_lag = self.lags["target"][0] if "target" in self.lags else None - # WHHHHHYYYYYYYY max_target_lag = self.output_chunk_length - 1 + self.output_chunk_shift - # max_target_lag = ( - # self.output_chunk_length + self.lags["target"][-1] + self.output_chunk_shift - # if "target" in self.lags - # else self.output_chunk_length - 1 + self.output_chunk_shift - # ) min_past_cov_lag = self.lags["past"][0] if "past" in self.lags else None max_past_cov_lag = self.lags["past"][-1] if "past" in self.lags else None min_future_cov_lag = self.lags["future"][0] if "future" in self.lags else None diff --git a/darts/tests/utils/historical_forecasts/test_historical_forecasts.py b/darts/tests/utils/historical_forecasts/test_historical_forecasts.py index f696724cb2..7ace5e0692 100644 --- a/darts/tests/utils/historical_forecasts/test_historical_forecasts.py +++ b/darts/tests/utils/historical_forecasts/test_historical_forecasts.py @@ -72,6 +72,8 @@ {}, (5, 3), ), + (LinearRegressionModel, {"lags": [-5]}, {}, (5, 1)), + (LinearRegressionModel, {"lags": [-5], "output_chunk_shift": 1}, {}, (5, 2)), ] if not isinstance(CatBoostModel, NotImportedModule): models_reg_no_cov_cls_kwargs.append(( @@ -665,7 +667,7 @@ def test_historical_forecasts_negative_rangeindex(self): def test_historical_forecasts(self, config): """Tests historical forecasts with retraining for expected forecast lengths and times""" forecast_horizon = 8 - # if no fit and retrain=false, should fit at fist iteration + # if no fit and retrain=false, should fit at first iteration model_cls, kwargs, model_kwarg, bounds = config model = model_cls(**kwargs, **model_kwarg) # set train length to be the minimum required training length diff --git a/darts/utils/data/tabularization.py b/darts/utils/data/tabularization.py index 9137e74f9c..1742f7ccd1 100644 --- a/darts/utils/data/tabularization.py +++ b/darts/utils/data/tabularization.py @@ -341,7 +341,6 @@ def create_lagged_data( logger, ) if use_moving_windows and series_equal_freq: - # TODO look here X_i, y_i, times_i, weights_i = _create_lagged_data_by_moving_window( target_series=target_i, output_chunk_length=output_chunk_length, @@ -989,7 +988,6 @@ def _create_lagged_data_by_moving_window( Assumes that all the lags are sorted in ascending order. """ - # TODO look here feature_times, min_lags, max_lags = _get_feature_times( target_series=target_series, past_covariates=past_covariates, @@ -1674,7 +1672,6 @@ def _get_feature_times( # Append times to end of series - see Step 1b for extracting features # times from `future_covariates`, or Step 1 for extracting features # from `target_series`/`past_covariates` in `Notes`: - # TODO look at this line new_end = ( times_i[-1] + series_i.freq * (min_lag_i) if min_lag_i > 0 else None ) diff --git a/darts/utils/historical_forecasts/utils.py b/darts/utils/historical_forecasts/utils.py index c65e3f2607..158114946b 100644 --- a/darts/utils/historical_forecasts/utils.py +++ b/darts/utils/historical_forecasts/utils.py @@ -1007,7 +1007,7 @@ def _get_historical_forecast_boundaries( # `max_target_lag_train` is redundant, since optimized hist fc is running in predict mode only ( min_target_lag, - max_target_lag, + _, min_past_cov_lag, max_past_cov_lag, min_future_cov_lag, @@ -1020,12 +1020,13 @@ def _get_historical_forecast_boundaries( hist_fct_tgt_start, hist_fct_tgt_end = historical_forecasts_time_index if min_target_lag is not None: hist_fct_tgt_start += min_target_lag * freq - # BUGFIX this is strange, why not - # hist_fct_tgt_end += 1 * freq * (max_target_lag - 1) - if hasattr(model, "lags") and "target" in model.lags: - hist_fct_tgt_end += 1 * freq * model.lags["target"][-1] + + # target lag has a gap between the max lag and the present + if hasattr(model, "lags") and model._get_lags("target"): + hist_fct_tgt_end += 1 * freq * model._get_lags("target")[-1] else: hist_fct_tgt_end -= 1 * freq + # past lags are <= 0 hist_fct_pc_start, hist_fct_pc_end = historical_forecasts_time_index if min_past_cov_lag is not None: From 8d0e49efe255a901fea77b4c3ba4df1ae65b493d Mon Sep 17 00:00:00 2001 From: authierj Date: Tue, 4 Mar 2025 18:09:07 +0100 Subject: [PATCH 06/13] note removal --- .../optimized_historical_forecasts_regression.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/darts/utils/historical_forecasts/optimized_historical_forecasts_regression.py b/darts/utils/historical_forecasts/optimized_historical_forecasts_regression.py index 8a6b09a773..a8a1444731 100644 --- a/darts/utils/historical_forecasts/optimized_historical_forecasts_regression.py +++ b/darts/utils/historical_forecasts/optimized_historical_forecasts_regression.py @@ -81,11 +81,6 @@ def _optimized_historical_forecasts_last_points_only( show_warnings=show_warnings, ) - # TODO get target lags and adjust hist_fct_tgt_end - # lags = model._get_lags("target") - # if lags is not None and lags[-1] < -1: - # hist_fct_tgt_end += (lags[-1] + 1) * freq - # Additional shift, to account for the model output_chunk_length if model.output_chunk_length != forecast_horizon and not model.multi_models: # used to convert the shift into the appropriate unit From 17755de075f05bede70c96b12fc84a2ebb4c8019 Mon Sep 17 00:00:00 2001 From: authierj Date: Wed, 5 Mar 2025 10:33:40 +0100 Subject: [PATCH 07/13] overlap_end taken into account --- .../utils/historical_forecasts/test_historical_forecasts.py | 6 ++++++ darts/utils/historical_forecasts/utils.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/darts/tests/utils/historical_forecasts/test_historical_forecasts.py b/darts/tests/utils/historical_forecasts/test_historical_forecasts.py index 7ace5e0692..0388227a2a 100644 --- a/darts/tests/utils/historical_forecasts/test_historical_forecasts.py +++ b/darts/tests/utils/historical_forecasts/test_historical_forecasts.py @@ -134,6 +134,12 @@ {}, (6, 2), ), + ( + LinearRegressionModel, + {"lags": [-3], "lags_past_covariates": 6, "lags_future_covariates": [0, 1]}, + {}, + (6, 2), + ), ] if TORCH_AVAILABLE: diff --git a/darts/utils/historical_forecasts/utils.py b/darts/utils/historical_forecasts/utils.py index 158114946b..fda6bbc501 100644 --- a/darts/utils/historical_forecasts/utils.py +++ b/darts/utils/historical_forecasts/utils.py @@ -1022,7 +1022,7 @@ def _get_historical_forecast_boundaries( hist_fct_tgt_start += min_target_lag * freq # target lag has a gap between the max lag and the present - if hasattr(model, "lags") and model._get_lags("target"): + if hasattr(model, "lags") and model._get_lags("target") and not overlap_end: hist_fct_tgt_end += 1 * freq * model._get_lags("target")[-1] else: hist_fct_tgt_end -= 1 * freq From 4a3054e2a520724f46c58f62cf5736d41ba5b504 Mon Sep 17 00:00:00 2001 From: authierj Date: Wed, 5 Mar 2025 15:02:12 +0100 Subject: [PATCH 08/13] pr corrections --- .../test_historical_forecasts.py | 6 -- darts/utils/historical_forecasts/utils.py | 3 +- testing2.py | 59 ------------------- 3 files changed, 1 insertion(+), 67 deletions(-) delete mode 100644 testing2.py diff --git a/darts/tests/utils/historical_forecasts/test_historical_forecasts.py b/darts/tests/utils/historical_forecasts/test_historical_forecasts.py index 0388227a2a..7ace5e0692 100644 --- a/darts/tests/utils/historical_forecasts/test_historical_forecasts.py +++ b/darts/tests/utils/historical_forecasts/test_historical_forecasts.py @@ -134,12 +134,6 @@ {}, (6, 2), ), - ( - LinearRegressionModel, - {"lags": [-3], "lags_past_covariates": 6, "lags_future_covariates": [0, 1]}, - {}, - (6, 2), - ), ] if TORCH_AVAILABLE: diff --git a/darts/utils/historical_forecasts/utils.py b/darts/utils/historical_forecasts/utils.py index fda6bbc501..b947a3941f 100644 --- a/darts/utils/historical_forecasts/utils.py +++ b/darts/utils/historical_forecasts/utils.py @@ -782,8 +782,7 @@ def _adjust_historical_forecasts_time_index( show_warnings: bool, ) -> TimeIndex: """ - Shrink the beginning and end of the historical forecasts time index based on the values of `start`, - `forecast_horizon` and `overlap_end`. + Shrink the beginning and end of the historical forecasts time index based on the value of `start`. """ # retrieve actual start # when applicable, shift the start of the forecastable index based on `start` diff --git a/testing2.py b/testing2.py deleted file mode 100644 index dc02f9da71..0000000000 --- a/testing2.py +++ /dev/null @@ -1,59 +0,0 @@ -from itertools import product - -from sklearn.preprocessing import MaxAbsScaler - -from darts.dataprocessing.transformers import Scaler -from darts.models import LinearRegressionModel -from darts.tests.utils.historical_forecasts.test_historical_forecasts import ( - TestHistoricalforecast, -) -from darts.utils import timeseries_generation as tg - -tester = TestHistoricalforecast() - -sine_univariate1 = tg.sine_timeseries(length=50) * 2 + 1.5 -sine_univariate2 = tg.sine_timeseries(length=50, value_phase=1.5705) * 5 + 1.5 -sine_univariate3 = tg.sine_timeseries(length=50, value_phase=0.1963125) * -9 + 1.5 - -params = product( - [ - ( - { - "series": sine_univariate1 - 11, - }, - {"series": Scaler(scaler=MaxAbsScaler())}, - ), - ( - { - "series": sine_univariate3 + 2, - "past_covariates": sine_univariate1 * 3 + 3, - }, - {"past_covariates": Scaler()}, - ), - ( - { - "series": sine_univariate3 + 5, - "future_covariates": sine_univariate1 * (-4) + 3, - }, - {"future_covariates": Scaler(scaler=MaxAbsScaler())}, - ), - ( - { - "series": sine_univariate3 * 2 + 7, - "past_covariates": sine_univariate1 + 2, - "future_covariates": sine_univariate2 + 3, - }, - {"series": Scaler(), "past_covariates": Scaler()}, - ), - ], - [True, False], # retrain - [True, False], # last point only - [LinearRegressionModel], -) - -i = 0 - -for param in params: - if i == 2 or i == 3: - tester.test_historical_forecasts_with_scaler(params=param) - i += 1 From a0f9066157302adab2a12f43861f722fbab095b0 Mon Sep 17 00:00:00 2001 From: authierj Date: Wed, 5 Mar 2025 15:52:38 +0100 Subject: [PATCH 09/13] changelog updated --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a592e63e5d..6ecd965c5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ but cannot always guarantee backwards compatibility. Changes that may **break co **Fixed** - 🔴 / 🟢 Fixed a bug which raised an error when loading torch models that were saved with Darts versions < 0.33.0. This is a breaking change and models saved with version 0.33.0 will not be loadable anymore. [#2692](https://github.com/unit8co/darts/pull/2692) by [Dennis Bader](https://github.com/dennisbader). +- Fixed a bug where the historical forecast target window was wrong when regression models had discrete lags < -1. [#2715](https://github.com/unit8co/darts/pull/2715) by [Jules Authier](https://github.com/authierj) **Dependencies** From 132507c9b08092bc929cdc71599a3eb32a3d4b13 Mon Sep 17 00:00:00 2001 From: authierj Date: Fri, 7 Mar 2025 14:25:50 +0100 Subject: [PATCH 10/13] comment adpated --- darts/utils/historical_forecasts/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/darts/utils/historical_forecasts/utils.py b/darts/utils/historical_forecasts/utils.py index b947a3941f..ec109adfcb 100644 --- a/darts/utils/historical_forecasts/utils.py +++ b/darts/utils/historical_forecasts/utils.py @@ -991,7 +991,7 @@ def _get_historical_forecast_boundaries( overlap_end, ) - # adjust boundaries based on start, forecast_horizon and overlap_end + # adjust boundaries based on start historical_forecasts_time_index = _adjust_historical_forecasts_time_index( series=series, series_idx=series_idx, From 45288a2cb0e4ad76a7bc789d5f08cbaaabc43cc9 Mon Sep 17 00:00:00 2001 From: dennisbader Date: Fri, 7 Mar 2025 14:14:47 +0100 Subject: [PATCH 11/13] make optimized hfc work identically as non optimized --- .../utils/historical_forecasts/test_historical_forecasts.py | 5 ++++- darts/utils/historical_forecasts/utils.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/darts/tests/utils/historical_forecasts/test_historical_forecasts.py b/darts/tests/utils/historical_forecasts/test_historical_forecasts.py index 7ace5e0692..13824cd8fc 100644 --- a/darts/tests/utils/historical_forecasts/test_historical_forecasts.py +++ b/darts/tests/utils/historical_forecasts/test_historical_forecasts.py @@ -1250,11 +1250,12 @@ def test_regression_auto_start_multiple_no_cov(self, config): [ts_univariate, ts_multivariate], models_reg_no_cov_cls_kwargs + models_reg_cov_cls_kwargs, [True, False], + [True, False], [1, 5], ), ) def test_optimized_historical_forecasts_regression(self, config): - ts, model_config, multi_models, forecast_horizon = config + ts, model_config, multi_models, overlap_end, forecast_horizon = config # slightly longer to not affect the last predictable timestamp ts_covs = self.ts_covs start = 14 @@ -1303,6 +1304,7 @@ def test_optimized_historical_forecasts_regression(self, config): last_points_only=last_points_only, stride=stride, forecast_horizon=forecast_horizon, + overlap_end=overlap_end, enable_optimization=False, ) @@ -1319,6 +1321,7 @@ def test_optimized_historical_forecasts_regression(self, config): last_points_only=last_points_only, stride=stride, forecast_horizon=forecast_horizon, + overlap_end=overlap_end, ) self.helper_compare_hf(hist_fct, opti_hist_fct) diff --git a/darts/utils/historical_forecasts/utils.py b/darts/utils/historical_forecasts/utils.py index ec109adfcb..6cab1d9840 100644 --- a/darts/utils/historical_forecasts/utils.py +++ b/darts/utils/historical_forecasts/utils.py @@ -1021,7 +1021,7 @@ def _get_historical_forecast_boundaries( hist_fct_tgt_start += min_target_lag * freq # target lag has a gap between the max lag and the present - if hasattr(model, "lags") and model._get_lags("target") and not overlap_end: + if hasattr(model, "lags") and model._get_lags("target"): hist_fct_tgt_end += 1 * freq * model._get_lags("target")[-1] else: hist_fct_tgt_end -= 1 * freq From 75bc7bb8bf6c910160d4689bf05455f8f513ccf6 Mon Sep 17 00:00:00 2001 From: dennisbader Date: Fri, 7 Mar 2025 14:52:40 +0100 Subject: [PATCH 12/13] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad7f4fc115..89d279a7be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ but cannot always guarantee backwards compatibility. Changes that may **break co - Fixed a bug where the historical forecast target window was wrong when regression models had discrete lags < -1. [#2715](https://github.com/unit8co/darts/pull/2715) by [Jules Authier](https://github.com/authierj) - Fixed a bug in `StaticCovariatesTransformer` which raised an error when trying to inverse transform one-hot encoded categorical static covariates with identical values across time-series. Each categorical static covariates is now referred to by `{covariate_name}_{category_name}`, regardless of the number of categories. [#2710](https://github.com/unit8co/darts/pull/2710) by [Antoine Madrona](https://github.com/madtoinou) - Fixed a bug in `13-TFT-examples.ipynb` where two calls to `TimeSeries.from_series()` were not providing `series` but `pd.Index`. The method calls were changed to `TimeSeries.from_values()`. [#2719](https://github.com/unit8co/darts/pull/2719) by [Jules Authier](https://github.com/authierj) +- Fixed a bug in `RegressionModel` where performing optimized historical forecasts with `max(lags) < -1` resulted in forecasts that extended too far into the future. [#2715](https://github.com/unit8co/darts/pull/2715) by [Jules Authier](https://github.com/authierj) **Dependencies** From 0d417811d12f4fc28839f3d91eee716c75ab02a0 Mon Sep 17 00:00:00 2001 From: dennisbader Date: Fri, 7 Mar 2025 14:55:24 +0100 Subject: [PATCH 13/13] update changelog --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89d279a7be..f8810eea2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,6 @@ but cannot always guarantee backwards compatibility. Changes that may **break co **Fixed** - 🔴 / 🟢 Fixed a bug which raised an error when loading torch models that were saved with Darts versions < 0.33.0. This is a breaking change and models saved with version 0.33.0 will not be loadable anymore. [#2692](https://github.com/unit8co/darts/pull/2692) by [Dennis Bader](https://github.com/dennisbader). -- Fixed a bug where the historical forecast target window was wrong when regression models had discrete lags < -1. [#2715](https://github.com/unit8co/darts/pull/2715) by [Jules Authier](https://github.com/authierj) - Fixed a bug in `StaticCovariatesTransformer` which raised an error when trying to inverse transform one-hot encoded categorical static covariates with identical values across time-series. Each categorical static covariates is now referred to by `{covariate_name}_{category_name}`, regardless of the number of categories. [#2710](https://github.com/unit8co/darts/pull/2710) by [Antoine Madrona](https://github.com/madtoinou) - Fixed a bug in `13-TFT-examples.ipynb` where two calls to `TimeSeries.from_series()` were not providing `series` but `pd.Index`. The method calls were changed to `TimeSeries.from_values()`. [#2719](https://github.com/unit8co/darts/pull/2719) by [Jules Authier](https://github.com/authierj) - Fixed a bug in `RegressionModel` where performing optimized historical forecasts with `max(lags) < -1` resulted in forecasts that extended too far into the future. [#2715](https://github.com/unit8co/darts/pull/2715) by [Jules Authier](https://github.com/authierj)