openstef 3.4.11__py3-none-any.whl → 3.4.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -25,7 +25,6 @@ class PredictionJobDataClass(BaseModel):
25
25
  - ``"xgb_quantile"``
26
26
  - ``"lgb"``
27
27
  - ``"linear"``
28
- - ``"proloaf"`` (extra dependencies requiered, see README)
29
28
 
30
29
  If unsure what to pick, choose ``"xgb"``.
31
30
 
openstef/enums.py CHANGED
@@ -10,7 +10,6 @@ class MLModelType(Enum):
10
10
  XGB_QUANTILE = "xgb_quantile"
11
11
  LGB = "lgb"
12
12
  LINEAR = "linear"
13
- ProLoaf = "proloaf"
14
13
  ARIMA = "arima"
15
14
 
16
15
 
@@ -14,9 +14,6 @@ Examples of features that are added:
14
14
  import pandas as pd
15
15
 
16
16
  from openstef.data_classes.prediction_job import PredictionJobDataClass
17
- from openstef.feature_engineering.historic_features import (
18
- add_historic_load_as_a_feature,
19
- )
20
17
  from openstef.feature_engineering.holiday_features import (
21
18
  generate_holiday_feature_functions,
22
19
  )
@@ -69,9 +66,6 @@ def apply_features(
69
66
  np.random.uniform(0.7,1.7, 200)))
70
67
 
