共用方式為


快速入門:使用多變量異常偵測器用戶端程式庫

重要

從 2023 年 9 月 20 日起,您將無法建立新的異常偵測器資源。 異常偵測器服務將於 2026 年 10 月 1 日淘汰。

開始使用適用於 C# 的異常偵測程式多變量用戶端程式庫。 請遵循下列步驟安裝套件,並開始使用服務提供的演算法。 新的多變量異常偵測程式 API 可讓開發人員輕鬆整合進階 AI 來偵測計量群組中的異常,而不需要機器學習知識或標籤資料。 不同信號之間的相依性和相互關聯會自動視為主要因素。 這可協助您主動保護複雜的系統免於失敗。

使用適用於 C# 的異常偵測程式多變量用戶端程式庫來:

  • 偵測一組時間序列中的系統層級異常。
  • 當您無法從任何個別的時間序列得知太多資訊,而您必須查看所有信號來偵測問題。
  • 透過數十到數百種不同類型感應器預測性維護昂貴的實體資產,以測量各個層面的系統健康情況。

程式庫參考文件 | 程式庫原始程式碼 | 套件 (NuGet)

必要條件

  • Azure 訂用帳戶 - 建立免費帳戶
  • 最新版 .NET Core
  • 擁有 Azure 訂用帳戶之後,在 Azure 入口網站中建立異常偵測程式資源,以取得您的金鑰和端點。 部署完成後,選取 [移至資源] 按鈕。
    • 您需要來自所建立資源的金鑰和端點,以將應用程式連線至異常偵測器 API。 稍後會在快速入門中將金鑰和端點貼到下列程式碼中。 您可以使用免費定價層 (F0) 來試用服務,之後可升級至付費層以用於實際執行環境。

設定

建立儲存體帳戶

多變量異常偵測程式需要您將範例檔案儲存在 Azure Blob 儲存體中。

  1. 建立 Azure 儲存體帳戶
  2. 移至 [存取控制 (IAM)],然後選取 [新增] 以新增角色指派。
  3. 搜尋 [儲存體 Blob 資料] 的角色以醒目顯示此帳戶類型,然後選取 [下一步]。
  4. 選取 [將存取權指派給受控識別],並選取 [成員],然後選擇您稍早建立的 [異常偵測程式資源],再選取 [檢閱 + 指派]。

這種設定有時可能會有點令人困惑,如果您遇到問題,建議您諮詢我們的多變量 Jupyter Notebook 範例,該範例能更深入地逐步解說此流程。

下載範例資料

本快速入門會針對範例資料 sample_data_5_3000.csv 使用一個檔案。 檔案可從我們的 GitHub 範本資料中進行下載

您也可以執行下列項目來下載範例資料:

curl "https://github.com/Azure-Samples/AnomalyDetector/blob/master/sampledata/multivariate/sample_data_5_3000.csv" --output sample_data_5_3000_.csv

將範例資料上傳至儲存體帳戶

  1. 移至您的 [儲存體帳戶],選取 [容器],然後建立新的容器。
  2. 選取 [上傳] 並上傳 sample_data_5_3000.csv
  3. 選取您所上傳的資料,並複製 Blob URL,因為您需要在幾個步驟後將其新增至程式碼範例中。

擷取金鑰和端點

若要成功對異常偵測程式服務發出呼叫,您需要下列值:

變數名稱
ANOMALY_DETECTOR_ENDPOINT 從 Azure 入口網站查看您的資源時,可以在 [金鑰與端點] 區段中找到此值。 範例端點:https://YOUR_RESOURCE_NAME.cognitiveservices.azure.com/
ANOMALY_DETECTOR_API_KEY 當您透過 Azure 入口網站查看資源時,可以在 [金鑰和端點] 區段中找到 API 金鑰值。 您可以使用 KEY1KEY2

移至您在 Azure 入口網站中的資源。 您可以在 [資源管理] 區段中找到 [端點和金鑰]。 複製您的端點和存取金鑰,因為您需要這兩者才能驗證 API 呼叫。 您可以使用 KEY1KEY2。 隨時持有兩個金鑰可讓您安全地輪替和重新產生金鑰,而不會造成服務中斷。

建立環境變數

為您的金鑰和端點建立及指派永續性環境變數。

重要

如果您使用 API 金鑰,請將其安全地儲存在別處,例如 Azure Key Vault。 請勿在程式碼中直接包含 API 金鑰,且切勿公開張貼金鑰。

如需 AI 服務安全性的詳細資訊,請參閱驗證對 Azure AI 服務的要求 (英文)。

setx ANOMALY_DETECTOR_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx ANOMALY_DETECTOR_ENDPOINT "REPLACE_WITH_YOUR_ENDPOINT_HERE"

建立新的 .NET Core 應用程式

在主控台視窗中 (例如 cmd、PowerShell 或 Bash),使用 dotnet new 命令建立名為 anomaly-detector-quickstart-multivariate 的新主控台應用程式。 此命令會建立簡單的 "Hello World" 專案,內含單一 C# 來源檔案:Program.cs

dotnet new console -n anomaly-detector-quickstart-multivariate

將目錄變更為新建立的應用程式資料夾。 您可以使用下列命令來建置應用程式:

dotnet build

建置輸出應該不會有警告或錯誤。

...
Build succeeded.
 0 Warning(s)
 0 Error(s)
...

安裝用戶端程式庫

在應用程式目錄中,使用下列命令安裝適用於 .NET 的 Anomaly Detector 用戶端程式庫:

dotnet add package Azure.AI.AnomalyDetector --prerelease

從專案目錄中開啟 program.cs 檔案,並取代為下列程式碼:

using Azure.AI.AnomalyDetector;
using Azure;
using static System.Environment;

