Skip to content

Commit 5443085

Browse files
DavidZeLiang1228David Liang
andauthored
Add multivariate sample (Azure#18156)
Co-authored-by: David Liang <liangze@microsoft.com>
1 parent b3f18e7 commit 5443085

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
"""
5+
FILE: sample_multivariate_detect.py
6+
7+
DESCRIPTION:
8+
This sample demonstrates how to use multivariate dataset to train a model and use the model to detect anomalies.
9+
10+
Prerequisites:
11+
* The Anomaly Detector client library for Python
12+
* A valid data feed
13+
14+
USAGE:
15+
python sample_multivariate_detect.py
16+
17+
Set the environment variables with your own values before running the sample:
18+
1) ANOMALY_DETECTOR_KEY - your source Form Anomaly Detector API key.
19+
2) ANOMALY_DETECTOR_ENDPOINT - the endpoint to your source Anomaly Detector resource.
20+
"""
21+
22+
import os
23+
import time
24+
from datetime import datetime
25+
26+
from azure.ai.anomalydetector import AnomalyDetectorClient
27+
from azure.ai.anomalydetector.models import DetectionRequest, ModelInfo
28+
from azure.core.credentials import AzureKeyCredential
29+
from azure.core.exceptions import HttpResponseError
30+
31+
32+
class MultivariateSample():
33+
34+
def __init__(self, subscription_key, anomaly_detector_endpoint, data_source=None):
35+
self.sub_key = subscription_key
36+
self.end_point = anomaly_detector_endpoint
37+
38+
# Create an Anomaly Detector client
39+
40+
# <client>
41+
self.ad_client = AnomalyDetectorClient(AzureKeyCredential(self.sub_key), self.end_point)
42+
# </client>
43+
44+
self.data_source = data_source
45+
46+
def train(self, start_time, end_time, max_tryout=500):
47+
48+
# Number of models available now
49+
model_list = list(self.ad_client.list_multivariate_model(skip=0, top=10000))
50+
print("{:d} available models before training.".format(len(model_list)))
51+
52+
# Use sample data to train the model
53+
print("Training new model...")
54+
data_feed = ModelInfo(start_time=start_time, end_time=end_time, source=self.data_source)
55+
response_header = \
56+
self.ad_client.train_multivariate_model(data_feed, cls=lambda *args: [args[i] for i in range(len(args))])[
57+
-1]
58+
trained_model_id = response_header['Location'].split("/")[-1]
59+
60+
# Model list after training
61+
new_model_list = list(self.ad_client.list_multivariate_model(skip=0, top=10000))
62+
63+
# Wait until the model is ready. It usually takes several minutes
64+
model_status = None
65+
tryout_count = 0
66+
while (tryout_count < max_tryout and model_status != "READY"):
67+
model_status = self.ad_client.get_multivariate_model(trained_model_id).model_info.status
68+
tryout_count += 1
69+
time.sleep(2)
70+
71+
assert model_status == "READY"
72+
73+
print("Done.", "\n--------------------")
74+
print("{:d} available models after training.".format(len(new_model_list)))
75+
76+
# Return the latest model id
77+
return trained_model_id
78+
79+
def detect(self, model_id, start_time, end_time, max_tryout=500):
80+
81+
# Detect anomaly in the same data source (but a different interval)
82+
try:
83+
detection_req = DetectionRequest(source=self.data_source, start_time=start_time, end_time=end_time)
84+
response_header = self.ad_client.detect_anomaly(model_id, detection_req,
85+
cls=lambda *args: [args[i] for i in range(len(args))])[-1]
86+
result_id = response_header['Location'].split("/")[-1]
87+
88+
# Get results (may need a few seconds)
89+
r = self.ad_client.get_detection_result(result_id)
90+
tryout_count = 0
91+
while r.summary.status != "READY" and tryout_count < max_tryout:
92+
time.sleep(1)
93+
r = self.ad_client.get_detection_result(result_id)
94+
tryout_count += 1
95+
96+
if r.summary.status != "READY":
97+
print("Request timeout after %d tryouts.".format(max_tryout))
98+
return None
99+
100+
except HttpResponseError as e:
101+
print('Error code: {}'.format(e.error.code), 'Error message: {}'.format(e.error.message))
102+
except Exception as e:
103+
raise e
104+
105+
return r
106+
107+
def export_model(self, model_id, model_path="model.zip"):
108+
109+
# Export the model
110+
model_stream_generator = self.ad_client.export_model(model_id)
111+
with open(model_path, "wb") as f_obj:
112+
while True:
113+
try:
114+
f_obj.write(next(model_stream_generator))
115+
except StopIteration:
116+
break
117+
except Exception as e:
118+
raise e
119+
120+
def delete_model(self, model_id):
121+
122+
# Delete the mdoel
123+
self.ad_client.delete_multivariate_model(model_id)
124+
model_list_after_delete = list(self.ad_client.list_multivariate_model(skip=0, top=10000))
125+
print("{:d} available models after deletion.".format(len(model_list_after_delete)))
126+
127+
128+
if __name__ == '__main__':
129+
SUBSCRIPTION_KEY = os.environ["ANOMALY_DETECTOR_KEY"]
130+
ANOMALY_DETECTOR_ENDPOINT = os.environ["ANOMALY_DETECTOR_ENDPOINT"]
131+
132+
# *****************************
133+
# Use your own data source here
134+
# *****************************
135+
data_source = "<YOUR OWN DATA SOURCE>"
136+
137+
# Create a new sample and client
138+
sample = MultivariateSample(SUBSCRIPTION_KEY, ANOMALY_DETECTOR_ENDPOINT, data_source)
139+
140+
# Train a new model
141+
model_id = sample.train(datetime(2021, 1, 1, 0, 0, 0), datetime(2021, 1, 2, 12, 0, 0))
142+
143+
# Reference
144+
result = sample.detect(model_id, datetime(2021, 1, 2, 12, 0, 0), datetime(2021, 1, 3, 0, 0, 0))
145+
print("Result ID:\t", result.result_id)
146+
print("Result summary:\t", result.summary)
147+
print("Result length:\t", len(result.results))
148+
149+
# Export model
150+
sample.export_model(model_id, "model.zip")
151+
152+
# Delete model
153+
sample.delete_model(model_id)

0 commit comments

Comments
 (0)