Dela via


Snabbstart: Använda klientbiblioteket multivariate Avvikelseidentifiering

Viktigt!

Från och med den 20 september 2023 kan du inte skapa nya Avvikelseidentifiering resurser. Tjänsten Avvikelseidentifiering dras tillbaka den 1 oktober 2026.

Kom igång med Avvikelseidentifiering multivariate-klientbiblioteket för C#. Följ de här stegen för att installera paketet och börja använda de algoritmer som tillhandahålls av tjänsten. De nya API:erna för multivariatavvikelseidentifiering gör det möjligt för utvecklare genom att enkelt integrera avancerad AI för att identifiera avvikelser från grupper av mått, utan att behöva maskininlärningskunskaper eller märkta data. Beroenden och korrelationer mellan olika signaler räknas automatiskt som nyckelfaktorer. Detta hjälper dig att proaktivt skydda dina komplexa system mot fel.

Använd Avvikelseidentifiering klientbibliotek för flera variater för C# för att:

  • Identifiera avvikelser på systemnivå från en grupp med tidsserier.
  • När en enskild tidsserie inte berättar mycket och du måste titta på alla signaler för att upptäcka ett problem.
  • Förebyggande underhåll av dyra fysiska tillgångar med tiotals till hundratals olika typer av sensorer som mäter olika aspekter av systemets hälsa.

Biblioteksreferensdokumentation Bibliotekets källkodspaket | (NuGet) |

Förutsättningar

  • Azure-prenumeration – Skapa en kostnadsfritt
  • Den aktuella versionen av .NET Core
  • När du har din Azure-prenumeration skapar du en Avvikelseidentifiering resurs i Azure Portal för att hämta din nyckel och slutpunkt. Vänta tills den har distribuerats och välj knappen Gå till resurs .
    • Du behöver nyckeln och slutpunkten från resursen som du skapar för att ansluta ditt program till Avvikelseidentifiering-API:et. Klistra in din nyckel och slutpunkt i koden nedan senare i snabbstarten. Du kan använda den kostnadsfria prisnivån (F0) för att prova tjänsten och uppgradera senare till en betald nivå för produktion.

Konfigurera

Skapa ett lagringskonto

Multivariat Avvikelseidentifiering kräver att exempelfilen lagras i Azure Blob Storage.

  1. Skapa ett Azure Storage-konto.
  2. Gå till Åtkomstkontroll (IAM) och välj LÄGG till i Lägg till rolltilldelning.
  3. Sökrollen för Storage Blob Data Reader, markera den här kontotypen och välj sedan Nästa.
  4. Välj tilldela åtkomst till hanterad identitet och Välj medlemmar och välj sedan den Avvikelseidentifiering resurs som du skapade tidigare och välj sedan Granska + tilldela.

Den här konfigurationen kan ibland vara lite förvirrande, om du har problem rekommenderar vi att du konsulterar vårt Jupyter Notebook-exempel med flera varivariationer, som går igenom den här processen mer ingående.

Ladda ned exempeldata

Den här snabbstarten använder en fil för exempeldata sample_data_5_3000.csv. Den här filen kan laddas ned från våra GitHub-exempeldata

Du kan också ladda ned exempeldata genom att köra:

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

Ladda upp exempeldata till lagringskontot

  1. Gå till ditt lagringskonto, välj Containrar och skapa en ny container.
  2. Välj Ladda upp och ladda upp sample_data_5_3000.csv
  3. Välj de data som du laddade upp och kopiera blob-URL:en när du behöver lägga till den i kodexemplet i några få steg.

Hämta nyckel och slutpunkt

Om du vill göra ett anrop mot Avvikelseidentifiering-tjänsten behöver du följande värden:

Variabelnamn Värde
ANOMALY_DETECTOR_ENDPOINT Det här värdet finns i avsnittet Nycklar och slutpunkt när du undersöker resursen från Azure-portalen. Exempelslutpunkt: https://YOUR_RESOURCE_NAME.cognitiveservices.azure.com/
ANOMALY_DETECTOR_API_KEY API-nyckelvärdet finns i avsnittet Nycklar och slutpunkter när du undersöker resursen från Azure Portal. Du kan använda antingen KEY1 eller KEY2.