71
68
  """
72
- # Add if needed the proloaf feature (historic_load)
73
- data = add_historic_load_as_a_feature(data, pj)
74
-
75
69
  # Get lag feature functions
76
70
  feature_functions = generate_lag_feature_functions(feature_names, horizon)
77
71
 
@@ -149,11 +149,7 @@ class TrainFeatureApplicator(AbstractFeatureApplicator):
149
149
 
150
150
  # NOTE this is required since apply_features could add additional features
151
151
  if self.feature_names is not None:
152
- # Add horizon to requested features else it is removed, and if needed the proloaf feature (historic_load)
153
- if pj.get("model") == "proloaf":
154
- features = self.feature_names + ["historic_load"] + ["horizon"]
155
- else:
156
- features = self.feature_names + ["horizon"]
152
+ features = self.feature_names + ["horizon"]
157
153
  result = remove_non_requested_feature_columns(result, features)
158
154
 
159
155
  # Sort all features except for the (first) load and (last) horizon columns
@@ -15,11 +15,6 @@ from openstef.model.regressors.xgb_quantile import XGBQuantileOpenstfRegressor
15
15
  from openstef.model.regressors.arima import ARIMAOpenstfRegressor
16
16
 
17
17
  logger = structlog.get_logger(__name__)
18
- try:
19
- from openstef.model.regressors.proloaf import OpenstfProloafRegressor
20
- except ImportError:
21
- logger.info("Proloaf not available, setting constructor to None")
22
- OpenstfProloafRegressor = None
23
18
 
24
19
  valid_model_kwargs = {
25
20
  MLModelType.XGB: [
@@ -84,27 +79,6 @@ valid_model_kwargs = {
84
79
  "max_depth",
85
80
  "early_stopping_rounds",
86
81
  ],
87
- MLModelType.ProLoaf: [
88
- "relu_leak",
89
- "encoder_features",
90
- "decoder_features",
91
- "core_layers",
92
- "rel_linear_hidden_size",
93
- "rel_core_hidden_size",
94
- "dropout_fc",
95
- "dropout_core",
96
- "training_metric",
97
- "metric_options",
98
- "optimizer_name",
99
- "early_stopping_patience",
100
- "early_stopping_margin",
101
- "learning_rate",
102
- "max_epochs",
103
- "device",
104
- "batch_size",
105
- "history_horizon",
106
- "horizon_minutes",
107
- ],
108
82
  MLModelType.LINEAR: [
109
83
  "missing_values",
110
84
  "imputation_strategy",
@@ -127,7 +101,6 @@ class ModelCreator:
127
101
  MLModelType.XGB: XGBOpenstfRegressor,
128
102
  MLModelType.LGB: LGBMOpenstfRegressor,
129
103
  MLModelType.XGB_QUANTILE: XGBQuantileOpenstfRegressor,
130
- MLModelType.ProLoaf: OpenstfProloafRegressor,
131
104
  MLModelType.LINEAR: LinearOpenstfRegressor,
132
105
  MLModelType.ARIMA: ARIMAOpenstfRegressor,
133
106
  }
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # SPDX-License-Identifier: MPL-2.0
4
4
  import copy
5
- from datetime import datetime
5
+ from datetime import datetime, timezone
6
6
  from typing import Any, Callable, Optional
7
7
 
8
8
  import optuna
@@ -59,7 +59,7 @@ class RegressorObjective:
59
59
  self.validation_data = None
60
60
  self.test_data = None
61
61
  self.model = model
62
- self.start_time = datetime.utcnow()
62
+ self.start_time = datetime.now(timezone.utc)
63
63
  self.test_fraction = test_fraction
64
64
  self.validation_fraction = validation_fraction
65
65
  self.eval_metric = eval_metric
@@ -94,7 +94,7 @@ class RegressorObjective:
94
94
  split_args = self.split_args
95
95
  if split_args is None:
96
96
  split_args = {
97
- "stratification_min_max": self.model_type != MLModelType.ProLoaf,
97
+ "stratification_min_max": True,
98
98
  "back_test": True,
99
99
  }
100
100
  (
@@ -349,53 +349,6 @@ class XGBQuantileRegressorObjective(RegressorObjective):
349
349
  )
350
350
 
351
351
 
352
- class ProLoafRegressorObjective(RegressorObjective):
353
- def __init__(self, *args, **kwargs):
354
- super().__init__(*args, **kwargs)
355
- self.model_type = MLModelType.ProLoaf
356
-
357
- def get_params(self, trial: optuna.trial.FrozenTrial) -> dict:
358
- """Get parameters for ProLoaf Regressor Objective with objective specific parameters.
359
-
360
- Args: trial
361
-
362
- Returns:
363
- Dictionary with hyperparameter name as key and hyperparamer value as value.
364
-
365
- """
366
- # Filtered default parameters
367
- model_params = super().get_params(trial)
368
-
369
- # ProLoaf specific parameters
370
- params = {
371
- # TODO: look into optimizing this pipeline for proloaf
372
- # "relu_leak": trial.suggest_float("relu_leak", 0.1, 1.0),
373
- # "core_layers": trial.suggest_int("core_layers", 1, 3),
374
- # "rel_linear_hidden_size": trial.suggest_float(
375
- # "rel_linear_hidden_size", 0.1, 1
376
- # ),
377
- # "rel_core_hidden_size": trial.suggest_float("rel_core_hidden_size", 0.1, 1),
378
- # "dropout_fc": trial.suggest_float("dropout_fc", 0.1, 0.9),
379
- # "dropout_core": trial.suggest_float("dropout_core", 0.1, 0.9),
380
- # "early_stopping_patience": trial.suggest_int(
381
- # "early_stopping_patience", 5, 10
382
- # ),
383
- # "early_stopping_margin": trial.suggest_float(
384
- # "early_stopping_margin", 0.1, 0.9
385
- # ),
386
- "max_epochs": trial.suggest_int(
387
- "max_epochs", 1, 1
388
- ), # TODO: change after having availability to gpu resource
389
- "batch_size": trial.suggest_int("batch_size", 1, 24),
390
- }
391
- return {**model_params, **params}
392
-
393
- def get_pruning_callback(self, trial: optuna.trial.FrozenTrial):
394
- return optuna.integration.PyTorchLightningPruningCallback(
395
- trial, monitor="val_loss"
396
- )
397
-
398
-
399
352
  class LinearRegressorObjective(RegressorObjective):
400
353
  def __init__(self, *args, **kwargs):
401
354
  super().__init__(*args, **kwargs)
@@ -8,7 +8,6 @@ from openstef.enums import MLModelType
8
8
  from openstef.model.objective import (
9
9
  LGBRegressorObjective,
10
10
  LinearRegressorObjective,
11
- ProLoafRegressorObjective,
12
11
  RegressorObjective,
13
12
  XGBQuantileRegressorObjective,
14
13
  XGBRegressorObjective,
@@ -25,7 +24,6 @@ class ObjectiveCreator:
25
24
  MLModelType.XGB: XGBRegressorObjective,
26
25
  MLModelType.LGB: LGBRegressorObjective,
27
26
  MLModelType.XGB_QUANTILE: XGBQuantileRegressorObjective,
28
- MLModelType.ProLoaf: ProLoafRegressorObjective,
29
27
  MLModelType.LINEAR: LinearRegressorObjective,
30
28
  MLModelType.ARIMA: ARIMARegressorObjective,
31
29
  }
@@ -175,18 +175,6 @@ def optimize_hyperparameters_pipeline_core(
175
175
  horizons=horizons, feature_names=feature_names, feature_modules=feature_modules
176
176
  ).add_features(validated_data, pj=pj)
177
177
 
178
- # Adds additional proloaf features to the input data, historic_load (equal to the load, first column)
179
- if pj["model"] == "proloaf" and "historic_load" not in list(
180
- validated_data_with_features.columns
181
- ):
182
- validated_data_with_features[
183
- "historic_load"
184
- ] = validated_data_with_features.iloc[:, 0]
185
- # Make sure horizons is last column
186
- temp_cols = validated_data_with_features.columns.tolist()
187
- new_cols = temp_cols[:-2] + [temp_cols[-1]] + [temp_cols[-2]]
188
- validated_data_with_features = validated_data_with_features[new_cols]
189
-
190
178
  # Create objective (NOTE: this is a callable class)
191
179
  objective = ObjectiveCreator.create_objective(model_type=pj["model"])
192
180
 
@@ -268,7 +256,7 @@ def optuna_optimization(
268
256
  if pj.train_split_func is None:
269
257
  split_func = split_data_train_validation_test
270
258
  split_args = {
271
- "stratification_min_max": pj["model"] != "proloaf",
259
+ "stratification_min_max": True,
272
260
  "back_test": True,
273
261
  }
274
262
  else:
@@ -59,7 +59,7 @@ def train_model_and_forecast_back_test(
59
59
  """