internal class Program
{
    private static void Main(string[] args)
    {
        string endpoint = GetEnvironmentVariable("ANOMALY_DETECTOR_ENDPOINT"); 
        string apiKey = GetEnvironmentVariable("ANOMALY_DETECTOR_API_KEY");
        string datasource = "Path-to-sample-file-in-your-storage-account";  // example path:https://docstest001.blob.core.windows.net/test/sample_data_5_3000.csv
        Console.WriteLine(endpoint);
        var endpointUri = new Uri(endpoint);
        var credential = new AzureKeyCredential(apiKey);

        //create client
        AnomalyDetectorClient client = new AnomalyDetectorClient(endpointUri, credential);

        // train
        TimeSpan offset = new TimeSpan(0);
        DateTimeOffset start_time = new DateTimeOffset(2021, 1, 2, 0, 0, 0, offset);
        DateTimeOffset end_time = new DateTimeOffset(2021, 1, 2, 5, 0, 0, offset);
        string model_id = null;
        try
        {
            model_id = TrainModel(client, datasource, start_time, end_time);

            // detect
            end_time = new DateTimeOffset(2021, 1, 2, 1, 0, 0, offset);
            MultivariateDetectionResult result = BatchDetect(client, datasource, model_id, start_time, end_time);
            if (result != null)
            {
                Console.WriteLine(string.Format("Result ID: {0}", result.ResultId.ToString()));
                Console.WriteLine(string.Format("Result summary: {0}", result.Summary.ToString()));
                Console.WriteLine(string.Format("Result length: {0}", result.Results.Count));
                Console.WriteLine(string.Format("Anomalies found: {0}", result.Results.Where(r => r.Value.IsAnomaly).Count()));
            }

            // delete
            DeleteModel(client, model_id);
        }
        catch (Exception e)
        {
            string msg = string.Format("Multivariate error. {0}", e.Message);
            Console.WriteLine(msg);
            throw;
        }

        int GetModelNumber(AnomalyDetectorClient client)
        {
            int model_number = 0;
            foreach (var multivariateModel in client.GetMultivariateModels())
            {
                model_number++;
            }
            return model_number;
        }

        string TrainModel(AnomalyDetectorClient client, string datasource, DateTimeOffset start_time, DateTimeOffset end_time, int max_tryout = 500)
        {
            try
            {
                Console.WriteLine("Training new model...");

                Console.WriteLine(string.Format("{0} available models before training.", GetModelNumber(client)));

                ModelInfo request = new ModelInfo(datasource, start_time, end_time);
                request.SlidingWindow = 200;

                Console.WriteLine("Training new model...(it may take a few minutes)");
                AnomalyDetectionModel response = client.TrainMultivariateModel(request);
                string trained_model_id = response.ModelId;
                Console.WriteLine(string.Format("Training model id is {0}", trained_model_id));

                // Wait until the model is ready. It usually takes several minutes
                ModelStatus? model_status = null;
                int tryout_count = 1;
                response = client.GetMultivariateModel(trained_model_id);
                while (tryout_count < max_tryout & model_status != ModelStatus.Ready & model_status != ModelStatus.Failed)
                {
                    Thread.Sleep(1000);
                    response = client.GetMultivariateModel(trained_model_id);
                    model_status = response.ModelInfo.Status;
                    Console.WriteLine(string.Format("try {0}, model_id: {1}, status: {2}.", tryout_count, trained_model_id, model_status));
                    tryout_count += 1;
                };

                if (model_status == ModelStatus.Ready)
                {
                    Console.WriteLine("Creating model succeeds.");
                    Console.WriteLine(string.Format("{0} available models after training.", GetModelNumber(client)));
                    return trained_model_id;
                }

                if (model_status == ModelStatus.Failed)
                {
                    Console.WriteLine("Creating model failed.");
                    Console.WriteLine("Errors:");
                    try
                    {
                        Console.WriteLine(string.Format("Error code: {0}, Message: {1}", response.ModelInfo.Errors[0].Code.ToString(), response.ModelInfo.Errors[0].Message.ToString()));
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(string.Format("Get error message fail: {0}", e.Message));
                    }
                }
                return null;
            }
            catch (Exception e)
            {
                Console.WriteLine(string.Format("Train error. {0}", e.Message));
                throw;
            }
        }

        MultivariateDetectionResult BatchDetect(AnomalyDetectorClient client, string datasource, string model_id, DateTimeOffset start_time, DateTimeOffset end_time, int max_tryout = 500)
        {
            try
            {
                Console.WriteLine("Start batch detect...");
                MultivariateBatchDetectionOptions request = new MultivariateBatchDetectionOptions(datasource, 10, start_time, end_time);

                Console.WriteLine("Start batch detection, this might take a few minutes...");
                MultivariateDetectionResult response = client.DetectMultivariateBatchAnomaly(model_id, request);
                string result_id = response.ResultId;
                Console.WriteLine(string.Format("result id is: {0}", result_id));

                // get detection result
                MultivariateDetectionResult resultResponse = client.GetMultivariateBatchDetectionResult(result_id);
                MultivariateBatchDetectionStatus result_status = resultResponse.Summary.Status;
                int tryout_count = 0;
                while (tryout_count < max_tryout & result_status != MultivariateBatchDetectionStatus.Ready & result_status != MultivariateBatchDetectionStatus.Failed)
                {
                    Thread.Sleep(1000);
                    resultResponse = client.GetMultivariateBatchDetectionResult(result_id);
                    result_status = resultResponse.Summary.Status;
                    Console.WriteLine(string.Format("try: {0}, result id: {1} Detection status is {2}", tryout_count, result_id, result_status.ToString()));
                    Console.Out.Flush();
                }

                if (result_status == MultivariateBatchDetectionStatus.Failed)
                {
                    Console.WriteLine("Detection failed.");
                    Console.WriteLine("Errors:");
                    try
                    {
                        Console.WriteLine(string.Format("Error code: {}. Message: {}", resultResponse.Summary.Errors[0].Code.ToString(), resultResponse.Summary.Errors[0].Message.ToString()));
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(string.Format("Get error message fail: {0}", e.Message));
                    }
                    return null;
                }
                return resultResponse;
            }
            catch (Exception e)
            {
                Console.WriteLine(string.Format("Detection error. {0}", e.Message));
                throw;
            }
        }

        void DeleteModel(AnomalyDetectorClient client, string model_id)
        {
            client.DeleteMultivariateModel(model_id);
            int model_number = GetModelNumber(client);
            Console.WriteLine(string.Format("{0} available models after deletion.", model_number));
        }
 
    }
}

