Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
## [9.0.0-rc.1](https://github.com/sequential-parameter-optimization/spotforecast2/compare/v8.1.1...v9.0.0-rc.1) (2026-06-12)

### ⚠ BREAKING CHANGES

* **tasks:** the spotforecast-demo, spotforecast-n2o1,
spotforecast-n2o1-df, spotforecast-n2o1-cov, and spotforecast-n2o1-cov-df
console scripts and the spotforecast2.tasks.task_demo /
spotforecast2.tasks.task_n_to_1* modules are removed.
spotforecast2-entsoe and spotforecast2.tasks.task_entsoe are unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

### Features

* **tasks:** remove unused demo and n-to-1 task modules and console scripts ([98dc393](https://github.com/sequential-parameter-optimization/spotforecast2/commit/98dc393a06f1e34b675275144f8a37c88178e755))

## [8.1.1](https://github.com/sequential-parameter-optimization/spotforecast2/compare/v8.1.0...v8.1.1) (2026-06-12)

### Code Refactoring
Expand Down
7 changes: 2 additions & 5 deletions MODEL_CARD.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ The current release is 3.3.0, tracking the stable public interface re-exported a

## 2. Intended Use and Scope

spotforecast2 supports exploratory and applied forecasting of hourly electricity load and spot prices on ENTSO-E data, end to end, through the `spotforecast2-entsoe` and `spotforecast-demo` console scripts. Its distinctive capabilities are hyperparameter search — Bayesian search over lags, window features, and regressor parameters with Optuna (`bayesian_search_forecaster`), or surrogate-model search with SpotOptim (`spotoptim_search_forecaster`) — interactive inspection through Plotly figures, and global SHAP feature importances via `shap.TreeExplainer`. The `MultiTask` dispatcher and the `run()` entry point orchestrate multi-target pipelines: per-target data preparation, outlier handling, imputation, feature engineering, tuning, and prediction.
spotforecast2 supports exploratory and applied forecasting of hourly electricity load and spot prices on ENTSO-E data, end to end, through the `spotforecast2-entsoe` console script. Its distinctive capabilities are hyperparameter search — Bayesian search over lags, window features, and regressor parameters with Optuna (`bayesian_search_forecaster`), or surrogate-model search with SpotOptim (`spotoptim_search_forecaster`) — interactive inspection through Plotly figures, and global SHAP feature importances via `shap.TreeExplainer`. The `MultiTask` dispatcher and the `run()` entry point orchestrate multi-target pipelines: per-target data preparation, outlier handling, imputation, feature engineering, tuning, and prediction.

The intended downstream use is development and model selection: choosing lag windows and regressor hyperparameters here, then promoting the validated configuration into a spotforecast2-safe deployment for the deterministic inference path. Tuned `ForecasterRecursiveLGBMFull` and `ForecasterRecursiveXGBFull` models, or just their best parameters, also feed research notebooks and reporting.

Expand All @@ -60,15 +60,12 @@ importances = model.get_global_shap_feature_importance(frac=0.1)
print(importances.head())
```

Run a complete multi-target pipeline programmatically via `run()`, or use the bundled console scripts:
Run a complete multi-target pipeline programmatically via `run()`, or use the bundled console script:

```bash
spotforecast2-entsoe # ENTSO-E download / train / predict (needs ENTSOE_API_KEY)
spotforecast-demo # baseline vs. covariate vs. custom-LightGBM comparison
```

Additional N-to-1 pipeline variants are registered as `spotforecast-n2o1`, `spotforecast-n2o1-df`, `spotforecast-n2o1-cov`, and `spotforecast-n2o1-cov-df`.

## 4. Technical Specification

### Task and model family
Expand Down
19 changes: 1 addition & 18 deletions _quarto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,18 +132,8 @@ website:
file: docs/reference/stats.autocorrelation.qmd
- section: "Tasks"
contents:
- text: "task_demo"
file: docs/reference/tasks.task_demo.qmd
- text: "task_entsoe"
file: docs/reference/tasks.task_entsoe.qmd
- text: "task_n_to_1"
file: docs/reference/tasks.task_n_to_1.qmd
- text: "task_n_to_1_dataframe"
file: docs/reference/tasks.task_n_to_1_dataframe.qmd
- text: "task_n_to_1_with_covariates"
file: docs/reference/tasks.task_n_to_1_with_covariates.qmd
- text: "task_n_to_1_with_covariates_and_dataframe"
file: docs/reference/tasks.task_n_to_1_with_covariates_and_dataframe.qmd

- section: "Processing Guides"
contents:
Expand All @@ -166,8 +156,6 @@ website:

- section: "Tasks Guide"
contents:
- text: "Overview"
file: docs/tasks/tasks.qmd
- text: "Multitask Tutorial"
file: docs/tasks/multitask.qmd
- text: "ENTSO-E CLI"
Expand Down Expand Up @@ -264,14 +252,9 @@ quartodoc:
- stats.autocorrelation

- title: "Tasks"
desc: "Demonstration and predefined forecasting tasks."
desc: "ENTSO-E forecasting task and CLI."
contents:
- tasks.task_demo
- tasks.task_entsoe
- tasks.task_n_to_1
- tasks.task_n_to_1_dataframe
- tasks.task_n_to_1_with_covariates
- tasks.task_n_to_1_with_covariates_and_dataframe

- title: "Warnings"
desc: "Warning-style configuration for spotforecast2."
Expand Down
1 change: 0 additions & 1 deletion docs/tasks/entsoe.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,5 @@ uv run pytest tests/test_tasks_entsoe.py -v

## See Also

- [Tasks Overview](../tasks/tasks.qmd) - All available CLI commands
- [API Reference](../reference/index.qmd#preprocessing) - Detailed API documentation
- [Model Persistence](../processing/model_persistence.qmd) - Saving and loading models
141 changes: 0 additions & 141 deletions docs/tasks/tasks.qmd

This file was deleted.

7 changes: 1 addition & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "spotforecast2"
version = "8.1.1"
version = "9.0.0-rc.1"
description = "Forecasting with spot"
readme = "README.md"
license = { text = "AGPL-3.0-or-later" }
Expand Down Expand Up @@ -75,11 +75,6 @@ dev = [

[project.scripts]
spotforecast2-entsoe = "spotforecast2.tasks.task_entsoe:main"
spotforecast-demo = "spotforecast2.tasks.task_demo:main"
spotforecast-n2o1 = "spotforecast2.tasks.task_n_to_1:main"
spotforecast-n2o1-df = "spotforecast2.tasks.task_n_to_1_dataframe:main"
spotforecast-n2o1-cov = "spotforecast2.tasks.task_n_to_1_with_covariates:main"
spotforecast-n2o1-cov-df = "spotforecast2.tasks.task_n_to_1_with_covariates_and_dataframe:main"

[tool.uv]
# Accept pre-releases ONLY for dependencies whose specifier carries an explicit
Expand Down
2 changes: 2 additions & 0 deletions src/spotforecast2/multitask/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

from spotforecast2_safe.multitask.base import ( # noqa: F401 (re-exported)
BaseTask as SafeBaseTask,
)
from spotforecast2_safe.multitask.base import (
PipelineConfig,
agg_predictor,
)
Expand Down
14 changes: 5 additions & 9 deletions src/spotforecast2/plots/diagnostics.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,23 +185,19 @@ def plot_feature_importance_by_family(
print(type(fig).__name__)
```
"""
ranking = sorted(
zip(names, importances), key=lambda kv: kv[1], reverse=True
)[:top_n]
ranking = sorted(zip(names, importances), key=lambda kv: kv[1], reverse=True)[
:top_n
]
labels = [n for n, _ in ranking][::-1]
values = [v for _, v in ranking][::-1]
colors = [_FAMILY_COLOR.get(feature_family(n), "#888888") for n in labels]

fig, ax = plt.subplots(figsize=(8.5, 5.5))
ax.barh(labels, values, color=colors)
ax.set_xlabel("split count (feature importance)")
ax.set_title(
f"Top-{top_n} feature importances (coloured by family; lags in red)"
)
ax.set_title(f"Top-{top_n} feature importances (coloured by family; lags in red)")
ax.grid(True, axis="x", color="#E5E5E5", linewidth=0.5)
handles = [
plt.Rectangle((0, 0), 1, 1, color=c) for c in _FAMILY_COLOR.values()
]
handles = [plt.Rectangle((0, 0), 1, 1, color=c) for c in _FAMILY_COLOR.values()]
ax.legend(handles, _FAMILY_COLOR.keys(), fontsize=7, loc="lower right")
for spine in ("top", "right"):
ax.spines[spine].set_visible(False)
Expand Down
Loading