Gå till resursen i Azure Portal. Slutpunkten och nycklarna finns i avsnittet Resurshantering . Kopiera slutpunkten och åtkomstnyckeln när du behöver båda för att autentisera dina API-anrop. Du kan använda antingen KEY1 eller KEY2. Om du alltid har två nycklar kan du rotera och återskapa nycklar på ett säkert sätt utan att orsaka avbrott i tjänsten.

Skapa miljövariabler

Skapa och tilldela beständiga miljövariabler för din nyckel och slutpunkt.

Viktigt!

Om du använder en API-nyckel lagrar du den på ett säkert sätt någon annanstans, till exempel i Azure Key Vault. Inkludera inte API-nyckeln direkt i koden och publicera den aldrig offentligt.

Mer information om säkerhet för AI-tjänster finns i Autentisera begäranden till Azure AI-tjänster.

setx ANOMALY_DETECTOR_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx ANOMALY_DETECTOR_ENDPOINT "REPLACE_WITH_YOUR_ENDPOINT_HERE"

Skapa en ny .NET Core-app

I ett konsolfönster (till exempel cmd, PowerShell eller Bash) använder du dotnet new kommandot för att skapa en ny konsolapp med namnet anomaly-detector-quickstart-multivariate. Det här kommandot skapar ett enkelt "Hello World"-projekt med en enda C#-källfil: Program.cs.

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

Ändra katalogen till den nyligen skapade appmappen. Du kan skapa programmet med:

dotnet build

Kompileringsutdata får inte innehålla några varningar eller fel.

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

Installera klientbiblioteket

Installera Avvikelseidentifiering-klientbiblioteket för .NET i programkatalogen med följande kommando:

dotnet add package Azure.AI.AnomalyDetector --prerelease

Öppna filen program.cs från projektkatalogen och ersätt med följande kod:

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));
        }
 
    }
}

Kör appen

Kör programmet med kommandot från programkatalogen dotnet run .

dotnet run

Rensa resurser

Om du vill rensa och ta bort en Azure AI-tjänstprenumeration kan du ta bort resursen eller resursgruppen. Om du tar bort resursgruppen tas även alla andra resurser som är associerade med resursgruppen bort.

Nästa steg

Kom igång med Avvikelseidentifiering multivariate-klientbiblioteket för JavaScript. Följ de här stegen för att installera paketet och börja använda de algoritmer som tillhandahålls av tjänsten. De nya API:erna för multivariatavvikelseidentifiering gör det möjligt för utvecklare genom att enkelt integrera avancerad AI för att identifiera avvikelser från grupper av mått, utan att behöva maskininlärningskunskaper eller märkta data. Beroenden och korrelationer mellan olika signaler räknas automatiskt som nyckelfaktorer. Detta hjälper dig att proaktivt skydda dina komplexa system mot fel.

Använd Avvikelseidentifiering multivariate-klientbiblioteket för JavaScript för att:

  • Identifiera avvikelser på systemnivå från en grupp med tidsserier.
  • När en enskild tidsserie inte berättar mycket för dig, och du måste titta på alla signaler för att upptäcka ett problem.
  • Förebyggande underhåll av dyra fysiska tillgångar med tiotals till hundratals olika typer av sensorer som mäter olika aspekter av systemets hälsa.

Biblioteksreferensdokumentation Bibliotek källkodspaket | (npm) | Exempelkod |

Förutsättningar

  • Azure-prenumeration – Skapa en kostnadsfritt
  • Den aktuella versionen av Node.js
  • När du har din Azure-prenumeration skapar du en Avvikelseidentifiering resurs i Azure Portal för att hämta din nyckel och slutpunkt. Vänta tills den har distribuerats och välj knappen Gå till resurs .
    • Du behöver nyckeln och slutpunkten från resursen som du skapar för att ansluta ditt program till Avvikelseidentifiering-API:et. Du klistrar in nyckeln och slutpunkten i koden nedan senare i snabbstarten. Du kan använda den kostnadsfria prisnivån (F0) för att prova tjänsten och uppgradera senare till en betald nivå för produktion.

Konfigurera

Skapa ett nytt Node.js-program

Skapa en ny katalog för din app i ett konsolfönster (till exempel cmd, PowerShell eller bash) och navigera till den.