執行應用程式

使用 dotnet run 命令,從您的應用程式目錄執行應用程式。

dotnet run

清除資源

如果您想要清除和移除 Azure AI 服務訂用帳戶,則可以刪除資源或資源群組。 刪除資源群組也會刪除與資源群組相關聯的任何其他資源。

下一步

開始使用適用於 JavaScript 的異常偵測程式多變量用戶端程式庫。 請遵循下列步驟安裝套件,並開始使用服務提供的演算法。 新的多變量異常偵測程式 API 可讓開發人員輕鬆整合進階 AI 來偵測計量群組中的異常,而不需要機器學習知識或標籤資料。 不同信號之間的相依性和相互關聯會自動視為主要因素。 這可協助您主動保護複雜的系統免於失敗。

使用適用於 JavaScript 的異常偵測程式多變量用戶端程式庫來:

  • 偵測一組時間序列中的系統層級異常。
  • 當您無法從任何個別的時間序列得知太多資訊,而必須查看所有信號來偵測問題時。
  • 透過數十到數百種不同類型感應器預測性維護昂貴的實體資產,以測量各個層面的系統健康情況。

程式庫參考文件 | 程式庫原始程式碼 | 套件 (npm) | 範例程式碼

必要條件

  • Azure 訂用帳戶 - 建立免費帳戶
  • 最新版的 Node.js
  • 擁有 Azure 訂用帳戶之後,在 Azure 入口網站中建立異常偵測程式資源,以取得您的金鑰和端點。 部署完成後,選取 [移至資源] 按鈕。
    • 您需要來自所建立資源的金鑰和端點,以將應用程式連線至異常偵測器 API。 您稍後會在快速入門中將金鑰和端點貼到下列程式碼中。 您可以使用免費定價層 (F0) 來試用服務,之後可升級至付費層以用於實際執行環境。

設定

建立新的 Node.js 應用程式

在主控台視窗 (例如 cmd、PowerShell 或 Bash) 中,為您的應用程式建立新的目錄,並瀏覽至該目錄。

mkdir myapp && cd myapp

執行命令 npm init,以使用 package.json 檔案建立節點應用程式。

npm init

建立名為 index.js 的檔案,並匯入下列程式庫:

'use strict'

const fs = require('fs');
const parse = require("csv-parse/lib/sync");
const { AnomalyDetectorClient } = require('@azure/ai-anomaly-detector');
const { AzureKeyCredential } = require('@azure/core-auth');

為資源的 Azure 端點和金鑰建立變數。 為範例資料檔案建立另一個變數。

注意

您一律可以選擇使用兩個金鑰的其中一個。 這是為了進行安全金鑰輪替。 基於本快速入門的目的,請使用第一個金鑰。

const apiKey = "YOUR_API_KEY";
const endpoint = "YOUR_ENDPOINT";
const data_source = "YOUR_SAMPLE_ZIP_FILE_LOCATED_IN_AZURE_BLOB_STORAGE_WITH_SAS";

重要

完成時,請記得從程式碼中移除金鑰,且不要公開張貼金鑰。 在生產環境中,請使用安全的方式來儲存和存取您的認證,例如 Azure Key Vault。 如需詳細資訊,請參閱 Azure AI 服務安全性一文。

若要使用異常偵測程式多變量 API,您必須先定型您自己的模型。 定型資料是一組符合下列需求的多個時間序列:

每個時間序列都應該是具有兩個 (且只有兩個) 資料行 ("timestamp" 和 "value",皆為小寫) 做為標頭列的 CSV 檔案。 "timestamp" 值應符合 ISO 8601;"value" 可以是整數,也可以是具有任意小數位數的十進位數。 例如:

timestamp value
2019-04-01T00:00:00Z 5
2019-04-01T00:01:00Z 3.6
2019-04-01T00:02:00Z 4
... ...

每個 CSV 檔案都應該以將用於模型定型的不同變數命名。 例如,"temperature.csv" 和 "humidity.csv"。 所有 CSV 檔案都應該壓縮成單一 ZIP 檔案,而不需要任何子資料夾。 ZIP 檔案可以使用任何您想要的名稱。 ZIP 檔案應上傳至 Azure Blob 儲存體。 一旦您產生 ZIP 檔案的 blob SAS (共用存取簽章) URL 後,就可將其用於定型。 請參閱本文件,以了解如何從 Azure Blob 儲存體產生 SAS URL。

安裝用戶端程式庫

安裝 ms-rest-azureazure-ai-anomalydetector NPM 套件。 本快速入門中也會使用 csv-parse 程式庫:

npm install @azure/ai-anomaly-detector csv-parse

您應用程式的 package.json 檔案會隨著相依性而更新。

程式碼範例

這些程式碼片段會示範如何使用適用於 Node.js 的 Anomaly Detector 用戶端程式庫來執行下列動作:

驗證用戶端

使用您的端點和認證將 AnomalyDetectorClient 物件具現化。

const client = new AnomalyDetectorClient(endpoint, new AzureKeyCredential(apiKey));

將模型定型

建構模型結果

首先,我們需要建構模型要求。 請確定開始和結束時間與您的資料來源一致。

const Modelrequest = {
  source: data_source,
  startTime: new Date(2021,0,1,0,0,0),
  endTime: new Date(2021,0,2,12,0,0),
  slidingWindow:200
};

定型新的模型

您將模型要求傳遞至異常偵測程式用戶端 trainMultivariateModel 方法。

console.log("Training a new model...")
const train_response = await client.trainMultivariateModel(Modelrequest)
const model_id = train_response.location?.split("/").pop() ?? ""
console.log("New model ID: " + model_id)

