Självstudie: Lär dig multivariera avvikelseidentifiering på en timme
Avvikelseidentifiering med multivarierad avvikelseidentifiering (MVAD) är ett avancerat AI-verktyg för att identifiera avvikelser från en grupp mått på ett oövervakat sätt.
I allmänhet kan du vidta följande steg för att använda MVAD:
- Skapa en Avvikelseidentifiering som stöder MVAD på Azure.
- Förbered dina data.
- Träna en MVAD-modell.
- Fråga efter status för din modell.
- Identifiera avvikelser med den tränade MVAD-modellen.
- Hämta och tolka inferensresultatet.
I den här självstudien kommer du att:
- Förstå hur du förbereder dina data i rätt format.
- Förstå hur du tränar och härledning med MVAD.
- Förstå indataparametrarna och hur du tolkar resultatet av inferensresultatet.
1. Skapa en Avvikelseidentifiering som stöder MVAD
- Skapa en Azure-prenumeration om du inte har en – Skapa en kostnadsfritt
- När du har din Azure-prenumeration skapar du en Avvikelseidentifiering i Azure Portal för att hämta API-nyckeln och API-slutpunkten.
Anteckning
Under förhandsversionsfasen är MVAD endast tillgängligt i begränsade regioner. Bokmärket What's new in Avvikelseidentifiering to keep up to up to date with MVAD region roll-outs (Vad är nytt i den här regionen Avvikelseidentifiering hålla dig uppdaterad med MVAD-region-utrullningar. Du kan också skicka en GitHub eller kontakta oss på för AnomalyDetector@microsoft.com att begära specifika regioner.
2. Förberedelse av data
Sedan måste du förbereda dina träningsdata (och härledningsdata).
Schema för indata
MVAD identifierar avvikelser från en grupp mått och vi kallar varje mått för en variabel eller en tidsserie.
Du kan ladda ned exempeldatafilen från Microsoft för att kontrollera det godkända schemat från: https://aka.ms/AnomalyDetector/MVADSampleData
Varje variabel måste ha två och endast två fält, och , och ska lagras i en fil med
timestampvaluekommaavgränsade värden (CSV).Kolumnnamnen för CSV-filen ska vara exakt och
timestampvalue, fallkänsliga.Värdena
timestampska överensstämma med ISO 8601. Kan vara heltal ellervaluedecimaler med val annat antal decimaler. Ett bra exempel på innehållet i en CSV-fil:timestamp värde 2019-04-01T00:00:00Z 5 2019-04-01T00:01:00Z 3,6 2019-04-01T00:02:00Z 4 ... ... Anteckning
Om dina tidsstämplar har timmar, minuter och/eller sekunder ser du till att de avrundas korrekt uppåt innan du anropar API:erna.
Om din datafrekvens till exempel ska vara en datapunkt var 30:e sekund, men du ser tidsstämplar som "12:00:01" och "12:00:28", är det en stark signal att du ska bearbeta tidsstämplar till nya värden som "12:00:00" och "12:00:30".
Mer information finns i avsnittet "Avrundning av tidsstämpel" i dokumentet om bästa praxis.
Namnet på csv-filen används som variabelnamn och ska vara unikt. Till exempel "temperature.csv" och "humidity.csv".
Variabler för träning och variabler för slutsatsledning ska vara konsekventa. Om du till exempel använder , , , och för träning bör du
series_1ange exakt samma variabler förseries_2series_3series_4series_5slutsatsledning.CSV-filer ska komprimeras till en zip-fil och laddas upp till en Azure-blobcontainer. Zip-filen kan ha vilket namn du vill.
Mappstrukturen
Ett vanligt misstag vid förberedelse av data är extra mappar i ZIP-filen. Anta till exempel att namnet på zip-filen är series.zip . Efter dekomprimering av filerna till en ny mapp är sedan rätt sökväg till CSV-filer och ./series fel sökväg kan vara ./series/series_1.csv ./series/foo/bar/series_1.csv .
Rätt exempel på katalogträdet efter dekomprimering av zip-filen i Windows
.
└── series
├── series_1.csv
├── series_2.csv
├── series_3.csv
├── series_4.csv
└── series_5.csv
Ett felaktigt exempel på katalogträdet efter dekomprimering av zip-filen i Windows
.
└── series
└── series
├── series_1.csv
├── series_2.csv
├── series_3.csv
├── series_4.csv
└── series_5.csv
Verktyg för att zippa och ladda upp data
I det här avsnittet delar vi lite exempelkod och verktyg som du kan kopiera och redigera för att lägga till i din egen programlogik som hanterar MVAD-indata.
Komprimera CSV-filer i * nix
zip -j series.zip series/*.csv
Komprimera CSV-filer i Windows
- Navigera till mappen med alla CSV-filer.
- Välj alla CSV-filer som du behöver.
- Högerklicka på en av CSV-filerna och välj
Send to. - Välj
Compressed (zipped) folderi listrutan. - Byt namn på zip-filen efter behov.
Python-kod zippar & laddar upp data till Azure Blob Storage
Du kan läsa det här dokumentet för att lära dig hur du laddar upp en fil till Azure Blob.
Eller så kan du referera till exempelkoden nedan som kan zippa och ladda upp åt dig. Du kan kopiera och spara Python-koden i det här avsnittet som en .py-fil (till exempel ) och köra den med hjälp zipAndUpload.py av kommandorader som dessa:
python zipAndUpload.py -s "foo\bar" -z test123.zip -c {azure blob connection string} -n container_xxxDet här kommandot komprimerar alla CSV-filer i
foo\bartill en enda zip-fil med namnettest123.zip. Den laddas upptest123.ziptill containerncontainer_xxxi din blob.python zipAndUpload.py -s "foo\bar" -z test123.zip -c {azure blob connection string} -n container_xxx -rDet här kommandot gör samma sak som ovan, men det tar bort zip-filen
test123.zipefter uppladdningen.
Argument:
--source-folder,-s, sökväg till källmappen som innehåller CSV-filer--zipfile-name,-z, namnet på zip-filen--connection-string,-c, anslutningssträng till din blob--container-name,-n, namnet på containern--remove-zipfile,-r, om det är på, ta bort zip-filen
import os
import argparse
import shutil
import sys
from azure.storage.blob import BlobClient
import zipfile
class ZipError(Exception):
pass
class UploadError(Exception):
pass
def zip_file(root, name):
try:
z = zipfile.ZipFile(name, "w", zipfile.ZIP_DEFLATED)
for f in os.listdir(root):
if f.endswith("csv"):
z.write(os.path.join(root, f), f)
z.close()
print("Compress files success!")
except Exception as ex:
raise ZipError(repr(ex))
def upload_to_blob(file, conn_str, cont_name, blob_name):
try:
blob_client = BlobClient.from_connection_string(conn_str, container_name=cont_name, blob_name=blob_name)
with open(file, "rb") as f:
blob_client.upload_blob(f, overwrite=True)
print("Upload Success!")
except Exception as ex:
raise UploadError(repr(ex))
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--source-folder", "-s", type=str, required=True, help="path to source folder")
parser.add_argument("--zipfile-name", "-z", type=str, required=True, help="name of the zip file")
parser.add_argument("--connection-string", "-c", type=str, help="connection string")
parser.add_argument("--container-name", "-n", type=str, help="container name")
parser.add_argument("--remove-zipfile", "-r", action="store_true", help="whether delete the zip file after uploading")
args = parser.parse_args()
try:
zip_file(args.source_folder, args.zipfile_name)
upload_to_blob(args.zipfile_name, args.connection_string, args.container_name, args.zipfile_name)
except ZipError as ex:
print(f"Failed to compress files. {repr(ex)}")
sys.exit(-1)
except UploadError as ex:
print(f"Failed to upload files. {repr(ex)}")
sys.exit(-1)
except Exception as ex:
print(f"Exception encountered. {repr(ex)}")
try:
if args.remove_zipfile:
os.remove(args.zipfile_name)
except Exception as ex:
print(f"Failed to delete the zip file. {repr(ex)}")
3. Träna en MVAD-modell
Här är ett exempel på begärandetexten och exempelkoden i Python för att träna en MVAD-modell.
// Sample Request Body
{
"slidingWindow": 200,
"alignPolicy": {
"alignMode": "Outer",
"fillNAMethod": "Linear",
"paddingValue": 0
},
// This could be your own ZIP file of training data stored on Azure Blob and a SAS url could be used here
"source": "https://aka.ms/AnomalyDetector/MVADSampleData",
"startTime": "2021-01-01T00:00:00Z",
"endTime": "2021-01-02T12:00:00Z",
"displayName": "Contoso model"
}
# Sample Code in Python
########### Python 3.x #############
import http.client, urllib.request, urllib.parse, urllib.error, base64
headers = {
# Request headers
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': '{API key}',
}
params = urllib.parse.urlencode({})
try:
conn = http.client.HTTPSConnection('{endpoint}')
conn.request("POST", "/anomalydetector/v1.1-preview/multivariate/models?%s" % params, "{request body}", headers)
response = conn.getresponse()
data = response.read()
print(data)
conn.close()
except Exception as e:
print("[Errno {0}] {1}".format(e.errno, e.strerror))
####################################
Svarskoden 201 anger en lyckad begäran.
Indataparametrar
Obligatoriska parametrar
Dessa tre parametrar krävs i API-begäranden för träning och slutsatsledning:
source– Länken till zip-filen som finns i Azure Blob Storage signatur för delad åtkomst (SAS).startTime– Starttiden för data som används för träning eller slutsatsledning. Om den är tidigare än den faktiska tidigaste tidsstämpeln i data används den faktiska tidigaste tidsstämpeln som startpunkt.endTime- Sluttiden för data som används för träning eller slutsatsledning som måste vara senare än eller lika medstartTime. Om är senare än den faktiska senaste tidsstämpeln i data används den faktiska senaste tidsstämpelnendTimesom slutpunkt. OmendTimeär lika med innebär detstartTimehärledning av en enskild datapunkt som ofta används i strömningsscenarier.
Valfria parametrar för tränings-API
Andra parametrar för tränings-API är valfria:
slidingWindow– Hur många datapunkter som används för att fastställa avvikelser. Ett heltal mellan 28 och 2 880. Standardvärdet är 300. Om är för modellträning bör minst punkter vara tillgängliga från källfilenslidingWindowkunderkinferensen för att få giltiga resultat.MVAD tar ett segment med datapunkter för att avgöra om nästa datapunkt är en avvikelse. Längden på segmentet är
slidingWindow. Tänk på två saker när du väljer ettslidingWindowvärde:- Egenskaperna för dina data: om de är periodiska och samplingsfrekvensen. När dina data är periodiska kan du ange längden på 1–3 cykler som
slidingWindow. När dina data har hög frekvens (liten kornighet) som på minutnivå eller sekundnivå kan du ange ett relativt högre värde förslidingWindow. - Avvägningen mellan träning/slutsatsledningstid och potentiell prestandapåverkan. En större
slidingWindowkan orsaka längre tränings-/inferenstid. Det finns ingen garanti för att större S leder tillslidingWindownoggrannhetsförbättringar. En litenslidingWindowkan göra att modellen är svår att konvergera till en optimal lösning. Det är till exempel svårt att identifiera avvikelser när baraslidingWindowhar två punkter.
- Egenskaperna för dina data: om de är periodiska och samplingsfrekvensen. När dina data är periodiska kan du ange längden på 1–3 cykler som
alignMode– Justera flera variabler (tidsserier) efter tidsstämplar. Det finns två alternativ för den härInnerOuterparametern, och , och standardvärdet ärOuter.Den här parametern är kritisk när det finns feljustering mellan variablernas tidsstämpelsekvenser. Modellen måste justera variablerna till samma tidsstämpelsekvens innan ytterligare bearbetning.
Innerinnebär att modellen endast rapporterar identifieringsresultat för tidsstämplar där varje variabel har ett värde, dvs. skärningspunkten för alla variabler.Outerinnebär att modellen rapporterar identifieringsresultat för tidsstämplar där alla variabler har ett värde, dvs. union av alla variabler.Här är ett exempel som förklarar olika
alignModelvärden.Variabel-1
timestamp värde 2020-11-01 1 2020-11-02 2 2020-11-04 4 2020-11-05 5 Variabel-2
timestamp värde 2020-11-01 1 2020-11-02 2 2020-11-03 3 2020-11-04 4 Innerkoppla ihop två variablertimestamp Variabel-1 Variabel-2 2020-11-01 1 1 2020-11-02 2 2 2020-11-04 4 4 Outerkoppla ihop två variablertimestamp Variabel-1 Variabel-2 2020-11-01 1 1 2020-11-02 2 2 2020-11-03 nan3 2020-11-04 4 4 2020-11-05 5 nanfillNAMethod– Så här fyller dunani den sammanslagna tabellen. Det kan saknas värden i den sammanslagna tabellen och de bör hanteras korrekt. Vi tillhandahåller flera metoder för att fylla dem. Alternativen ärLinear, , , och ochPreviousSubsequentZeroFixedstandardvärdet ärLinear.Alternativ Metod LinearFyll nani värden efter linjär interpoleringPreviousSprid det sista giltiga värdet för att fylla i luckor. Exempel: [1, 2, nan, 3, nan, 4]->[1, 2, 2, 3, 3, 4]SubsequentAnvänd nästa giltiga värde för att fylla i luckor. Exempel: [1, 2, nan, 3, nan, 4]->[1, 2, 3, 3, 4, 4]ZeroFyll nani värden med 0.FixedFyll nani värden med ett angivet giltigt värde som ska anges ipaddingValue.paddingValue– Utfyllnadsvärdet används för att fyllanani när är och måste anges i detfillNAMethodFixedfallet. I andra fall är det valfritt.displayName– Det här är en valfri parameter som används för att identifiera modeller. Du kan till exempel använda den för att markera parametrar, datakällor och andra metadata om modellen och dess indata. Standardvärdet är en tom sträng.
4. Hämta modellstatus
Eftersom tränings-API:et är asynkront får du inte modellen omedelbart när du har anropat tränings-API:et. Du kan dock fråga efter status för modeller antingen efter API-nyckel, som visar en lista över alla modeller, eller efter modell-ID, som visar information om den specifika modellen.
Visa en lista över alla modeller
Du kan gå till den här sidan för information om begärande-URL och begärandehuvuden. Observera att vi bara returnerar 10 modeller sorterade efter uppdateringstid, men du kan besöka andra modeller genom att ange parametrarna och $skip $top i begärande-URL:en. Om din begärande-URL till exempel är hoppar vi över de https://{endpoint}/anomalydetector/v1.1-preview/multivariate/models?$skip=10&$top=20 senaste 10 modellerna och returnerar de kommande 20 modellerna.
Ett exempelsvar är
{
"models": [
{
"createdTime":"2020-12-01T09:43:45Z",
"displayName":"DevOps-Test",
"lastUpdatedTime":"2020-12-01T09:46:13Z",
"modelId":"b4c1616c-33b9-11eb-824e-0242ac110002",
"status":"READY",
"variablesCount":18
},
{
"createdTime":"2020-12-01T09:43:30Z",
"displayName":"DevOps-Test",
"lastUpdatedTime":"2020-12-01T09:45:10Z",
"modelId":"ab9d3e30-33b9-11eb-a3f4-0242ac110002",
"status":"READY",
"variablesCount":18
}
],
"currentCount": 1,
"maxCount": 50,
"nextLink": "<link to more models>"
}
Svaret innehåller 4 fält, models , currentCount , och maxCount nextLink .
modelsinnehåller tiden då den skapades, tiden för senaste uppdatering, modell-ID, visningsnamn, variabelantal och status för varje modell.currentCountinnehåller antalet tränade multivarierade modeller.maxCountär det maximala antalet modeller som stöds av den här Avvikelseidentifiering resursen.nextLinkkan användas för att hämta fler modeller.
Hämta modeller efter modell-ID
Den här sidan beskriver begärande-URL:en för att fråga modellinformation efter modell-ID. Ett exempelsvar ser ut så här
{
"modelId": "45aad126-aafd-11ea-b8fb-d89ef3400c5f",
"createdTime": "2020-06-30T00:00:00Z",
"lastUpdatedTime": "2020-06-30T00:00:00Z",
"modelInfo": {
"slidingWindow": 300,
"alignPolicy": {
"alignMode": "Outer",
"fillNAMethod": "Linear",
"paddingValue": 0
},
"source": "<TRAINING_ZIP_FILE_LOCATED_IN_AZURE_BLOB_STORAGE_WITH_SAS>",
"startTime": "2019-04-01T00:00:00Z",
"endTime": "2019-04-02T00:00:00Z",
"displayName": "Devops-MultiAD",
"status": "READY",
"errors": [],
"diagnosticsInfo": {
"modelState": {
"epochIds": [10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
"trainLosses": [0.6291328072547913, 0.1671326905488968, 0.12354248017072678, 0.1025966405868533,
0.0958492755889896, 0.09069952368736267,0.08686016499996185, 0.0860302299260931,
0.0828735455870684, 0.08235538005828857],
"validationLosses": [1.9232804775238037, 1.0645641088485718, 0.6031560301780701, 0.5302737951278687,
0.4698025286197664, 0.4395163357257843, 0.4182931482799006, 0.4057914316654053,
0.4056498706340729, 0.3849248886108984],
"latenciesInSeconds": [0.3398594856262207, 0.3659665584564209, 0.37360644340515137,
0.3513407707214355, 0.3370304107666056, 0.31876277923583984,
0.3283309936523475, 0.3503587245941162, 0.30800247192382812,
0.3327946662902832]
},
"variableStates": [
{
"variable": "ad_input",
"filledNARatio": 0,
"effectiveCount": 1441,
"startTime": "2019-04-01T00:00:00Z",
"endTime": "2019-04-02T00:00:00Z",
"errors": []
},
{
"variable": "ad_ontimer_output",
"filledNARatio": 0,
"effectiveCount": 1441,
"startTime": "2019-04-01T00:00:00Z",
"endTime": "2019-04-02T00:00:00Z",
"errors": []
},
// More variables
]
}
}
}
Du får mer detaljerad information om den efterfrågade modellen. Svaret innehåller metainformation om modellen, dess träningsparametrar och diagnostikinformation. Diagnostisk information är användbar för felsökning och spårning av träningsförlopp.
epochIdsanger hur många epoker modellen har tränats ut av totalt 100 epoker. Om modellen till exempel fortfarande är i träningsstatus kan det vara så att den har slutfört sinepochId50:e träningsepoker och det är[10, 20, 30, 40, 50]halvvägs.trainLossesochvalidationLossesanvänds för att kontrollera om optimeringsförloppet konvergerar i vilket fall de två förlusterna bör minska gradvis.latenciesInSecondsinnehåller tidskostnaden för varje epok och registreras var 10:e epok. I det här exemplet tar den 10:e epoken cirka 0,34 sekunder. Detta skulle vara användbart för att uppskatta slutförandetiden för träningen.variableStatessammanfattar information om varje variabel. Det är en lista rangordnadfilledNARatioefter i fallande ordning. Den visar hur många datapunkter som används för varje variabelfilledNARatiooch anger hur många punkter som saknas. Vanligtvis behöver vi minskafilledNARatioså mycket som möjligt. För många saknade datapunkter kommer att påverka modellens noggrannhet.- Fel under databearbetningen tas med i
errorsfältet .
5. Slutsatsledning med MVAD
Om du vill utföra slutsatsledning anger du blobkällan till zip-filen som innehåller härledningsdata, starttid och sluttid.
Slutsatsledning är också asynkron, så resultatet returneras inte omedelbart. Observera att du måste spara länken för resultatet i svarshuvudet i en variabel som innehåller , så att du kan veta var resultId du ska hämta resultatet efteråt.
Fel orsakas vanligtvis av modellproblem eller dataproblem. Du kan inte utföra slutsatsledning om modellen inte är klar eller om datalänken är ogiltig. Kontrollera att träningsdata och härledningsdata är konsekventa, vilket innebär att de ska vara exakt samma variabler men med olika tidsstämplar. Fler variabler, färre variabler eller härledning med en annan uppsättning variabler kommer inte att klara fasen för dataverifiering och fel uppstår. Dataverifieringen skjuts upp så att du endast får felmeddelandet när du frågar resultatet.
6. Hämta slutsatsledningsresultat
Du behöver för resultId att få resultat. resultId hämtas från svarshuvudet när du skickar inferensbegäran. Den här sidan innehåller instruktioner för att köra frågor mot inferensresultatet.
Ett exempelsvar ser ut så här
{
"resultId": "663884e6-b117-11ea-b3de-0242ac130004",
"summary": {
"status": "READY",
"errors": [],
"variableStates": [
{
"variable": "ad_input",
"filledNARatio": 0,
"effectiveCount": 26,
"startTime": "2019-04-01T00:00:00Z",
"endTime": "2019-04-01T00:25:00Z",
"errors": []
},
{
"variable": "ad_ontimer_output",
"filledNARatio": 0,
"effectiveCount": 26,
"startTime": "2019-04-01T00:00:00Z",
"endTime": "2019-04-01T00:25:00Z",
"errors": []
},
// more variables
],
"setupInfo": {
"source": "https://aka.ms/AnomalyDetector/MVADSampleData",
"startTime": "2019-04-01T00:15:00Z",
"endTime": "2019-04-01T00:40:00Z"
}
},
"results": [
{
"timestamp": "2019-04-01T00:15:00Z",
"errors": [
{
"code": "InsufficientHistoricalData",
"message": "historical data is not enough."
}
]
},
// more results
{
"timestamp": "2019-04-01T00:20:00Z",
"value": {
"contributors": [],
"isAnomaly": false,
"severity": 0,
"score": 0.17805261260751692
}
},
// more results
{
"timestamp": "2019-04-01T00:27:00Z",
"value": {
"contributors": [
{
"contributionScore": 0.0007775013367514271,
"variable": "ad_ontimer_output"
},
{
"contributionScore": 0.0007989604079048129,
"variable": "ad_series_init"
},
{
"contributionScore": 0.0008900927229851369,
"variable": "ingestion"
},
{
"contributionScore": 0.008068144477478554,
"variable": "cpu"
},
{
"contributionScore": 0.008222036467507165,
"variable": "data_in_speed"
},
{
"contributionScore": 0.008674941549594993,
"variable": "ad_input"
},
{
"contributionScore": 0.02232242629793674,
"variable": "ad_output"
},
{
"contributionScore": 0.1583773213660846,
"variable": "flink_last_ckpt_duration"
},
{
"contributionScore": 0.9816531517495176,
"variable": "data_out_speed"
}
],
"isAnomaly": true,
"severity": 0.42135109874230336,
"score": 1.213510987423033
}
},
// more results
]
}
Svaret innehåller resultatstatus, variabelinformation, härledningsparametrar och slutsatsledningsresultat.
variableStatesvisar information om varje variabel i slutsatsledningsbegäran.setupInfoär begärandetexten som skickades för den här här slutsatsledning.resultsinnehåller identifieringsresultaten. Det finns tre vanliga typer av identifieringsresultat.- Felkod
InsufficientHistoricalData. Detta inträffar vanligtvis bara med de första tidsstämplarna eftersom modellen härledningsdata på ett fönsterbaserat sätt och den behöver historiska data för att fatta ett beslut. För de första tidsstämplar finns det inte tillräckligt med historiska data, så inferens kan inte utföras på dem. I det här fallet kan felmeddelandet ignoreras. "isAnomaly": falseanger att den aktuella tidsstämpeln inte är en avvikelse.severityanger den relativa allvarlighetsgraden för avvikelsen och för normala data är den alltid 0.scoreär rådatautdata för modellen där modellen fattar ett beslut som kan vara icke-noll även för normala datapunkter.
"isAnomaly": trueanger en avvikelse vid den aktuella tidsstämpeln.severityanger den relativa allvarlighetsgraden för avvikelsen och för onormala data är den alltid större än 0.scoreär rådatautdata för modellen som modellen fattar ett beslut om.severityär ett härlett värde frånscore. Varje datapunkt harscoreen .contributorsär en lista som innehåller bidragspoängen för varje variabel. Högre bidragspoäng indikerar högre risk för rotorsaken. Den här listan används ofta för att tolka avvikelser och diagnostisera rotorsakerna.
- Felkod
Anteckning
En vanlig fallgrop är att ta alla datapunkter isAnomaly = true med som avvikelser. Det kan leda till för många falska positiva resultat.
Du bör använda både och (eller ) för att gå igenom avvikelser som inte är allvarliga och (valfritt) använda gruppering för att kontrollera varaktigheten för avvikelserna för att isAnomaly severity förhindra score slumpmässigt brus. Se vanliga frågor och svar i dokumentet med metodtips för skillnaden mellan severity och score .