mkdir myapp && cd myapp

Kör kommandot npm init för att skapa ett nodprogram med en package.json-fil.

npm init

Skapa en fil med namnet index.js och importera följande bibliotek: "

'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');

Skapa variabler för resursens Azure-slutpunkt och -nyckel. Skapa en annan variabel för exempeldatafilen.

Kommentar

Du har alltid möjlighet att använda en av två nycklar. Detta är för att tillåta säker nyckelrotation. I den här snabbstarten använder du den första nyckeln.

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

Viktigt!

Kom ihåg att ta bort nyckeln från koden när du är klar och publicera den aldrig offentligt. För produktion använder du ett säkert sätt att lagra och komma åt dina autentiseringsuppgifter som Azure Key Vault. Mer information finns i säkerhetsartikeln för Azure AI-tjänster.

Om du vill använda Avvikelseidentifiering multivarierade API:er måste du först träna dina egna modeller. Träningsdata är en uppsättning med flera tidsserier som uppfyller följande krav:

Varje tidsserie ska vara en CSV-fil med två (och endast två) kolumner, "tidsstämpel" och "värde" (alla i gemener) som rubrikrad. Tidsstämpelvärdena ska överensstämma med ISO 8601. "värdet" kan vara heltal eller decimaler med valfritt antal decimaler. Till exempel:

timestamp värde
2019-04-01T00:00:00Z 5
2019-04-01T00:01:00Z 3,6
2019-04-01T00:02:00Z 4
... ...

Varje CSV-fil ska namnges efter en annan variabel som ska användas för modellträning. Till exempel "temperature.csv" och "humidity.csv". Alla CSV-filer ska zippas in i en zip-fil utan undermappar. Zip-filen kan ha det namn du vill. Zip-filen ska laddas upp till Azure Blob Storage. När du har genererat URL:en för blob-SAS (signaturer för delad åtkomst) för zip-filen kan den användas för träning. I det här dokumentet finns information om hur du genererar SAS-URL:er från Azure Blob Storage.

Installera klientbiblioteket

Installera NPM-paketen ms-rest-azure och azure-ai-anomalydetector . Csv-parse-biblioteket används också i den här snabbstarten:

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

Appens package.json fil uppdateras med beroendena.

Kodexempel

De här kodfragmenten visar hur du gör följande med Avvikelseidentifiering-klientbiblioteket för Node.js:

Autentisera klienten

Instansiera ett AnomalyDetectorClient objekt med din slutpunkt och dina autentiseringsuppgifter.

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

Träna en modell

Skapa ett modellresultat

Först måste vi skapa en modellbegäran. Kontrollera att start- och sluttiden överensstämmer med datakällan.

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
};

Träna en ny modell

Du skickar din modellbegäran till Avvikelseidentifiering-klientmetodentrainMultivariateModel.

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)

Om du vill kontrollera om träningen av din modell är klar kan du spåra modellens status:

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.");

Identifiera avvikelser

detectAnomaly Använd funktionerna och getDectectionResult för att avgöra om det finns några avvikelser i datakällan.

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);

Exportera modell

Kommentar

Exportkommandot är avsett att användas för att tillåta körning av Avvikelseidentifiering multivariate-modeller i en containerbaserad miljö. Detta stöds för närvarande inte för multivariat, men support kommer att läggas till i framtiden.

Om du vill exportera din tränade modell använder du exportModel funktionen.

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+".")

Ta bort modell

Om du vill ta bort en befintlig modell som är tillgänglig för den aktuella resursen använder du deleteMultivariateModel funktionen.

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

Kör appen

Innan du kör programmet kan det vara bra att kontrollera koden mot den fullständiga exempelkoden

Kör programmet med kommandot node på din snabbstartsfil.

node index.js

Rensa resurser

Om du vill rensa och ta bort en Azure AI-tjänstprenumeration kan du ta bort resursen eller resursgruppen. Om du tar bort resursgruppen tas även alla andra resurser som är associerade med resursgruppen bort.

Nästa steg

Biblioteksreferensdokumentation Bibliotekets källkodspaket | (PyPi) |Hitta exempelkoden på GitHub |