60
60
  if pj.backtest_split_func is None:
61
61
  backtest_split_func = backtest_split_default
62
- backtest_split_args = {"stratification_min_max": pj["model"] != "proloaf"}
62
+ backtest_split_args = {"stratification_min_max": True}
63
63
  else:
64
64
  backtest_split_func, backtest_split_args = pj.backtest_split_func.load(
65
65
  required_arguments=["data", "n_folds"]
@@ -348,10 +348,6 @@ def train_pipeline_step_compute_features(
348
348
  ValueError: when the horizon is a string and the corresponding column in not in the input data
349
349
 
350
350
  """
351
- if pj["model"] == "proloaf":
352
- # proloaf is only able to train with one horizon
353
- horizons = [horizons[0]]
354
-
355
351
  if input_data.empty:
356
352
  raise InputDataInsufficientError("Input dataframe is empty")
357
353
  elif "load" not in input_data.columns:
@@ -523,7 +519,7 @@ def train_pipeline_step_split_data(
523
519
  if pj.train_split_func is None:
524
520
  split_func = split_data_train_validation_test
525
521
  split_args = {
526
- "stratification_min_max": pj["model"] != "proloaf",
522
+ "stratification_min_max": True,
527
523
  "back_test": backtest,
528
524
  }
529
525
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openstef
3
- Version: 3.4.11
3
+ Version: 3.4.13
4
4
  Summary: Open short term energy forecaster
5
5
  Home-page: https://github.com/OpenSTEF/openstef
6
6
  Author: Alliander N.V
@@ -22,6 +22,7 @@ Requires-Dist: matplotlib ~=3.7
22
22
  Requires-Dist: mlflow ~=2.3
23
23
  Requires-Dist: networkx ~=3.1
24
24
  Requires-Dist: optuna ~=3.1
25
+ Requires-Dist: optuna-integration ~=3.6
25
26
  Requires-Dist: pandas ~=2.2.0
26
27
  Requires-Dist: plotly ~=5.18
27
28
  Requires-Dist: pvlib ==0.9.4
@@ -30,12 +31,8 @@ Requires-Dist: pymsteams ~=0.2.2
30
31
  Requires-Dist: scikit-learn ~=1.3
31
32
  Requires-Dist: scipy ~=1.10
32
33
  Requires-Dist: statsmodels ~=0.13.5
33
- Requires-Dist: structlog ~=23.1
34
+ Requires-Dist: structlog <25,>=23.1
34
35
  Requires-Dist: xgboost ~=2.0
35
- Provides-Extra: proloaf
36
- Requires-Dist: proloaf ==0.2.0 ; extra == 'proloaf'
37
- Requires-Dist: torch ==1.10.0 ; extra == 'proloaf'
38
- Requires-Dist: pytorch-lightning ==1.5.1 ; extra == 'proloaf'
39
36
 
40
37
  <!--
41
38
  SPDX-FileCopyrightText: 2017-2023 Contributors to the OpenSTEF project <korte.termijn.prognoses@alliander.com>
@@ -57,20 +54,27 @@ SPDX-License-Identifier: MPL-2.0
57
54
  [![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=OpenSTEF_openstef&metric=sqale_index)](https://sonarcloud.io/dashboard?id=OpenSTEF_openstef)
58
55
  [![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=OpenSTEF_openstef&metric=vulnerabilities)](https://sonarcloud.io/dashboard?id=OpenSTEF_openstef)
59
56
  [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5585/badge)](https://bestpractices.coreinfrastructure.org/projects/5585)
57
+ [![Downloads](https://static.pepy.tech/badge/openstef)](https://pepy.tech/project/openstef)
58
+ [![Downloads](https://static.pepy.tech/badge/openstef/month)](https://pepy.tech/project/openstef)
60
59
 
61
60
  # OpenSTEF
62
61
  OpenSTEF is a Python package designed for generating short-term forecasts in the energy sector. The repository includes all the essential components required for machine learning pipelines that facilitate the forecasting process. To utilize the package, users are required to furnish their own data storage and retrieval interface.
63
62
 
64
63
  # Table of contents
64
+ - [OpenSTEF](#openstef)
65
+ - [Table of contents](#table-of-contents)
65
66
  - [External information sources](#external-information-sources)
66
- - [Installation](install)
67
- - [Usage](usage)
68
- - [Reference Implementation](reference-implementation)
69
- - [Database connector for OpenSTEF](Openstef-dbc-Database-connector-for-openstef)
70
- - [License](license)
71
- - [Licences third-party libraries](licenses-third-party-libraries)
72
- - [Contributing](contributing)
73
- - [Contact](contact)
67
+ - [Installation](#installation)
68
+ - [Install the openstef package](#install-the-openstef-package)
69
+ - [Remark regarding installation within a **conda environment on Windows**:](#remark-regarding-installation-within-a-conda-environment-on-windows)
70
+ - [Usage](#usage)
71
+ - [Reference Implementation](#reference-implementation)
72
+ - [Openstef-dbc - Database connector for openstef](#openstef-dbc---database-connector-for-openstef)
73
+ - [Example notebooks](#example-notebooks)
74
+ - [License](#license)
75
+ - [Licenses third-party libraries](#licenses-third-party-libraries)
76
+ - [Contributing](#contributing)
77
+ - [Contact](#contact)
74
78
 
75
79
  # External information sources
76
80
  - [Documentation website](https://openstef.github.io/openstef/index.html);
@@ -89,10 +93,6 @@ OpenSTEF is a Python package designed for generating short-term forecasts in the
89
93
  pip install openstef
90
94
  ```
91
95
 
92
- _**Optional**_: if you would like to use the proloaf model with OpenSTEF install the proloaf dependencies by running:
93
- ```shell
94
- pip install openstef[proloaf]
95
- ```
96
96
  ### Remark regarding installation within a **conda environment on Windows**:
97
97
 
98
98
  A version of the pywin32 package will be installed as a secondary dependency along with the installation of the openstef package. Since conda relies on an old version of pywin32, the new installation can break conda's functionality. The following command can solve this issue:
@@ -1,6 +1,6 @@
1
1
  openstef/__init__.py,sha256=93UM6m0LLQhO69-mSqLuUy73jgs4W7Iuxfo3Lm8c98g,419
2
2
  openstef/__main__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,163
3
- openstef/enums.py,sha256=dFpGFySauUt-m_bsPNcmc5WVG33ZXcWsbJeQp_4iEBE,753
3
+ openstef/enums.py,sha256=4NxcBobpn1Z6J_qHaIsJCarZ2BGZph_S_1PcwCDjg5o,729
4
4
  openstef/exceptions.py,sha256=fVqjyrVMBiSGxcoZ3JfTcgZjIur1cPennZpfwqgc9qY,1992
5
5
  openstef/data/dutch_holidays_2020-2022.csv,sha256=pS-CjE0igYXd-2dG-MlqyvR2fgYgXkbNmgCKyTjmwxs,23704
6
6
  openstef/data/dutch_holidays_2020-2022.csv.license,sha256=AxxHusqwIXU5RHl5ZMU65LyXmgtbj6QlcnFaOEN4kEE,145
@@ -27,15 +27,14 @@ openstef/data/dazls_model_3.4.7/dazls_stored_3.4.7_target_scaler.z.license,sha25
27
27
  openstef/data_classes/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,163
28
28
  openstef/data_classes/data_prep.py,sha256=3SLvHDXlL-fBw8IFGBP_pKXTfWjQsKjgVxDyYlgic1o,3417
29
29
  openstef/data_classes/model_specifications.py,sha256=Uod1W3QzhRqVLb6zvXwxh9wRL3EHCzSvX0oDNd28cFk,1197
30
- openstef/data_classes/prediction_job.py,sha256=YrPaUACW7u09yabmwXkXu3fRpu-M90FPgprd7vjSP0A,4856
30
+ openstef/data_classes/prediction_job.py,sha256=N2iD1B3LlnBAhvQaLJxIKe6K_0iWpTG0Qt6gHq5Vn6o,4789
31
31
  openstef/data_classes/split_function.py,sha256=ljQIQQu1t1Y_CVWGAy25jrM6wG9odIVVQVimrT1n-1s,3358
32
32
  openstef/feature_engineering/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,163
33
- openstef/feature_engineering/apply_features.py,sha256=pKvTl2c-L5OUuRPWy9mr_OcGExSNbwDRhTuLmNzGFqE,4114
33
+ openstef/feature_engineering/apply_features.py,sha256=-3fyisOVj9ckIkRe2iYfWutbXSX8iqBkcvt8AYr-gmE,3906
34
34
  openstef/feature_engineering/data_preparation.py,sha256=vFdCdXrX7RWWa4uj1D8rVkHymacbfhvwoLiEnUk-v6g,5399
35
35
  openstef/feature_engineering/feature_adder.py,sha256=aSqDl_gUrB3H2TD3cNvU5JniY_KOb4u4a2A6J7zB2BQ,6835
36
- openstef/feature_engineering/feature_applicator.py,sha256=FpEEirbOTuOKZipoGHYliKvY0r_XE5f2z-r8NiAx4oU,7712
36
+ openstef/feature_engineering/feature_applicator.py,sha256=DR7jayrEMlra4BFL1Ps5WV2fxbkQ6VaOTa5RIKM-YNk,7447
37
37
  openstef/feature_engineering/general.py,sha256=igAPyejYN5d09-a_c53C79a0A4cHjvMCa47KC4IfgCo,4072
38
- openstef/feature_engineering/historic_features.py,sha256=aDxoS42ndUmLmwqpII8rZ_-L86NFer-Gw_fGf0TAobU,1215
39
38
  openstef/feature_engineering/holiday_features.py,sha256=3Ff4Lkm26h8wJVoBplUewt4HfsvOUS9zj0x0MxewIm8,7842
40
39
  openstef/feature_engineering/lag_features.py,sha256=Dr6qS8UhdgEHPZZSe-w6ibtjl_lcbcQohhqdZN9fqEU,5652
41
40
  openstef/feature_engineering/weather_features.py,sha256=wy3KFXUIIwSydFJZpiejsJMwURtDpv9l0HBHu-uLAGQ,15561
@@ -47,9 +46,9 @@ openstef/model/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,16
47
46
  openstef/model/basecase.py,sha256=caI6Q-8y0ymlxGK9Js_H3Vh0q6ruNHlGD5RG0_kE5M0,2878
48
47
  openstef/model/confidence_interval_applicator.py,sha256=7E1_JFLZ4-hyEhleacMvp5szdmYZS4tpKAjfhGvXXvg,8602
49
48
  openstef/model/fallback.py,sha256=VV9ehgnoMZtWzqKk9H1t8wnERFh5CyC4TvDIuRP_ZDI,2861
50
- openstef/model/model_creator.py,sha256=U1Lw4HFyajfxQ2o5lEnCxnmRC62DEu5PBHXrm_jnEJU,5582
51
- openstef/model/objective.py,sha256=qBZGij4P2uZXFt-1x4MxCkIRmpVY3TJoo4Mycxu9dO8,15433
52
- openstef/model/objective_creator.py,sha256=OiPPFSiSu7z9K_983ib5iqhhu6_9tt7iyTyKNZ2Iz68,2057
49
+ openstef/model/model_creator.py,sha256=uDLn5fte8nGmxMOGA2xvTkeyslaA4kATuu-w1QOI4FI,4790
50
+ openstef/model/objective.py,sha256=eqNBYGfhEVGegOm0PbizowuFImKblRqHgxkp9lgaKQc,13500
51
+ openstef/model/objective_creator.py,sha256=QxHolw60aSvqSKO6VO-uDslwg3VC_T4BZ2cm-sy7E3U,1970
53
52
  openstef/model/serializer.py,sha256=Q7pKkA-K1bszER_tkOWhvwTQsj6-qZoX5zaXIemRKGs,16934
54
53
  openstef/model/standard_deviation_generator.py,sha256=Od9bzXi2TLb1v8Nz-VhBMZHSopWH6ssaDe8gYLlqO1I,2911
55
54
  openstef/model/metamodels/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,163
@@ -61,7 +60,6 @@ openstef/model/regressors/custom_regressor.py,sha256=Hsmxahc9nfSWD0aEZ6cm4pxW2no
61
60
  openstef/model/regressors/dazls.py,sha256=cCYFewJEv3Fn01wdZpaKNSiYmEwzuED7PQrrWzwyTEg,8084
62
61
  openstef/model/regressors/lgbm.py,sha256=zCdn1euEdSFxYJzH8XqQFFnb6R4JVUnmineKjX_Gy-g,800
63
62
  openstef/model/regressors/linear.py,sha256=uOvZMLGZH_9nXfmS5honCMfyVeyGXP1Cza9A_BdXlVw,3665
64
- openstef/model/regressors/proloaf.py,sha256=HjyfEQRiFMFzyfYSrFL3yPhduhL1igGr1FTO6d0ET7I,9081
65
63
  openstef/model/regressors/regressor.py,sha256=uJcx59AyCPE9f_yPcAQ59h2ZS7eNsDpIHJrladKvHIw,3461
66
64
  openstef/model/regressors/xgb.py,sha256=HggA1U10srzdysjV560BMMX66kfaxCKAnOZB3JyyT_Y,808
67
65
  openstef/model/regressors/xgb_quantile.py,sha256=Oenhe0cMLAEXlinHZF588zNTjwR-hB7NB0anQZPwPKU,7710
@@ -74,9 +72,9 @@ openstef/pipeline/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU
74
72
  openstef/pipeline/create_basecase_forecast.py,sha256=7jig8lt-e3xwIWDSk-bMwUC45y2mwKe9-zDZYHiiQMY,4324
75
73
  openstef/pipeline/create_component_forecast.py,sha256=ksX5r7H5IrMrfPVuRK0OWOtsdns1Rrn1L9ZG0Si0TI4,6255
76
74
  openstef/pipeline/create_forecast.py,sha256=El9xXKN8DeIADy_76-V22wBY8AMSa4KEfYuW00jw85k,5083
77
- openstef/pipeline/optimize_hyperparameters.py,sha256=BnahfVHlE1z9so0gxPyd75OKCXSZvtFvuqicH6skm5U,10892
78
- openstef/pipeline/train_create_forecast_backtest.py,sha256=upuoiE01vjjxUu_sY0tANPqdOtpGKrQQ3azhVDnBJdc,5512
79
- openstef/pipeline/train_model.py,sha256=cPTXDUjsQK5o5ygMNnmH-DfXins1khAnvt8gVF5eK4Q,18677
75
+ openstef/pipeline/optimize_hyperparameters.py,sha256=QlM_TN2sVelfrYFqZfy-gkRJMlt4j3fr65HvcEGhdac,10272
76
+ openstef/pipeline/train_create_forecast_backtest.py,sha256=QkkpccW4BW0TC5uq22_juTcp8uvPZ4Qk-ewdnlYpNTE,5492
77
+ openstef/pipeline/train_model.py,sha256=ELIHkGjzvIdV4V7IMiy8tw7A_wc1QJ7eXY_rPXOgytU,18533
80
78
  openstef/pipeline/utils.py,sha256=fkc-oNirJ-JiyuOAL08RFrnPYPwudWal_N-BO6Cw980,2086
81
79
  openstef/postprocessing/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,163
82
80
  openstef/postprocessing/postprocessing.py,sha256=nehd0tDpkdIaWFJggQ-fDizIKdfmqJ3IOGfk0sDnrzk,8409
@@ -99,8 +97,8 @@ openstef/tasks/utils/predictionjobloop.py,sha256=Ysy3zF5lzPMz_asYDKeF5m0qgVT3tCt
99
97
  openstef/tasks/utils/taskcontext.py,sha256=yI6TntOkZcW8JiNVuw4uJIigEBL0_iIrkPklF4ZeCX4,5401
100
98
  openstef/validation/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,163
101
99
  openstef/validation/validation.py,sha256=SaI-Mff9UOHQPnQ2jodXzZAVZilc-2AXZsPpSjDRqAg,10346
102
- openstef-3.4.11.dist-info/LICENSE,sha256=7Pm2fWFFHHUG5lDHed1vl5CjzxObIXQglnYsEdtjo_k,14907
103
- openstef-3.4.11.dist-info/METADATA,sha256=ZRh77dwGdWxFGtexZEx9ZvU7_KP6VKeBx4C8rVFhvx4,7872
104
- openstef-3.4.11.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
105
- openstef-3.4.11.dist-info/top_level.txt,sha256=kD0H4PqrQoncZ957FvqwfBxa89kTrun4Z_RAPs_HhLs,9
106
- openstef-3.4.11.dist-info/RECORD,,
100
+ openstef-3.4.13.dist-info/LICENSE,sha256=7Pm2fWFFHHUG5lDHed1vl5CjzxObIXQglnYsEdtjo_k,14907
101
+ openstef-3.4.13.dist-info/METADATA,sha256=l5HsBWQbm_94pKxUsJxpOW6QAUBGw2Dd-z3_sdDxDWM,8124
102
+ openstef-3.4.13.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
103
+ openstef-3.4.13.dist-info/top_level.txt,sha256=kD0H4PqrQoncZ957FvqwfBxa89kTrun4Z_RAPs_HhLs,9
104
+ openstef-3.4.13.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: bdist_wheel (0.43.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,40 +0,0 @@
1
- # SPDX-FileCopyrightText: 2017-2023 Alliander N.V. <korte.termijn.prognoses@alliander.com> # noqa E501>
2
- #
3
- # SPDX-License-Identifier: MPL-2.0
4
-
5
- """This module contains historic load related functions used for feature engineering."""
6
-
7
- import pandas as pd
8
- import structlog
9
-
10
- from openstef.data_classes.prediction_job import PredictionJobDataClass
11
-
12
-
13
- def add_historic_load_as_a_feature(
14
- data: pd.DataFrame,
15
- pj: PredictionJobDataClass = None,
16
- ) -> pd.DataFrame:
17
- """Adds additional proloaf features to the input data, historic_load (equal to the load).
18
-
19
- Args:
20
- data: Dataframe to which the wind features have to be added
21
- pj: Prediction job.
22
-
23
- Returns:
24
- DataFrame that is the same as input dataframe with extra columns for the added proloaf features
25
-
26
- """
27
- logger = structlog.get_logger(__name__)
28
-
29
- if pj is None:
30
- pj = {}
31
-
32
- if pj.get("model") == "proloaf":
33
- data["historic_load"] = data["load"]
34
- logger.warning(
35
- "The historic_load is added to the data, this is a copy of the load. Adding"
36
- " this feature is in most of the cases not a good idea, it is designed for"
37
- " the proloaf model."
38
- )
39
-
40
- return data
@@ -1,281 +0,0 @@
1
- # SPDX-FileCopyrightText: 2017-2023 Alliander N.V. <korte.termijn.prognoses@alliander.com> # noqa E501>
2
- #
3
- # SPDX-License-Identifier: MPL-2.0
4
- from typing import Any, Union
5
-
6
- import numpy as np
7
- import pandas as pd
8
-
9
- # These imports will require the proloaf optional dependencies to be installed
10
- import proloaf.datahandler as dh
11
- import torch
12
- from proloaf.modelhandler import ModelWrapper
13
-
14
- from openstef.model.regressors.regressor import OpenstfRegressor
15
-
16
- # TODO: implement the hyperparameter optimalisation via optuna
17
- # TODO: set the default for hyperparameters in the init of OpenstfProloafRegressor
18
- # TODO: implement function for defining encoder and decoder features
19
-
20
-
21
- def divide_scaling_groups(x: pd.DataFrame) -> tuple[list[str], list[str], list[str]]:
22
- """Divides the column names over different type of scaling groups.
23
-
24
- Args:
25
- x: Dataframe from which columns have to be divided
26
-
27
- Returns:
28
- List of all the grouped features for scaling (three groups)
29
-
30
- """
31
- minmax_scale_features = []
32
- oh_scale_features = []
33
- no_scale_features = []
34
-
35
- for column in x.columns:
36
- if (x[column].min() <= -1) or (x[column].max() >= 1):
37
- minmax_scale_features.append(column)
38
- elif x[column].dtype == "bool":
39
- oh_scale_features.append(column)
40
- else:
41
- no_scale_features.append(column)
42
-
43
- return minmax_scale_features, oh_scale_features, no_scale_features
44
-
45
-
46
- def apply_scaling(
47
- scaler_features: tuple[list[str], list[str], list[str]],
48
- data: pd.DataFrame,
49
- scalers=None,
50
- ):
51
- """Applies different scaling methods to a certain dataframe (minmax, one hot, or no scaling).
52
-
53
- Args:
54
- scaler_features: Three different lists with features for each scaling
55
- x: Dataframe from which columns have to be divided
56
- scalers: scalers resulting from the previous scaling
57
-
58
- Returns:
59
- Dataframe with all the scaled features
60
-
61
- """
62
- selected_features, scalers = dh.scale_all(
63
- data,
64
- scalers=scalers,
65
- feature_groups=[
66
- {
67
- "name": "main",
68
- "scaler": ["minmax", -1.0, 1.0],
69
- "features": scaler_features[0],
70
- },
71
- {"name": "aux", "scaler": None, "features": scaler_features[2]},
72
- ],
73
- )
74
-
75
- # One hot encoding certain features
76
- onehot_feature_groups = [
77
- {
78
- "name": "main",
79
- "scaler": [
80
- "onehot",
81
- ],
82
- "features": scaler_features[1],
83
- }
84
- ]
85
- for group in onehot_feature_groups:
86
- df_onehot = data.filter(group["features"])
87
- result_oh_scale = np.transpose(np.array(df_onehot.iloc[:, :], dtype=np.int))
88
- df_onehot.iloc[:, :] = result_oh_scale.T
89
-
90
- if not df_onehot.columns.empty:
91
- selected_features = pd.concat([selected_features, df_onehot], axis=1)
92
- data = selected_features.iloc[:, :].replace(np.nan, 0)
93
-
94
- return data, scalers
95
-
96
-
97
- class OpenstfProloafRegressor(OpenstfRegressor, ModelWrapper):
98
- def __init__(
99
- self,
100
- name: str = "model",
101
- core_net: str = "torch.nn.LSTM",
102
- relu_leak: float = 0.1,
103
- encoder_features: list[str] = [
104
- "historic_load",
105
- ], # make sure historic load is present, TODO: implement so you can use None
106
- decoder_features: list[str] = [
107
- "air_density"
108
- ], # TODO: implement so you can use None
109
- core_layers: int = 1,
110
- rel_linear_hidden_size: float = 1.0,
111
- rel_core_hidden_size: float = 1.0,
112
- dropout_fc: float = 0.4,
113
- dropout_core: float = 0.3,
114
- training_metric: str = "nllgauss",
115
- metric_options: dict[str, Any] = {},
116
- optimizer_name: str = "adam",
117
- early_stopping_patience: int = 7,
118
- early_stopping_margin: float = 0,
119
- learning_rate: float = 1e-3,
120
- max_epochs: int = 100,
121
- device: Union[str, int] = "cpu", # "cuda" or "cpu"
122
- batch_size: int = 6,
123
- history_horizon: int = 24,
124
- horizon_minutes: int = 2880, # 2 days in minutes,
125
- ):
126
- self.device = device
127
- self.batch_size = batch_size
128
- self.history_horizon = history_horizon
129
- self.forecast_horizon = int(horizon_minutes / 60)
130
- ModelWrapper.__init__(
131
- self,
132
- name=name,
133
- core_net=core_net,
134
- relu_leak=relu_leak,
135
- encoder_features=encoder_features,
136
- decoder_features=decoder_features,
137
- core_layers=core_layers,
138
- rel_linear_hidden_size=rel_linear_hidden_size,
139
- rel_core_hidden_size=rel_core_hidden_size,
140
- dropout_fc=dropout_fc,
141
- dropout_core=dropout_core,
142
- training_metric=training_metric,
143
- metric_options=metric_options,
144
- optimizer_name=optimizer_name,
145
- early_stopping_patience=early_stopping_patience,
146
- early_stopping_margin=early_stopping_margin,
147
- learning_rate=learning_rate,
148
- max_epochs=max_epochs,
149
- )
150
- self.to(device)
151
-
152
- @property
153
- def feature_names(self):
154
- return (
155
- ["load"] + self.encoder_features + self.decoder_features
156
- ) # TODO: gehele range, of een enkele feature
157
-
158
- @property
159
- def can_predict_quantiles(self):
160
- return False
161
-
162
- def predict(self, x: pd.DataFrame) -> np.ndarray:
163
- x = x[list(self.feature_names)[1:]]
164
- # Apply scaling and interpolation for NaN values
165
- x = dh.fill_if_missing(x, periodicity=24)
166
- x, _ = apply_scaling(
167
- [
168
- self.minmax_scale_features,
169
- self.oh_scale_features,
170
- self.no_scale_features,
171
- ],
172
- x,
173
- self.scalers,
174
- )
175
-
176
- inputs_enc = torch.tensor(
177
- x[self.encoder_features].to_numpy(), dtype=torch.float
178
- ).unsqueeze(dim=0)
179
- inputs_dec = torch.tensor(
180
- x[self.decoder_features].to_numpy(), dtype=torch.float
181
- ).unsqueeze(dim=0)
182
- prediction = (
183
- ModelWrapper.predict(self, inputs_enc, inputs_dec)[:, :, 0]
184
- .squeeze()
185
- .detach()
186
- .numpy()
187
- )
188
-
189
- return prediction
190
-
191
- def fit(
192
- self,
193
- x: pd.DataFrame,
194
- y: pd.DataFrame,
195
- eval_set: tuple = None,
196
- early_stopping_rounds: int = None,
197
- verbose: bool = False,
198
- **kwargs,
199
- ) -> ModelWrapper:
200
- x = x[list(self.feature_names)[1:]]
201
- # Apply scaling and interpolation for NaN values
202
- x = dh.fill_if_missing(x, periodicity=24)
203
- (
204
- self.minmax_scale_features,
205
- self.oh_scale_features,
206
- self.no_scale_features,
207
- ) = divide_scaling_groups(x)
208
- x, self.scalers = apply_scaling(
209
- [
210
- self.minmax_scale_features,
211
- self.oh_scale_features,
212
- self.no_scale_features,
213
- ],
214
- x,
215
- self.scalers,
216
- )
217
- y = y.to_frame()
218
- self.target_id = [y.columns[0]]
219
-
220
- df_train = pd.concat([x, y], axis="columns", verify_integrity=True)
221
-
222
- print(f"{self.encoder_features = }")
223
- print(f"{self.decoder_features = }")
224
-
225
- train_dl, _, _ = dh.transform(
226
- df=df_train,
227
- encoder_features=self.encoder_features,
228
- decoder_features=self.decoder_features,
229
- batch_size=self.batch_size,
230
- history_horizon=self.history_horizon,
231
- forecast_horizon=self.forecast_horizon,
232
- target_id=self.target_id,
233
- train_split=1.0,
234
- validation_split=1.0,
235
- device=self.device,
236
- )
237
-
238
- val_x, val_y = eval_set[1][0], eval_set[1][1]
239
- val_x = dh.fill_if_missing(val_x, periodicity=24)
240
- val_x, _ = apply_scaling(
241
- [
242
- self.minmax_scale_features,
243
- self.oh_scale_features,
244
- self.no_scale_features,
245
- ],
246
- val_x,
247
- self.scalers,
248
- )
249
-
250
- df_val = pd.concat([val_x, val_y], axis="columns", verify_integrity=True)
251
- _, validation_dl, _ = dh.transform(
252
- df=df_val,
253
- encoder_features=self.encoder_features,
254
- decoder_features=self.decoder_features,
255
- batch_size=self.batch_size,
256
- history_horizon=self.history_horizon,
257
- forecast_horizon=self.forecast_horizon,
258
- target_id=self.target_id,
259
- train_split=0.0,
260
- validation_split=1.0,
261
- device=self.device,
262
- )
263
- self.to(self.device)
264
- self.init_model()
265
- self.is_fitted_ = True
266
-
267
- return self.run_training(train_dl, validation_dl)
268
-
269
- def get_params(self, deep=True):
270
- model_params = self.get_model_config()
271
- training_params = self.get_training_config()
272
- return {**model_params, **training_params}
273
-
274
- def set_params(self, **params):
275
- self.update(**params)
276
- return self
277
-
278
-
279
- if __name__ == "__main__":
280
- test = OpenstfProloafRegressor()
281
- print(test)