@@ -6,7 +6,7 @@ author: mrbullwinkle
6
6
manager : nitinme
7
7
ms.service : cognitive-services
8
8
ms.topic : include
9
- ms.date : 02/09 /2023
9
+ ms.date : 03/13 /2023
10
10
ms.author : mbullwin
11
11
---
12
12
@@ -36,7 +36,7 @@ pip install --upgrade azure.ai.anomalydetector
36
36
37
37
### Create a storage account
38
38
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.
40
40
41
41
1 . Create an <a href =" https://portal.azure.com/#create/Microsoft.StorageAccount-ARM " target =" _blank " >Azure Storage account</a >.
42
42
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
47
47
48
48
### Download sample data
49
49
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/ )
51
51
52
52
You can also download the sample data by running:
53
53
54
54
``` cmd
55
55
curl "https://github.com/Azure-Samples/AnomalyDetector/blob/master/sampledata/multivariate/sample_data_5_3000.csv" --output sample_data_5_3000_.csv
56
56
```
57
57
58
- ``` cmd
59
- curl "https://github.com/Azure-Samples/AnomalyDetector/blob/master/sampledata/multivariate/5_3000.json" --output 5_3000_.json
60
- ```
61
-
62
58
### Upload sample data to Storage Account
63
59
64
60
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/
116
112
117
113
1 . Create a new Python file called ** sample_multivariate_detect.py** . Then open it up in your preferred editor or IDE.
118
114
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 ` .
120
116
121
- ``` python
122
- import json
123
- import os
117
+ ``` Python
124
118
import time
125
119
from datetime import datetime, timezone
126
-
127
120
from azure.ai.anomalydetector import AnomalyDetectorClient
128
121
from azure.core.credentials import AzureKeyCredential
129
- from azure.core.exceptions import HttpResponseError
130
122
from azure.ai.anomalydetector.models import *
131
123
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-%d T%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-%d T%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 ,
310
200
)
311
- if r.value.interpretation:
312
- for contributor in r.value.interpretation:
313
- print (
314
- " \t contributor 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
+ " \t contributor variable: { :<10 } , contributor score: { :.4f } " .format(
206
+ contributor.variable, contributor.contribution_score
317
207
)
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" ],
347
208
)
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)
365
209
```
366
210
367
211
## Run the application
0 commit comments