Skip to content

Commit d281a5e

Browse files
authored
Raise error for short series (#1492)
1 parent 24c3457 commit d281a5e

2 files changed

Lines changed: 45 additions & 0 deletions

File tree

neuralforecast/core.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,21 @@ def fit(
584584
"Validation set size is larger than the shorter time-series."
585585
)
586586

587+
for model in self.models:
588+
input_size = getattr(model, "input_size", None)
589+
if input_size is None:
590+
continue # Auto models have a tunable input_size; skip validation
591+
train_size = self.dataset.min_size - (val_size or 0)
592+
start_padding_enabled = getattr(model, "start_padding_enabled", False)
593+
min_required = 1 if start_padding_enabled else input_size
594+
if train_size < min_required:
595+
raise ValueError(
596+
f"{model.__class__.__name__} requires at least {min_required} training "
597+
f"timestamp(s) (input_size={input_size}, start_padding_enabled="
598+
f"{start_padding_enabled}), but the shortest series has only "
599+
f"{train_size} timestamp(s) available for training after removing val_size."
600+
)
601+
587602
# Recover initial model if use_init_models
588603
if use_init_models:
589604
self._reset_models()

tests/test_core.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,36 @@ def test_neural_forecast_val_monitor_invalid():
170170
)
171171

172172

173+
# test that fit raises ValueError when series are too short for input_size + h
174+
def test_fit_raises_on_short_series():
175+
# 10 timestamps, h=12, input_size=24 → train_size=10 < 24
176+
series = generate_series(n_series=2, min_length=10, max_length=10, equal_ends=True)
177+
model = NHITS(h=12, input_size=24, max_steps=2)
178+
nf = NeuralForecast(models=[model], freq="D")
179+
with pytest.raises(ValueError, match="requires at least"):
180+
nf.fit(series)
181+
182+
183+
# test that fit passes when start_padding_enabled=True relaxes the constraint
184+
def test_fit_short_series_with_start_padding():
185+
# 10 timestamps, h=12, input_size=24 but padding enabled → only needs 1 timestamp
186+
series = generate_series(n_series=2, min_length=10, max_length=10, equal_ends=True)
187+
model = NHITS(h=12, input_size=24, max_steps=2, start_padding_enabled=True)
188+
nf = NeuralForecast(models=[model], freq="D")
189+
nf.fit(series) # should not raise
190+
191+
192+
# test that cross_validation raises ValueError when series are too short (refit=True
193+
# calls fit() per window, which validates the training slice length)
194+
def test_cross_validation_raises_on_short_series():
195+
# 30 timestamps, h=12, n_windows=1 → train slice=18 timestamps < input_size=24
196+
series = generate_series(n_series=2, min_length=30, max_length=30, equal_ends=True)
197+
model = NHITS(h=12, input_size=24, max_steps=2)
198+
nf = NeuralForecast(models=[model], freq="D")
199+
with pytest.raises(ValueError, match="requires at least"):
200+
nf.cross_validation(series, n_windows=1, refit=True)
201+
202+
173203
# test fit+cross_validation behaviour
174204
def test_neural_forecast_fit_cross_validation(setup_airplane_data):
175205
AirPassengersPanel_train, _ = setup_airplane_data

0 commit comments

Comments
 (0)