若要檢查模型的定型是否已完成,您可以追蹤模型的狀態:

let model_response = await client.getMultivariateModel(model_id);
let model_status = model_response.modelInfo.status;

while (model_status != 'READY' && model_status != 'FAILED'){
  await sleep(10000).then(() => {});
  model_response = await client.getMultivariateModel(model_id);
  model_status = model_response.modelInfo.status;
}

if (model_status == 'FAILED') {
  console.log("Training failed.\nErrors:");
  for (let error of model_response.modelInfo?.errors ?? []) {
    console.log("Error code: " + error.code + ". Message: " + error.message);
  }
}

console.log("TRAINING FINISHED.");

偵測異常

使用 detectAnomalygetDectectionResult 函數來判斷資料來源內是否有任何異常。

console.log("Start detecting...");
const detect_request = {
  source: data_source,
  startTime: new Date(2021,0,2,12,0,0),
  endTime: new Date(2021,0,3,0,0,0)
};
const result_header = await client.detectAnomaly(model_id, detect_request);
const result_id = result_header.location?.split("/").pop() ?? "";
let result = await client.getDetectionResult(result_id);
let result_status = result.summary.status;

while (result_status != 'READY' && result_status != 'FAILED'){
  await sleep(2000).then(() => {});
  result = await client.getDetectionResult(result_id);
  result_status = result.summary.status;
}

if (result_status == 'FAILED') {
  console.log("Detection failed.\nErrors:");
  for (let error of result.summary.errors ?? []) {
    console.log("Error code: " + error.code + ". Message: " + error.message)
  }
}
console.log("Result status: " + result_status);
console.log("Result Id: " + result.resultId);

匯出模式

注意

export 命令旨在用來允許在容器化環境中執行異常偵測程式多變量模型。 多變量目前不支援此功能,但未來將會新增支援。

若要匯出定型的模型,請使用 exportModel 函數。

const export_result = await client.exportModel(model_id)
const model_path = "model.zip"
const destination = fs.createWriteStream(model_path)
export_result.readableStreamBody?.pipe(destination)
console.log("New model has been exported to "+model_path+".")

刪除模型

若要刪除可供目前資源使用的現有模型,請使用 deleteMultivariateModel 函數。

client.deleteMultivariateModel(model_id)
console.log("New model has been deleted.")

執行應用程式

在執行應用程式之前,檢查您的程式碼是否有完整的範例程式碼可能會有所幫助

使用快速入門檔案上使用 node 命令執行應用程式。

node index.js

清除資源

如果您想要清除和移除 Azure AI 服務訂用帳戶,則可以刪除資源或資源群組。 刪除資源群組也會刪除與資源群組相關聯的任何其他資源。

下一步

程式庫參考文件 |程式庫原始程式碼 | 套件 (PyPi) |在 GitHub 上尋找範例程式碼

開始使用適用於 Python 的異常偵測程式多變量用戶端程式庫。 請遵循下列步驟安裝套件,並開始使用服務提供的演算法。 新的多變量異常偵測程式 API 可讓開發人員輕鬆整合進階 AI 來偵測計量群組中的異常,而不需要機器學習知識或標籤資料。 不同信號之間的相依性和相互關聯會自動視為主要因素。 這可協助您主動保護複雜的系統免於失敗。

使用適用於 Python 的異常偵測程式多變量用戶端程式庫來:

  • 偵測一組時間序列中的系統層級異常。
  • 當您無法從任何個別的時間序列得知太多資訊,而必須查看所有信號來偵測問題時。
  • 透過數十到數百種不同類型感應器預測性維護昂貴的實體資產,以測量各個層面的系統健康情況。

必要條件

  • Azure 訂用帳戶 - 建立免費帳戶
  • Python 3.x
  • 擁有 Azure 訂用帳戶之後,在 Azure 入口網站中建立異常偵測程式資源,以取得您的金鑰和端點。 部署完成後,選取 [移至資源] 按鈕。 您可以使用免費定價層 (F0) 來試用服務,之後可升級至付費層以用於實際執行環境。

設定

安裝用戶端程式庫。 您可以使用下列命令來安裝用戶端程式庫:

pip install --upgrade azure.ai.anomalydetector

建立儲存體帳戶

多變量異常偵測程式需要您將範例檔案儲存在 Azure Blob 儲存體中。

  1. 建立 Azure 儲存體帳戶
  2. 移至 [存取控制 (IAM)],然後選取 [新增] 以新增角色指派。
  3. 搜尋 [儲存體 Blob 資料] 的角色以醒目顯示此帳戶類型,然後選取 [下一步]。
  4. 選取 [將存取權指派給受控識別],並選取 [成員],然後選擇您稍早建立的 [異常偵測程式資源],再選取 [檢閱 + 指派]。

這種設定有時可能會有點令人困惑,如果您遇到問題,建議您諮詢我們的多變量 Jupyter Notebook 範例,該範例能更深入地逐步解說此流程。

下載範例資料

本快速入門會針對範例資料 sample_data_5_3000.csv 使用一個檔案。 檔案可從我們的 GitHub 範本資料中進行下載

您也可以執行下列項目來下載範例資料:

curl "https://github.com/Azure-Samples/AnomalyDetector/blob/master/sampledata/multivariate/sample_data_5_3000.csv" --output sample_data_5_3000_.csv

將範例資料上傳至儲存體帳戶

  1. 移至您的 [儲存體帳戶],選取 [容器],然後建立新的容器。
  2. 選取 [上傳] 並上傳 sample_data_5_3000.csv
  3. 選取您所上傳的資料,並複製 Blob URL,因為您需要在幾個步驟後將其新增至程式碼範例中。

擷取金鑰和端點

若要成功對異常偵測程式服務發出呼叫,您需要下列值:

變數名稱
ANOMALY_DETECTOR_ENDPOINT 從 Azure 入口網站查看您的資源時,可以在 [金鑰與端點] 區段中找到此值。 範例端點:https://YOUR_RESOURCE_NAME.cognitiveservices.azure.com/
ANOMALY_DETECTOR_API_KEY 當您透過 Azure 入口網站查看資源時,可以在 [金鑰和端點] 區段中找到 API 金鑰值。 您可以使用 KEY1KEY2

移至您在 Azure 入口網站中的資源。 您可以在 [資源管理] 區段中找到 [端點和金鑰]。 複製您的端點和存取金鑰,因為您需要這兩者才能驗證 API 呼叫。 您可以使用 KEY1KEY2。 隨時持有兩個金鑰可讓您安全地輪替和重新產生金鑰,而不會造成服務中斷。

建立環境變數

為您的金鑰和端點建立及指派永續性環境變數。

重要

如果您使用 API 金鑰,請將其安全地儲存在別處,例如 Azure Key Vault。 請勿在程式碼中直接包含 API 金鑰,且切勿公開張貼金鑰。

如需 AI 服務安全性的詳細資訊,請參閱驗證對 Azure AI 服務的要求 (英文)。

setx ANOMALY_DETECTOR_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx ANOMALY_DETECTOR_ENDPOINT "REPLACE_WITH_YOUR_ENDPOINT_HERE"

建立新的 Python 應用程式

  1. 建立名為 sample_multivariate_detect.py 的新 Python 檔案。 然後,以您慣用的編輯器或 IDE 加以開啟。

  2. 以下列程式碼取代 sample_multivariate_detect.py.cs 的內容。 您必須修改變數 blob_url 的路徑。

import time
from datetime import datetime, timezone
from azure.ai.anomalydetector import AnomalyDetectorClient
from azure.core.credentials import AzureKeyCredential
from azure.ai.anomalydetector.models import *
import os

SUBSCRIPTION_KEY =  os.environ['ANOMALY_DETECTOR_API_KEY']
ANOMALY_DETECTOR_ENDPOINT = os.environ['ANOMALY_DETECTOR_ENDPOINT']

ad_client = AnomalyDetectorClient(ANOMALY_DETECTOR_ENDPOINT, AzureKeyCredential(SUBSCRIPTION_KEY))

time_format = "%Y-%m-%dT%H:%M:%SZ"
blob_url = "Path-to-sample-file-in-your-storage-account"  # example path: https://docstest001.blob.core.windows.net/test/sample_data_5_3000.csv

train_body = ModelInfo(
    data_source=blob_url,
    start_time=datetime.strptime("2021-01-02T00:00:00Z", time_format),
    end_time=datetime.strptime("2021-01-02T05:00:00Z", time_format),
    data_schema="OneTable",
    display_name="sample",
    sliding_window=200,
    align_policy=AlignPolicy(
        align_mode=AlignMode.OUTER,
        fill_n_a_method=FillNAMethod.LINEAR,
        padding_value=0,
    ),
)

batch_inference_body = MultivariateBatchDetectionOptions(
       data_source=blob_url,
       top_contributor_count=10,
       start_time=datetime.strptime("2021-01-02T00:00:00Z", time_format),
       end_time=datetime.strptime("2021-01-02T05:00:00Z", time_format),
   )


print("Training new model...(it may take a few minutes)")
model = ad_client.train_multivariate_model(train_body)
model_id = model.model_id
print("Training model id is {}".format(model_id))

## Wait until the model is ready. It usually takes several minutes
model_status = None
model = None

while model_status != ModelStatus.READY and model_status != ModelStatus.FAILED:
    model = ad_client.get_multivariate_model(model_id)
    print(model)
    model_status = model.model_info.status
    print("Model is {}".format(model_status))
    time.sleep(30)
if model_status == ModelStatus.READY:
    print("Done.\n--------------------")
    # Return the latest model id

# Detect anomaly in the same data source (but a different interval)
result = ad_client.detect_multivariate_batch_anomaly(model_id, batch_inference_body)
result_id = result.result_id

# Get results (may need a few seconds)
anomaly_results = ad_client.get_multivariate_batch_detection_result(result_id)
print("Get detection result...(it may take a few seconds)")

while anomaly_results.summary.status != MultivariateBatchDetectionStatus.READY and anomaly_results.summary.status != MultivariateBatchDetectionStatus.FAILED:
    anomaly_results = ad_client.get_multivariate_batch_detection_result(result_id)
    print("Detection is {}".format(anomaly_results.summary.status))
    time.sleep(5)
    
   
print("Result ID:\t", anomaly_results.result_id)
print("Result status:\t", anomaly_results.summary.status)
print("Result length:\t", len(anomaly_results.results))

# See detailed inference result
for r in anomaly_results.results:
    print(
        "timestamp: {}, is_anomaly: {:<5}, anomaly score: {:.4f}, severity: {:.4f}, contributor count: {:<4d}".format(
            r.timestamp,
            r.value.is_anomaly,
            r.value.score,
            r.value.severity,
            len(r.value.interpretation) if r.value.is_anomaly else 0,
        )
    )
    if r.value.interpretation:
        for contributor in r.value.interpretation:
            print(
                "\tcontributor variable: {:<10}, contributor score: {:.4f}".format(
                    contributor.variable, contributor.contribution_score
                )
            )

執行應用程式

使用快速入門檔案上使用 python 命令執行應用程式。

python sample_multivariate_detect.py

輸出

