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
ads/cli.py
CHANGED
@@ -8,8 +8,8 @@ import traceback
|
|
8
8
|
import sys
|
9
9
|
|
10
10
|
import fire
|
11
|
+
from dataclasses import is_dataclass
|
11
12
|
from ads.common import logger
|
12
|
-
from ads.aqua.cli import AquaCommand
|
13
13
|
|
14
14
|
try:
|
15
15
|
import click
|
@@ -71,9 +71,28 @@ def _SeparateFlagArgs(args):
|
|
71
71
|
fire.core.parser.SeparateFlagArgs = _SeparateFlagArgs
|
72
72
|
|
73
73
|
|
74
|
+
def serialize(data):
|
75
|
+
"""Serialize dataclass objects or lists of dataclass objects.
|
76
|
+
Parameters:
|
77
|
+
data: A dataclass object or a list of dataclass objects.
|
78
|
+
Returns:
|
79
|
+
None
|
80
|
+
Prints:
|
81
|
+
The string representation of each dataclass object.
|
82
|
+
"""
|
83
|
+
if isinstance(data, list):
|
84
|
+
[print(str(item)) for item in data]
|
85
|
+
else:
|
86
|
+
print(str(data))
|
87
|
+
|
88
|
+
|
74
89
|
def cli():
|
75
90
|
if len(sys.argv) > 1 and sys.argv[1] == "aqua":
|
76
|
-
|
91
|
+
from ads.aqua.cli import AquaCommand
|
92
|
+
|
93
|
+
fire.Fire(
|
94
|
+
AquaCommand, command=sys.argv[2:], name="ads aqua", serialize=serialize
|
95
|
+
)
|
77
96
|
else:
|
78
97
|
click_cli()
|
79
98
|
|
ads/common/serializer.py
CHANGED
@@ -195,7 +195,10 @@ class Serializable(ABC):
|
|
195
195
|
`None` in case when `uri` provided.
|
196
196
|
"""
|
197
197
|
json_string = json.dumps(
|
198
|
-
self.to_dict(**kwargs),
|
198
|
+
self.to_dict(**kwargs),
|
199
|
+
cls=encoder,
|
200
|
+
default=default or self.serialize,
|
201
|
+
indent=4,
|
199
202
|
)
|
200
203
|
if uri:
|
201
204
|
self._write_to_file(s=json_string, uri=uri, **kwargs)
|
@@ -463,9 +466,7 @@ class DataClassSerializable(Serializable):
|
|
463
466
|
"These fields will be ignored."
|
464
467
|
)
|
465
468
|
|
466
|
-
obj = cls(
|
467
|
-
**{key: obj_dict.get(key) for key in allowed_fields if key in obj_dict}
|
468
|
-
)
|
469
|
+
obj = cls(**{key: obj_dict.get(key) for key in allowed_fields})
|
469
470
|
|
470
471
|
for key, value in obj_dict.items():
|
471
472
|
if (
|
ads/common/utils.py
CHANGED
@@ -102,6 +102,8 @@ DIMENSION = 2
|
|
102
102
|
# The number of worker processes to use in parallel for uploading individual parts of a multipart upload.
|
103
103
|
DEFAULT_PARALLEL_PROCESS_COUNT = 9
|
104
104
|
|
105
|
+
LOG_LEVELS = ["NOTSET", "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
106
|
+
|
105
107
|
|
106
108
|
class FileOverwriteError(Exception): # pragma: no cover
|
107
109
|
pass
|
@@ -1751,7 +1753,7 @@ def get_log_links(
|
|
1751
1753
|
) -> str:
|
1752
1754
|
"""
|
1753
1755
|
This method returns the web console link for the given log ids.
|
1754
|
-
|
1756
|
+
|
1755
1757
|
Parameters
|
1756
1758
|
----------
|
1757
1759
|
log_group_id: str, required
|
@@ -1776,7 +1778,9 @@ def get_log_links(
|
|
1776
1778
|
query_range = f'''search "{compartment_id}/{log_group_id}/{log_id}"'''
|
1777
1779
|
query_source = f"source='{source_id}'"
|
1778
1780
|
sort_condition = f"sort by datetime desc®ions={region}"
|
1779
|
-
search_query =
|
1781
|
+
search_query = (
|
1782
|
+
f"search?searchQuery={query_range} | {query_source} | {sort_condition}"
|
1783
|
+
)
|
1780
1784
|
console_link_url = f"https://cloud.oracle.com/logging/{search_query}"
|
1781
1785
|
elif log_group_id:
|
1782
1786
|
console_link_url = f"https://cloud.oracle.com/logging/log-groups/{log_group_id}?region={region}"
|
ads/config.py
CHANGED
@@ -79,6 +79,7 @@ AQUA_TELEMETRY_BUCKET = os.environ.get(
|
|
79
79
|
"AQUA_TELEMETRY_BUCKET", "service-managed-models"
|
80
80
|
)
|
81
81
|
AQUA_TELEMETRY_BUCKET_NS = os.environ.get("AQUA_TELEMETRY_BUCKET_NS", CONDA_BUCKET_NS)
|
82
|
+
|
82
83
|
DEBUG_TELEMETRY = os.environ.get("DEBUG_TELEMETRY", None)
|
83
84
|
AQUA_SERVICE_NAME = "aqua"
|
84
85
|
DATA_SCIENCE_SERVICE_NAME = "data-science"
|
ads/data_labeling/metadata.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
2
|
# -*- coding: utf-8; -*-
|
3
3
|
|
4
|
-
# Copyright (c) 2021,
|
4
|
+
# Copyright (c) 2021, 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
|
from dataclasses import asdict, dataclass, field
|
@@ -75,7 +75,7 @@ class Metadata(DataClassSerializable):
|
|
75
75
|
def _repr_html_(self):
|
76
76
|
"""Shows metadata in dataframe format."""
|
77
77
|
return (
|
78
|
-
self.to_dataframe().style.set_properties(**{"margin-left": "0px"}).
|
78
|
+
self.to_dataframe().style.set_properties(**{"margin-left": "0px"}).to_html()
|
79
79
|
)
|
80
80
|
|
81
81
|
@classmethod
|
ads/dataset/dataset.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
2
|
# -*- coding: utf-8 -*--
|
3
3
|
|
4
|
-
# Copyright (c) 2020,
|
4
|
+
# Copyright (c) 2020, 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
|
from __future__ import print_function, absolute_import, division
|
@@ -85,7 +85,6 @@ class ADSDataset(PandasDataset):
|
|
85
85
|
interactive=False,
|
86
86
|
**kwargs,
|
87
87
|
):
|
88
|
-
|
89
88
|
#
|
90
89
|
# to keep performance high and linear no matter the size of the distributed dataset we
|
91
90
|
# create a pandas df that's used internally because this has a fixed upper size.
|
@@ -204,7 +203,7 @@ class ADSDataset(PandasDataset):
|
|
204
203
|
.style.set_table_styles(utils.get_dataframe_styles())
|
205
204
|
.set_table_attributes("class=table")
|
206
205
|
.hide_index()
|
207
|
-
.
|
206
|
+
.to_html()
|
208
207
|
)
|
209
208
|
)
|
210
209
|
)
|
@@ -263,7 +262,7 @@ class ADSDataset(PandasDataset):
|
|
263
262
|
self.style.set_table_styles(utils.get_dataframe_styles())
|
264
263
|
.set_table_attributes("class=table")
|
265
264
|
.hide_index()
|
266
|
-
.
|
265
|
+
.to_html()
|
267
266
|
)
|
268
267
|
)
|
269
268
|
)
|
@@ -1265,7 +1264,6 @@ class ADSDataset(PandasDataset):
|
|
1265
1264
|
n=None,
|
1266
1265
|
**init_kwargs,
|
1267
1266
|
):
|
1268
|
-
|
1269
1267
|
prev_doc_mode = utils.is_documentation_mode()
|
1270
1268
|
|
1271
1269
|
set_documentation_mode(False)
|
ads/dataset/factory.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
2
|
# -*- coding: utf-8; -*-
|
3
3
|
|
4
|
-
# Copyright (c) 2020,
|
4
|
+
# Copyright (c) 2020, 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
|
from __future__ import print_function, absolute_import
|
@@ -367,7 +367,7 @@ class DatasetFactory:
|
|
367
367
|
HTML(
|
368
368
|
list_df.style.set_table_attributes("class=table")
|
369
369
|
.hide_index()
|
370
|
-
.
|
370
|
+
.to_html()
|
371
371
|
)
|
372
372
|
)
|
373
373
|
return list_df
|
@@ -884,7 +884,6 @@ class CustomFormatReaders:
|
|
884
884
|
import xml.etree.cElementTree as et
|
885
885
|
|
886
886
|
def get_children(df, node, parent, i):
|
887
|
-
|
888
887
|
for name in node.attrib.keys():
|
889
888
|
df.at[i, parent + name] = node.attrib[name]
|
890
889
|
for child in list(node):
|
ads/dataset/label_encoder.py
CHANGED
@@ -52,7 +52,7 @@ class DataFrameLabelEncoder(TransformerMixin):
|
|
52
52
|
|
53
53
|
"""
|
54
54
|
for column in X.columns:
|
55
|
-
if X[column].dtype.name in ["object", "category"]:
|
55
|
+
if X[column].dtype.name in ["object", "category", "bool"]:
|
56
56
|
X[column] = X[column].astype(str)
|
57
57
|
self.label_encoders[column] = LabelEncoder()
|
58
58
|
self.label_encoders[column].fit(X[column])
|
ads/dataset/sampled_dataset.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
2
|
# -*- coding: utf-8; -*-
|
3
3
|
|
4
|
-
# Copyright (c) 2020,
|
4
|
+
# Copyright (c) 2020, 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 matplotlib
|
@@ -49,6 +49,7 @@ from ads.common.decorator.runtime_dependency import (
|
|
49
49
|
|
50
50
|
NATURAL_EARTH_DATASET = "naturalearth_lowres"
|
51
51
|
|
52
|
+
|
52
53
|
class PandasDataset(object):
|
53
54
|
"""
|
54
55
|
This class provides APIs that can work on a sampled dataset.
|
@@ -107,7 +108,6 @@ class PandasDataset(object):
|
|
107
108
|
self.sampled_df = self.sampled_df.reset_index(drop=True)
|
108
109
|
|
109
110
|
def _find_feature_subset(self, df, target_name, include_n_features=32):
|
110
|
-
|
111
111
|
if len(df.columns) <= include_n_features:
|
112
112
|
return self.sampled_df
|
113
113
|
else:
|
@@ -212,7 +212,6 @@ class PandasDataset(object):
|
|
212
212
|
def _generate_features_html(
|
213
213
|
self, is_wide_dataset, n_features, df_stats, visualizations_follow
|
214
214
|
):
|
215
|
-
|
216
215
|
html = utils.get_bootstrap_styles()
|
217
216
|
|
218
217
|
if is_wide_dataset:
|
@@ -233,7 +232,7 @@ class PandasDataset(object):
|
|
233
232
|
if ("float" in str(type(x))) or ("int" in str(type(x)))
|
234
233
|
else x
|
235
234
|
)
|
236
|
-
.
|
235
|
+
.to_html()
|
237
236
|
)
|
238
237
|
|
239
238
|
if visualizations_follow:
|
@@ -244,7 +243,6 @@ class PandasDataset(object):
|
|
244
243
|
def _generate_warnings_html(
|
245
244
|
self, is_wide_dataset, n_rows, n_features, df_stats, out, accordion
|
246
245
|
):
|
247
|
-
|
248
246
|
#
|
249
247
|
# create the "Warnings" accordion section:
|
250
248
|
# - show high cardinal categoricals
|
ads/jobs/ads_job.py
CHANGED
@@ -10,6 +10,7 @@ from urllib.parse import urlparse
|
|
10
10
|
|
11
11
|
import fsspec
|
12
12
|
import oci
|
13
|
+
import yaml
|
13
14
|
from ads.common.auth import default_signer
|
14
15
|
from ads.common.decorator.utils import class_or_instance_method
|
15
16
|
from ads.jobs.builders.base import Builder
|
@@ -263,6 +264,9 @@ class Job(Builder):
|
|
263
264
|
Job runtime, by default None.
|
264
265
|
|
265
266
|
"""
|
267
|
+
# Saves a copy of the auth object from the class to the instance.
|
268
|
+
# Future changes to the class level Job.auth will not affect the auth of existing instances.
|
269
|
+
self.auth = self.auth.copy()
|
266
270
|
for key in ["config", "signer", "client_kwargs"]:
|
267
271
|
if kwargs.get(key):
|
268
272
|
self.auth[key] = kwargs.pop(key)
|
@@ -545,6 +549,26 @@ class Job(Builder):
|
|
545
549
|
"spec": spec,
|
546
550
|
}
|
547
551
|
|
552
|
+
@class_or_instance_method
|
553
|
+
def from_yaml(
|
554
|
+
cls,
|
555
|
+
yaml_string: str = None,
|
556
|
+
uri: str = None,
|
557
|
+
loader: callable = yaml.SafeLoader,
|
558
|
+
**kwargs,
|
559
|
+
):
|
560
|
+
if inspect.isclass(cls):
|
561
|
+
job = cls(**cls.auth)
|
562
|
+
else:
|
563
|
+
job = cls.__class__(**cls.auth)
|
564
|
+
|
565
|
+
if yaml_string:
|
566
|
+
return job.from_dict(yaml.load(yaml_string, Loader=loader))
|
567
|
+
if uri:
|
568
|
+
yaml_dict = yaml.load(cls._read_from_file(uri=uri, **kwargs), Loader=loader)
|
569
|
+
return job.from_dict(yaml_dict)
|
570
|
+
raise ValueError("Must provide either YAML string or URI location")
|
571
|
+
|
548
572
|
@class_or_instance_method
|
549
573
|
def from_dict(cls, config: dict) -> "Job":
|
550
574
|
"""Initializes a job from a dictionary containing the configurations.
|
@@ -573,9 +597,9 @@ class Job(Builder):
|
|
573
597
|
"runtime": cls._RUNTIME_MAPPING,
|
574
598
|
}
|
575
599
|
if inspect.isclass(cls):
|
576
|
-
job = cls()
|
600
|
+
job = cls(**cls.auth)
|
577
601
|
else:
|
578
|
-
job = cls.__class__()
|
602
|
+
job = cls.__class__(**cls.auth)
|
579
603
|
|
580
604
|
for key, value in spec.items():
|
581
605
|
if key in mappings:
|
@@ -6,8 +6,8 @@
|
|
6
6
|
from __future__ import annotations
|
7
7
|
|
8
8
|
import datetime
|
9
|
+
import inspect
|
9
10
|
import logging
|
10
|
-
import oci
|
11
11
|
import os
|
12
12
|
import time
|
13
13
|
import traceback
|
@@ -17,11 +17,12 @@ from string import Template
|
|
17
17
|
from typing import Any, Dict, List, Optional, Union
|
18
18
|
|
19
19
|
import fsspec
|
20
|
+
import oci
|
20
21
|
import oci.data_science
|
21
22
|
import oci.util as oci_util
|
22
|
-
import yaml
|
23
23
|
from oci.data_science.models import JobInfrastructureConfigurationDetails
|
24
24
|
from oci.exceptions import ServiceError
|
25
|
+
import yaml
|
25
26
|
from ads.common import utils
|
26
27
|
from ads.common.oci_datascience import DSCNotebookSession, OCIDataScienceMixin
|
27
28
|
from ads.common.oci_logging import OCILog
|
@@ -782,7 +783,7 @@ class DataScienceJobRun(
|
|
782
783
|
# Update runtime from job run
|
783
784
|
from ads.jobs import Job
|
784
785
|
|
785
|
-
job = Job.from_dict(job_dict)
|
786
|
+
job = Job(**self.auth).from_dict(job_dict)
|
786
787
|
envs = job.runtime.envs
|
787
788
|
run_config_override = run_dict.get("jobConfigurationOverrideDetails", {})
|
788
789
|
envs.update(run_config_override.get("environmentVariables", {}))
|
@@ -811,7 +812,7 @@ class DataScienceJobRun(
|
|
811
812
|
"""
|
812
813
|
from ads.jobs import Job
|
813
814
|
|
814
|
-
return Job.from_datascience_job(self.job_id)
|
815
|
+
return Job(**self.auth).from_datascience_job(self.job_id)
|
815
816
|
|
816
817
|
def download(self, to_dir):
|
817
818
|
"""Downloads files from job run output URI to local.
|
@@ -953,9 +954,9 @@ class DataScienceJob(Infrastructure):
|
|
953
954
|
if key not in attribute_map and key.lower() in snake_to_camel_map:
|
954
955
|
value = spec.pop(key)
|
955
956
|
if isinstance(value, dict):
|
956
|
-
spec[
|
957
|
-
|
958
|
-
|
957
|
+
spec[snake_to_camel_map[key.lower()]] = (
|
958
|
+
DataScienceJob.standardize_spec(value)
|
959
|
+
)
|
959
960
|
else:
|
960
961
|
spec[snake_to_camel_map[key.lower()]] = value
|
961
962
|
return spec
|
@@ -971,6 +972,9 @@ class DataScienceJob(Infrastructure):
|
|
971
972
|
Specification as keyword arguments.
|
972
973
|
If spec contains the same key as the one in kwargs, the value from kwargs will be used.
|
973
974
|
"""
|
975
|
+
# Saves a copy of the auth object from the class to the instance.
|
976
|
+
# Future changes to the class level Job.auth will not affect the auth of existing instances.
|
977
|
+
self.auth = self.auth.copy()
|
974
978
|
for key in ["config", "signer", "client_kwargs"]:
|
975
979
|
if kwargs.get(key):
|
976
980
|
self.auth[key] = kwargs.pop(key)
|
@@ -1710,6 +1714,15 @@ class DataScienceJob(Infrastructure):
|
|
1710
1714
|
"""
|
1711
1715
|
return cls.from_dsc_job(DSCJob(**cls.auth).from_ocid(job_id))
|
1712
1716
|
|
1717
|
+
@class_or_instance_method
|
1718
|
+
def from_dict(cls, obj_dict: dict):
|
1719
|
+
"""Initialize the object from a Python dictionary"""
|
1720
|
+
if inspect.isclass(cls):
|
1721
|
+
job_cls = cls
|
1722
|
+
else:
|
1723
|
+
job_cls = cls.__class__
|
1724
|
+
return job_cls(spec=obj_dict.get("spec"), **cls.auth)
|
1725
|
+
|
1713
1726
|
@class_or_instance_method
|
1714
1727
|
def list_jobs(cls, compartment_id: str = None, **kwargs) -> List[DataScienceJob]:
|
1715
1728
|
"""Lists all jobs in a compartment.
|
@@ -1,3 +1,9 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*--
|
3
|
+
|
4
|
+
# Copyright (c) 2024 Oracle and/or its affiliates.
|
5
|
+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
6
|
+
|
1
7
|
from langchain.schema.runnable import RunnableParallel
|
2
8
|
from langchain.load.dump import dumpd
|
3
9
|
from langchain.load.load import load
|
@@ -10,7 +16,7 @@ class RunnableParallelSerializer:
|
|
10
16
|
|
11
17
|
@staticmethod
|
12
18
|
def load(config: dict, **kwargs):
|
13
|
-
steps = config
|
19
|
+
steps = config.get("kwargs", dict()).get("steps", dict())
|
14
20
|
steps = {k: load(v, **kwargs) for k, v in steps.items()}
|
15
21
|
return RunnableParallel(**steps)
|
16
22
|
|
@@ -29,7 +29,7 @@ _cwd = os.path.dirname(__file__)
|
|
29
29
|
TESTS_PATH = os.path.join(_cwd, "resources", "tests.yaml")
|
30
30
|
HTML_PATH = os.path.join(_cwd, "resources", "template.html")
|
31
31
|
CONFIG_PATH = os.path.join(_cwd, "resources", "config.yaml")
|
32
|
-
PYTHON_VER_PATTERN = "^([3])(\.[6-9])(\.\d+)?$"
|
32
|
+
PYTHON_VER_PATTERN = "^([3])(\.([6-9]|1[0-2]))(\.\d+)?$"
|
33
33
|
PAR_URL = "https://objectstorage.us-ashburn-1.oraclecloud.com/p/WyjtfVIG0uda-P3-2FmAfwaLlXYQZbvPZmfX1qg0-sbkwEQO6jpwabGr2hMDBmBp/n/ociodscdev/b/service-conda-packs/o/service_pack/index.json"
|
34
34
|
|
35
35
|
TESTS = {
|
@@ -35,7 +35,7 @@ All generated configurations should be ready to use without the need for any add
|
|
35
35
|
To run anomaly detection locally, create and activate a new conda environment (`ads-anomaly`). Install all the required libraries listed in the `environment.yaml` file.
|
36
36
|
|
37
37
|
```yaml
|
38
|
-
-
|
38
|
+
- report-creator
|
39
39
|
- cerberus
|
40
40
|
- oracle-automlx==23.4.1
|
41
41
|
- oracle-automlx[classic]==23.4.1
|
@@ -10,7 +10,6 @@ from ads.opctl.operator.lowcode.common.utils import (
|
|
10
10
|
merge_category_columns,
|
11
11
|
)
|
12
12
|
from ads.opctl.operator.lowcode.common.data import AbstractData
|
13
|
-
from ads.opctl.operator.lowcode.common.data import AbstractData
|
14
13
|
from ads.opctl.operator.lowcode.anomaly.utils import get_frequency_of_datetime
|
15
14
|
from ads.opctl import logger
|
16
15
|
import pandas as pd
|
@@ -56,6 +55,10 @@ class AnomalyDatasets:
|
|
56
55
|
self.X_valid_dict = self.valid_data.X_valid_dict
|
57
56
|
self.y_valid_dict = self.valid_data.y_valid_dict
|
58
57
|
|
58
|
+
# Returns raw data based on the series_id i.e; the merged target_category_column value
|
59
|
+
def get_raw_data_by_cat(self, category):
|
60
|
+
return self._data.get_raw_data_by_cat(category)
|
61
|
+
|
59
62
|
|
60
63
|
class AnomalyOutput:
|
61
64
|
def __init__(self, date_column):
|
@@ -94,38 +97,28 @@ class AnomalyOutput:
|
|
94
97
|
outliers = pd.merge(outliers, scores, on=self.date_column, how="inner")
|
95
98
|
return outliers
|
96
99
|
|
97
|
-
def get_inliers(self,
|
100
|
+
def get_inliers(self, datasets):
|
98
101
|
inliers = pd.DataFrame()
|
99
102
|
|
100
103
|
for category in self.list_categories():
|
101
104
|
inliers = pd.concat(
|
102
105
|
[
|
103
106
|
inliers,
|
104
|
-
self.get_inliers_by_cat(
|
105
|
-
category,
|
106
|
-
data[data[OutputColumns.Series] == category]
|
107
|
-
.reset_index(drop=True)
|
108
|
-
.drop(OutputColumns.Series, axis=1),
|
109
|
-
),
|
107
|
+
self.get_inliers_by_cat(category, datasets.get_raw_data_by_cat(category)),
|
110
108
|
],
|
111
109
|
axis=0,
|
112
110
|
ignore_index=True,
|
113
111
|
)
|
114
112
|
return inliers
|
115
113
|
|
116
|
-
def get_outliers(self,
|
114
|
+
def get_outliers(self, datasets):
|
117
115
|
outliers = pd.DataFrame()
|
118
116
|
|
119
117
|
for category in self.list_categories():
|
120
118
|
outliers = pd.concat(
|
121
119
|
[
|
122
120
|
outliers,
|
123
|
-
self.get_outliers_by_cat(
|
124
|
-
category,
|
125
|
-
data[data[OutputColumns.Series] == category]
|
126
|
-
.reset_index(drop=True)
|
127
|
-
.drop(OutputColumns.Series, axis=1),
|
128
|
-
),
|
121
|
+
self.get_outliers_by_cat(category, datasets.get_raw_data_by_cat(category)),
|
129
122
|
],
|
130
123
|
axis=0,
|
131
124
|
ignore_index=True,
|
@@ -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 pandas as pd
|
@@ -26,8 +26,14 @@ class AutoMLXOperatorModel(AnomalyOperatorBaseModel):
|
|
26
26
|
)
|
27
27
|
def _build_model(self) -> pd.DataFrame:
|
28
28
|
from automlx import init
|
29
|
+
import logging
|
30
|
+
|
29
31
|
try:
|
30
|
-
init(
|
32
|
+
init(
|
33
|
+
engine="ray",
|
34
|
+
engine_opts={"ray_setup": {"_temp_dir": "/tmp/ray-temp"}},
|
35
|
+
loglevel=logging.CRITICAL,
|
36
|
+
)
|
31
37
|
except Exception as e:
|
32
38
|
logger.info("Ray already initialized")
|
33
39
|
date_column = self.spec.datetime_column.name
|
@@ -67,21 +73,21 @@ class AutoMLXOperatorModel(AnomalyOperatorBaseModel):
|
|
67
73
|
return anomaly_output
|
68
74
|
|
69
75
|
def _generate_report(self):
|
70
|
-
import
|
76
|
+
import report_creator as rc
|
71
77
|
|
72
78
|
"""The method that needs to be implemented on the particular model level."""
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
79
|
+
other_sections = [
|
80
|
+
rc.Heading("Selected Models Overview", level=2),
|
81
|
+
rc.Text(
|
82
|
+
"The following tables provide information regarding the chosen model."
|
83
|
+
),
|
84
|
+
]
|
78
85
|
|
79
|
-
model_description =
|
86
|
+
model_description = rc.Text(
|
80
87
|
"The automlx model automatically pre-processes, selects and engineers "
|
81
88
|
"high-quality features in your dataset, which then given to an automatically "
|
82
89
|
"chosen and optimized machine learning model.."
|
83
90
|
)
|
84
|
-
other_sections = all_sections
|
85
91
|
|
86
92
|
return (
|
87
93
|
model_description,
|
@@ -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 pandas as pd
|
@@ -81,21 +81,20 @@ class AutoTSOperatorModel(AnomalyOperatorBaseModel):
|
|
81
81
|
return anomaly_output
|
82
82
|
|
83
83
|
def _generate_report(self):
|
84
|
-
import
|
84
|
+
import report_creator as rc
|
85
85
|
|
86
86
|
"""The method that needs to be implemented on the particular model level."""
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
model_description =
|
87
|
+
other_sections = [
|
88
|
+
rc.Heading("Selected Models Overview", level=2),
|
89
|
+
rc.Text(
|
90
|
+
"The following tables provide information regarding the chosen model."
|
91
|
+
),
|
92
|
+
]
|
93
|
+
model_description = rc.Text(
|
94
94
|
"The automlx model automatically pre-processes, selects and engineers "
|
95
95
|
"high-quality features in your dataset, which then given to an automatically "
|
96
96
|
"chosen and optimized machine learning model.."
|
97
97
|
)
|
98
|
-
other_sections = all_sections
|
99
98
|
|
100
99
|
return (
|
101
100
|
model_description,
|