Kom igång med Avvikelseidentifiering multivariate-klientbiblioteket för Python. Följ de här stegen för att installera paketet och börja använda de algoritmer som tillhandahålls av tjänsten. De nya API:erna för multivariatavvikelseidentifiering gör det möjligt för utvecklare genom att enkelt integrera avancerad AI för att identifiera avvikelser från grupper av mått, utan att behöva maskininlärningskunskaper eller märkta data. Beroenden och korrelationer mellan olika signaler räknas automatiskt som nyckelfaktorer. Detta hjälper dig att proaktivt skydda dina komplexa system mot fel.

Använd Avvikelseidentifiering multivariate-klientbiblioteket för Python för att:

  • Identifiera avvikelser på systemnivå från en grupp med tidsserier.
  • När en enskild tidsserie inte berättar mycket för dig, och du måste titta på alla signaler för att upptäcka ett problem.
  • Förebyggande underhåll av dyra fysiska tillgångar med tiotals till hundratals olika typer av sensorer som mäter olika aspekter av systemets hälsa.

Förutsättningar

  • En Azure-prenumeration – Skapa en kostnadsfritt
  • Python 3.x
  • När du har din Azure-prenumeration skapar du en Avvikelseidentifiering resurs i Azure Portal för att hämta din nyckel och slutpunkt. Vänta tills den har distribuerats och välj knappen Gå till resurs . Du kan använda den kostnadsfria prisnivån (F0) för att prova tjänsten och uppgradera senare till en betald nivå för produktion.

Konfigurera

Installera klientbiblioteket. Du kan installera klientbiblioteket med:

pip install --upgrade azure.ai.anomalydetector

Skapa ett lagringskonto

Multivariat Avvikelseidentifiering kräver att exempelfilen lagras i Azure Blob Storage.

  1. Skapa ett Azure Storage-konto.
  2. Gå till Åtkomstkontroll (IAM) och välj LÄGG till i Lägg till rolltilldelning.
  3. Sökrollen för Storage Blob Data Reader, markera den här kontotypen och välj sedan Nästa.
  4. Välj tilldela åtkomst till hanterad identitet och Välj medlemmar och välj sedan den Avvikelseidentifiering resurs som du skapade tidigare och välj sedan Granska + tilldela.

Den här konfigurationen kan ibland vara lite förvirrande, om du har problem rekommenderar vi att du konsulterar vårt Jupyter Notebook-exempel med flera varivariationer, som går igenom den här processen mer ingående.

Ladda ned exempeldata

Den här snabbstarten använder en fil för exempeldata sample_data_5_3000.csv. Den här filen kan laddas ned från våra GitHub-exempeldata

Du kan också ladda ned exempeldata genom att köra:

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

Ladda upp exempeldata till lagringskontot

  1. Gå till ditt lagringskonto, välj Containrar och skapa en ny container.
  2. Välj Ladda upp och ladda upp sample_data_5_3000.csv
  3. Välj de data som du laddade upp och kopiera blob-URL:en när du behöver lägga till den i kodexemplet i några få steg.

Hämta nyckel och slutpunkt

Om du vill göra ett anrop mot Avvikelseidentifiering-tjänsten behöver du följande värden:

Variabelnamn Värde
ANOMALY_DETECTOR_ENDPOINT Det här värdet finns i avsnittet Nycklar och slutpunkt när du undersöker resursen från Azure-portalen. Exempelslutpunkt: https://YOUR_RESOURCE_NAME.cognitiveservices.azure.com/
ANOMALY_DETECTOR_API_KEY API-nyckelvärdet finns i avsnittet Nycklar och slutpunkter när du undersöker resursen från Azure Portal. Du kan använda antingen KEY1 eller KEY2.

Gå till resursen i Azure Portal. Slutpunkten och nycklarna finns i avsnittet Resurshantering . Kopiera slutpunkten och åtkomstnyckeln när du behöver båda för att autentisera dina API-anrop. Du kan använda antingen KEY1 eller KEY2. Om du alltid har två nycklar kan du rotera och återskapa nycklar på ett säkert sätt utan att orsaka avbrott i tjänsten.

Skapa miljövariabler

Skapa och tilldela beständiga miljövariabler för din nyckel och slutpunkt.

Viktigt!

