oracle-ads 2.13.2__py3-none-any.whl → 2.13.2rc1__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/opctl/operator/lowcode/anomaly/model/base_model.py +3 -3
- ads/opctl/operator/lowcode/anomaly/model/randomcutforest.py +1 -1
- ads/opctl/operator/lowcode/anomaly/utils.py +1 -1
- ads/opctl/operator/lowcode/common/transformations.py +5 -1
- ads/opctl/operator/lowcode/common/utils.py +7 -2
- ads/opctl/operator/lowcode/forecast/model/arima.py +15 -10
- ads/opctl/operator/lowcode/forecast/model/automlx.py +31 -9
- ads/opctl/operator/lowcode/forecast/model/autots.py +7 -5
- ads/opctl/operator/lowcode/forecast/model/base_model.py +127 -101
- ads/opctl/operator/lowcode/forecast/model/forecast_datasets.py +14 -6
- ads/opctl/operator/lowcode/forecast/model/ml_forecast.py +2 -2
- ads/opctl/operator/lowcode/forecast/model/neuralprophet.py +46 -32
- ads/opctl/operator/lowcode/forecast/model/prophet.py +82 -29
- ads/opctl/operator/lowcode/forecast/model_evaluator.py +136 -54
- ads/opctl/operator/lowcode/forecast/operator_config.py +29 -3
- ads/opctl/operator/lowcode/forecast/whatifserve/deployment_manager.py +103 -58
- {oracle_ads-2.13.2.dist-info → oracle_ads-2.13.2rc1.dist-info}/METADATA +1 -1
- {oracle_ads-2.13.2.dist-info → oracle_ads-2.13.2rc1.dist-info}/RECORD +21 -21
- {oracle_ads-2.13.2.dist-info → oracle_ads-2.13.2rc1.dist-info}/WHEEL +0 -0
- {oracle_ads-2.13.2.dist-info → oracle_ads-2.13.2rc1.dist-info}/entry_points.txt +0 -0
- {oracle_ads-2.13.2.dist-info → oracle_ads-2.13.2rc1.dist-info}/licenses/LICENSE.txt +0 -0
@@ -23,14 +23,14 @@ from ..operator_config import ForecastOperatorConfig
|
|
23
23
|
|
24
24
|
|
25
25
|
class HistoricalData(AbstractData):
|
26
|
-
def __init__(self, spec, historical_data
|
26
|
+
def __init__(self, spec, historical_data=None):
|
27
27
|
super().__init__(spec=spec, name="historical_data", data=historical_data)
|
28
28
|
|
29
29
|
def _ingest_data(self, spec):
|
30
30
|
try:
|
31
31
|
self.freq = get_frequency_of_datetime(self.data.index.get_level_values(0))
|
32
32
|
except TypeError as e:
|
33
|
-
logger.
|
33
|
+
logger.warning(
|
34
34
|
f"Error determining frequency: {e.args}. Setting Frequency to None"
|
35
35
|
)
|
36
36
|
logger.debug(f"Full traceback: {e}")
|
@@ -106,7 +106,7 @@ class AdditionalData(AbstractData):
|
|
106
106
|
_spec = spec
|
107
107
|
self.additional_regressors = list(self.data.columns)
|
108
108
|
if not self.additional_regressors:
|
109
|
-
logger.
|
109
|
+
logger.warning(
|
110
110
|
f"No additional variables found in the additional_data. Only columns found: {self.data.columns}. Skipping for now."
|
111
111
|
)
|
112
112
|
# Check that datetime column matches historical datetime column
|
@@ -121,7 +121,13 @@ class TestData(AbstractData):
|
|
121
121
|
|
122
122
|
|
123
123
|
class ForecastDatasets:
|
124
|
-
def __init__(
|
124
|
+
def __init__(
|
125
|
+
self,
|
126
|
+
config: ForecastOperatorConfig,
|
127
|
+
historical_data=None,
|
128
|
+
additional_data=None,
|
129
|
+
test_data=None,
|
130
|
+
):
|
125
131
|
"""Instantiates the DataIO instance.
|
126
132
|
|
127
133
|
Properties
|
@@ -136,7 +142,9 @@ class ForecastDatasets:
|
|
136
142
|
self._target_col = config.spec.target_column
|
137
143
|
if historical_data is not None:
|
138
144
|
self.historical_data = HistoricalData(config.spec, historical_data)
|
139
|
-
self.additional_data = AdditionalData(
|
145
|
+
self.additional_data = AdditionalData(
|
146
|
+
config.spec, self.historical_data, additional_data
|
147
|
+
)
|
140
148
|
else:
|
141
149
|
self._load_data(config.spec)
|
142
150
|
self.test_data = TestData(config.spec, test_data)
|
@@ -147,7 +155,7 @@ class ForecastDatasets:
|
|
147
155
|
self.additional_data = AdditionalData(spec, self.historical_data)
|
148
156
|
|
149
157
|
if spec.generate_explanations and spec.additional_data is None:
|
150
|
-
logger.
|
158
|
+
logger.warning(
|
151
159
|
"Unable to generate explanations as there is no additional data passed in. Either set generate_explanations to False, or pass in additional data."
|
152
160
|
)
|
153
161
|
spec.generate_explanations = False
|
@@ -168,8 +168,8 @@ class MLForecastOperatorModel(ForecastOperatorBaseModel):
|
|
168
168
|
"error": str(e),
|
169
169
|
"error_trace": traceback.format_exc(),
|
170
170
|
}
|
171
|
-
logger.
|
172
|
-
logger.
|
171
|
+
logger.warning(f"Encountered Error: {e}. Skipping.")
|
172
|
+
logger.warning(traceback.format_exc())
|
173
173
|
raise e
|
174
174
|
|
175
175
|
def _build_model(self) -> pd.DataFrame:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
2
|
|
3
|
-
# Copyright (c) 2023,
|
3
|
+
# Copyright (c) 2023, 2025 Oracle and/or its affiliates.
|
4
4
|
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
5
5
|
|
6
6
|
import logging
|
@@ -40,7 +40,7 @@ from .forecast_datasets import ForecastDatasets, ForecastOutput
|
|
40
40
|
# "rmse": MeanSquaredError,
|
41
41
|
# }
|
42
42
|
# if selected_metric not in metric_translation.keys():
|
43
|
-
# logger.
|
43
|
+
# logger.warning(
|
44
44
|
# f"Could not find the metric: {selected_metric} in torchmetrics. Defaulting to MAE and RMSE"
|
45
45
|
# )
|
46
46
|
# return {"MAE": MeanAbsoluteError(), "RMSE": MeanSquaredError()}
|
@@ -149,28 +149,42 @@ class NeuralProphetOperatorModel(ForecastOperatorBaseModel):
|
|
149
149
|
logger.debug(f"-----------------Model {i}----------------------")
|
150
150
|
logger.debug(forecast.tail())
|
151
151
|
|
152
|
-
# TODO; could also extract trend and seasonality?
|
153
|
-
cols_to_read = filter(
|
154
|
-
lambda x: x.startswith("future_regressor"), forecast.columns
|
155
|
-
)
|
156
|
-
self.explanations_info[s_id] = forecast[cols_to_read]
|
157
|
-
self.explanations_info[s_id]["Date"] = forecast["ds"]
|
158
|
-
self.explanations_info[s_id] = self.explanations_info[s_id].set_index(
|
159
|
-
"Date"
|
160
|
-
)
|
161
|
-
|
162
152
|
self.outputs[s_id] = forecast
|
153
|
+
upper_bound_col_name = f"yhat1 {model_kwargs['quantiles'][1]*100}%"
|
154
|
+
lower_bound_col_name = f"yhat1 {model_kwargs['quantiles'][0]*100}%"
|
163
155
|
self.forecast_output.populate_series_output(
|
164
156
|
series_id=s_id,
|
165
157
|
fit_val=self.drop_horizon(forecast["yhat1"]).values,
|
166
158
|
forecast_val=self.get_horizon(forecast["yhat1"]).values,
|
167
|
-
upper_bound=self.get_horizon(
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
159
|
+
upper_bound=self.get_horizon(forecast[upper_bound_col_name]).values,
|
160
|
+
lower_bound=self.get_horizon(forecast[lower_bound_col_name]).values,
|
161
|
+
)
|
162
|
+
core_columns = set(forecast.columns) - set(
|
163
|
+
[
|
164
|
+
"y",
|
165
|
+
"yhat1",
|
166
|
+
upper_bound_col_name,
|
167
|
+
lower_bound_col_name,
|
168
|
+
"future_regressors_additive",
|
169
|
+
"future_regressors_multiplicative",
|
170
|
+
]
|
171
|
+
)
|
172
|
+
exog_variables = set(
|
173
|
+
filter(lambda x: x.startswith("future_regressor_"), list(core_columns))
|
173
174
|
)
|
175
|
+
combine_terms = list(core_columns - exog_variables - set(["ds"]))
|
176
|
+
temp_df = (
|
177
|
+
forecast[list(core_columns)]
|
178
|
+
.rename({"ds": "Date"}, axis=1)
|
179
|
+
.set_index("Date")
|
180
|
+
)
|
181
|
+
if combine_terms:
|
182
|
+
temp_df[self.spec.target_column] = temp_df[combine_terms].sum(axis=1)
|
183
|
+
temp_df = temp_df.drop(combine_terms, axis=1)
|
184
|
+
else:
|
185
|
+
temp_df[self.spec.target_column] = 0
|
186
|
+
# Todo: check for columns that were dropped, and set them to 0
|
187
|
+
self.explanations_info[s_id] = temp_df
|
174
188
|
|
175
189
|
self.trainers[s_id] = model.trainer
|
176
190
|
self.models[s_id] = {}
|
@@ -207,7 +221,7 @@ class NeuralProphetOperatorModel(ForecastOperatorBaseModel):
|
|
207
221
|
"error": str(e),
|
208
222
|
"error_trace": traceback.format_exc(),
|
209
223
|
}
|
210
|
-
logger.
|
224
|
+
logger.warning(traceback.format_exc())
|
211
225
|
raise e
|
212
226
|
|
213
227
|
def _build_model(self) -> pd.DataFrame:
|
@@ -215,7 +229,6 @@ class NeuralProphetOperatorModel(ForecastOperatorBaseModel):
|
|
215
229
|
self.models = {}
|
216
230
|
self.trainers = {}
|
217
231
|
self.outputs = {}
|
218
|
-
self.errors_dict = {}
|
219
232
|
self.explanations_info = {}
|
220
233
|
self.accepted_regressors = {}
|
221
234
|
self.additional_regressors = self.datasets.get_additional_data_column_names()
|
@@ -363,7 +376,9 @@ class NeuralProphetOperatorModel(ForecastOperatorBaseModel):
|
|
363
376
|
pd.Series(
|
364
377
|
m.state_dict(),
|
365
378
|
index=m.state_dict().keys(),
|
366
|
-
name=s_id
|
379
|
+
name=s_id
|
380
|
+
if self.target_cat_col
|
381
|
+
else self.original_target_column,
|
367
382
|
)
|
368
383
|
)
|
369
384
|
all_model_states = pd.concat(model_states, axis=1)
|
@@ -377,11 +392,15 @@ class NeuralProphetOperatorModel(ForecastOperatorBaseModel):
|
|
377
392
|
self.explain_model()
|
378
393
|
|
379
394
|
if not self.target_cat_col:
|
380
|
-
self.formatted_global_explanation =
|
381
|
-
|
382
|
-
|
395
|
+
self.formatted_global_explanation = (
|
396
|
+
self.formatted_global_explanation.rename(
|
397
|
+
{"Series 1": self.original_target_column},
|
398
|
+
axis=1,
|
399
|
+
)
|
400
|
+
)
|
401
|
+
self.formatted_local_explanation.drop(
|
402
|
+
"Series", axis=1, inplace=True
|
383
403
|
)
|
384
|
-
self.formatted_local_explanation.drop("Series", axis=1, inplace=True)
|
385
404
|
|
386
405
|
# Create a markdown section for the global explainability
|
387
406
|
global_explanation_section = rc.Block(
|
@@ -412,7 +431,7 @@ class NeuralProphetOperatorModel(ForecastOperatorBaseModel):
|
|
412
431
|
]
|
413
432
|
except Exception as e:
|
414
433
|
# Do not fail the whole run due to explanations failure
|
415
|
-
logger.
|
434
|
+
logger.warning(f"Failed to generate Explanations with error: {e}.")
|
416
435
|
logger.debug(f"Full Traceback: {traceback.format_exc()}")
|
417
436
|
|
418
437
|
model_description = rc.Text(
|
@@ -453,9 +472,7 @@ class NeuralProphetOperatorModel(ForecastOperatorBaseModel):
|
|
453
472
|
for s_id, expl_df in self.explanations_info.items():
|
454
473
|
expl_df = expl_df.rename(rename_cols, axis=1)
|
455
474
|
# Local Expl
|
456
|
-
self.local_explanation[s_id] = self.get_horizon(expl_df)
|
457
|
-
["future_regressors_additive"], axis=1
|
458
|
-
)
|
475
|
+
self.local_explanation[s_id] = self.get_horizon(expl_df)
|
459
476
|
self.local_explanation[s_id]["Series"] = s_id
|
460
477
|
self.local_explanation[s_id].index.rename(self.dt_column_name, inplace=True)
|
461
478
|
# Global Expl
|
@@ -463,9 +480,6 @@ class NeuralProphetOperatorModel(ForecastOperatorBaseModel):
|
|
463
480
|
g_expl.name = s_id
|
464
481
|
global_expl.append(g_expl)
|
465
482
|
self.global_explanation = pd.concat(global_expl, axis=1)
|
466
|
-
self.global_explanation = self.global_explanation.drop(
|
467
|
-
index=["future_regressors_additive"], axis=0
|
468
|
-
)
|
469
483
|
self.formatted_global_explanation = (
|
470
484
|
self.global_explanation / self.global_explanation.sum(axis=0) * 100
|
471
485
|
)
|
@@ -22,7 +22,6 @@ from ads.opctl.operator.lowcode.forecast.utils import (
|
|
22
22
|
from ..const import (
|
23
23
|
DEFAULT_TRIALS,
|
24
24
|
PROPHET_INTERNAL_DATE_COL,
|
25
|
-
ForecastOutputColumns,
|
26
25
|
SupportedModels,
|
27
26
|
)
|
28
27
|
from .base_model import ForecastOperatorBaseModel
|
@@ -44,12 +43,23 @@ def _fit_model(data, params, additional_regressors):
|
|
44
43
|
from prophet import Prophet
|
45
44
|
|
46
45
|
monthly_seasonality = params.pop("monthly_seasonality", False)
|
46
|
+
data_floor = params.pop("min", None)
|
47
|
+
data_cap = params.pop("max", None)
|
48
|
+
if data_cap or data_floor:
|
49
|
+
params["growth"] = "logistic"
|
47
50
|
model = Prophet(**params)
|
48
51
|
if monthly_seasonality:
|
49
52
|
model.add_seasonality(name="monthly", period=30.5, fourier_order=5)
|
50
53
|
params["monthly_seasonality"] = monthly_seasonality
|
51
54
|
for add_reg in additional_regressors:
|
52
55
|
model.add_regressor(add_reg)
|
56
|
+
if data_floor:
|
57
|
+
data["floor"] = float(data_floor)
|
58
|
+
params["floor"] = data_floor
|
59
|
+
if data_cap:
|
60
|
+
data["cap"] = float(data_cap)
|
61
|
+
params["cap"] = data_cap
|
62
|
+
|
53
63
|
model.fit(data)
|
54
64
|
return model
|
55
65
|
|
@@ -112,6 +122,41 @@ class ProphetOperatorModel(ForecastOperatorBaseModel):
|
|
112
122
|
upper_bound=self.get_horizon(forecast["yhat_upper"]).values,
|
113
123
|
lower_bound=self.get_horizon(forecast["yhat_lower"]).values,
|
114
124
|
)
|
125
|
+
# Get all features that make up the forecast. Exclude CI (upper/lower)
|
126
|
+
core_columns = forecast.columns[
|
127
|
+
~forecast.columns.str.endswith("_lower")
|
128
|
+
& ~forecast.columns.str.endswith("_upper")
|
129
|
+
]
|
130
|
+
core_columns = set(core_columns) - {
|
131
|
+
"additive_terms",
|
132
|
+
"extra_regressors_additive",
|
133
|
+
"multiplicative_terms",
|
134
|
+
"extra_regressors_multiplicative",
|
135
|
+
"cap",
|
136
|
+
"floor",
|
137
|
+
"yhat",
|
138
|
+
}
|
139
|
+
combine_terms = list(
|
140
|
+
core_columns.intersection(
|
141
|
+
{
|
142
|
+
"trend",
|
143
|
+
"daily",
|
144
|
+
"weekly",
|
145
|
+
"yearly",
|
146
|
+
"monthly",
|
147
|
+
"holidays",
|
148
|
+
"zeros",
|
149
|
+
}
|
150
|
+
)
|
151
|
+
)
|
152
|
+
|
153
|
+
temp_df = (
|
154
|
+
forecast[list(core_columns)]
|
155
|
+
.rename({"ds": "Date"}, axis=1)
|
156
|
+
.set_index("Date")
|
157
|
+
)
|
158
|
+
temp_df[self.spec.target_column] = temp_df[combine_terms].sum(axis=1)
|
159
|
+
self.explanations_info[series_id] = temp_df.drop(combine_terms, axis=1)
|
115
160
|
|
116
161
|
self.models[series_id] = {}
|
117
162
|
self.models[series_id]["model"] = model
|
@@ -133,13 +178,14 @@ class ProphetOperatorModel(ForecastOperatorBaseModel):
|
|
133
178
|
"error": str(e),
|
134
179
|
"error_trace": traceback.format_exc(),
|
135
180
|
}
|
136
|
-
logger.
|
137
|
-
logger.
|
181
|
+
logger.warning(f"Encountered Error: {e}. Skipping.")
|
182
|
+
logger.warning(traceback.format_exc())
|
138
183
|
|
139
184
|
def _build_model(self) -> pd.DataFrame:
|
140
185
|
full_data_dict = self.datasets.get_data_by_series()
|
141
186
|
self.models = {}
|
142
187
|
self.outputs = {}
|
188
|
+
self.explanations_info = {}
|
143
189
|
self.additional_regressors = self.datasets.get_additional_data_column_names()
|
144
190
|
model_kwargs = self.set_kwargs()
|
145
191
|
self.forecast_output = ForecastOutput(
|
@@ -149,9 +195,6 @@ class ProphetOperatorModel(ForecastOperatorBaseModel):
|
|
149
195
|
dt_column=self.spec.datetime_column.name,
|
150
196
|
)
|
151
197
|
|
152
|
-
# if os.environ["OCI__IS_SPARK"]:
|
153
|
-
# pass
|
154
|
-
# else:
|
155
198
|
Parallel(n_jobs=-1, require="sharedmem")(
|
156
199
|
delayed(ProphetOperatorModel._train_model)(
|
157
200
|
self, i, series_id, df, model_kwargs.copy()
|
@@ -222,7 +265,7 @@ class ProphetOperatorModel(ForecastOperatorBaseModel):
|
|
222
265
|
try:
|
223
266
|
return np.mean(df_p[self.spec.metric])
|
224
267
|
except KeyError:
|
225
|
-
logger.
|
268
|
+
logger.warning(
|
226
269
|
f"Could not find the metric {self.spec.metric} within "
|
227
270
|
f"the performance metrics: {df_p.columns}. Defaulting to `rmse`"
|
228
271
|
)
|
@@ -249,6 +292,25 @@ class ProphetOperatorModel(ForecastOperatorBaseModel):
|
|
249
292
|
model_kwargs_i = study.best_params
|
250
293
|
return model_kwargs_i
|
251
294
|
|
295
|
+
def explain_model(self):
|
296
|
+
self.local_explanation = {}
|
297
|
+
global_expl = []
|
298
|
+
|
299
|
+
for s_id, expl_df in self.explanations_info.items():
|
300
|
+
# Local Expl
|
301
|
+
self.local_explanation[s_id] = self.get_horizon(expl_df)
|
302
|
+
self.local_explanation[s_id]["Series"] = s_id
|
303
|
+
self.local_explanation[s_id].index.rename(self.dt_column_name, inplace=True)
|
304
|
+
# Global Expl
|
305
|
+
g_expl = self.drop_horizon(expl_df).mean()
|
306
|
+
g_expl.name = s_id
|
307
|
+
global_expl.append(g_expl)
|
308
|
+
self.global_explanation = pd.concat(global_expl, axis=1)
|
309
|
+
self.formatted_global_explanation = (
|
310
|
+
self.global_explanation / self.global_explanation.sum(axis=0) * 100
|
311
|
+
)
|
312
|
+
self.formatted_local_explanation = pd.concat(self.local_explanation.values())
|
313
|
+
|
252
314
|
def _generate_report(self):
|
253
315
|
import report_creator as rc
|
254
316
|
from prophet.plot import add_changepoints_to_plot
|
@@ -274,7 +336,9 @@ class ProphetOperatorModel(ForecastOperatorBaseModel):
|
|
274
336
|
)
|
275
337
|
|
276
338
|
sec2 = _select_plot_list(
|
277
|
-
lambda s_id: self.models[s_id]["model"].plot_components(
|
339
|
+
lambda s_id: self.models[s_id]["model"].plot_components(
|
340
|
+
self.outputs[s_id]
|
341
|
+
),
|
278
342
|
series_ids=series_ids,
|
279
343
|
target_category_column=self.target_cat_col,
|
280
344
|
)
|
@@ -283,11 +347,14 @@ class ProphetOperatorModel(ForecastOperatorBaseModel):
|
|
283
347
|
)
|
284
348
|
|
285
349
|
sec3_figs = {
|
286
|
-
s_id: self.models[s_id]["model"].plot(self.outputs[s_id])
|
350
|
+
s_id: self.models[s_id]["model"].plot(self.outputs[s_id])
|
351
|
+
for s_id in series_ids
|
287
352
|
}
|
288
353
|
for s_id in series_ids:
|
289
354
|
add_changepoints_to_plot(
|
290
|
-
sec3_figs[s_id].gca(),
|
355
|
+
sec3_figs[s_id].gca(),
|
356
|
+
self.models[s_id]["model"],
|
357
|
+
self.outputs[s_id],
|
291
358
|
)
|
292
359
|
sec3 = _select_plot_list(
|
293
360
|
lambda s_id: sec3_figs[s_id],
|
@@ -322,22 +389,6 @@ class ProphetOperatorModel(ForecastOperatorBaseModel):
|
|
322
389
|
# If the key is present, call the "explain_model" method
|
323
390
|
self.explain_model()
|
324
391
|
|
325
|
-
# Convert the global explanation data to a DataFrame
|
326
|
-
global_explanation_df = pd.DataFrame(self.global_explanation)
|
327
|
-
|
328
|
-
self.formatted_global_explanation = (
|
329
|
-
global_explanation_df / global_explanation_df.sum(axis=0) * 100
|
330
|
-
)
|
331
|
-
|
332
|
-
aggregate_local_explanations = pd.DataFrame()
|
333
|
-
for s_id, local_ex_df in self.local_explanation.items():
|
334
|
-
local_ex_df_copy = local_ex_df.copy()
|
335
|
-
local_ex_df_copy[ForecastOutputColumns.SERIES] = s_id
|
336
|
-
aggregate_local_explanations = pd.concat(
|
337
|
-
[aggregate_local_explanations, local_ex_df_copy], axis=0
|
338
|
-
)
|
339
|
-
self.formatted_local_explanation = aggregate_local_explanations
|
340
|
-
|
341
392
|
if not self.target_cat_col:
|
342
393
|
self.formatted_global_explanation = (
|
343
394
|
self.formatted_global_explanation.rename(
|
@@ -351,7 +402,7 @@ class ProphetOperatorModel(ForecastOperatorBaseModel):
|
|
351
402
|
|
352
403
|
# Create a markdown section for the global explainability
|
353
404
|
global_explanation_section = rc.Block(
|
354
|
-
rc.Heading("Global
|
405
|
+
rc.Heading("Global Explainability", level=2),
|
355
406
|
rc.Text(
|
356
407
|
"The following tables provide the feature attribution for the global explainability."
|
357
408
|
),
|
@@ -360,7 +411,7 @@ class ProphetOperatorModel(ForecastOperatorBaseModel):
|
|
360
411
|
|
361
412
|
blocks = [
|
362
413
|
rc.DataTable(
|
363
|
-
local_ex_df.
|
414
|
+
local_ex_df.drop("Series", axis=1),
|
364
415
|
label=s_id if self.target_cat_col else None,
|
365
416
|
index=True,
|
366
417
|
)
|
@@ -378,8 +429,10 @@ class ProphetOperatorModel(ForecastOperatorBaseModel):
|
|
378
429
|
]
|
379
430
|
except Exception as e:
|
380
431
|
# Do not fail the whole run due to explanations failure
|
381
|
-
logger.
|
432
|
+
logger.warning(f"Failed to generate Explanations with error: {e}.")
|
382
433
|
logger.debug(f"Full Traceback: {traceback.format_exc()}")
|
434
|
+
self.errors_dict["explainer_error"] = str(e)
|
435
|
+
self.errors_dict["explainer_error_error"] = traceback.format_exc()
|
383
436
|
|
384
437
|
model_description = rc.Text(
|
385
438
|
"""Prophet is a procedure for forecasting time series data based on an additive model where non-linear trends are fit with yearly, weekly, and daily seasonality, plus holiday effects. It works best with time series that have strong seasonal effects and several seasons of historical data. Prophet is robust to missing data and shifts in the trend, and typically handles outliers well."""
|