oracle-ads 2.11.7__py3-none-any.whl → 2.11.8__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.
- ads/aqua/__init__.py +24 -14
- ads/aqua/base.py +0 -2
- ads/aqua/cli.py +50 -2
- ads/aqua/decorator.py +8 -0
- ads/aqua/deployment.py +37 -34
- ads/aqua/evaluation.py +106 -49
- ads/aqua/extension/base_handler.py +18 -10
- ads/aqua/extension/common_handler.py +21 -2
- ads/aqua/extension/deployment_handler.py +1 -4
- ads/aqua/extension/evaluation_handler.py +1 -2
- ads/aqua/extension/finetune_handler.py +0 -1
- ads/aqua/extension/ui_handler.py +1 -12
- ads/aqua/extension/utils.py +4 -4
- ads/aqua/finetune.py +24 -11
- ads/aqua/model.py +2 -4
- ads/aqua/utils.py +39 -23
- ads/cli.py +19 -1
- ads/common/serializer.py +5 -4
- ads/common/utils.py +6 -2
- ads/config.py +1 -0
- ads/llm/serializers/runnable_parallel.py +7 -1
- ads/opctl/operator/lowcode/anomaly/README.md +1 -1
- ads/opctl/operator/lowcode/anomaly/environment.yaml +1 -1
- ads/opctl/operator/lowcode/anomaly/model/automlx.py +15 -10
- ads/opctl/operator/lowcode/anomaly/model/autots.py +9 -10
- ads/opctl/operator/lowcode/anomaly/model/base_model.py +34 -37
- ads/opctl/operator/lowcode/anomaly/model/tods.py +4 -4
- ads/opctl/operator/lowcode/anomaly/schema.yaml +1 -1
- ads/opctl/operator/lowcode/forecast/README.md +1 -1
- ads/opctl/operator/lowcode/forecast/environment.yaml +4 -4
- ads/opctl/operator/lowcode/forecast/model/arima.py +19 -21
- ads/opctl/operator/lowcode/forecast/model/automlx.py +36 -42
- ads/opctl/operator/lowcode/forecast/model/autots.py +41 -25
- ads/opctl/operator/lowcode/forecast/model/base_model.py +93 -107
- ads/opctl/operator/lowcode/forecast/model/neuralprophet.py +51 -45
- ads/opctl/operator/lowcode/forecast/model/prophet.py +32 -27
- ads/opctl/operator/lowcode/forecast/schema.yaml +2 -2
- ads/opctl/operator/lowcode/forecast/utils.py +4 -4
- ads/opctl/operator/lowcode/pii/README.md +1 -1
- ads/opctl/operator/lowcode/pii/environment.yaml +1 -1
- ads/opctl/operator/lowcode/pii/model/report.py +71 -70
- {oracle_ads-2.11.7.dist-info → oracle_ads-2.11.8.dist-info}/METADATA +5 -5
- {oracle_ads-2.11.7.dist-info → oracle_ads-2.11.8.dist-info}/RECORD +46 -46
- {oracle_ads-2.11.7.dist-info → oracle_ads-2.11.8.dist-info}/LICENSE.txt +0 -0
- {oracle_ads-2.11.7.dist-info → oracle_ads-2.11.8.dist-info}/WHEEL +0 -0
- {oracle_ads-2.11.7.dist-info → oracle_ads-2.11.8.dist-info}/entry_points.txt +0 -0
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
2
|
# -*- coding: utf-8 -*--
|
3
3
|
|
4
|
-
# Copyright (c) 2023 Oracle and/or its affiliates.
|
4
|
+
# Copyright (c) 2023, 2024 Oracle and/or its affiliates.
|
5
5
|
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
6
6
|
|
7
7
|
import copy
|
@@ -82,13 +82,19 @@ class AutoTSOperatorModel(ForecastOperatorBaseModel):
|
|
82
82
|
drop_data_older_than_periods=self.spec.model_kwargs.get(
|
83
83
|
"drop_data_older_than_periods", None
|
84
84
|
),
|
85
|
-
model_list=self.spec.model_kwargs.get(
|
86
|
-
|
85
|
+
model_list=self.spec.model_kwargs.get(
|
86
|
+
"model_list", "fast_parallel"
|
87
|
+
),
|
88
|
+
transformer_list=self.spec.model_kwargs.get(
|
89
|
+
"transformer_list", "auto"
|
90
|
+
),
|
87
91
|
transformer_max_depth=self.spec.model_kwargs.get(
|
88
92
|
"transformer_max_depth", 6
|
89
93
|
),
|
90
94
|
models_mode=self.spec.model_kwargs.get("models_mode", "random"),
|
91
|
-
num_validations=self.spec.model_kwargs.get(
|
95
|
+
num_validations=self.spec.model_kwargs.get(
|
96
|
+
"num_validations", "auto"
|
97
|
+
),
|
92
98
|
models_to_validate=self.spec.model_kwargs.get(
|
93
99
|
"models_to_validate", AUTOTS_MODELS_TO_VALIDATE
|
94
100
|
),
|
@@ -138,14 +144,15 @@ class AutoTSOperatorModel(ForecastOperatorBaseModel):
|
|
138
144
|
values=additional_regressors,
|
139
145
|
)
|
140
146
|
future_reg = future_regressor[: -self.spec.horizon]
|
141
|
-
regr_fcst = future_regressor[-self.spec.horizon:]
|
147
|
+
regr_fcst = future_regressor[-self.spec.horizon :]
|
142
148
|
else:
|
143
149
|
future_reg = None
|
144
150
|
regr_fcst = None
|
145
151
|
|
146
152
|
for s_id in self.datasets.list_series_ids():
|
147
153
|
self.forecast_output.init_series_output(
|
148
|
-
series_id=s_id,
|
154
|
+
series_id=s_id,
|
155
|
+
data_at_series=self.datasets.get_data_at_series(s_id),
|
149
156
|
)
|
150
157
|
|
151
158
|
if self.loaded_models is None:
|
@@ -213,7 +220,7 @@ class AutoTSOperatorModel(ForecastOperatorBaseModel):
|
|
213
220
|
|
214
221
|
Returns:
|
215
222
|
tuple: A tuple containing the following elements:
|
216
|
-
- model_description (
|
223
|
+
- model_description (rc.Text): A text object containing the description of the AutoTS model.
|
217
224
|
- other_sections (list): A list of sections to be included in the report.
|
218
225
|
- forecast_col_name (str): The name of the forecast column.
|
219
226
|
- train_metrics (bool): A boolean indicating whether to include train metrics.
|
@@ -221,37 +228,48 @@ class AutoTSOperatorModel(ForecastOperatorBaseModel):
|
|
221
228
|
- ds_forecast_col (pd.Index): A pandas Index containing the forecast column values.
|
222
229
|
- ci_col_names (list): A list of column names for confidence intervals.
|
223
230
|
"""
|
224
|
-
import
|
231
|
+
import report_creator as rc
|
232
|
+
|
225
233
|
all_sections = []
|
226
234
|
if self.models:
|
227
235
|
# Section 1: Forecast Overview
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
lambda s_id: self.outputs.plot(self.models.df_wide_numeric, series=s_id),
|
236
|
+
|
237
|
+
sec_1_plots = _select_plot_list(
|
238
|
+
lambda s_id: self.outputs.plot(
|
239
|
+
self.models.df_wide_numeric, series=s_id
|
240
|
+
),
|
234
241
|
self.datasets.list_series_ids(),
|
235
242
|
)
|
243
|
+
section_1 = rc.Block(
|
244
|
+
rc.Heading("Forecast Overview", level=2),
|
245
|
+
rc.Text(
|
246
|
+
"These plots show your forecast in the context of historical data."
|
247
|
+
),
|
248
|
+
sec_1_plots,
|
249
|
+
)
|
236
250
|
|
237
251
|
# Section 2: AutoTS Model Parameters
|
238
|
-
sec2_text =
|
252
|
+
sec2_text = rc.Heading("AutoTS Model Parameters", level=2)
|
239
253
|
try:
|
240
|
-
sec2 =
|
241
|
-
|
242
|
-
language="yaml",
|
254
|
+
sec2 = rc.Yaml(
|
255
|
+
yaml.dump(list(self.models.best_model.T.to_dict().values())[0]),
|
243
256
|
)
|
244
257
|
|
245
258
|
except KeyError as ke:
|
246
|
-
logger.warn(
|
247
|
-
|
248
|
-
|
259
|
+
logger.warn(
|
260
|
+
f"Issue generating Model Parameters Table Section. Skipping"
|
261
|
+
)
|
262
|
+
sec2 = rc.Text("Error generating model parameters.")
|
263
|
+
|
264
|
+
section_2 = rc.Block(sec2_text, sec2)
|
265
|
+
|
266
|
+
all_sections = [sec_1_plots, section_2]
|
249
267
|
|
250
268
|
if self.spec.generate_explanations:
|
251
269
|
logger.warn(f"Explanations not yet supported for the AutoTS Module")
|
252
270
|
|
253
271
|
# Model Description
|
254
|
-
model_description =
|
272
|
+
model_description = rc.Text(
|
255
273
|
"AutoTS is a time series package for Python designed for rapidly deploying high-accuracy forecasts at scale. "
|
256
274
|
"In 2023, AutoTS has won in the M6 forecasting competition, "
|
257
275
|
"delivering the highest performance investment decisions across 12 months of stock market forecasting."
|
@@ -284,9 +302,7 @@ class AutoTSOperatorModel(ForecastOperatorBaseModel):
|
|
284
302
|
).T
|
285
303
|
df = pd.concat([mapes, scores])
|
286
304
|
except Exception as e:
|
287
|
-
logger.debug(
|
288
|
-
f"Failed to generate training metrics"
|
289
|
-
)
|
305
|
+
logger.debug(f"Failed to generate training metrics")
|
290
306
|
logger.debug(f"Received Error Statement: {e}")
|
291
307
|
|
292
308
|
return df
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
2
|
# -*- coding: utf-8 -*--
|
3
3
|
|
4
|
-
# Copyright (c) 2023 Oracle and/or its affiliates.
|
4
|
+
# Copyright (c) 2023, 2024 Oracle and/or its affiliates.
|
5
5
|
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
6
6
|
|
7
7
|
import json
|
@@ -88,7 +88,9 @@ class ForecastOperatorBaseModel(ABC):
|
|
88
88
|
self.formatted_local_explanation = None
|
89
89
|
|
90
90
|
self.forecast_col_name = "yhat"
|
91
|
-
self.perform_tuning = (self.spec.tuning != None) and (
|
91
|
+
self.perform_tuning = (self.spec.tuning != None) and (
|
92
|
+
self.spec.tuning.n_trials != None
|
93
|
+
)
|
92
94
|
|
93
95
|
def generate_report(self):
|
94
96
|
"""Generates the forecasting report."""
|
@@ -100,7 +102,7 @@ class ForecastOperatorBaseModel(ABC):
|
|
100
102
|
warnings.simplefilter(action="ignore", category=UserWarning)
|
101
103
|
warnings.simplefilter(action="ignore", category=RuntimeWarning)
|
102
104
|
warnings.simplefilter(action="ignore", category=ConvergenceWarning)
|
103
|
-
import
|
105
|
+
import report_creator as rc
|
104
106
|
|
105
107
|
# load models if given
|
106
108
|
if self.spec.previous_output_dir is not None:
|
@@ -140,69 +142,58 @@ class ForecastOperatorBaseModel(ABC):
|
|
140
142
|
other_sections,
|
141
143
|
) = self._generate_report()
|
142
144
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
model_description,
|
153
|
-
dp.Text(
|
154
|
-
"Based on your dataset, you could have also selected "
|
155
|
-
f"any of the models: `{'`, `'.join(SupportedModels.keys())}`."
|
145
|
+
header_section = rc.Block(
|
146
|
+
rc.Heading("Forecast Report", level=1),
|
147
|
+
rc.Text(
|
148
|
+
f"You selected the {self.spec.model} model.\n{model_description}\nBased on your dataset, you could have also selected any of the models: {SupportedModels.keys()}."
|
149
|
+
),
|
150
|
+
rc.Group(
|
151
|
+
rc.Metric(
|
152
|
+
heading="Analysis was completed in ",
|
153
|
+
value=human_time_friendly(elapsed_time),
|
156
154
|
),
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
),
|
162
|
-
dp.BigNumber(
|
163
|
-
heading="Starting time index",
|
164
|
-
value=self.datasets.get_earliest_timestamp().strftime(
|
165
|
-
"%B %d, %Y"
|
166
|
-
),
|
155
|
+
rc.Metric(
|
156
|
+
heading="Starting time index",
|
157
|
+
value=self.datasets.get_earliest_timestamp().strftime(
|
158
|
+
"%B %d, %Y"
|
167
159
|
),
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
),
|
174
|
-
dp.BigNumber(
|
175
|
-
heading="Num series",
|
176
|
-
value=len(self.datasets.list_series_ids()),
|
160
|
+
),
|
161
|
+
rc.Metric(
|
162
|
+
heading="Ending time index",
|
163
|
+
value=self.datasets.get_latest_timestamp().strftime(
|
164
|
+
"%B %d, %Y"
|
177
165
|
),
|
178
|
-
columns=4,
|
179
166
|
),
|
180
|
-
|
167
|
+
rc.Metric(
|
168
|
+
heading="Num series",
|
169
|
+
value=len(self.datasets.list_series_ids()),
|
170
|
+
),
|
171
|
+
),
|
181
172
|
)
|
182
173
|
|
183
|
-
|
184
|
-
|
185
|
-
df.head(
|
186
|
-
caption="Start",
|
174
|
+
first_5_rows_blocks = [
|
175
|
+
rc.DataTable(
|
176
|
+
df.head(5),
|
187
177
|
label=s_id,
|
178
|
+
index=True,
|
188
179
|
)
|
189
180
|
for s_id, df in self.full_data_dict.items()
|
190
181
|
]
|
191
182
|
|
192
|
-
|
193
|
-
|
194
|
-
df.tail(
|
195
|
-
caption="End",
|
183
|
+
last_5_rows_blocks = [
|
184
|
+
rc.DataTable(
|
185
|
+
df.tail(5),
|
196
186
|
label=s_id,
|
187
|
+
index=True,
|
197
188
|
)
|
198
189
|
for s_id, df in self.full_data_dict.items()
|
199
190
|
]
|
200
191
|
|
201
192
|
data_summary_blocks = [
|
202
|
-
|
193
|
+
rc.DataTable(
|
203
194
|
df.describe(),
|
204
|
-
caption="Summary Statistics",
|
205
195
|
label=s_id,
|
196
|
+
index=True,
|
206
197
|
)
|
207
198
|
for s_id, df in self.full_data_dict.items()
|
208
199
|
]
|
@@ -210,44 +201,33 @@ class ForecastOperatorBaseModel(ABC):
|
|
210
201
|
series_name = merged_category_column_name(
|
211
202
|
self.spec.target_category_columns
|
212
203
|
)
|
213
|
-
series_subtext =
|
214
|
-
first_10_title =
|
215
|
-
last_10_title =
|
216
|
-
summary_title =
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
first_10_title,
|
237
|
-
first_10_rows_blocks[0],
|
238
|
-
last_10_title,
|
239
|
-
last_10_rows_blocks[0],
|
240
|
-
summary_title,
|
241
|
-
data_summary_blocks[0],
|
242
|
-
dp.Text("----"),
|
243
|
-
]
|
244
|
-
)
|
204
|
+
# series_subtext = rc.Text(f"Indexed by {series_name}")
|
205
|
+
first_10_title = rc.Heading("First 5 Rows of Data", level=3)
|
206
|
+
last_10_title = rc.Heading("Last 5 Rows of Data", level=3)
|
207
|
+
summary_title = rc.Heading("Data Summary Statistics", level=3)
|
208
|
+
|
209
|
+
data_summary_sec = rc.Block(
|
210
|
+
rc.Block(
|
211
|
+
first_10_title,
|
212
|
+
# series_subtext,
|
213
|
+
rc.Select(blocks=first_5_rows_blocks),
|
214
|
+
),
|
215
|
+
rc.Block(
|
216
|
+
last_10_title,
|
217
|
+
# series_subtext,
|
218
|
+
rc.Select(blocks=last_5_rows_blocks),
|
219
|
+
),
|
220
|
+
rc.Block(
|
221
|
+
summary_title,
|
222
|
+
# series_subtext,
|
223
|
+
rc.Select(blocks=data_summary_blocks),
|
224
|
+
),
|
225
|
+
rc.Separator(),
|
226
|
+
)
|
245
227
|
|
246
|
-
summary =
|
247
|
-
|
248
|
-
|
249
|
-
data_summary_sec,
|
250
|
-
]
|
228
|
+
summary = rc.Block(
|
229
|
+
header_section,
|
230
|
+
data_summary_sec,
|
251
231
|
)
|
252
232
|
|
253
233
|
test_metrics_sections = []
|
@@ -255,41 +235,47 @@ class ForecastOperatorBaseModel(ABC):
|
|
255
235
|
self.test_eval_metrics is not None
|
256
236
|
and not self.test_eval_metrics.empty
|
257
237
|
):
|
258
|
-
sec7_text =
|
259
|
-
sec7 =
|
238
|
+
sec7_text = rc.Heading("Test Data Evaluation Metrics", level=2)
|
239
|
+
sec7 = rc.DataTable(self.test_eval_metrics, index=True)
|
260
240
|
test_metrics_sections = test_metrics_sections + [sec7_text, sec7]
|
261
241
|
|
262
242
|
if summary_metrics is not None and not summary_metrics.empty:
|
263
|
-
sec8_text =
|
264
|
-
sec8 =
|
243
|
+
sec8_text = rc.Heading("Test Data Summary Metrics", level=2)
|
244
|
+
sec8 = rc.DataTable(summary_metrics, index=True)
|
265
245
|
test_metrics_sections = test_metrics_sections + [sec8_text, sec8]
|
266
246
|
|
267
247
|
train_metrics_sections = []
|
268
248
|
if self.eval_metrics is not None and not self.eval_metrics.empty:
|
269
|
-
sec9_text =
|
270
|
-
sec9 =
|
249
|
+
sec9_text = rc.Heading("Training Data Metrics", level=2)
|
250
|
+
sec9 = rc.DataTable(self.eval_metrics, index=True)
|
271
251
|
train_metrics_sections = [sec9_text, sec9]
|
272
252
|
|
273
|
-
|
274
253
|
forecast_plots = []
|
275
254
|
if len(self.forecast_output.list_series_ids()) > 0:
|
276
|
-
forecast_text =
|
255
|
+
forecast_text = rc.Heading(
|
256
|
+
"Forecasted Data Overlaying Historical", level=2
|
257
|
+
)
|
277
258
|
forecast_sec = get_forecast_plots(
|
278
259
|
self.forecast_output,
|
279
260
|
horizon=self.spec.horizon,
|
280
261
|
test_data=test_data,
|
281
262
|
ci_interval_width=self.spec.confidence_interval_width,
|
282
263
|
)
|
283
|
-
if
|
284
|
-
|
264
|
+
if (
|
265
|
+
series_name is not None
|
266
|
+
and len(self.datasets.list_series_ids()) > 1
|
267
|
+
):
|
268
|
+
forecast_plots = [
|
269
|
+
forecast_text,
|
270
|
+
forecast_sec,
|
271
|
+
] # series_subtext,
|
285
272
|
else:
|
286
273
|
forecast_plots = [forecast_text, forecast_sec]
|
287
274
|
|
288
|
-
yaml_appendix_title =
|
289
|
-
yaml_appendix =
|
275
|
+
yaml_appendix_title = rc.Heading("Reference: YAML File", level=2)
|
276
|
+
yaml_appendix = rc.Yaml(self.config.to_dict())
|
290
277
|
report_sections = (
|
291
|
-
[
|
292
|
-
+ [summary]
|
278
|
+
[summary]
|
293
279
|
+ forecast_plots
|
294
280
|
+ other_sections
|
295
281
|
+ test_metrics_sections
|
@@ -421,7 +407,7 @@ class ForecastOperatorBaseModel(ABC):
|
|
421
407
|
test_metrics_df: pd.DataFrame,
|
422
408
|
):
|
423
409
|
"""Saves resulting reports to the given folder."""
|
424
|
-
import
|
410
|
+
import report_creator as rc
|
425
411
|
|
426
412
|
unique_output_dir = find_output_dirname(self.spec.output_directory)
|
427
413
|
|
@@ -430,13 +416,13 @@ class ForecastOperatorBaseModel(ABC):
|
|
430
416
|
else:
|
431
417
|
storage_options = dict()
|
432
418
|
|
433
|
-
#
|
419
|
+
# report-creator html report
|
434
420
|
if self.spec.generate_report:
|
435
|
-
# datapane html report
|
436
421
|
with tempfile.TemporaryDirectory() as temp_dir:
|
437
422
|
report_local_path = os.path.join(temp_dir, "___report.html")
|
438
423
|
disable_print()
|
439
|
-
|
424
|
+
with rc.ReportCreator("My Report") as report:
|
425
|
+
report.save(rc.Block(*report_sections), report_local_path)
|
440
426
|
enable_print()
|
441
427
|
|
442
428
|
report_path = os.path.join(unique_output_dir, self.spec.report_filename)
|
@@ -655,11 +641,10 @@ class ForecastOperatorBaseModel(ABC):
|
|
655
641
|
include_horizon=False
|
656
642
|
).items():
|
657
643
|
if s_id in self.models:
|
658
|
-
|
659
644
|
explain_predict_fn = self.get_explain_predict_fn(series_id=s_id)
|
660
|
-
data_trimmed = data_i.tail(
|
661
|
-
|
662
|
-
)
|
645
|
+
data_trimmed = data_i.tail(
|
646
|
+
max(int(len(data_i) * ratio), 5)
|
647
|
+
).reset_index(drop=True)
|
663
648
|
data_trimmed[datetime_col_name] = data_trimmed[datetime_col_name].apply(
|
664
649
|
lambda x: x.timestamp()
|
665
650
|
)
|
@@ -667,7 +652,8 @@ class ForecastOperatorBaseModel(ABC):
|
|
667
652
|
# Explainer fails when boolean columns are passed
|
668
653
|
|
669
654
|
_, data_trimmed_encoded = _label_encode_dataframe(
|
670
|
-
data_trimmed,
|
655
|
+
data_trimmed,
|
656
|
+
no_encode={datetime_col_name, self.original_target_column},
|
671
657
|
)
|
672
658
|
|
673
659
|
kernel_explnr = PermutationExplainer(
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
2
|
# -*- coding: utf-8 -*--
|
3
3
|
|
4
|
-
# Copyright (c) 2023 Oracle and/or its affiliates.
|
4
|
+
# Copyright (c) 2023, 2024 Oracle and/or its affiliates.
|
5
5
|
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
6
6
|
|
7
7
|
import numpy as np
|
@@ -41,20 +41,20 @@ from .forecast_datasets import ForecastDatasets, ForecastOutput
|
|
41
41
|
import traceback
|
42
42
|
|
43
43
|
|
44
|
-
def _get_np_metrics_dict(selected_metric):
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
44
|
+
# def _get_np_metrics_dict(selected_metric):
|
45
|
+
# metric_translation = {
|
46
|
+
# "mape": MeanAbsolutePercentageError,
|
47
|
+
# "smape": SymmetricMeanAbsolutePercentageError,
|
48
|
+
# "mae": MeanAbsoluteError,
|
49
|
+
# "r2": R2Score,
|
50
|
+
# "rmse": MeanSquaredError,
|
51
|
+
# }
|
52
|
+
# if selected_metric not in metric_translation.keys():
|
53
|
+
# logger.warn(
|
54
|
+
# f"Could not find the metric: {selected_metric} in torchmetrics. Defaulting to MAE and RMSE"
|
55
|
+
# )
|
56
|
+
# return {"MAE": MeanAbsoluteError(), "RMSE": MeanSquaredError()}
|
57
|
+
# return {selected_metric: metric_translation[selected_metric]()}
|
58
58
|
|
59
59
|
|
60
60
|
@runtime_dependency(
|
@@ -70,7 +70,7 @@ def _fit_model(data, params, additional_regressors, select_metric):
|
|
70
70
|
disable_print()
|
71
71
|
|
72
72
|
m = NeuralProphet(**params)
|
73
|
-
m.metrics = _get_np_metrics_dict(select_metric)
|
73
|
+
# m.metrics = _get_np_metrics_dict(select_metric)
|
74
74
|
for add_reg in additional_regressors:
|
75
75
|
m = m.add_future_regressor(name=add_reg)
|
76
76
|
m.fit(df=data)
|
@@ -135,7 +135,8 @@ class NeuralProphetOperatorModel(ForecastOperatorBaseModel):
|
|
135
135
|
data=data_i,
|
136
136
|
params=model_kwargs,
|
137
137
|
additional_regressors=self.additional_regressors,
|
138
|
-
select_metric=
|
138
|
+
select_metric=None,
|
139
|
+
# select_metric=self.spec.metric,
|
139
140
|
)
|
140
141
|
|
141
142
|
logger.debug(
|
@@ -209,6 +210,7 @@ class NeuralProphetOperatorModel(ForecastOperatorBaseModel):
|
|
209
210
|
logger.debug("===========Done===========")
|
210
211
|
except Exception as e:
|
211
212
|
self.errors_dict[s_id] = {"model_name": self.spec.model, "error": str(e)}
|
213
|
+
raise e
|
212
214
|
|
213
215
|
def _build_model(self) -> pd.DataFrame:
|
214
216
|
full_data_dict = self.datasets.get_data_by_series()
|
@@ -309,44 +311,52 @@ class NeuralProphetOperatorModel(ForecastOperatorBaseModel):
|
|
309
311
|
return selected_params
|
310
312
|
|
311
313
|
def _generate_report(self):
|
312
|
-
import
|
314
|
+
import report_creator as rc
|
315
|
+
|
313
316
|
series_ids = self.models.keys()
|
314
317
|
all_sections = []
|
315
318
|
if len(series_ids) > 0:
|
316
319
|
try:
|
317
|
-
sec1_text = dp.Text(
|
318
|
-
"## Forecast Overview \nThese plots show your "
|
319
|
-
"forecast in the context of historical data."
|
320
|
-
)
|
321
320
|
sec1 = _select_plot_list(
|
322
321
|
lambda s_id: self.models[s_id].plot(self.outputs[s_id]),
|
323
322
|
series_ids=series_ids,
|
324
323
|
)
|
325
|
-
|
324
|
+
section_1 = rc.Block(
|
325
|
+
rc.Heading("Forecast Overview", level=2),
|
326
|
+
rc.Text(
|
327
|
+
"These plots show your forecast in the context of historical data."
|
328
|
+
),
|
329
|
+
sec1,
|
330
|
+
)
|
331
|
+
all_sections = all_sections + [section_1]
|
326
332
|
except Exception as e:
|
327
333
|
logger.debug(f"Failed to plot with exception: {e.args}")
|
328
334
|
|
329
335
|
try:
|
330
|
-
sec2_text = dp.Text(f"## Forecast Broken Down by Trend Component")
|
331
336
|
sec2 = _select_plot_list(
|
332
337
|
lambda s_id: self.models[s_id].plot_components(self.outputs[s_id]),
|
333
338
|
series_ids=series_ids,
|
334
339
|
)
|
335
|
-
|
340
|
+
section_2 = rc.Block(
|
341
|
+
rc.Heading("Forecast Broken Down by Trend Component", level=2), sec2
|
342
|
+
)
|
343
|
+
all_sections = all_sections + [section_2]
|
336
344
|
except Exception as e:
|
337
345
|
logger.debug(f"Failed to plot with exception: {e.args}")
|
338
346
|
|
339
347
|
try:
|
340
|
-
sec3_text = dp.Text(f"## Forecast Parameter Plots")
|
341
348
|
sec3 = _select_plot_list(
|
342
349
|
lambda s_id: self.models[s_id].plot_parameters(),
|
343
350
|
series_ids=series_ids,
|
344
351
|
)
|
345
|
-
|
352
|
+
section_3 = rc.Block(
|
353
|
+
rc.Heading("Forecast Parameter Plots", level=2), sec3
|
354
|
+
)
|
355
|
+
all_sections = all_sections + [section_3]
|
346
356
|
except Exception as e:
|
347
357
|
logger.debug(f"Failed to plot with exception: {e.args}")
|
348
358
|
|
349
|
-
sec5_text =
|
359
|
+
sec5_text = rc.Heading("Neural Prophet Model Parameters", level=2)
|
350
360
|
model_states = []
|
351
361
|
for i, (s_id, m) in enumerate(self.models.items()):
|
352
362
|
model_states.append(
|
@@ -357,7 +367,7 @@ class NeuralProphetOperatorModel(ForecastOperatorBaseModel):
|
|
357
367
|
)
|
358
368
|
)
|
359
369
|
all_model_states = pd.concat(model_states, axis=1)
|
360
|
-
sec5 =
|
370
|
+
sec5 = rc.DataTable(all_model_states, index=True)
|
361
371
|
|
362
372
|
all_sections = all_sections + [sec5_text, sec5]
|
363
373
|
|
@@ -366,35 +376,31 @@ class NeuralProphetOperatorModel(ForecastOperatorBaseModel):
|
|
366
376
|
# If the key is present, call the "explain_model" method
|
367
377
|
self.explain_model()
|
368
378
|
|
369
|
-
# Create a markdown text block for the global explanation section
|
370
|
-
global_explanation_text = dp.Text(
|
371
|
-
f"## Global Explanation of Models \n "
|
372
|
-
"The following tables provide the feature attribution for the global explainability."
|
373
|
-
)
|
374
|
-
|
375
379
|
# Create a markdown section for the global explainability
|
376
|
-
global_explanation_section =
|
377
|
-
"
|
378
|
-
|
380
|
+
global_explanation_section = rc.Block(
|
381
|
+
rc.Heading("Global Explainability", level=2),
|
382
|
+
rc.Text(
|
383
|
+
"The following tables provide the feature attribution for the global explainability."
|
384
|
+
),
|
385
|
+
rc.DataTable(self.formatted_global_explanation, index=True),
|
379
386
|
)
|
380
387
|
|
381
|
-
local_explanation_text = dp.Text(f"## Local Explanation of Models \n ")
|
382
388
|
blocks = [
|
383
|
-
|
389
|
+
rc.DataTable(
|
384
390
|
local_ex_df.drop("Series", axis=1),
|
385
391
|
label=s_id,
|
392
|
+
index=True,
|
386
393
|
)
|
387
394
|
for s_id, local_ex_df in self.local_explanation.items()
|
388
395
|
]
|
389
|
-
local_explanation_section = (
|
390
|
-
|
396
|
+
local_explanation_section = rc.Block(
|
397
|
+
rc.Heading("Local Explanation of Models", level=2),
|
398
|
+
rc.Select(blocks=blocks),
|
391
399
|
)
|
392
400
|
|
393
401
|
# Append the global explanation text and section to the "all_sections" list
|
394
402
|
all_sections = all_sections + [
|
395
|
-
global_explanation_text,
|
396
403
|
global_explanation_section,
|
397
|
-
local_explanation_text,
|
398
404
|
local_explanation_section,
|
399
405
|
]
|
400
406
|
except Exception as e:
|
@@ -402,7 +408,7 @@ class NeuralProphetOperatorModel(ForecastOperatorBaseModel):
|
|
402
408
|
logger.warn(f"Failed to generate Explanations with error: {e}.")
|
403
409
|
logger.debug(f"Full Traceback: {traceback.format_exc()}")
|
404
410
|
|
405
|
-
model_description =
|
411
|
+
model_description = rc.Text(
|
406
412
|
"NeuralProphet is an easy to learn framework for interpretable time "
|
407
413
|
"series forecasting. NeuralProphet is built on PyTorch and combines "
|
408
414
|
"Neural Network and traditional time-series algorithms, inspired by "
|