10 available models before training.
Training new model...(it may take a few minutes)
Training model id is 3a695878-a88f-11ed-a16c-b290e72010e0
{'modelId': '3a695878-a88f-11ed-a16c-b290e72010e0', 'createdTime': '2023-02-09T15:34:23Z', 'lastUpdatedTime': '2023-02-09T15:34:23Z', 'modelInfo': {'dataSource': 'https://docstest001.blob.core.windows.net/test/sample_data_5_3000 (1).csv', 'dataSchema': 'OneTable', 'startTime': '2021-01-02T00:00:00Z', 'endTime': '2021-01-02T05:00:00Z', 'displayName': 'sample', 'slidingWindow': 200, 'alignPolicy': {'alignMode': 'Outer', 'fillNAMethod': 'Linear', 'paddingValue': 0.0}, 'status': 'CREATED', 'errors': [], 'diagnosticsInfo': {'modelState': {'epochIds': [], 'trainLosses': [], 'validationLosses': [], 'latenciesInSeconds': []}, 'variableStates': []}}}
Model is CREATED
{'modelId': '3a695878-a88f-11ed-a16c-b290e72010e0', 'createdTime': '2023-02-09T15:34:23Z', 'lastUpdatedTime': '2023-02-09T15:34:55Z', 'modelInfo': {'dataSource': 'https://docstest001.blob.core.windows.net/test/sample_data_5_3000 (1).csv', 'dataSchema': 'OneTable', 'startTime': '2021-01-02T00:00:00Z', 'endTime': '2021-01-02T05:00:00Z', 'displayName': 'sample', 'slidingWindow': 200, 'alignPolicy': {'alignMode': 'Outer', 'fillNAMethod': 'Linear', 'paddingValue': 0.0}, 'status': 'READY', 'errors': [], 'diagnosticsInfo': {'modelState': {'epochIds': [10, 20, 30, 40, 50, 60, 70, 80, 90, 100], 'trainLosses': [1.0493712276220322, 0.5454281121492386, 0.42524269968271255, 0.38019897043704987, 0.3472398854792118, 0.34301353991031647, 0.3219067454338074, 0.3108387663960457, 0.30357857793569565, 0.29986055195331573], 'validationLosses': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 'latenciesInSeconds': [0.3412797451019287, 0.25798678398132324, 0.2556419372558594, 0.3165152072906494, 0.2748451232910156, 0.26111531257629395, 0.2571413516998291, 0.257282018661499, 0.2549862861633301, 0.25806593894958496]}, 'variableStates': [{'variable': 'series_0', 'filledNARatio': 0.0, 'effectiveCount': 301, 'firstTimestamp': '2021-01-02T00:00:00Z', 'lastTimestamp': '2021-01-02T05:00:00Z'}, {'variable': 'series_1', 'filledNARatio': 0.0, 'effectiveCount': 301, 'firstTimestamp': '2021-01-02T00:00:00Z', 'lastTimestamp': '2021-01-02T05:00:00Z'}, {'variable': 'series_2', 'filledNARatio': 0.0, 'effectiveCount': 301, 'firstTimestamp': '2021-01-02T00:00:00Z', 'lastTimestamp': '2021-01-02T05:00:00Z'}, {'variable': 'series_3', 'filledNARatio': 0.0, 'effectiveCount': 301, 'firstTimestamp': '2021-01-02T00:00:00Z', 'lastTimestamp': '2021-01-02T05:00:00Z'}, {'variable': 'series_4', 'filledNARatio': 0.0, 'effectiveCount': 301, 'firstTimestamp': '2021-01-02T00:00:00Z', 'lastTimestamp': '2021-01-02T05:00:00Z'}]}}}
Model is READY
Done.
--------------------
10 available models after training.
Get detection result...(it may take a few seconds)
Detection is CREATED
Detection is READY
Result ID:	 70a6cdf8-a88f-11ed-a461-928899e62c38
Result status:	 READY
Result length:	 301
timestamp: 2021-01-02 00:00:00+00:00, is_anomaly: 0    , anomaly score: 0.1770, severity: 0.0000, contributor count: 0   
timestamp: 2021-01-02 00:01:00+00:00, is_anomaly: 0    , anomaly score: 0.3446, severity: 0.0000, contributor count: 0   
timestamp: 2021-01-02 00:02:00+00:00, is_anomaly: 0    , anomaly score: 0.2397, severity: 0.0000, contributor count: 0   
timestamp: 2021-01-02 00:03:00+00:00, is_anomaly: 0    , anomaly score: 0.1270, severity: 0.0000, contributor count: 0   
timestamp: 2021-01-02 00:04:00+00:00, is_anomaly: 0    , anomaly score: 0.3321, severity: 0.0000, contributor count: 0   
timestamp: 2021-01-02 00:05:00+00:00, is_anomaly: 0    , anomaly score: 0.4053, severity: 0.0000, contributor count: 0   
timestamp: 2021-01-02 00:06:00+00:00, is_anomaly: 0    , anomaly score: 0.4371, severity: 0.0000, contributor count: 0   
timestamp: 2021-01-02 00:07:00+00:00, is_anomaly: 1    , anomaly score: 0.6615, severity: 0.3850, contributor count: 5   
	contributor variable: series_3  , contributor score: 0.2939
	contributor variable: series_1  , contributor score: 0.2834
	contributor variable: series_4  , contributor score: 0.2329
	contributor variable: series_0  , contributor score: 0.1543
	contributor variable: series_2  , contributor score: 0.0354

為了簡潔起見,輸出結果已截斷。

清除資源

如果您想要清除和移除異常偵測器資源,可以刪除資源或資源群組。 刪除資源群組也會刪除與其相關聯的任何其他資源。 如果您不想再使用您所建立的環境變數,建議您也考慮刪除環境變數

開始使用適用於 JAVA 的異常偵測程式多變量用戶端程式庫。 請依照下列步驟,開始使用服務提供的演算法安裝套件。 新的多變量異常偵測程式 API 可讓開發人員輕鬆整合進階 AI 來偵測計量群組中的異常,而不需要機器學習知識或標籤資料。 不同信號之間的相依性和相互關聯會自動視為主要因素。 這可協助您主動保護複雜的系統免於失敗。

使用適用於 JAVA 的異常偵測程式多變量用戶端程式庫來:

  • 偵測一組時間序列中的系統層級異常。
  • 當您無法從任何個別的時間序列得知太多資訊,而必須查看所有信號來偵測問題時。
  • 透過數十到數百種不同類型感應器預測性維護昂貴的實體資產,以測量各個層面的系統健康情況。

