oracle-ads 2.11.6__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/catalog/model.py +3 -3
- ads/catalog/notebook.py +3 -3
- ads/catalog/project.py +2 -2
- ads/catalog/summary.py +2 -4
- ads/cli.py +21 -2
- ads/common/serializer.py +5 -4
- ads/common/utils.py +6 -2
- ads/config.py +1 -0
- ads/data_labeling/metadata.py +2 -2
- ads/dataset/dataset.py +3 -5
- ads/dataset/factory.py +2 -3
- ads/dataset/label_encoder.py +1 -1
- ads/dataset/sampled_dataset.py +3 -5
- ads/jobs/ads_job.py +26 -2
- ads/jobs/builders/infrastructure/dsc_job.py +20 -7
- ads/llm/serializers/runnable_parallel.py +7 -1
- ads/model/model_artifact_boilerplate/artifact_introspection_test/model_artifact_validate.py +1 -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/anomaly_dataset.py +8 -15
- ads/opctl/operator/lowcode/anomaly/model/automlx.py +16 -10
- ads/opctl/operator/lowcode/anomaly/model/autots.py +9 -10
- ads/opctl/operator/lowcode/anomaly/model/base_model.py +36 -39
- ads/opctl/operator/lowcode/anomaly/model/tods.py +4 -4
- ads/opctl/operator/lowcode/anomaly/operator_config.py +18 -1
- ads/opctl/operator/lowcode/anomaly/schema.yaml +16 -4
- ads/opctl/operator/lowcode/common/data.py +16 -2
- ads/opctl/operator/lowcode/common/transformations.py +48 -14
- ads/opctl/operator/lowcode/forecast/README.md +1 -1
- ads/opctl/operator/lowcode/forecast/environment.yaml +5 -4
- ads/opctl/operator/lowcode/forecast/model/arima.py +36 -29
- ads/opctl/operator/lowcode/forecast/model/automlx.py +91 -90
- ads/opctl/operator/lowcode/forecast/model/autots.py +200 -166
- ads/opctl/operator/lowcode/forecast/model/base_model.py +144 -140
- ads/opctl/operator/lowcode/forecast/model/neuralprophet.py +86 -80
- ads/opctl/operator/lowcode/forecast/model/prophet.py +68 -63
- ads/opctl/operator/lowcode/forecast/operator_config.py +18 -2
- ads/opctl/operator/lowcode/forecast/schema.yaml +20 -4
- ads/opctl/operator/lowcode/forecast/utils.py +8 -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
- ads/pipeline/ads_pipeline_step.py +11 -12
- {oracle_ads-2.11.6.dist-info → oracle_ads-2.11.8.dist-info}/METADATA +8 -7
- {oracle_ads-2.11.6.dist-info → oracle_ads-2.11.8.dist-info}/RECORD +64 -64
- {oracle_ads-2.11.6.dist-info → oracle_ads-2.11.8.dist-info}/LICENSE.txt +0 -0
- {oracle_ads-2.11.6.dist-info → oracle_ads-2.11.8.dist-info}/WHEEL +0 -0
- {oracle_ads-2.11.6.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
|
@@ -54,145 +54,161 @@ class AutoTSOperatorModel(ForecastOperatorBaseModel):
|
|
54
54
|
target_column=self.original_target_column,
|
55
55
|
dt_column=self.spec.datetime_column.name,
|
56
56
|
)
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
"
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
future_reg = future_regressor[: -self.spec.horizon]
|
140
|
-
regr_fcst = future_regressor[-self.spec.horizon :]
|
141
|
-
else:
|
142
|
-
future_reg = None
|
143
|
-
regr_fcst = None
|
144
|
-
|
145
|
-
if self.loaded_models is None:
|
146
|
-
model = model.fit(
|
147
|
-
df_train,
|
148
|
-
future_regressor=future_reg,
|
149
|
-
date_col=self.spec.datetime_column.name,
|
150
|
-
value_col=self.original_target_column,
|
151
|
-
id_col=ForecastOutputColumns.SERIES,
|
152
|
-
)
|
153
|
-
# Store the trained model and generate forecasts
|
154
|
-
self.models = copy.deepcopy(model)
|
155
|
-
else:
|
156
|
-
self.models = self.loaded_models
|
157
|
-
|
158
|
-
self.outputs = model.predict(future_regressor=regr_fcst)
|
159
|
-
logger.debug("===========Forecast Generated===========")
|
160
|
-
|
161
|
-
hist_df = model.back_forecast().forecast
|
162
|
-
|
163
|
-
params = vars(model).copy()
|
164
|
-
for param in [
|
165
|
-
"ens_copy",
|
166
|
-
"df_wide_numeric",
|
167
|
-
"future_regressor_train",
|
168
|
-
"initial_results",
|
169
|
-
"score_per_series",
|
170
|
-
"validation_results",
|
171
|
-
"validation_train_indexes",
|
172
|
-
"validation_test_indexes",
|
173
|
-
"validation_indexes",
|
174
|
-
"best_model",
|
175
|
-
]:
|
176
|
-
if param in params:
|
177
|
-
params.pop(param)
|
178
|
-
|
179
|
-
for s_id in self.datasets.list_series_ids():
|
180
|
-
self.forecast_output.init_series_output(
|
181
|
-
series_id=s_id, data_at_series=self.datasets.get_data_at_series(s_id)
|
182
|
-
)
|
183
|
-
|
184
|
-
self.forecast_output.populate_series_output(
|
185
|
-
series_id=s_id,
|
186
|
-
fit_val=hist_df[s_id].values,
|
187
|
-
forecast_val=self.outputs.forecast[s_id].values,
|
188
|
-
upper_bound=self.outputs.upper_forecast[s_id].values,
|
189
|
-
lower_bound=self.outputs.lower_forecast[s_id].values,
|
57
|
+
try:
|
58
|
+
model = self.loaded_models if self.loaded_models is not None else None
|
59
|
+
if model is None:
|
60
|
+
# Initialize the AutoTS model with specified parameters
|
61
|
+
model = AutoTS(
|
62
|
+
forecast_length=self.spec.horizon,
|
63
|
+
frequency=self.spec.model_kwargs.get(
|
64
|
+
"frequency", "infer"
|
65
|
+
), # TODO: Use datasets.get_datetime_frequency ?
|
66
|
+
prediction_interval=self.spec.confidence_interval_width,
|
67
|
+
max_generations=self.spec.model_kwargs.get(
|
68
|
+
"max_generations", AUTOTS_MAX_GENERATION
|
69
|
+
),
|
70
|
+
no_negatives=self.spec.model_kwargs.get("no_negatives", False),
|
71
|
+
constraint=self.spec.model_kwargs.get("constraint", None),
|
72
|
+
ensemble=self.spec.model_kwargs.get("ensemble", "auto"),
|
73
|
+
initial_template=self.spec.model_kwargs.get(
|
74
|
+
"initial_template", "General+Random"
|
75
|
+
),
|
76
|
+
random_seed=self.spec.model_kwargs.get("random_seed", 2022),
|
77
|
+
holiday_country=self.spec.model_kwargs.get("holiday_country", "US"),
|
78
|
+
subset=self.spec.model_kwargs.get("subset", None),
|
79
|
+
aggfunc=self.spec.model_kwargs.get("aggfunc", "first"),
|
80
|
+
na_tolerance=self.spec.model_kwargs.get("na_tolerance", 1),
|
81
|
+
drop_most_recent=self.spec.model_kwargs.get("drop_most_recent", 0),
|
82
|
+
drop_data_older_than_periods=self.spec.model_kwargs.get(
|
83
|
+
"drop_data_older_than_periods", None
|
84
|
+
),
|
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
|
+
),
|
91
|
+
transformer_max_depth=self.spec.model_kwargs.get(
|
92
|
+
"transformer_max_depth", 6
|
93
|
+
),
|
94
|
+
models_mode=self.spec.model_kwargs.get("models_mode", "random"),
|
95
|
+
num_validations=self.spec.model_kwargs.get(
|
96
|
+
"num_validations", "auto"
|
97
|
+
),
|
98
|
+
models_to_validate=self.spec.model_kwargs.get(
|
99
|
+
"models_to_validate", AUTOTS_MODELS_TO_VALIDATE
|
100
|
+
),
|
101
|
+
max_per_model_class=self.spec.model_kwargs.get(
|
102
|
+
"max_per_model_class", None
|
103
|
+
),
|
104
|
+
validation_method=self.spec.model_kwargs.get(
|
105
|
+
"validation_method", "backwards"
|
106
|
+
),
|
107
|
+
min_allowed_train_percent=self.spec.model_kwargs.get(
|
108
|
+
"min_allowed_train_percent", 0.5
|
109
|
+
),
|
110
|
+
remove_leading_zeroes=self.spec.model_kwargs.get(
|
111
|
+
"remove_leading_zeroes", False
|
112
|
+
),
|
113
|
+
prefill_na=self.spec.model_kwargs.get("prefill_na", None),
|
114
|
+
introduce_na=self.spec.model_kwargs.get("introduce_na", None),
|
115
|
+
preclean=self.spec.model_kwargs.get("preclean", None),
|
116
|
+
model_interrupt=self.spec.model_kwargs.get("model_interrupt", True),
|
117
|
+
generation_timeout=self.spec.model_kwargs.get(
|
118
|
+
"generation_timeout", None
|
119
|
+
),
|
120
|
+
current_model_file=self.spec.model_kwargs.get(
|
121
|
+
"current_model_file", None
|
122
|
+
),
|
123
|
+
verbose=-1 if logger.level > 40 else 1,
|
124
|
+
n_jobs=self.spec.model_kwargs.get("n_jobs", -1),
|
125
|
+
)
|
126
|
+
|
127
|
+
full_data_indexed = self.datasets.get_data_multi_indexed()
|
128
|
+
|
129
|
+
dates = full_data_indexed.index.get_level_values(0).unique().tolist()
|
130
|
+
train_idx = dates[: -self.spec.horizon]
|
131
|
+
|
132
|
+
df_train = full_data_indexed[
|
133
|
+
full_data_indexed.index.get_level_values(0).isin(train_idx)
|
134
|
+
][[self.original_target_column]].reset_index()
|
135
|
+
|
136
|
+
# Future regressors need to be in wide format - (num_unique_dates x (num_unique_series x num_unique_cols))
|
137
|
+
additional_regressors = list(
|
138
|
+
set(full_data_indexed.columns) - {self.original_target_column}
|
190
139
|
)
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
140
|
+
if len(additional_regressors) > 1:
|
141
|
+
future_regressor = full_data_indexed.reset_index().pivot(
|
142
|
+
index=self.spec.datetime_column.name,
|
143
|
+
columns=ForecastOutputColumns.SERIES,
|
144
|
+
values=additional_regressors,
|
145
|
+
)
|
146
|
+
future_reg = future_regressor[: -self.spec.horizon]
|
147
|
+
regr_fcst = future_regressor[-self.spec.horizon :]
|
148
|
+
else:
|
149
|
+
future_reg = None
|
150
|
+
regr_fcst = None
|
151
|
+
|
152
|
+
for s_id in self.datasets.list_series_ids():
|
153
|
+
self.forecast_output.init_series_output(
|
154
|
+
series_id=s_id,
|
155
|
+
data_at_series=self.datasets.get_data_at_series(s_id),
|
156
|
+
)
|
157
|
+
|
158
|
+
if self.loaded_models is None:
|
159
|
+
model = model.fit(
|
160
|
+
df_train,
|
161
|
+
future_regressor=future_reg,
|
162
|
+
date_col=self.spec.datetime_column.name,
|
163
|
+
value_col=self.original_target_column,
|
164
|
+
id_col=ForecastOutputColumns.SERIES,
|
165
|
+
)
|
166
|
+
# Store the trained model and generate forecasts
|
167
|
+
self.models = copy.deepcopy(model)
|
168
|
+
else:
|
169
|
+
self.models = self.loaded_models
|
170
|
+
|
171
|
+
self.outputs = model.predict(future_regressor=regr_fcst)
|
172
|
+
logger.debug("===========Forecast Generated===========")
|
173
|
+
|
174
|
+
hist_df = model.back_forecast().forecast
|
175
|
+
|
176
|
+
params = vars(model).copy()
|
177
|
+
for param in [
|
178
|
+
"ens_copy",
|
179
|
+
"df_wide_numeric",
|
180
|
+
"future_regressor_train",
|
181
|
+
"initial_results",
|
182
|
+
"score_per_series",
|
183
|
+
"validation_results",
|
184
|
+
"validation_train_indexes",
|
185
|
+
"validation_test_indexes",
|
186
|
+
"validation_indexes",
|
187
|
+
"best_model",
|
188
|
+
]:
|
189
|
+
if param in params:
|
190
|
+
params.pop(param)
|
191
|
+
|
192
|
+
for s_id in self.datasets.list_series_ids():
|
193
|
+
self.forecast_output.populate_series_output(
|
194
|
+
series_id=s_id,
|
195
|
+
fit_val=hist_df[s_id].values,
|
196
|
+
forecast_val=self.outputs.forecast[s_id].values,
|
197
|
+
upper_bound=self.outputs.upper_forecast[s_id].values,
|
198
|
+
lower_bound=self.outputs.lower_forecast[s_id].values,
|
199
|
+
)
|
200
|
+
|
201
|
+
self.model_parameters[s_id] = {
|
202
|
+
"framework": SupportedModels.AutoTS,
|
203
|
+
**params,
|
204
|
+
}
|
205
|
+
|
206
|
+
except Exception as e:
|
207
|
+
for s_id in self.datasets.list_series_ids():
|
208
|
+
self.errors_dict[s_id] = {
|
209
|
+
"model_name": self.spec.model,
|
210
|
+
"error": str(e),
|
211
|
+
}
|
196
212
|
|
197
213
|
logger.debug("===========Done===========")
|
198
214
|
|
@@ -204,7 +220,7 @@ class AutoTSOperatorModel(ForecastOperatorBaseModel):
|
|
204
220
|
|
205
221
|
Returns:
|
206
222
|
tuple: A tuple containing the following elements:
|
207
|
-
- model_description (
|
223
|
+
- model_description (rc.Text): A text object containing the description of the AutoTS model.
|
208
224
|
- other_sections (list): A list of sections to be included in the report.
|
209
225
|
- forecast_col_name (str): The name of the forecast column.
|
210
226
|
- train_metrics (bool): A boolean indicating whether to include train metrics.
|
@@ -212,36 +228,48 @@ class AutoTSOperatorModel(ForecastOperatorBaseModel):
|
|
212
228
|
- ds_forecast_col (pd.Index): A pandas Index containing the forecast column values.
|
213
229
|
- ci_col_names (list): A list of column names for confidence intervals.
|
214
230
|
"""
|
215
|
-
import
|
231
|
+
import report_creator as rc
|
216
232
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
"These plots show your forecast in the context of historical data."
|
221
|
-
)
|
222
|
-
sec_1 = _select_plot_list(
|
223
|
-
lambda s_id: self.outputs.plot(self.models.df_wide_numeric, series=s_id),
|
224
|
-
self.datasets.list_series_ids(),
|
225
|
-
)
|
233
|
+
all_sections = []
|
234
|
+
if self.models:
|
235
|
+
# Section 1: Forecast Overview
|
226
236
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
237
|
+
sec_1_plots = _select_plot_list(
|
238
|
+
lambda s_id: self.outputs.plot(
|
239
|
+
self.models.df_wide_numeric, series=s_id
|
240
|
+
),
|
241
|
+
self.datasets.list_series_ids(),
|
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,
|
233
249
|
)
|
234
250
|
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
251
|
+
# Section 2: AutoTS Model Parameters
|
252
|
+
sec2_text = rc.Heading("AutoTS Model Parameters", level=2)
|
253
|
+
try:
|
254
|
+
sec2 = rc.Yaml(
|
255
|
+
yaml.dump(list(self.models.best_model.T.to_dict().values())[0]),
|
256
|
+
)
|
257
|
+
|
258
|
+
except KeyError as ke:
|
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]
|
239
267
|
|
240
268
|
if self.spec.generate_explanations:
|
241
269
|
logger.warn(f"Explanations not yet supported for the AutoTS Module")
|
242
270
|
|
243
271
|
# Model Description
|
244
|
-
model_description =
|
272
|
+
model_description = rc.Text(
|
245
273
|
"AutoTS is a time series package for Python designed for rapidly deploying high-accuracy forecasts at scale. "
|
246
274
|
"In 2023, AutoTS has won in the M6 forecasting competition, "
|
247
275
|
"delivering the highest performance investment decisions across 12 months of stock market forecasting."
|
@@ -266,9 +294,15 @@ class AutoTSOperatorModel(ForecastOperatorBaseModel):
|
|
266
294
|
r2 -4.60E-06
|
267
295
|
Explained Variance 0.002177087
|
268
296
|
"""
|
269
|
-
|
270
|
-
|
271
|
-
self.models.
|
272
|
-
|
273
|
-
|
297
|
+
df = pd.DataFrame()
|
298
|
+
try:
|
299
|
+
mapes = pd.DataFrame(self.models.best_model_per_series_mape()).T
|
300
|
+
scores = pd.DataFrame(
|
301
|
+
self.models.best_model_per_series_score(), columns=["AutoTS Score"]
|
302
|
+
).T
|
303
|
+
df = pd.concat([mapes, scores])
|
304
|
+
except Exception as e:
|
305
|
+
logger.debug(f"Failed to generate training metrics")
|
306
|
+
logger.debug(f"Received Error Statement: {e}")
|
307
|
+
|
274
308
|
return df
|