Om du använder en API-nyckel lagrar du den på ett säkert sätt någon annanstans, till exempel i Azure Key Vault. Inkludera inte API-nyckeln direkt i koden och publicera den aldrig offentligt.

Mer information om säkerhet för AI-tjänster finns i Autentisera begäranden till Azure AI-tjänster.

setx ANOMALY_DETECTOR_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx ANOMALY_DETECTOR_ENDPOINT "REPLACE_WITH_YOUR_ENDPOINT_HERE"

Skapa ett nytt Python-program

  1. Skapa en ny Python-fil med namnet sample_multivariate_detect.py. Öppna den sedan i önskad redigerare eller IDE.

  2. Ersätt innehållet i sample_multivariate_detect.py med följande kod. Du måste ändra sökvägarna för variablerna 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
                )
            )

Kör appen

Kör programmet med kommandot python på din snabbstartsfil.

python sample_multivariate_detect.py

Output

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

Utdataresultaten har trunkerats för korthet.

Rensa resurser

Om du vill rensa och ta bort en Avvikelseidentifiering resurs kan du ta bort resursen eller resursgruppen. Om du tar bort resursgruppen tas även alla andra resurser som är associerade med den bort. Du kan också överväga att ta bort de miljövariabler som du skapade om du inte längre tänker använda dem.

Kom igång med Avvikelseidentifiering multivariat-klientbibliotek för Java. Följ de här stegen för att installera paketet med hjälp av de algoritmer som tillhandahålls av tjänsten. De nya API:erna för multivariatavvikelseidentifiering gör det möjligt för utvecklare genom att enkelt integrera avancerad AI för att identifiera avvikelser från grupper av mått, utan att behöva maskininlärningskunskaper eller märkta data. Beroenden och korrelationer mellan olika signaler räknas automatiskt som nyckelfaktorer. Detta hjälper dig att proaktivt skydda dina komplexa system mot fel.

Använd Avvikelseidentifiering multivariate-klientbiblioteket för Java för att:

  • Identifiera avvikelser på systemnivå från en grupp med tidsserier.
  • När en enskild tidsserie inte berättar mycket för dig, och du måste titta på alla signaler för att upptäcka ett problem.
  • Förebyggande underhåll av dyra fysiska tillgångar med tiotals till hundratals olika typer av sensorer som mäter olika aspekter av systemets hälsa.

Biblioteksreferensdokumentation Bibliotek källkodspaket | (Maven) | Exempelkod |

Förutsättningar

  • Azure-prenumeration – Skapa en kostnadsfritt
  • Den aktuella versionen av Java Development Kit (JDK)
  • Build-verktyget Gradle eller en annan beroendehanterare.
  • När du har din Azure-prenumeration skapar du en Avvikelseidentifiering resurs i Azure Portal för att hämta din nyckel och slutpunkt. Vänta tills den har distribuerats och välj knappen Gå till resurs .
    • Du behöver nyckeln och slutpunkten från resursen som du skapar för att ansluta ditt program till Avvikelseidentifiering-API:et. Du klistrar in nyckeln och slutpunkten i koden nedan senare i snabbstarten. Du kan använda den kostnadsfria prisnivån (F0) för att prova tjänsten och uppgradera senare till en betald nivå för produktion.

Konfigurera

Skapa ett nytt Gradle-projekt

Den här snabbstarten använder Gradle-beroendehanteraren. Du hittar mer information om klientbiblioteket på den centrala Maven-lagringsplatsen.

Skapa en ny katalog för din app i ett konsolfönster (till exempel cmd, PowerShell eller bash) och navigera till den.

mkdir myapp && cd myapp

Kör kommandot från arbetskatalogen gradle init . Det här kommandot skapar viktiga byggfiler för Gradle, inklusive build.gradle.kts som används vid körning för att skapa och konfigurera ditt program.

gradle init --type basic

Välj en DSL när du uppmanas till det och välj Kotlin.

Installera klientbiblioteket

Leta upp build.gradle.kts och öppna det med önskad IDE eller textredigerare . Kopiera sedan i den här byggkonfigurationen. Se till att inkludera projektberoenden.

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

Skapa en Java-fil

Skapa en mapp för exempelappen. Kör följande kommando från arbetskatalogen:

mkdir -p src/main/java

