diff --git a/packages/openstef-beam/src/openstef_beam/evaluation/metric_providers.py b/packages/openstef-beam/src/openstef_beam/evaluation/metric_providers.py index 285e9ce32..384dd6e54 100644 --- a/packages/openstef-beam/src/openstef_beam/evaluation/metric_providers.py +++ b/packages/openstef-beam/src/openstef_beam/evaluation/metric_providers.py @@ -227,8 +227,8 @@ def compute_deterministic( ) metrics: MetricsDict = {} - metrics["num_predicted_peaks"] = cm.true_positives.sum() + cm.false_positives.sum() - metrics["num_true_peaks"] = cm.true_positives.sum() + cm.false_negatives.sum() + metrics["num_predicted_peaks"] = int(cm.true_positives.sum() + cm.false_positives.sum()) + metrics["num_true_peaks"] = int(cm.true_positives.sum() + cm.false_negatives.sum()) peak_pr = precision_recall(cm, effective=False) effective_pr = precision_recall(cm, effective=True) metrics["precision"], metrics["recall"] = peak_pr diff --git a/packages/openstef-models/src/openstef_models/models/component_splitting/linear_component_splitter.py b/packages/openstef-models/src/openstef_models/models/component_splitting/linear_component_splitter.py index 8cad04fff..5a6a816ed 100644 --- a/packages/openstef-models/src/openstef_models/models/component_splitting/linear_component_splitter.py +++ b/packages/openstef-models/src/openstef_models/models/component_splitting/linear_component_splitter.py @@ -87,7 +87,7 @@ class LinearComponentSplitter(ComponentSplitter): ... components=[EnergyComponentType.SOLAR, EnergyComponentType.WIND, EnergyComponentType.OTHER], ... ) >>> splitter = LinearComponentSplitter(config) - >>> components = splitter.predict(time_series_data) # doctest: +SKIP + >>> components = splitter.predict(time_series_data) # doctest: +SKIP """ _config: LinearComponentSplitterConfig diff --git a/packages/openstef-models/src/openstef_models/models/forecasting/gblinear_forecaster.py b/packages/openstef-models/src/openstef_models/models/forecasting/gblinear_forecaster.py index 45e5f6a86..02bd87ea8 100644 --- a/packages/openstef-models/src/openstef_models/models/forecasting/gblinear_forecaster.py +++ b/packages/openstef-models/src/openstef_models/models/forecasting/gblinear_forecaster.py @@ -201,7 +201,7 @@ def model_post_init(self, _context: object, /) -> None: # Boosting structure control feature_selector=self.hyperparams.feature_selector, updater=self.hyperparams.updater, - quantile_alpha=[float(q) for q in self.quantiles], + quantile_alpha=sorted([float(q) for q in self.quantiles]), top_k=self.hyperparams.top_k if self.hyperparams.feature_selector == "thrifty" else None, # Objective objective=get_objective_function(function_type=self.hyperparams.objective, quantiles=self.quantiles) diff --git a/packages/openstef-models/src/openstef_models/utils/multi_quantile_regressor.py b/packages/openstef-models/src/openstef_models/utils/multi_quantile_regressor.py index 729676d4f..748163ab3 100644 --- a/packages/openstef-models/src/openstef_models/utils/multi_quantile_regressor.py +++ b/packages/openstef-models/src/openstef_models/utils/multi_quantile_regressor.py @@ -6,6 +6,7 @@ Designed to work with scikit-learn compatible regressors that support quantile regression. """ +import inspect import logging import numpy as np @@ -89,15 +90,27 @@ def fit( for model in self._models: # Check if early stopping is supported - # Check that eval_set is supported if eval_set is None and "early_stopping_rounds" in self.hyperparams: model.set_params(early_stopping_rounds=None) if eval_set is not None and self.learner_eval_sample_weight_param is not None: - kwargs["eval_set"] = [ - (x_array if eval_x is X else np.asarray(eval_x), eval_y) for eval_x, eval_y in eval_set - ] - kwargs[self.learner_eval_sample_weight_param] = eval_sample_weight + fit_signature = inspect.signature(getattr(model, "fit")) # noqa: B009 + has_eval_x_param = "eval_X" in fit_signature.parameters + + if has_eval_x_param: + # Extract X and y from eval_set tuples for LightGBM + eval_x_data = tuple((x_array if eval_x is X else np.asarray(eval_x)) for eval_x, _ in eval_set) + eval_y_data = tuple(eval_y for _, eval_y in eval_set) + kwargs["eval_X"] = eval_x_data + kwargs["eval_y"] = eval_y_data + kwargs["eval_sample_weight"] = eval_sample_weight + else: + # XGBoost uses eval_set + kwargs["eval_set"] = [ + (x_array if eval_x is X else np.asarray(eval_x), eval_y) for eval_x, eval_y in eval_set + ] + kwargs[self.learner_eval_sample_weight_param] = eval_sample_weight + if "early_stopping_rounds" in self.hyperparams: model.set_params(early_stopping_rounds=self.hyperparams["early_stopping_rounds"]) diff --git a/packages/openstef-models/tests/unit/transforms/time_domain/test_holiday_features_adder.py b/packages/openstef-models/tests/unit/transforms/time_domain/test_holiday_features_adder.py index 32a9cfe22..46f988306 100644 --- a/packages/openstef-models/tests/unit/transforms/time_domain/test_holiday_features_adder.py +++ b/packages/openstef-models/tests/unit/transforms/time_domain/test_holiday_features_adder.py @@ -27,8 +27,8 @@ (date(2025, 4, 26), "King's Day", "king_s_day"), (date(2025, 5, 5), "Liberation Day", "liberation_day"), (date(2025, 5, 29), "Ascension Day", "ascension_day"), - (date(2025, 6, 8), "Whit Sunday", "whit_sunday"), - (date(2025, 6, 9), "Whit Monday", "whit_monday"), + (date(2025, 6, 8), "Pentecost", "pentecost"), + (date(2025, 6, 9), "Pentecost Monday", "pentecost_monday"), (date(2025, 12, 25), "Christmas Day", "christmas_day"), (date(2025, 12, 26), "Second Day of Christmas", "second_day_of_christmas"), ] diff --git a/pyproject.toml b/pyproject.toml index 4beb70a71..9bced7d71 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -192,6 +192,9 @@ ini_options.filterwarnings = [ # that Python cannot propagate. Scope the ignore to CPython's fixed ctypes-callback # wording so genuine unraisable exceptions still fail. "ignore:.*Exception ignored on calling ctypes callback function.*:pytest.PytestUnraisableExceptionWarning", + # joblib upstream: NumPy 2.5+ deprecated array.shape assignment. joblib 1.5.3 uses this + # in its unpickling code and cannot be fixed without upgrading joblib (not yet available). + "ignore:.*Setting the shape on a NumPy array has been deprecated.*:DeprecationWarning:joblib", # Ignore fork() deprecation warning from multiprocessing on macOS # This warning occurs when pytest (multi-threaded) spawns processes using fork() # Using spawn instead breaks test infrastructure (fixtures not picklable) diff --git a/uv.lock b/uv.lock index 7112f7f83..f0d7a2198 100644 --- a/uv.lock +++ b/uv.lock @@ -1838,14 +1838,14 @@ wheels = [ [[package]] name = "gitpython" -version = "3.1.50" +version = "3.1.58" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "gitdb" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/33/f6/354ae6491228b5eb40e10d89c4d13c651fe1cf7556e35ebdded50cff57ce/gitpython-3.1.50.tar.gz", hash = "sha256:80da2d12504d52e1f998772dc5baf6e553f8d2fcfe1fcc226c9d9a2ee3372dcc", size = 219798, upload-time = "2026-05-06T04:01:26.571Z" } +sdist = { url = "https://files.pythonhosted.org/packages/26/d6/5f358ff283325580c2003a6d953aea18cfe10ae87b46f5ebc80fa3a386dc/gitpython-3.1.58.tar.gz", hash = "sha256:621416df10ef3fd0e19fabf9172ddeed0fa704d353d04f194eec56a625a95b22", size = 228498, upload-time = "2026-08-04T15:05:49.47Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl", hash = "sha256:d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9", size = 212507, upload-time = "2026-05-06T04:01:23.799Z" }, + { url = "https://files.pythonhosted.org/packages/ec/0c/9d8752098bc442f0726e64aa6135940b3a96809915d1aa4206c1bb97881d/gitpython-3.1.58-py3-none-any.whl", hash = "sha256:d331e722577f0fd7fc1f857419b3ecc07af66282b933d2a4d95f84a042fdd50f", size = 220183, upload-time = "2026-08-04T15:05:48.025Z" }, ] [[package]] @@ -3838,11 +3838,11 @@ wheels = [ [[package]] name = "nvidia-nccl-cu13" -version = "2.31.2" +version = "2.30.7" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/52/a0/530efd7db8857c0436868bb7df9764f09fde2bd4d1f0bae546eec9fc40d0/nvidia_nccl_cu13-2.31.2-py3-none-manylinux_2_18_aarch64.whl", hash = "sha256:b5563f8e2534f363d93ace022670ba016d3717e190ac4eba564d05fbbe8495b1", size = 252479893, upload-time = "2026-08-11T23:22:01.53Z" }, - { url = "https://files.pythonhosted.org/packages/14/fb/94933e00bb3dcfdf66ea3456739c6a51d322353f7cc64fa1f5f660e695ac/nvidia_nccl_cu13-2.31.2-py3-none-manylinux_2_18_x86_64.whl", hash = "sha256:0bcaf0308854cb55fcc35af72e2c83143f3b71e65a4e865e2c586b1cdcdb5ae0", size = 252442223, upload-time = "2026-08-11T23:22:40.341Z" }, + { url = "https://files.pythonhosted.org/packages/d1/21/a73174c6157101bdf1ffc22b517f76ff0082613989dd9bc8f43e8034caac/nvidia_nccl_cu13-2.30.7-py3-none-manylinux_2_18_aarch64.whl", hash = "sha256:ca786ffa5a647c75d4d1f5cc72a6c4f537947e2ba8823d7c8aaf768e7a7b9f77", size = 215983881, upload-time = "2026-06-09T03:23:15.633Z" }, + { url = "https://files.pythonhosted.org/packages/3f/34/c500f90c7ae641b8e0f98965b36b8a7ac79cc8b296e8d251fe3eb592ee54/nvidia_nccl_cu13-2.30.7-py3-none-manylinux_2_18_x86_64.whl", hash = "sha256:cefa7fdb9710efd0f39c5f1be1d61ff6fc9a996c451265bd7fbdcf9455ed4b50", size = 215965170, upload-time = "2026-06-09T03:23:39.73Z" }, ] [[package]]