Skip to content

Commit e6d62f8

Browse files
committed
update python code sample
1 parent b654180 commit e6d62f8

File tree

1 file changed

+87
-243
lines changed

1 file changed

+87
-243
lines changed

articles/cognitive-services/Anomaly-Detector/includes/quickstarts/anomaly-detector-client-library-python-multivariate.md

Lines changed: 87 additions & 243 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ author: mrbullwinkle
66
manager: nitinme
77
ms.service: cognitive-services
88
ms.topic: include
9-
ms.date: 02/09/2023
9+
ms.date: 03/13/2023
1010
ms.author: mbullwin
1111
---
1212

@@ -36,7 +36,7 @@ pip install --upgrade azure.ai.anomalydetector
3636

3737
### Create a storage account
3838

39-
Multivariate Anomaly Detector requires your sample file to be stored as a .zip file in Azure Blob Storage.
39+
Multivariate Anomaly Detector requires your sample file to be stored in Azure Blob Storage.
4040

4141
1. Create an <a href="https://portal.azure.com/#create/Microsoft.StorageAccount-ARM" target="_blank">Azure Storage account</a>.
4242
2. Go to Access Control(IAM), and select **ADD** to Add role assignment.
@@ -47,18 +47,14 @@ This configuration can sometimes be a little confusing, if you have trouble we r
4747

4848
### Download sample data
4949