Gå till den nya mappen och skapa en fil med namnet MetricsAdvisorQuickstarts.java. Öppna den i önskad redigerare eller IDE och lägg till följande import instruktioner:

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;

Skapa variabler för resursens Azure-slutpunkt och -nyckel. Skapa en annan variabel för exempeldatafilen.

Kommentar

Du har alltid möjlighet att använda en av två nycklar. Detta är för att tillåta säker nyckelrotation. I den här snabbstarten använder du den första nyckeln.

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

Viktigt!

Kom ihåg att ta bort nyckeln från koden när du är klar och publicera den aldrig offentligt. För produktion använder du ett säkert sätt att lagra och komma åt dina autentiseringsuppgifter som Azure Key Vault. Mer information finns i säkerhetsartikeln för Azure AI-tjänster.

Om du vill använda Avvikelseidentifiering multivarierade API:er måste du först träna dina egna modeller. Träningsdata är en uppsättning med flera tidsserier som uppfyller följande krav:

Varje tidsserie ska vara en CSV-fil med två (och endast två) kolumner, "tidsstämpel" och "värde" (alla i gemener) som rubrikrad. Tidsstämpelvärdena ska överensstämma med ISO 8601. "värdet" kan vara heltal eller decimaler med valfritt antal decimaler. Till exempel:

timestamp värde
2019-04-01T00:00:00Z 5
2019-04-01T00:01:00Z 3,6
2019-04-01T00:02:00Z 4
... ...

Varje CSV-fil ska namnges efter en annan variabel som ska användas för modellträning. Till exempel "temperature.csv" och "humidity.csv". Alla CSV-filer ska zippas in i en zip-fil utan undermappar. Zip-filen kan ha det namn du vill. Zip-filen ska laddas upp till Azure Blob Storage. När du har genererat URL:en för blob-SAS (signaturer för delad åtkomst) för zip-filen kan den användas för träning. I det här dokumentet finns information om hur du genererar SAS-URL:er från Azure Blob Storage.

Kodexempel

De här kodfragmenten visar hur du gör följande med Avvikelseidentifiering-klientbiblioteket för Node.js:

Autentisera klienten

Instansiera ett anomalyDetectorClient objekt med din slutpunkt och dina autentiseringsuppgifter.

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();

Träna en modell

Konstruera ett modellresultat och träna modell

Först måste vi skapa en modellbegäran. Kontrollera att start- och sluttiden överensstämmer med datakällan.

För att kunna använda Avvikelseidentifiering multivarierade API:er måste vi träna vår egen modell innan vi använder identifiering. Data som används för träning är en batch med tidsserier, varje tidsserie ska finnas i en CSV-fil med endast två kolumner, "tidsstämpel" och "värde"(kolumnnamnen ska vara exakt samma). Varje CSV-fil ska namnges efter varje variabel för tidsserien. Alla tidsserier ska zippas in i en zip-fil och laddas upp till Azure Blob Storage, och det finns inget krav på zip-filnamnet. Du kan också inkludera en extra meta.json fil i zip-filen om du vill att namnet på variabeln ska skilja sig från .zip filnamn. När vi har genererat URL:en för blob-SAS (signaturer för delad åtkomst) kan vi använda URL:en till zip-filen för träning.

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());
    }
}

Identifiera avvikelser

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());
    }
}

Exportera modell

Kommentar

Exportkommandot är avsett att användas för att tillåta körning av Avvikelseidentifiering multivariate-modeller i en containerbaserad miljö. Detta stöds för närvarande inte för multivariat, men support kommer att läggas till i framtiden.

Om du vill exportera din tränade modell använder du 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));

Ta bort modell

Om du vill ta bort en befintlig modell som är tillgänglig för den aktuella resursen använder du deleteMultivariateModelWithResponse funktionen.

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

Kör appen

Du kan skapa appen med:

gradle build

Kör appen

Innan du kör kan det vara bra att kontrollera koden mot den fullständiga exempelkoden.

Kör programmet med målet run :

gradle run

Rensa resurser

Om du vill rensa och ta bort en Azure AI-tjänstprenumeration kan du ta bort resursen eller resursgruppen. Om du tar bort resursgruppen tas även alla andra resurser som är associerade med resursgruppen bort.

Nästa steg