程式庫參考文件 | 程式庫原始程式碼 | 套件 (Maven) | 範例程式碼

必要條件

  • Azure 訂用帳戶 - 建立免費帳戶
  • 最新版的 Java Development Kit (JDK)
  • Gradle 建置工具,或其他相依性管理員。
  • 擁有 Azure 訂用帳戶之後,在 Azure 入口網站中建立異常偵測程式資源,以取得您的金鑰和端點。 部署完成後,選取 [移至資源] 按鈕。
    • 您需要來自所建立資源的金鑰和端點,以將應用程式連線至異常偵測器 API。 您稍後會在快速入門中將金鑰和端點貼到下列程式碼中。 您可以使用免費定價層 (F0) 來試用服務,之後可升級至付費層以用於實際執行環境。

設定

建立新的 Gradle 專案

本快速入門會使用 Gradle 相依性管理員。 您可以在 Maven 中央存放庫中找到更多用戶端程式庫資訊。

在主控台視窗 (例如 cmd、PowerShell 或 Bash) 中,為您的應用程式建立新的目錄,並瀏覽至該目錄。

mkdir myapp && cd myapp

從您的工作目錄執行 gradle init 命令。 此命令會建立 Gradle 的基本組建檔案,包括 build.gradle.kts,將在執行階段使用 build.gradle.kts,來建立及設定應用程式。

gradle init --type basic

出現選擇 DSL 的提示時,請選取 [Kotlin]

安裝用戶端程式庫

找出 build.gradle.kts,並使用您慣用的 IDE 或文字編輯器加以開啟。 然後,在此組建組態中複製下列內容。 請務必包含專案相依性。

dependencies {
    compile("com.azure:azure-ai-anomalydetector")
}

建立 Java 檔案

建立範例應用程式的資料夾。 從工作目錄執行下列命令:

mkdir -p src/main/java

瀏覽至新的資料夾,並建立名為 MetricsAdvisorQuickstarts.java 的檔案。 在您慣用的編輯器或 IDE 中開啟該檔案,並新增下列 import 陳述式:

package com.azure.ai.anomalydetector;

import com.azure.ai.anomalydetector.models.*;
import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.http.*;
import com.azure.core.http.policy.*;
import com.azure.core.http.rest.PagedIterable;
import com.azure.core.http.rest.PagedResponse;
import com.azure.core.http.rest.Response;
import com.azure.core.http.rest.StreamResponse;
import com.azure.core.util.Context;
import reactor.core.publisher.Flux;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

為資源的 Azure 端點和金鑰建立變數。 為範例資料檔案建立另一個變數。

注意

您一律可以選擇使用兩個金鑰的其中一個。 這是為了進行安全金鑰輪替。 基於本快速入門的目的,請使用第一個金鑰。

String key = "YOUR_API_KEY";
String endpoint = "YOUR_ENDPOINT";

重要

完成時,請記得從程式碼中移除金鑰,且不要公開張貼金鑰。 在生產環境中,請使用安全的方式來儲存和存取您的認證,例如 Azure Key Vault。 如需詳細資訊,請參閱 Azure AI 服務安全性一文。

若要使用異常偵測程式多變量 API,您必須先定型您自己的模型。 定型資料是一組符合下列需求的多個時間序列:

每個時間序列都應該是具有兩個 (且只有兩個) 資料行 ("timestamp" 和 "value",皆為小寫) 做為標頭列的 CSV 檔案。 "timestamp" 值應符合 ISO 8601;"value" 可以是整數,也可以是具有任意小數位數的十進位數。 例如:

timestamp value
2019-04-01T00:00:00Z 5
2019-04-01T00:01:00Z 3.6
2019-04-01T00:02:00Z 4
... ...

每個 CSV 檔案都應該以將用於模型定型的不同變數命名。 例如,"temperature.csv" 和 "humidity.csv"。 所有 CSV 檔案都應該壓縮成單一 ZIP 檔案,而不需要任何子資料夾。 ZIP 檔案可以使用任何您想要的名稱。 ZIP 檔案應上傳至 Azure Blob 儲存體。 一旦您產生 ZIP 檔案的 blob SAS (共用存取簽章) URL 後,就可將其用於定型。 請參閱本文件,以了解如何從 Azure Blob 儲存體產生 SAS URL。

程式碼範例

這些程式碼片段會示範如何使用適用於 Node.js 的 Anomaly Detector 用戶端程式庫來執行下列動作:

驗證用戶端

使用您的端點和認證將 anomalyDetectorClient 物件具現化。

HttpHeaders headers = new HttpHeaders()
    .put("Accept", ContentType.APPLICATION_JSON);

HttpPipelinePolicy authPolicy = new AzureKeyCredentialPolicy("Ocp-Apim-Subscription-Key",
 new AzureKeyCredential(key));
AddHeadersPolicy addHeadersPolicy = new AddHeadersPolicy(headers);

HttpPipeline httpPipeline = new HttpPipelineBuilder().httpClient(HttpClient.createDefault())
    .policies(authPolicy, addHeadersPolicy).build();
// Instantiate a client that will be used to call the service.
HttpLogOptions httpLogOptions = new HttpLogOptions();
httpLogOptions.setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS);

AnomalyDetectorClient anomalyDetectorClient = new AnomalyDetectorClientBuilder()
    .pipeline(httpPipeline)
    .endpoint(endpoint)
    .httpLogOptions(httpLogOptions)
    .buildClient();

將模型定型

建構模型結果和定型模型

首先,我們需要建構模型要求。 請確定開始和結束時間與您的資料來源一致。

若要使用異常偵測程式多變量 API,我們必須在使用偵測之前定型自己的模型。 用於定型的資料是批次時間序列,每個時間序列都應該在只有兩個資料行 ("timestamp""value") 的 CSV 檔案中 (資料行名稱應該完全相同)。 每個 CSV 檔案都應該以時間序列的每個變數命名。 所有的時間序列都應壓縮成單一 ZIP 檔案,並上傳至 Azure Blob 儲存體,且不需要 ZIP 檔案名稱。 或者,如果您需要變數的名稱與 .zip 檔案名稱不同,則可以將額外的 meta.json 檔案包含在 ZIP 檔案中。 當我們產生 blob SAS (共用存取簽章) URL 之後,就可以使用 ZIP 檔案的 URL 來進行定型。