50-
This quickstart uses two files for sample data `sample_data_5_3000.csv` and `5_3000.json`. These files can both be downloaded from our [GitHub sample data](https://github.com/Azure-Samples/AnomalyDetector/blob/master/sampledata/multivariate/)
50+
This quickstart uses one file for sample data `sample_data_5_3000.csv`. This file can be downloaded from our [GitHub sample data](https://github.com/Azure-Samples/AnomalyDetector/blob/master/sampledata/multivariate/)
5151

5252
You can also download the sample data by running:
5353

5454
```cmd
5555
curl "https://github.com/Azure-Samples/AnomalyDetector/blob/master/sampledata/multivariate/sample_data_5_3000.csv" --output sample_data_5_3000_.csv
5656
```
5757

58-
```cmd
59-
curl "https://github.com/Azure-Samples/AnomalyDetector/blob/master/sampledata/multivariate/5_3000.json" --output 5_3000_.json
60-
```
61-
6258
### Upload sample data to Storage Account
6359

6460
1. Go to your Storage Account, select Containers and create a new container.
@@ -116,252 +112,100 @@ echo export ANOMALY_DETECTOR_ENDPOINT="REPLACE_WITH_YOUR_ENDPOINT_HERE" >> /etc/
116112

117113
1. Create a new Python file called **sample_multivariate_detect.py**. Then open it up in your preferred editor or IDE.
118114

119-
2. Replace the contents of sample_multivariate_detect.py with the following code. You need to modify the paths for the variables `blob_url_path` and `local_json_file_path`.
115+
2. Replace the contents of sample_multivariate_detect.py with the following code. You need to modify the paths for the variables `blob_url`.
120116

121-
```python
122-
import json
123-
import os
117+
```Python
124118
import time
125119
from datetime import datetime, timezone
126-
127120
from azure.ai.anomalydetector import AnomalyDetectorClient
128121
from azure.core.credentials import AzureKeyCredential
129-
from azure.core.exceptions import HttpResponseError
130122
from azure.ai.anomalydetector.models import *
131123

132-
blob_url_path = "Path-to-sample-file-in-your-storage-account" # example path: https://docstest001.blob.core.windows.net/test/sample_data_5_3000.csv
133-
local_json_file_path = "Local-path-to-sample-json-file" # example where file is in same local directory as your Python script: "5_3000.json"
134-
135-
136-
class MultivariateSample:
137-
def __init__(self, subscription_key, anomaly_detector_endpoint):
138-
self.sub_key = subscription_key
139-
self.end_point = anomaly_detector_endpoint
140-
141-
# Create an Anomaly Detector client
142-
143-
# <client>
144-
self.ad_client = AnomalyDetectorClient(self.end_point, AzureKeyCredential(self.sub_key))
145-
# </client>
146-
147-
def list_models(self):
148-
149-
# List models
150-
models = self.ad_client.list_multivariate_models(skip=0, top=10)
151-
return list(models)
152-
153-
def train(self, body):
154-
155-
# Number of models available now
156-
try:
157-
model_list = self.list_models()
158-
print("{:d} available models before training.".format(len(model_list)))
159-
160-
# Use sample data to train the model
161-
print("Training new model...(it may take a few minutes)")
162-
model = self.ad_client.train_multivariate_model(body)
163-
trained_model_id = model.model_id
164-
print("Training model id is {}".format(trained_model_id))
165-
166-
## Wait until the model is ready. It usually takes several minutes
167-
model_status = None
168-
model = None
169-
170-
while model_status != ModelStatus.READY and model_status != ModelStatus.FAILED:
171-
model = self.ad_client.get_multivariate_model(trained_model_id)
172-
print(model)
173-
model_status = model.model_info.status
174-
print("Model is {}".format(model_status))
175-
time.sleep(30)
176-
177-
if model_status == ModelStatus.FAILED:
178-
print("Creating model failed.")
179-
print("Errors:")
180-
if len(model.model_info.errors) > 0:
181-
print(
182-
"Error code: {}. Message: {}".format(
183-
model.model_info.errors[0].code,
184-
model.model_info.errors[0].message,
185-
)
186-
)
187-
else:
188-
print("None")
189-
190-
if model_status == ModelStatus.READY:
191-
# Model list after training
192-
model_list = self.list_models()
193-
194-
print("Done.\n--------------------")
195-
print("{:d} available models after training.".format(len(model_list)))
196-
197-
# Return the latest model id
198-
return trained_model_id
199-
except HttpResponseError as e:
200-
print(
201-
"Error code: {}".format(e.error.code),
202-
"Error message: {}".format(e.error.message),
203-
)
204-
except Exception as e:
205-
raise e
206-
207-
return None
208-
209-
def batch_detect(self, model_id, body):
210-
211-
# Detect anomaly in the same data source (but a different interval)
212-
try:
213-
result = self.ad_client.detect_multivariate_batch_anomaly(model_id, body)
214-
result_id = result.result_id
215-
216-
# Get results (may need a few seconds)
217-
r = self.ad_client.get_multivariate_batch_detection_result(result_id)
218-
print("Get detection result...(it may take a few seconds)")
219-
220-
while r.summary.status != MultivariateBatchDetectionStatus.READY and r.summary.status != MultivariateBatchDetectionStatus.FAILED:
221-
r = self.ad_client.get_multivariate_batch_detection_result(result_id)
222-
print("Detection is {}".format(r.summary.status))
223-
time.sleep(15)
224-
225-
if r.summary.status == MultivariateBatchDetectionStatus.FAILED:
226-
print("Detection failed.")
227-
print("Errors:")
228-
if len(r.summary.errors) > 0:
229-
print("Error code: {}. Message: {}".format(r.summary.errors[0].code, r.summary.errors[0].message))
230-
else:
231-
print("None")
232-
return None
233-
234-
return r
235-
236-
except HttpResponseError as e:
237-
print(
238-
"Error code: {}".format(e.error.code),
239-
"Error message: {}".format(e.error.message),
240-
)
241-
except Exception as e:
242-
raise e
243-
244-
return None
245-
246-
def delete_model(self, model_id):
247-
248-
# Delete the model
249-
self.ad_client.delete_multivariate_model(model_id)
250-
model_list = self.list_models()
251-
print("{:d} available models after deletion.".format(len(model_list)))
252-
253-
def last_detect(self, model_id, variables):
254-
255-
# Detect anomaly by sync api
256-
r = self.ad_client.detect_multivariate_last_anomaly(model_id, variables)
257-
print("Get last detection result")
258-
return r
259-
260-
261-
if __name__ == "__main__":
262-
SUBSCRIPTION_KEY = os.environ["ANOMALY_DETECTOR_API_KEY"]
263-
ANOMALY_DETECTOR_ENDPOINT = os.environ["ANOMALY_DETECTOR_ENDPOINT"]
264-
265-
## Create a new sample and client
266-
sample = MultivariateSample(SUBSCRIPTION_KEY, ANOMALY_DETECTOR_ENDPOINT)
267-
268-
# Train a new model
269-
time_format = "%Y-%m-%dT%H:%M:%SZ"
270-
blob_url = blob_url_path
271-
train_body = ModelInfo(
272-
data_source=blob_url,
273-
start_time=datetime.strptime("2021-01-02T00:00:00Z", time_format),
274-
end_time=datetime.strptime("2021-01-02T05:00:00Z", time_format),
275-
data_schema="OneTable",
276-
display_name="sample",
277-
sliding_window=200,
278-
align_policy=AlignPolicy(
279-
align_mode=AlignMode.OUTER,
280-
fill_n_a_method=FillNAMethod.LINEAR,
281-
padding_value=0,
282-
),
283-
)
284-
model_id = sample.train(train_body)
285-
286-
# Batch Inference
287-
batch_inference_body = MultivariateBatchDetectionOptions(
288-
data_source=blob_url,
289-
top_contributor_count=10,
290-
start_time=datetime.strptime("2021-01-02T00:00:00Z", time_format),
291-
end_time=datetime.strptime("2021-01-02T05:00:00Z", time_format),
292-
)
293-
result = sample.batch_detect(model_id, batch_inference_body)
294-
assert result is not None
295-
296-
print("Result ID:\t", result.result_id)
297-
print("Result status:\t", result.summary.status)
298-
print("Result length:\t", len(result.results))
299-
300-
# See detailed inference result
301-
for r in result.results:
302-
print(
303-
"timestamp: {}, is_anomaly: {:<5}, anomaly score: {:.4f}, severity: {:.4f}, contributor count: {:<4d}".format(
304-
r.timestamp,
305-
r.value.is_anomaly,
306-
r.value.score,
307-
r.value.severity,
308-
len(r.value.interpretation) if r.value.is_anomaly else 0,
309-
)
124+
SUBSCRIPTION_KEY = os.environ['ANOMALY_DETECTOR_API_KEY']
125+
ANOMALY_DETECTOR_ENDPOINT = os.environ['ANOMALY_DETECTOR_ENDPOINT']
126+
127+
ad_client = AnomalyDetectorClient(ANOMALY_DETECTOR_ENDPOINT, AzureKeyCredential(SUBSCRIPTION_KEY))
128+
129+
time_format = "%Y-%m-%dT%H:%M:%SZ"
130+
blob_url = "Path-to-sample-file-in-your-storage-account" # example path: https://docstest001.blob.core.windows.net/test/sample_data_5_3000.csv
131+
132+
train_body = ModelInfo(
133+
data_source=blob_url,
134+
start_time=datetime.strptime("2021-01-02T00:00:00Z", time_format),
135+
end_time=datetime.strptime("2021-01-02T05:00:00Z", time_format),
136+
data_schema="OneTable",
137+
display_name="sample",
138+
sliding_window=200,
139+
align_policy=AlignPolicy(
140+
align_mode=AlignMode.OUTER,
141+
fill_n_a_method=FillNAMethod.LINEAR,
142+
padding_value=0,
143+
),
144+
)
145+
146+
batch_inference_body = MultivariateBatchDetectionOptions(
147+
data_source=blob_url,
148+
top_contributor_count=10,
149+
start_time=datetime.strptime("2021-01-02T00:00:00Z", time_format),
150+
end_time=datetime.strptime("2021-01-02T05:00:00Z", time_format),
151+
)
152+
153+
154+
print("Training new model...(it may take a few minutes)")
155+
model = ad_client.train_multivariate_model(train_body)
156+
model_id = model.model_id
157+
print("Training model id is {}".format(model_id))
158+
159+
## Wait until the model is ready. It usually takes several minutes
160+
model_status = None
161+
model = None
162+
163+
while model_status != ModelStatus.READY and model_status != ModelStatus.FAILED:
164+
model = ad_client.get_multivariate_model(model_id)
165+
print(model)
166+
model_status = model.model_info.status
167+
print("Model is {}".format(model_status))
168+
time.sleep(30)
169+
if model_status == ModelStatus.READY:
170+
print("Done.\n--------------------")
171+
# Return the latest model id
172+
173+
# Detect anomaly in the same data source (but a different interval)
174+
result = ad_client.detect_multivariate_batch_anomaly(model_id, batch_inference_body)
175+
result_id = result.result_id
176+
177+
# Get results (may need a few seconds)
178+
r = ad_client.get_multivariate_batch_detection_result(result_id)
179+
print("Get detection result...(it may take a few seconds)")
180+
181+
while r.summary.status != MultivariateBatchDetectionStatus.READY and r.summary.status != MultivariateBatchDetectionStatus.FAILED and r.summary.status !=MultivariateBatchDetectionStatus.CREATED:
182+
anomaly_results = ad_client.get_multivariate_batch_detection_result(result_id)
183+
print("Detection is {}".format(r.summary.status))
184+
time.sleep(5)
185+
186+
187+
print("Result ID:\t", anomaly_results.result_id)
188+
print("Result status:\t", anomaly_results.summary.status)
189+
print("Result length:\t", len(anomaly_results.results))
190+
191+
# See detailed inference result
192+
for r in anomaly_results.results:
193+
print(
194+
"timestamp: {}, is_anomaly: {:<5}, anomaly score: {:.4f}, severity: {:.4f}, contributor count: {:<4d}".format(
195+
r.timestamp,
196+
r.value.is_anomaly,
197+
r.value.score,
198+
r.value.severity,
199+
len(r.value.interpretation) if r.value.is_anomaly else 0,
310200
)
311-
if r.value.interpretation:
312-
for contributor in r.value.interpretation:
313-
print(
314-
"\tcontributor variable: {:<10}, contributor score: {:.4f}".format(
315-
contributor.variable, contributor.contribution_score
316-
)
201+
)
202+
if r.value.interpretation:
203+
for contributor in r.value.interpretation:
204+
print(
205+
"\tcontributor variable: {:<10}, contributor score: {:.4f}".format(
206+
contributor.variable, contributor.contribution_score
317207
)
318-
319-
# *******************************************************************************************************************
320-
# Use your own inference data sending to last detection api, you should define your own variables and detectingPoints
321-
# *****************************************************************************************************************
322-
# define "<YOUR OWN variables>"
323-
# variables = [
324-
# {
325-
# "name": "variables_name1",
326-
# "timestamps": ['2021-01-01T00:00:00Z', '2021-01-01T00:01:00Z', ...],
327-
# "values": [0, 0, ...]
328-
# },
329-
# {
330-
# "name": "variables_name2",
331-
# "timestamps": ['2021-01-01T00:00:00Z', '2021-01-01T00:01:00Z', ...],
332-
# "values": [0, 0, ...]
333-
# }
334-
# ]
335-
336-
# Last detection
337-
with open(local_json_file_path) as f:
338-
variables_data = json.load(f)
339-
340-
variables = []
341-
for item in variables_data["variables"]:
342-
variables.append(
343-
VariableValues(
344-
variable=item["variable"],
345-
timestamps=item["timestamps"],
346-
values=item["values"],
347208
)
348-
)
349-
350-
last_inference_body = MultivariateLastDetectionOptions(
351-
variables=variables,
352-
top_contributor_count=10,
353-
)
354-
last_detect_result = sample.last_detect(model_id, last_inference_body)
355-
356-
assert last_detect_result is not None
357-
358-
print("Variable States:\t", last_detect_result.variable_states)
359-
print("Variable States length:\t", len(last_detect_result.variable_states))
360-
print("Results:\t", last_detect_result.results)
361-
print("Results length:\t", len(last_detect_result.results))
362-
363-
# Delete model
364-
sample.delete_model(model_id)
365209
```
366210

367211
## Run the application

0 commit comments

Comments
 (0)