task_multi: Config-Driven Multi-Target Forecasting with MultiTask
What spotforecast2_safe.multitask provides, how ConfigMulti drives it, and a complete runnable example.
spotforecast2_safe.multitask is the config-driven orchestrator for multi-target time-series forecasting. It owns the complete pipeline — data preparation, outlier handling, imputation, exogenous features, training, prediction, persistence — and is driven by a single ConfigMulti object. The unrestricted sibling package spotforecast2 inherits this pipeline and adds only what is deliberately excluded here: hyperparameter tuning (Optuna, SpotOptim) and interactive plotting.
Before version 16.0.0 this pipeline existed twice: once in the sibling package and once, in procedural form, behind the n-to-1 task’s 18 keyword arguments and a hard-coded weight list. Both paths are now one implementation in this package, and the dependency between the siblings is strictly one-way: spotforecast2 imports from spotforecast2-safe, never the reverse.
Vocabulary
Definition 1 (MultiTask) The task dispatcher of the multitask package. A MultiTask instance is constructed from a ConfigMulti and a DataFrame, prepared with the four pipeline stages (prepare_data, detect_outliers, impute, build_exogenous_features), and executed with run(task=...), where task selects one of the available task modes.
Definition 2 (N-to-1 aggregation) The reduction of per-target forecasts to a single series as a weighted sum, with weights taken from ConfigMulti.agg_weights in target order. Equal weights are used when agg_weights is None.
Task modes
The safe package ships four task modes:
Mode
What it does
lazy
Fit one ForecasterRecursive per target with LightGBM defaults, applying cached tuning results when present.
defaults
Same fit, but ignoring any tuning cache — fully deterministic baseline.
predict
Load previously saved models and predict without retraining.
clean
Remove the pipeline’s cache directory (models, tuning results, logs).
The tuning modes optuna and spotoptim exist only in spotforecast2; requesting them here raises an explicit ValueError (see Fail-safe behaviour).
A complete worked example
Example 1 (Synthetic data and a minimal configuration) Two hourly target series over four weeks, a named DatetimeIndex matching ConfigMulti.index_name (default "DateTime"), and a configuration with the expensive options disabled so the example runs in seconds and offline.
Example 2 (Running the pipeline) The four stages chain (each returns the task), then run fits and predicts. The returned aggregated package carries the combined forecast under "future_pred"; the per-target packages live in task.results.
Example 4 (Train once, predict many times) With auto_save_models=True the fitted forecasters were persisted under cache_home. A later predict run loads them instead of retraining — the production pattern for scheduled forecasts:
Example 5 (Determinism) Same input, same configuration, bit-identical output — a hard requirement of this package, enforced by the test suite and demonstrable here with a fresh instance in a fresh cache directory:
Task 'spotoptim' requires auto-tuning, which is not available in spotforecast2-safe. Use the spotforecast2 package, or task='lazy'/'defaults'.
The same policy applies to unexpected keyword arguments (TypeError instead of silent dropping) and to plotting: MultiTask.plot_with_outliers() raises NotImplementedError because no plotting library is permitted in this package.
The n-to-1 task entry point
run_pipeline from task_safe_n_to_1_with_covariates_and_dataframe wraps exactly this pipeline with task="lazy" — one call from config and DataFrame to combined forecast:
from spotforecast2_safe.tasks.task_safe_n_to_1_with_covariates_and_dataframe import ( run_pipeline,)forecast = run_pipeline(config=cfg, dataframe=df, cache_home=cache)forecast.head(3)
forecast
2023-01-29 00:00:00+00:00
-117.612059
2023-01-29 01:00:00+00:00
-120.726869
2023-01-29 02:00:00+00:00
-117.511861
The matching console script accepts the same knobs as flags:
uv run spotforecast-safe-n2o1-cov-df --forecast_horizon 24 --lags 24 \--include_holiday_features true
Scaling up from the toy example
For a real run, switch the feature machinery on instead of off: use_exogenous_features=True with include_holiday_features, include_holiday_adjacency_features (bridge days), and include_weather_windows adds calendar, holiday, day/night, weather, and polynomial-interaction covariates before training. Weather features require network access; on_weather_failure keeps its fail-safe default "raise" unless you explicitly opt into "skip".
Upgrade path: the same config in spotforecast2
The unrestricted sibling subclasses this pipeline and re-adds tuning and plotting. The configuration object travels unchanged:
The dependency between the packages is strictly one-way: spotforecast2 imports from spotforecast2-safe, never the reverse. That is why the cell above is a listing rather than executed code — this documentation builds in an environment where spotforecast2 is, by design, absent.
Where to go next
API reference: run_pipeline — the CLI-facing wrapper around this pipeline.