openstef 3.4.60__tar.gz → 3.4.62__tar.gz
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.
- {openstef-3.4.60 → openstef-3.4.62}/PKG-INFO +1 -1
- {openstef-3.4.60 → openstef-3.4.62}/openstef/data_classes/data_prep.py +10 -5
- {openstef-3.4.60 → openstef-3.4.62}/openstef/data_classes/model_specifications.py +15 -11
- openstef-3.4.62/openstef/data_classes/prediction_job.py +151 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/data_classes/split_function.py +7 -6
- {openstef-3.4.60 → openstef-3.4.62}/openstef/feature_engineering/weather_features.py +0 -1
- {openstef-3.4.60 → openstef-3.4.62}/openstef/metrics/metrics.py +7 -4
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/confidence_interval_applicator.py +1 -1
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/fallback.py +2 -4
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/metamodels/missing_values_handler.py +2 -2
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/regressors/custom_regressor.py +2 -2
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/serializer.py +2 -3
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/standard_deviation_generator.py +1 -1
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model_selection/model_selection.py +3 -1
- {openstef-3.4.60 → openstef-3.4.62}/openstef/postprocessing/postprocessing.py +0 -5
- {openstef-3.4.60 → openstef-3.4.62}/openstef/tasks/calculate_kpi.py +5 -5
- {openstef-3.4.60 → openstef-3.4.62}/openstef/tasks/create_basecase_forecast.py +4 -4
- {openstef-3.4.60 → openstef-3.4.62}/openstef/tasks/create_components_forecast.py +4 -6
- {openstef-3.4.60 → openstef-3.4.62}/openstef/tasks/create_forecast.py +3 -3
- {openstef-3.4.60 → openstef-3.4.62}/openstef/tasks/create_solar_forecast.py +2 -3
- {openstef-3.4.60 → openstef-3.4.62}/openstef/tasks/optimize_hyperparameters.py +3 -3
- {openstef-3.4.60 → openstef-3.4.62}/openstef/tasks/split_forecast.py +3 -4
- {openstef-3.4.60 → openstef-3.4.62}/openstef/tasks/train_model.py +5 -5
- {openstef-3.4.60 → openstef-3.4.62}/openstef/validation/validation.py +7 -6
- {openstef-3.4.60 → openstef-3.4.62}/openstef.egg-info/PKG-INFO +1 -1
- {openstef-3.4.60 → openstef-3.4.62}/setup.py +1 -1
- openstef-3.4.60/openstef/data_classes/prediction_job.py +0 -135
- {openstef-3.4.60 → openstef-3.4.62}/LICENSE +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/README.md +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/__init__.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/__main__.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/app_settings.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/data/NL_terrestrial_radiation.csv +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/data/NL_terrestrial_radiation.csv.license +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/data/dazls_model_3.4.24/dazls_stored_3.4.24_baseline_model.z +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/data/dazls_model_3.4.24/dazls_stored_3.4.24_baseline_model.z.license +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/data/dazls_model_3.4.24/dazls_stored_3.4.24_model_card.md +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/data/dazls_model_3.4.24/dazls_stored_3.4.24_model_card.md.license +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/data/dutch_holidays.csv +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/data/dutch_holidays.csv.license +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/data/pv_single_coefs.csv +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/data/pv_single_coefs.csv.license +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/data_classes/__init__.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/enums.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/exceptions.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/feature_engineering/__init__.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/feature_engineering/apply_features.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/feature_engineering/bidding_zone_to_country_mapping.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/feature_engineering/cyclic_features.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/feature_engineering/data_preparation.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/feature_engineering/feature_adder.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/feature_engineering/feature_applicator.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/feature_engineering/general.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/feature_engineering/holiday_features.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/feature_engineering/lag_features.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/feature_engineering/missing_values_transformer.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/feature_engineering/rolling_features.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/metrics/__init__.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/metrics/figure.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/metrics/reporter.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/__init__.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/basecase.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/metamodels/__init__.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/metamodels/feature_clipper.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/metamodels/grouped_regressor.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/model_creator.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/objective.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/objective_creator.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/regressors/__init__.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/regressors/arima.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/regressors/dazls.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/regressors/flatliner.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/regressors/gblinear_quantile.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/regressors/lgbm.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/regressors/linear.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/regressors/linear_quantile.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/regressors/regressor.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/regressors/xgb.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/regressors/xgb_multioutput_quantile.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model/regressors/xgb_quantile.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/model_selection/__init__.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/monitoring/__init__.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/monitoring/performance_meter.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/monitoring/teams.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/pipeline/__init__.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/pipeline/create_basecase_forecast.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/pipeline/create_component_forecast.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/pipeline/create_forecast.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/pipeline/optimize_hyperparameters.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/pipeline/train_create_forecast_backtest.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/pipeline/train_model.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/pipeline/utils.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/postprocessing/__init__.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/preprocessing/__init__.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/preprocessing/preprocessing.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/settings.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/tasks/__init__.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/tasks/create_wind_forecast.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/tasks/utils/__init__.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/tasks/utils/dependencies.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/tasks/utils/predictionjobloop.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/tasks/utils/taskcontext.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef/validation/__init__.py +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef.egg-info/SOURCES.txt +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef.egg-info/dependency_links.txt +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef.egg-info/requires.txt +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/openstef.egg-info/top_level.txt +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/pyproject.toml +0 -0
- {openstef-3.4.60 → openstef-3.4.62}/setup.cfg +0 -0
@@ -2,12 +2,13 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
4
|
"""Specifies the split function dataclass."""
|
5
|
+
|
5
6
|
import inspect
|
6
7
|
import json
|
7
8
|
from importlib import import_module
|
8
9
|
from typing import Any, Sequence, TypeVar, Union
|
9
10
|
|
10
|
-
from pydantic
|
11
|
+
from pydantic import BaseModel, Field
|
11
12
|
|
12
13
|
DataPrepClass = TypeVar("DataPrepClass")
|
13
14
|
|
@@ -15,10 +16,14 @@ DataPrepClass = TypeVar("DataPrepClass")
|
|
15
16
|
class DataPrepDataClass(BaseModel):
|
16
17
|
"""Class that allows to specify a custom class to prepare the data (feature engineering , etc ...)."""
|
17
18
|
|
18
|
-
klass: Union[str, type[DataPrepClass]]
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
klass: Union[str, type[DataPrepClass]] = Field(
|
20
|
+
...,
|
21
|
+
description="The class that should be used to prepare the data. Can be a string with the path to the class or the class itself.",
|
22
|
+
)
|
23
|
+
arguments: Union[str, dict[str, Any]] = Field(
|
24
|
+
default=None,
|
25
|
+
description="The arguments that should be passed to the class. Can be a JSON string holding the function parameters or dict.",
|
26
|
+
)
|
22
27
|
|
23
28
|
def __getitem__(self, key: str):
|
24
29
|
"""Allows us to use subscription to get the items from the object."""
|
@@ -2,27 +2,31 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
4
|
"""Specifies the dataclass for model specifications."""
|
5
|
-
from typing import Optional, Union
|
6
5
|
|
7
|
-
from
|
6
|
+
from typing import Any, Optional, Union
|
7
|
+
|
8
|
+
from pydantic import BaseModel, Field
|
8
9
|
|
9
10
|
|
10
11
|
class ModelSpecificationDataClass(BaseModel):
|
11
12
|
"""Holds all information regarding the training procces of a specific model."""
|
12
13
|
|
13
|
-
id: Union[int, str]
|
14
|
-
hyper_params: Optional[dict] =
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
id: Union[int, str] = Field(description="The model id.")
|
15
|
+
hyper_params: Optional[dict] = Field(
|
16
|
+
default={}, description="Hyperparameters that should be used during training."
|
17
|
+
)
|
18
|
+
feature_names: Optional[list] = Field(
|
19
|
+
default=None, description="Features that should be used during training."
|
20
|
+
)
|
21
|
+
feature_modules: Optional[list] = Field(
|
22
|
+
default=[], description="Modules that should be used during training."
|
23
|
+
)
|
20
24
|
|
21
|
-
def __getitem__(self, item: str) ->
|
25
|
+
def __getitem__(self, item: str) -> Any:
|
22
26
|
"""Allows us to use subscription to get the items from the object."""
|
23
27
|
return getattr(self, item)
|
24
28
|
|
25
|
-
def __setitem__(self, key: str, value:
|
29
|
+
def __setitem__(self, key: str, value: Any) -> None:
|
26
30
|
"""Allows us to use subscription to set the items in the object."""
|
27
31
|
if hasattr(self, key):
|
28
32
|
self.__dict__[key] = value
|
@@ -0,0 +1,151 @@
|
|
1
|
+
# SPDX-FileCopyrightText: 2017-2023 Contributors to the OpenSTEF project <korte.termijn.prognoses@alliander.com> # noqa E501>
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MPL-2.0
|
4
|
+
"""Specifies the prediction job dataclass."""
|
5
|
+
|
6
|
+
from typing import Any, Optional, Union
|
7
|
+
|
8
|
+
from pydantic import BaseModel, Field
|
9
|
+
|
10
|
+
from openstef.data_classes.data_prep import DataPrepDataClass
|
11
|
+
from openstef.data_classes.model_specifications import ModelSpecificationDataClass
|
12
|
+
from openstef.data_classes.split_function import SplitFuncDataClass
|
13
|
+
from openstef.enums import AggregateFunction, BiddingZone, PipelineType
|
14
|
+
|
15
|
+
|
16
|
+
class PredictionJobDataClass(BaseModel):
|
17
|
+
"""Holds all information about the specific forecast that has to be made."""
|
18
|
+
|
19
|
+
id: Union[int, str] = Field(
|
20
|
+
..., description="The predictions job id (often abreviated as pid)."
|
21
|
+
)
|
22
|
+
model: str = Field(
|
23
|
+
...,
|
24
|
+
description="The model type that should be used. Options are: 'xgb', 'xgb_quantile', 'lgb', 'linear', 'linear_quantile', 'gblinear_quantile', 'xgb_multioutput_quantile', 'flatliner'.",
|
25
|
+
)
|
26
|
+
|
27
|
+
model_kwargs: Optional[dict] = Field(
|
28
|
+
default=None, description="The model parameters that should be used."
|
29
|
+
)
|
30
|
+
|
31
|
+
forecast_type: str = Field(
|
32
|
+
...,
|
33
|
+
description="The type of forecasts that should be made. Options are: 'demand', 'wind', 'basecase'. If unsure what to pick, choose 'demand'.",
|
34
|
+
)
|
35
|
+
horizon_minutes: Optional[int] = Field(
|
36
|
+
2880,
|
37
|
+
description="The horizon of the desired forecast in minutes used in tasks. Defaults to 2880 minutes (i.e. 2 days).",
|
38
|
+
)
|
39
|
+
|
40
|
+
resolution_minutes: int = Field(
|
41
|
+
60, description="The resolution of the desired forecast in minutes."
|
42
|
+
)
|
43
|
+
lat: Optional[float] = Field(
|
44
|
+
52.132633,
|
45
|
+
description="Latitude of the forecasted location in degrees. Used for fetching weather data in tasks, calculating derrived features and component splitting.",
|
46
|
+
)
|
47
|
+
lon: Optional[float] = Field(
|
48
|
+
5.291266,
|
49
|
+
description="Longitude of the forecasted location in degrees. Used for fetching weather data in tasks, calculating derrived features and component splitting.",
|
50
|
+
)
|
51
|
+
name: str = Field(..., description="Name of the forecast, e.g. the location name.")
|
52
|
+
|
53
|
+
electricity_bidding_zone: Optional[BiddingZone] = Field(
|
54
|
+
BiddingZone.NL,
|
55
|
+
description="The bidding zone of the forecasted location. Used for fetching electricity prices in tasks. It is also used to determine the holidays that should be used. Currently only ENTSO-E bidding zones are supported.",
|
56
|
+
)
|
57
|
+
train_components: Optional[bool] = Field(
|
58
|
+
None,
|
59
|
+
description="Whether splitting the forecasts in wind, solar, rest is desired.",
|
60
|
+
)
|
61
|
+
description: Optional[str] = Field(
|
62
|
+
None,
|
63
|
+
description="Optional description of the prediction job for human reference.",
|
64
|
+
)
|
65
|
+
|
66
|
+
quantiles: Optional[list[float]] = Field(
|
67
|
+
None,
|
68
|
+
description="Quantiles that have to be forecasted. Only used for quantile models.",
|
69
|
+
)
|
70
|
+
train_split_func: Optional[SplitFuncDataClass] = Field(
|
71
|
+
None, description="Optional custom splitting function for operational procces."
|
72
|
+
)
|
73
|
+
backtest_split_func: Optional[SplitFuncDataClass] = Field(
|
74
|
+
None, description="Optional custom splitting function for backtesting."
|
75
|
+
)
|
76
|
+
train_horizons_minutes: Optional[list[int]] = Field(
|
77
|
+
None,
|
78
|
+
description="List of horizons that should be taken into account during training.",
|
79
|
+
)
|
80
|
+
default_modelspecs: Optional[ModelSpecificationDataClass] = Field(
|
81
|
+
None, description="Default model specifications"
|
82
|
+
)
|
83
|
+
save_train_forecasts: bool = Field(
|
84
|
+
False,
|
85
|
+
description="Indicate wether the forecasts produced during the training process should be saved.",
|
86
|
+
)
|
87
|
+
completeness_threshold: float = Field(
|
88
|
+
0.5,
|
89
|
+
description="Minimum fraction of data that should be available for making a regular forecast.",
|
90
|
+
)
|
91
|
+
minimal_table_length: int = Field(
|
92
|
+
100,
|
93
|
+
description="Minimum length (in rows) of the forecast input for making a regular forecast.",
|
94
|
+
)
|
95
|
+
flatliner_threshold_minutes: int = Field(
|
96
|
+
1440,
|
97
|
+
description="Number of minutes that the load has to be constant to detect a flatliner.",
|
98
|
+
)
|
99
|
+
data_balancing_ratio: Optional[float] = Field(
|
100
|
+
None,
|
101
|
+
description="If data balancing is enabled, the data will be balanced with data from 1 year ago in the future.",
|
102
|
+
)
|
103
|
+
rolling_aggregate_features: Optional[list[AggregateFunction]] = Field(
|
104
|
+
[],
|
105
|
+
description="If not None, rolling aggregate(s) of load will be used as features in the model.",
|
106
|
+
)
|
107
|
+
depends_on: Optional[list[Union[int, str]]] = Field(
|
108
|
+
[],
|
109
|
+
description="Link to another prediction job on which this prediction job might depend.",
|
110
|
+
)
|
111
|
+
sid: Optional[str] = Field(
|
112
|
+
None, description="Only required for create_solar_forecast task"
|
113
|
+
)
|
114
|
+
turbine_type: Optional[str] = Field(
|
115
|
+
None, description="Only required for create_wind_forecast task"
|
116
|
+
)
|
117
|
+
n_turbines: Optional[float] = Field(
|
118
|
+
None, description="Only required for create_wind_forecast task"
|
119
|
+
)
|
120
|
+
hub_height: Optional[float] = Field(
|
121
|
+
None, description="Only required for create_wind_forecast task"
|
122
|
+
)
|
123
|
+
pipelines_to_run: list[PipelineType] = Field(
|
124
|
+
[PipelineType.TRAIN, PipelineType.HYPER_PARMATERS, PipelineType.FORECAST],
|
125
|
+
description="The pipelines to run for this pj",
|
126
|
+
)
|
127
|
+
alternative_forecast_model_pid: Optional[Union[int, str]] = Field(
|
128
|
+
None,
|
129
|
+
description="The pid that references another prediction job from which the model should be used for making forecasts.",
|
130
|
+
)
|
131
|
+
data_prep_class: Optional[DataPrepDataClass] = Field(
|
132
|
+
None, description="The import string for the custom data prep class"
|
133
|
+
)
|
134
|
+
|
135
|
+
def __getitem__(self, item: str) -> Any:
|
136
|
+
"""Allows us to use subscription to get the items from the object."""
|
137
|
+
return getattr(self, item)
|
138
|
+
|
139
|
+
def __setitem__(self, key: str, value: Any) -> None:
|
140
|
+
"""Allows us to use subscription to set the items in the object."""
|
141
|
+
if hasattr(self, key):
|
142
|
+
self.__dict__[key] = value
|
143
|
+
else:
|
144
|
+
raise AttributeError(f"{key} not an attribute of prediction job.")
|
145
|
+
|
146
|
+
def get(self, key: str, default: Any = None) -> Any:
|
147
|
+
"""Allows to use the get functions similar to a python dict."""
|
148
|
+
if hasattr(self, key):
|
149
|
+
return getattr(self, key)
|
150
|
+
else:
|
151
|
+
return default
|
@@ -2,27 +2,28 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
4
|
"""Specifies the split function dataclass."""
|
5
|
+
|
5
6
|
import inspect
|
6
7
|
import json
|
7
8
|
from importlib import import_module
|
8
9
|
from typing import Any, Callable, Sequence, Union
|
9
10
|
|
10
|
-
from pydantic
|
11
|
+
from pydantic import BaseModel, Field
|
11
12
|
|
12
13
|
|
13
14
|
class SplitFuncDataClass(BaseModel):
|
14
15
|
"""Class that allows to specify a custom function to generate a train, test and validation set."""
|
15
16
|
|
16
|
-
function: Union[str, Callable]
|
17
|
-
arguments: Union[
|
18
|
-
|
19
|
-
|
17
|
+
function: Union[str, Callable] = Field(..., description="The split function")
|
18
|
+
arguments: Union[str, dict[str, Any]] = Field(
|
19
|
+
..., description="JSON string holding the function parameters or dict"
|
20
|
+
)
|
20
21
|
|
21
22
|
def __getitem__(self, key: str):
|
22
23
|
"""Allows us to use subscription to get the items from the object."""
|
23
24
|
return getattr(self, key)
|
24
25
|
|
25
|
-
def __setitem__(self, key: str, value:
|
26
|
+
def __setitem__(self, key: str, value: Any):
|
26
27
|
"""Allows us to use subscription to set the items in the object."""
|
27
28
|
if hasattr(self, key):
|
28
29
|
self.__dict__[key] = value
|
@@ -397,7 +397,6 @@ def calculate_dni(radiation: pd.Series, pj: PredictionJobDataClass) -> pd.Series
|
|
397
397
|
solar_zenith = solpos.apparent_zenith
|
398
398
|
|
399
399
|
# convert radiation (ghi) to right unit (J/m^2 to kWh/m^2)
|
400
|
-
# TODO: check whether unit conversion is necessary
|
401
400
|
ghi_forecasted = radiation / 3600
|
402
401
|
# convert ghi to dni
|
403
402
|
dni_converted = pvlib.irradiance.dni(
|
@@ -9,7 +9,7 @@
|
|
9
9
|
#
|
10
10
|
# SPDX-License-Identifier: MIT
|
11
11
|
"""This module contains all metrics to assess forecast quality."""
|
12
|
-
from typing import Callable
|
12
|
+
from typing import Callable, Optional, Tuple
|
13
13
|
|
14
14
|
import numpy as np
|
15
15
|
import pandas as pd
|
@@ -299,12 +299,15 @@ def skill_score_positive_peaks(
|
|
299
299
|
|
300
300
|
|
301
301
|
def franks_skill_score(
|
302
|
-
realised: pd.Series,
|
302
|
+
realised: pd.Series,
|
303
|
+
forecast: pd.Series,
|
304
|
+
basecase: pd.Series,
|
305
|
+
range_: Optional[float] = None,
|
303
306
|
) -> float:
|
304
307
|
"""Calculate Franks skill score."""
|
305
308
|
# Combine series in one DataFrame
|
306
309
|
combined = pd.concat([realised, forecast], axis=1)
|
307
|
-
if range_
|
310
|
+
if not range_:
|
308
311
|
range_ = (
|
309
312
|
combined[realised.name].max() - combined[realised.name].min()
|
310
313
|
if (combined[realised.name].max() - combined[realised.name].min()) != 0
|
@@ -360,7 +363,7 @@ def franks_skill_score_peaks(
|
|
360
363
|
|
361
364
|
def xgb_quantile_eval(
|
362
365
|
preds: np.ndarray, dmatrix: xgboost.DMatrix, quantile: float = 0.2
|
363
|
-
) ->
|
366
|
+
) -> Tuple:
|
364
367
|
"""Customized evaluational metric that equals to quantile regression loss (also known as pinball loss).
|
365
368
|
|
366
369
|
Quantile regression is regression that estimates a specified quantile of target's distribution conditional on given features.
|
@@ -137,7 +137,7 @@ class ConfidenceIntervalApplicator:
|
|
137
137
|
# Determine now, rounded on 15 minutes,
|
138
138
|
# Rounding helps to prevent fractional t_aheads
|
139
139
|
now = (
|
140
|
-
pd.Series(datetime.
|
140
|
+
pd.Series(datetime.now(tz=forecast_copy.index.tzinfo))
|
141
141
|
.min()
|
142
142
|
.round(f"{minimal_resolution}T")
|
143
143
|
.to_pydatetime()
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# SPDX-FileCopyrightText: 2017-2023 Contributors to the OpenSTEF project <korte.termijn.prognoses@alliander.com> # noqa E501>
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
|
-
from datetime import datetime
|
4
|
+
from datetime import datetime, UTC
|
5
5
|
|
6
6
|
import pandas as pd
|
7
7
|
|
@@ -43,9 +43,7 @@ def generate_fallback(
|
|
43
43
|
|
44
44
|
# Find most extreme historic day (do not count today as it is incomplete)
|
45
45
|
day_with_highest_load_date = (
|
46
|
-
load[load.index
|
47
|
-
.idxmax()
|
48
|
-
.load.date()
|
46
|
+
load[load.index < datetime.now(tz=UTC)].idxmax().load.date()
|
49
47
|
)
|
50
48
|
# generate datetime range of the day with the highest load
|
51
49
|
from_datetime = pd.Timestamp(day_with_highest_load_date, tz=load.index.tz)
|
@@ -90,7 +90,7 @@ class MissingValuesHandler(BaseEstimator, RegressorMixin, MetaEstimatorMixin):
|
|
90
90
|
def fit(self, x, y):
|
91
91
|
"""Fit model."""
|
92
92
|
_, y = check_X_y(x, y, force_all_finite="allow-nan", y_numeric=True)
|
93
|
-
if
|
93
|
+
if not isinstance(x, pd.DataFrame):
|
94
94
|
x = pd.DataFrame(np.asarray(x))
|
95
95
|
self.feature_in_names_ = list(x.columns)
|
96
96
|
self.n_features_in_ = x.shape[1]
|
@@ -133,6 +133,6 @@ class MissingValuesHandler(BaseEstimator, RegressorMixin, MetaEstimatorMixin):
|
|
133
133
|
x,
|
134
134
|
force_all_finite="allow-nan",
|
135
135
|
)
|
136
|
-
if
|
136
|
+
if not isinstance(x, pd.DataFrame):
|
137
137
|
x = pd.DataFrame(np.array(x))
|
138
138
|
return self.pipeline_.predict(x[self.non_null_columns_])
|
@@ -26,9 +26,9 @@ class CustomOpenstfRegressor(OpenstfRegressor):
|
|
26
26
|
def valid_kwargs() -> list[str]:
|
27
27
|
...
|
28
28
|
|
29
|
-
@
|
29
|
+
@staticmethod
|
30
30
|
@abstractmethod
|
31
|
-
def objective(
|
31
|
+
def objective() -> Type[RegressorObjective]:
|
32
32
|
...
|
33
33
|
|
34
34
|
|
@@ -5,7 +5,7 @@ import json
|
|
5
5
|
import logging
|
6
6
|
import os
|
7
7
|
import shutil
|
8
|
-
from datetime import datetime
|
8
|
+
from datetime import datetime, UTC
|
9
9
|
from json import JSONDecodeError
|
10
10
|
from typing import Optional, Union
|
11
11
|
from urllib.parse import unquote, urlparse
|
@@ -283,8 +283,7 @@ class MLflowSerializer:
|
|
283
283
|
"""Determines how many days ago a model is trained from the mlflow run."""
|
284
284
|
try:
|
285
285
|
model_datetime = run.end_time.to_pydatetime()
|
286
|
-
|
287
|
-
model_age_days = (datetime.utcnow() - model_datetime).days
|
286
|
+
model_age_days = (datetime.now(tz=UTC) - model_datetime).days
|
288
287
|
except Exception as e:
|
289
288
|
self.logger.warning(
|
290
289
|
"Could not get model age. Returning infinite age!", exception=str(e)
|
@@ -69,7 +69,7 @@ class StandardDeviationGenerator:
|
|
69
69
|
# Calculate the error for each predicted point
|
70
70
|
error = realised - predicted
|
71
71
|
error.index = error.index.hour # Hour only, remove the rest
|
72
|
-
# For the time starts with 00, 01, 02, etc.
|
72
|
+
# For the time starts with 00, 01, 02, etc.
|
73
73
|
for hour in range(24):
|
74
74
|
hour_error = error[error.index == hour]
|
75
75
|
|
@@ -230,7 +230,9 @@ def split_data_train_validation_test(
|
|
230
230
|
for date_set in [max_dates, min_dates, other_dates]:
|
231
231
|
n_days_val = max(1, int(validation_fraction * len(date_set)))
|
232
232
|
val_dates += list(
|
233
|
-
np.random.choice(
|
233
|
+
np.random.default_rng().choice(
|
234
|
+
list(date_set), n_days_val, replace=False
|
235
|
+
)
|
234
236
|
)
|
235
237
|
train_dates += [x for x in date_set if x not in val_dates]
|
236
238
|
|
@@ -239,11 +239,6 @@ def add_prediction_job_properties_to_forecast(
|
|
239
239
|
if forecast_quality is not None:
|
240
240
|
forecast["quality"] = forecast_quality
|
241
241
|
|
242
|
-
# TODO rename prediction job typ to type
|
243
|
-
# TODO algtype = model_file_path, perhaps we can find a more logical name
|
244
|
-
# TODO perhaps better to make a forecast its own class!
|
245
|
-
# TODO double check and sync this with make_basecase_forecast (other fields are added)
|
246
|
-
# !!!!! TODO fix the requirement for customer
|
247
242
|
forecast["pid"] = pj["id"]
|
248
243
|
forecast["customer"] = pj["name"]
|
249
244
|
forecast["description"] = pj["description"]
|
@@ -21,7 +21,7 @@ Example:
|
|
21
21
|
import logging
|
22
22
|
|
23
23
|
# Import builtins
|
24
|
-
from datetime import datetime, timedelta
|
24
|
+
from datetime import datetime, timedelta, UTC
|
25
25
|
from pathlib import Path
|
26
26
|
|
27
27
|
import numpy as np
|
@@ -56,8 +56,8 @@ def main(model_type: ModelType = None, config=None, database=None) -> None:
|
|
56
56
|
|
57
57
|
with TaskContext(taskname, config, database) as context:
|
58
58
|
# Set start and end time
|
59
|
-
|
60
|
-
|
59
|
+
end_time = datetime.now(tz=UTC)
|
60
|
+
start_time = end_time - timedelta(days=1)
|
61
61
|
|
62
62
|
PredictionJobLoop(context, model_type=model_type).map(
|
63
63
|
check_kpi_task,
|
@@ -77,9 +77,9 @@ def check_kpi_task(
|
|
77
77
|
) -> None:
|
78
78
|
# Apply default parameters if none are provided
|
79
79
|
if start_time is None:
|
80
|
-
start_time = datetime.
|
80
|
+
start_time = datetime.now(tz=UTC) - timedelta(days=1)
|
81
81
|
if end_time is None:
|
82
|
-
end_time = datetime.
|
82
|
+
end_time = datetime.now(tz=UTC)
|
83
83
|
|
84
84
|
# Get realised load data
|
85
85
|
realised = context.database.get_load_pid(pj["id"], start_time, end_time, "15T")
|
@@ -16,7 +16,7 @@ Example:
|
|
16
16
|
$ python create_basecase_forecast.py
|
17
17
|
|
18
18
|
"""
|
19
|
-
from datetime import datetime, timedelta
|
19
|
+
from datetime import datetime, timedelta, UTC
|
20
20
|
from pathlib import Path
|
21
21
|
|
22
22
|
import pandas as pd
|
@@ -68,8 +68,8 @@ def create_basecase_forecast_task(
|
|
68
68
|
return
|
69
69
|
|
70
70
|
# Define datetime range for input data
|
71
|
-
datetime_start = datetime.
|
72
|
-
datetime_end = datetime.
|
71
|
+
datetime_start = datetime.now(tz=UTC) - timedelta(days=t_behind_days)
|
72
|
+
datetime_end = datetime.now(tz=UTC) + timedelta(days=t_ahead_days)
|
73
73
|
|
74
74
|
# Retrieve input data
|
75
75
|
input_data = context.database.get_model_input(
|
@@ -87,7 +87,7 @@ def create_basecase_forecast_task(
|
|
87
87
|
basecase_forecast = basecase_forecast.loc[
|
88
88
|
basecase_forecast.index
|
89
89
|
> (
|
90
|
-
pd.to_datetime(datetime.
|
90
|
+
pd.to_datetime(datetime.now(tz=UTC), utc=True)
|
91
91
|
+ timedelta(minutes=pj.horizon_minutes)
|
92
92
|
),
|
93
93
|
:,
|
@@ -22,7 +22,7 @@ Example:
|
|
22
22
|
|
23
23
|
"""
|
24
24
|
import logging
|
25
|
-
from datetime import datetime, timedelta,
|
25
|
+
from datetime import datetime, timedelta, UTC
|
26
26
|
from pathlib import Path
|
27
27
|
|
28
28
|
import pandas as pd
|
@@ -76,8 +76,8 @@ def create_components_forecast_task(
|
|
76
76
|
return
|
77
77
|
|
78
78
|
# Define datetime range for input data
|
79
|
-
datetime_start = datetime.
|
80
|
-
datetime_end = datetime.
|
79
|
+
datetime_start = datetime.now(tz=UTC) - timedelta(days=t_behind_days)
|
80
|
+
datetime_end = datetime.now(tz=UTC) + timedelta(days=t_ahead_days)
|
81
81
|
|
82
82
|
logger.info(
|
83
83
|
"Get predicted load", datetime_start=datetime_start, datetime_end=datetime_end
|
@@ -120,9 +120,7 @@ def create_components_forecast_task(
|
|
120
120
|
logger.debug("Written forecast to database")
|
121
121
|
|
122
122
|
# Check if forecast was complete enough, otherwise raise exception
|
123
|
-
if forecasts.index.max() < datetime.
|
124
|
-
tzinfo=timezone.utc
|
125
|
-
) + timedelta(hours=30):
|
123
|
+
if forecasts.index.max() < datetime.now(tz=UTC) + timedelta(hours=30):
|
126
124
|
# Check which input data is missing the most.
|
127
125
|
# Do this by counting the NANs for (load)forecast, radiation and windspeed
|
128
126
|
max_index = forecasts.index.max()
|
@@ -20,7 +20,7 @@ Example:
|
|
20
20
|
$ python create_forecast.py
|
21
21
|
|
22
22
|
"""
|
23
|
-
from datetime import datetime, timedelta
|
23
|
+
from datetime import datetime, timedelta, UTC
|
24
24
|
from pathlib import Path
|
25
25
|
|
26
26
|
from openstef.data_classes.prediction_job import PredictionJobDataClass
|
@@ -73,8 +73,8 @@ def create_forecast_task(
|
|
73
73
|
mlflow_tracking_uri = context.config.paths_mlflow_tracking_uri
|
74
74
|
|
75
75
|
# Define datetime range for input data
|
76
|
-
datetime_start = datetime.
|
77
|
-
datetime_end = datetime.
|
76
|
+
datetime_start = datetime.now(tz=UTC) - timedelta(days=t_behind_days)
|
77
|
+
datetime_end = datetime.now(tz=UTC) + timedelta(seconds=pj.horizon_minutes * 60)
|
78
78
|
|
79
79
|
# Retrieve input data
|
80
80
|
input_data = context.database.get_model_input(
|
@@ -12,7 +12,7 @@ Example:
|
|
12
12
|
$ python create_solar_forecast
|
13
13
|
|
14
14
|
"""
|
15
|
-
from datetime import datetime, timedelta
|
15
|
+
from datetime import datetime, timedelta, UTC
|
16
16
|
from pathlib import Path
|
17
17
|
|
18
18
|
import numpy as np
|
@@ -23,7 +23,6 @@ from openstef import PROJECT_ROOT
|
|
23
23
|
from openstef.tasks.utils.predictionjobloop import PredictionJobLoop
|
24
24
|
from openstef.tasks.utils.taskcontext import TaskContext
|
25
25
|
|
26
|
-
# TODO move to config
|
27
26
|
PV_COEFS_FILEPATH = PROJECT_ROOT / "openstef" / "data" / "pv_single_coefs.csv"
|
28
27
|
|
29
28
|
|
@@ -231,7 +230,7 @@ def main(config=None, database=None, **kwargs):
|
|
231
230
|
num_prediction_jobs = len(prediction_jobs)
|
232
231
|
|
233
232
|
# only make customer = Provincie once an hour
|
234
|
-
utc_now_minute = datetime.
|
233
|
+
utc_now_minute = datetime.now(tz=UTC)().minute
|
235
234
|
if utc_now_minute >= 15:
|
236
235
|
prediction_jobs = [
|
237
236
|
pj for pj in prediction_jobs if str(pj["name"]).startswith("Provincie")
|
@@ -16,7 +16,7 @@ Example:
|
|
16
16
|
$ python optimize_hyperparameters.py
|
17
17
|
|
18
18
|
"""
|
19
|
-
from datetime import datetime, timedelta
|
19
|
+
from datetime import datetime, timedelta, UTC
|
20
20
|
from pathlib import Path
|
21
21
|
|
22
22
|
from openstef.data_classes.prediction_job import PredictionJobDataClass
|
@@ -88,8 +88,8 @@ def optimize_hyperparameters_task(
|
|
88
88
|
)
|
89
89
|
return
|
90
90
|
|
91
|
-
datetime_start = datetime.
|
92
|
-
datetime_end = datetime.
|
91
|
+
datetime_start = datetime.now(tz=UTC) - timedelta(days=DEFAULT_TRAINING_PERIOD_DAYS)
|
92
|
+
datetime_end = datetime.now(tz=UTC)
|
93
93
|
|
94
94
|
input_data = context.database.get_model_input(
|
95
95
|
pid=pj["id"],
|
@@ -23,7 +23,7 @@ Example:
|
|
23
23
|
|
24
24
|
"""
|
25
25
|
import logging
|
26
|
-
from datetime import datetime
|
26
|
+
from datetime import datetime, UTC
|
27
27
|
from pathlib import Path
|
28
28
|
|
29
29
|
import numpy as np
|
@@ -93,7 +93,6 @@ def split_forecast_task(
|
|
93
93
|
components, coefdict = find_components(input_split_function)
|
94
94
|
|
95
95
|
# Calculate mean absolute error (MAE)
|
96
|
-
# TODO: use a standard metric function for this
|
97
96
|
error = components[["load", "Inschatting"]].diff(axis=1).iloc[:, 1]
|
98
97
|
mae = error.abs().mean()
|
99
98
|
coefdict.update({"MAE": mae})
|
@@ -183,7 +182,7 @@ def convert_coefdict_to_coefsdf(
|
|
183
182
|
pj["id"],
|
184
183
|
input_split_function.index.min().date(),
|
185
184
|
input_split_function.index.max().date(),
|
186
|
-
datetime.
|
185
|
+
datetime.now(tz=UTC),
|
187
186
|
]
|
188
187
|
coefsdf = pd.DataFrame(
|
189
188
|
{"coef_name": list(coefdict.keys()), "coef_value": list(coefdict.values())}
|
@@ -237,7 +236,7 @@ def find_components(
|
|
237
236
|
|
238
237
|
# Carry out fitting
|
239
238
|
# See https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html # noqa
|
240
|
-
coefs,
|
239
|
+
coefs, _ = scipy.optimize.curve_fit(
|
241
240
|
weighted_sum,
|
242
241
|
xdata=df.iloc[:, 1:].values.T,
|
243
242
|
ydata=load.values,
|
@@ -19,7 +19,7 @@ Example:
|
|
19
19
|
$ python model_train.py
|
20
20
|
|
21
21
|
"""
|
22
|
-
from datetime import datetime, timedelta
|
22
|
+
from datetime import datetime, timedelta, UTC
|
23
23
|
from pathlib import Path
|
24
24
|
|
25
25
|
import pandas as pd
|
@@ -123,7 +123,7 @@ def train_model_task(
|
|
123
123
|
)
|
124
124
|
|
125
125
|
if datetime_end is None:
|
126
|
-
datetime_end = datetime.
|
126
|
+
datetime_end = datetime.now(tz=UTC)
|
127
127
|
if datetime_start is None:
|
128
128
|
datetime_start = datetime_end - timedelta(days=training_period_days_to_fetch)
|
129
129
|
|
@@ -184,9 +184,9 @@ def train_model_task(
|
|
184
184
|
"'save_train_forecasts option was activated.'"
|
185
185
|
)
|
186
186
|
context.database.write_train_forecasts(pj, data_sets)
|
187
|
-
context.logger.debug(
|
187
|
+
context.logger.debug("Saved Forecasts from trained model on datasets")
|
188
188
|
except SkipSaveTrainingForecasts:
|
189
|
-
context.logger.debug(
|
189
|
+
context.logger.debug("Skip saving forecasts")
|
190
190
|
except InputDataOngoingZeroFlatlinerError:
|
191
191
|
if (
|
192
192
|
context.config.known_zero_flatliners
|
@@ -213,7 +213,7 @@ def main(model_type=None, config=None, database=None):
|
|
213
213
|
model_type = [ml.value for ml in ModelType]
|
214
214
|
|
215
215
|
taskname = Path(__file__).name.replace(".py", "")
|
216
|
-
datetime_now = datetime.
|
216
|
+
datetime_now = datetime.now(tz=UTC)
|
217
217
|
with TaskContext(taskname, config, database) as context:
|
218
218
|
PredictionJobLoop(context, model_type=model_type).map(
|
219
219
|
train_model_task, context, datetime_end=datetime_now
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
4
|
import logging
|
5
5
|
import math
|
6
|
-
from datetime import datetime, timedelta
|
6
|
+
from datetime import datetime, timedelta, UTC
|
7
7
|
from typing import Union
|
8
8
|
|
9
9
|
import numpy as np
|
@@ -203,7 +203,7 @@ def calc_completeness_features(
|
|
203
203
|
df_copy.drop("horizon", inplace=True, axis=1)
|
204
204
|
|
205
205
|
if weights is None:
|
206
|
-
weights = np.array([1] * (
|
206
|
+
weights = np.array([1] * (len(df_copy.columns)))
|
207
207
|
|
208
208
|
length_weights = len(weights)
|
209
209
|
length_features = len(df_copy.columns)
|
@@ -243,7 +243,7 @@ def detect_ongoing_zero_flatliner(
|
|
243
243
|
|
244
244
|
"""
|
245
245
|
# remove all timestamps in the future
|
246
|
-
load = load[load.index
|
246
|
+
load = load[load.index <= datetime.now(tz=UTC)]
|
247
247
|
latest_measurement_time = load.dropna().index.max()
|
248
248
|
latest_measurements = load[
|
249
249
|
latest_measurement_time - timedelta(minutes=duration_threshold_minutes) :
|
@@ -297,9 +297,10 @@ def calc_completeness_dataframe(
|
|
297
297
|
# timecols: {delay:number of points expected to be missing}
|
298
298
|
# number of points expected to be missing = numberOfPointsUpToTwoDaysAhead - numberOfPointsAvailable
|
299
299
|
timecols = {
|
300
|
-
|
301
|
-
|
302
|
-
|
300
|
+
column: len(df)
|
301
|
+
- eval(column[2:].replace("min", "/60").replace("d", "*24.0")) / 0.25
|
302
|
+
for column in df.columns
|
303
|
+
if column.startswith("T-")
|
303
304
|
}
|
304
305
|
|
305
306
|
non_na_count = df.count()
|
@@ -29,7 +29,7 @@ def read_long_description_from_readme():
|
|
29
29
|
|
30
30
|
setup(
|
31
31
|
name="openstef",
|
32
|
-
version="3.4.
|
32
|
+
version="3.4.62",
|
33
33
|
packages=find_packages(include=["openstef", "openstef.*"]),
|
34
34
|
description="Open short term energy forecaster",
|
35
35
|
long_description=read_long_description_from_readme(),
|
@@ -1,135 +0,0 @@
|
|
1
|
-
# SPDX-FileCopyrightText: 2017-2023 Contributors to the OpenSTEF project <korte.termijn.prognoses@alliander.com> # noqa E501>
|
2
|
-
#
|
3
|
-
# SPDX-License-Identifier: MPL-2.0
|
4
|
-
"""Specifies the prediction job dataclass."""
|
5
|
-
from typing import Optional, Union
|
6
|
-
|
7
|
-
from pydantic.v1 import BaseModel
|
8
|
-
|
9
|
-
from openstef.data_classes.data_prep import DataPrepDataClass
|
10
|
-
from openstef.data_classes.model_specifications import ModelSpecificationDataClass
|
11
|
-
from openstef.data_classes.split_function import SplitFuncDataClass
|
12
|
-
from openstef.enums import PipelineType, BiddingZone, AggregateFunction
|
13
|
-
|
14
|
-
|
15
|
-
class PredictionJobDataClass(BaseModel):
|
16
|
-
"""Holds all information about the specific forecast that has to be made."""
|
17
|
-
|
18
|
-
id: Union[int, str]
|
19
|
-
"""The predictions job id (often abreviated as pid)."""
|
20
|
-
model: str
|
21
|
-
"""The model type that should be used.
|
22
|
-
|
23
|
-
Options are:
|
24
|
-
- ``"xgb"``
|
25
|
-
- ``"xgb_quantile"``
|
26
|
-
- ``"lgb"``
|
27
|
-
- ``"linear"``
|
28
|
-
- ``"linear_quantile"``
|
29
|
-
- ``"gblinear_quantile"``
|
30
|
-
- ``"xgb_multioutput_quantile"``
|
31
|
-
- ``"flatliner"``
|
32
|
-
|
33
|
-
If unsure what to pick, choose ``"xgb"``.
|
34
|
-
|
35
|
-
"""
|
36
|
-
model_kwargs: Optional[dict]
|
37
|
-
"""The model parameters that should be used."""
|
38
|
-
forecast_type: str
|
39
|
-
"""The type of forecasts that should be made.
|
40
|
-
|
41
|
-
Options are:
|
42
|
-
- ``"demand"``
|
43
|
-
- ``"wind"``
|
44
|
-
- ``"basecase"``
|
45
|
-
|
46
|
-
If unsure what to pick, choose ``"demand"``.
|
47
|
-
|
48
|
-
"""
|
49
|
-
horizon_minutes: Optional[int] = 2880
|
50
|
-
"""The horizon of the desired forecast in minutes used in tasks. Defaults to 2880 minutes (i.e. 2 days)."""
|
51
|
-
resolution_minutes: int
|
52
|
-
"""The resolution of the desired forecast in minutes."""
|
53
|
-
lat: Optional[float] = 52.132633
|
54
|
-
"""Latitude of the forecasted location in degrees. Used for fetching weather data in tasks, calculating derrived features and component splitting."""
|
55
|
-
lon: Optional[float] = 5.291266
|
56
|
-
"""Longitude of the forecasted location in degrees. Used for fetching weather data in tasks, calculating derrived features and component splitting."""
|
57
|
-
name: str
|
58
|
-
"""Bidding zone is used to determine the electricity price. It is also used to determine the holidays that should be used. Currently only ENTSO-E bidding zones are supported."""
|
59
|
-
electricity_bidding_zone: Optional[BiddingZone] = BiddingZone.NL
|
60
|
-
"""Name of the forecast, e.g. the location name."""
|
61
|
-
train_components: Optional[bool]
|
62
|
-
"""Whether splitting the forecasts in wind, solar, rest is desired."""
|
63
|
-
description: Optional[str]
|
64
|
-
"""Optional description of the prediction job for human reference."""
|
65
|
-
quantiles: Optional[list[float]]
|
66
|
-
"""Quantiles that have to be forecasted."""
|
67
|
-
train_split_func: Optional[SplitFuncDataClass]
|
68
|
-
"""Optional custom splitting function for operational procces."""
|
69
|
-
backtest_split_func: Optional[SplitFuncDataClass]
|
70
|
-
"""Optional custom splitting function for backtesting."""
|
71
|
-
train_horizons_minutes: Optional[list[int]]
|
72
|
-
"""List of horizons that should be taken into account during training."""
|
73
|
-
default_modelspecs: Optional[ModelSpecificationDataClass]
|
74
|
-
"""Default model specifications"""
|
75
|
-
save_train_forecasts: bool = False
|
76
|
-
"""Indicate wether the forecasts produced during the training process should be saved."""
|
77
|
-
completeness_threshold: float = 0.5
|
78
|
-
"""Minimum fraction of data that should be available for making a regular forecast."""
|
79
|
-
minimal_table_length: int = 100
|
80
|
-
"""Minimum length (in rows) of the forecast input for making a regular forecast."""
|
81
|
-
flatliner_threshold_minutes: int = 1440
|
82
|
-
"""Number of minutes that the load has to be constant to detect a flatliner. """
|
83
|
-
data_balancing_ratio: Optional[float] = None
|
84
|
-
"""If data balancing is enabled, the data will be balanced with data from 1 year
|
85
|
-
ago in the future."""
|
86
|
-
rolling_aggregate_features: Optional[list[AggregateFunction]] = None
|
87
|
-
"""If not None, rolling aggregate(s) of load will be used as features in the model."""
|
88
|
-
depends_on: Optional[list[Union[int, str]]]
|
89
|
-
"""Link to another prediction job on which this prediction job might depend."""
|
90
|
-
sid: Optional[str]
|
91
|
-
"""Only required for create_solar_forecast task"""
|
92
|
-
turbine_type: Optional[str]
|
93
|
-
"""Only required for create_wind_forecast task"""
|
94
|
-
n_turbines: Optional[float]
|
95
|
-
"""Only required for create_wind_forecast task"""
|
96
|
-
hub_height: Optional[float]
|
97
|
-
"""Only required for create_wind_forecast task"""
|
98
|
-
pipelines_to_run: list[PipelineType] = [
|
99
|
-
PipelineType.TRAIN,
|
100
|
-
PipelineType.HYPER_PARMATERS,
|
101
|
-
PipelineType.FORECAST,
|
102
|
-
]
|
103
|
-
"""The pipelines to run for this pj"""
|
104
|
-
alternative_forecast_model_pid: Optional[Union[int, str]]
|
105
|
-
"""The pid that references another prediction job from which the model should be used for making forecasts."""
|
106
|
-
data_prep_class: Optional[DataPrepDataClass]
|
107
|
-
"""The import string for the custom data prep class"""
|
108
|
-
|
109
|
-
class Config:
|
110
|
-
"""Pydantic model configuration.
|
111
|
-
|
112
|
-
This following configuration is needed to prevent ids in "depends_on" to be converted from int to str when we
|
113
|
-
use integer ids.
|
114
|
-
|
115
|
-
"""
|
116
|
-
|
117
|
-
smart_union = True
|
118
|
-
|
119
|
-
def __getitem__(self, item: str) -> any:
|
120
|
-
"""Allows us to use subscription to get the items from the object."""
|
121
|
-
return getattr(self, item)
|
122
|
-
|
123
|
-
def __setitem__(self, key: str, value: any) -> None:
|
124
|
-
"""Allows us to use subscription to set the items in the object."""
|
125
|
-
if hasattr(self, key):
|
126
|
-
self.__dict__[key] = value
|
127
|
-
else:
|
128
|
-
raise AttributeError(f"{key} not an attribute of prediction job.")
|
129
|
-
|
130
|
-
def get(self, key: str, default: any = None) -> any:
|
131
|
-
"""Allows to use the get functions similar to a python dict."""
|
132
|
-
if hasattr(self, key):
|
133
|
-
return getattr(self, key)
|
134
|
-
else:
|
135
|
-
return default
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{openstef-3.4.60 → openstef-3.4.62}/openstef/feature_engineering/bidding_zone_to_country_mapping.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{openstef-3.4.60 → openstef-3.4.62}/openstef/feature_engineering/missing_values_transformer.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|