Path path = Paths.get("test-data.csv");
List<String> requestData = Files.readAllLines(path);
List<TimeSeriesPoint> series = requestData.stream()
    .map(line -> line.trim())
    .filter(line -> line.length() > 0)
    .map(line -> line.split(",", 2))
    .filter(splits -> splits.length == 2)
    .map(splits -> {
        TimeSeriesPoint timeSeriesPoint = new TimeSeriesPoint();
        timeSeriesPoint.setTimestamp(OffsetDateTime.parse(splits[0]));
        timeSeriesPoint.setValue(Float.parseFloat(splits[1]));
        return timeSeriesPoint;
    })
    .collect(Collectors.toList());

Integer window = 28;
AlignMode alignMode = AlignMode.OUTER;
FillNAMethod fillNAMethod = FillNAMethod.LINEAR;
Integer paddingValue = 0;
AlignPolicy alignPolicy = new AlignPolicy()
                                .setAlignMode(alignMode)
                                .setFillNAMethod(fillNAMethod)
                                .setPaddingValue(paddingValue);
String source = "YOUR_SAMPLE_ZIP_FILE_LOCATED_IN_AZURE_BLOB_STORAGE_WITH_SAS";
OffsetDateTime startTime = OffsetDateTime.of(2021, 1, 2, 0, 0, 0, 0, ZoneOffset.UTC);
OffsetDateTime endTime = OffsetDateTime.of(2021, 1, 3, 0, 0, 0, 0, ZoneOffset.UTC);
String displayName = "Devops-MultiAD";

ModelInfo request = new ModelInfo()
                        .setSlidingWindow(window)
                        .setAlignPolicy(alignPolicy)
                        .setSource(source)
                        .setStartTime(startTime)
                        .setEndTime(endTime)
                        .setDisplayName(displayName);
TrainMultivariateModelResponse trainMultivariateModelResponse = anomalyDetectorClient.trainMultivariateModelWithResponse(request, Context.NONE);
String header = trainMultivariateModelResponse.getDeserializedHeaders().getLocation();
String[] substring = header.split("/");
UUID modelId = UUID.fromString(substring[substring.length - 1]);
System.out.println(modelId);

//Check model status until the model is ready
Response<Model> trainResponse;
while (true) {
    trainResponse = anomalyDetectorClient.getMultivariateModelWithResponse(modelId, Context.NONE);
    ModelStatus modelStatus = trainResponse.getValue().getModelInfo().getStatus();
    if (modelStatus == ModelStatus.READY || modelStatus == ModelStatus.FAILED) {
        break;
    }
    TimeUnit.SECONDS.sleep(10);
}

if (trainResponse.getValue().getModelInfo().getStatus() != ModelStatus.READY){
    System.out.println("Training failed.");
    List<ErrorResponse> errorMessages = trainResponse.getValue().getModelInfo().getErrors();
    for (ErrorResponse errorMessage : errorMessages) {
        System.out.println("Error code:  " + errorMessage.getCode());
        System.out.println("Error message:  " + errorMessage.getMessage());
    }
}

偵測異常

DetectionRequest detectionRequest = new DetectionRequest().setSource(source).setStartTime(startTime).setEndTime(endTime);
DetectAnomalyResponse detectAnomalyResponse = anomalyDetectorClient.detectAnomalyWithResponse(modelId, detectionRequest, Context.NONE);
String location = detectAnomalyResponse.getDeserializedHeaders().getLocation();
String[] substring = location.split("/");
UUID resultId = UUID.fromString(substring[substring.length - 1]);

DetectionResult detectionResult;
while (true) {
    detectionResult = anomalyDetectorClient.getDetectionResult(resultId);
    DetectionStatus detectionStatus = detectionResult.getSummary().getStatus();;
    if (detectionStatus == DetectionStatus.READY || detectionStatus == DetectionStatus.FAILED) {
        break;
    }
    TimeUnit.SECONDS.sleep(10);
}

if (detectionResult.getSummary().getStatus() != DetectionStatus.READY){
    System.out.println("Inference failed");
    List<ErrorResponse> detectErrorMessages = detectionResult.getSummary().getErrors();
    for (ErrorResponse errorMessage : detectErrorMessages) {
        System.out.println("Error code:  " + errorMessage.getCode());
        System.out.println("Error message:  " + errorMessage.getMessage());
    }
}

匯出模式

注意

export 命令旨在用來允許在容器化環境中執行異常偵測程式多變量模型。 多變量目前不支援此功能,但未來將會新增支援。

若要匯出定型的模型,請使用 exportModelWithResponse

StreamResponse response_export = anomalyDetectorClient.exportModelWithResponse(model_id, Context.NONE);
Flux<ByteBuffer> value = response_export.getValue();
FileOutputStream bw = new FileOutputStream("result.zip");
value.subscribe(s -> write(bw, s), (e) -> close(bw), () -> close(bw));

刪除模型

若要刪除可供目前資源使用的現有模型,請使用 deleteMultivariateModelWithResponse 函數。

Response<Void> deleteMultivariateModelWithResponse = anomalyDetectorClient.deleteMultivariateModelWithResponse(model_id, Context.NONE);

執行應用程式

您可以使用下列命令來建置應用程式:

gradle build

執行應用程式

在執行之前,檢查您的程式碼是否有完整的範例程式碼可能會有所幫助。

使用 run 目標執行應用程式:

gradle run

清除資源

如果您想要清除和移除 Azure AI 服務訂用帳戶,則可以刪除資源或資源群組。 刪除資源群組也會刪除與資源群組相關聯的任何其他資源。

下一步