detect_anomalous_spike_fl()
Gilt für: ✅Microsoft Fabric✅Azure Data Explorer✅Azure Monitor✅Microsoft Sentinel
Erkennen sie das Erscheinungsbild von anomaliealen Spitzen in numerischen Variablen in Zeitstempeldaten.
Die Funktion detect_anomalous_spike_fl()
ist eine UDF (benutzerdefinierte Funktion), die das Erscheinungsbild von anomaliealen Spitzen in numerischen Variablen erkennt , z. B. menge der exfiltrierten Daten oder fehlgeschlagene Anmeldeversuche - in Zeitstempeldaten, z. B. Datenverkehrsprotokolle. Im Kontext der Cybersicherheit können solche Ereignisse verdächtig sein und auf einen potenziellen Angriff oder eine Kompromittierung hinweisen.
Das Anomaliemodell basiert auf einer Kombination aus zwei Bewertungen: Z-Score (die Anzahl der Standardabweichungen über dem Durchschnitt) und Q-Score (die Anzahl der interquantile Bereiche über einem hohen Quantile). Z-Score ist eine einfache und häufige Ausreißermetrik; Q-Score basiert auf Tukeys Zaunen - aber wir erweitern die Definition auf alle Quantiles für mehr Kontrolle. Die Auswahl verschiedener Quantiles (standardmäßig werden 95. und 25. Quantiles verwendet) ermöglicht es, signifikantere Ausreißer zu erkennen und so die Genauigkeit zu verbessern. Das Modell basiert auf einer numerischen Variablen und wird pro Bereich (z. B. Abonnement oder Konto) und pro Entität wie Benutzer oder Gerät berechnet.
Nach der Berechnung der Bewertungen für einen einzelnen variierten numerischen Datenpunkt und der Überprüfung anderer Anforderungen (z. B. die Anzahl der aktiven Tage im Schulungszeitraum im Bereich liegt über einem vordefinierten Schwellenwert), überprüfen wir, ob die einzelnen Bewertungen über dem vordefinierten Schwellenwert liegen. Wenn dies der Grund ist, wird eine Spitzen erkannt, und der Datenpunkt wird als anomalien gekennzeichnet. Es werden zwei Modelle erstellt: eine für entitätsebene (definiert durch den Parameter "entityColumnName") – z. B. Benutzer oder Gerät pro Bereich (definiert durch scopeColumnName-Parameter) – z. B. Konto oder Abonnement. Das zweite Modell wird für den gesamten Bereich erstellt. Die Anomalieerkennungslogik wird für jedes Modell ausgeführt, und wenn Anomalien in einem dieser Modelle erkannt werden , wird sie angezeigt. Standardmäßig werden Aufwärtsspitzen erkannt; Abwärtsspitzen ('Dips') können auch in einigen Kontexten interessant sein und durch Anpassen der Logik erkannt werden.
Die direkte Ausgabe des Modells ist eine Anomaliebewertung basierend auf den Ergebnissen. Die Punktzahl ist monoton im Bereich von [0, 1], wobei 1 etwas Anomalie darstellt. Zusätzlich zur Anomaliebewertung gibt es ein binäres Flag für erkannte Anomalien (gesteuert durch einen minimalen Schwellenwertparameter) und andere erläuternde Felder.
Beachten Sie, dass die Funktion die zeitliche Struktur der Variablen ignoriert (hauptsächlich für Skalierbarkeit und Erläuterung). Wenn die Variable erhebliche zeitliche Komponenten wie Trend und Saisonalitäten aufweist, empfehlen wir, entweder die series_decompose_anomalies() Funktion zu berücksichtigen, oder verwenden Sie series_decompose(), um den Rest zu berechnen und detect_anomalous_spike_fl()
darüber auszuführen.
Syntax
Erfahren Sie mehr über Syntaxkonventionen.
Parameter
Name | Art | Erforderlich | Beschreibung |
---|---|---|---|
numericColumnName- | string |
✔️ | Der Name der Eingabetabellenspalte, die numerische Variable enthält, für die Anomaliemodelle berechnet werden. |
entityColumnName- | string |
✔️ | Der Name der Eingabetabellenspalte, die die Namen oder IDs der Entitäten enthält, für die ein Anomaliemodell berechnet wird. |
scopeColumnName- | string |
✔️ | Der Name der Eingabetabellenspalte, die die Partition oder den Bereich enthält, sodass für jeden Bereich ein anderes Anomaliemodell erstellt wird. |
timeColumnName- | string |
✔️ | Der Name der Eingabetabellenspalte, die die Zeitstempel enthält, die zum Definieren der Schulungs- und Erkennungszeiträume verwendet werden. |
startTraining | datetime |
✔️ | Der Beginn des Schulungszeitraums für das Anomaliemodell. Sein Ende wird durch den Anfang des Erkennungszeitraums definiert. |
startDetection- | datetime |
✔️ | Der Anfang des Erkennungszeitraums für Anomalieerkennung. |
endDetection- | datetime |
✔️ | Das Ende des Erkennungszeitraums für Anomalieerkennung. |
minTrainingDaysThresh | int |
Die mindeste Anzahl von Tagen im Schulungszeitraum, für die ein Bereich zum Berechnen von Anomalien vorhanden ist. Wenn er unter dem Schwellenwert liegt, wird der Bereich als zu neu und unbekannt betrachtet, sodass Anomalien nicht berechnet werden. Der Standardwert ist 14. | |
lowPercentileForQscore | real |
Eine Zahl im Bereich [0,0,1,0], die das Quantil darstellt, das als niedrige Grenze für Q-Score berechnet werden soll. In Tukeys Zäune wird 0,25 verwendet. Der Standardwert ist 0,25. Die Auswahl eines niedrigeren Quantils verbessert die Genauigkeit, da signifikantere Anomalien erkannt werden. | |
highPercentileForQscore | real |
Eine Zahl im Bereich [0,0,1,0], die das Quantil darstellt, das als hohe Grenze für Q-Score berechnet werden soll. In Tukeys Zäune wird 0,75 verwendet. Der Standardwert ist 0,9. Wenn Sie ein höheres Quantil auswählen, wird die Genauigkeit verbessert, da signifikantere Anomalien erkannt werden. | |
minSlicesPerEntity- | int |
Der mindeste Schwellenwert für "Segmente" (z. B. Tage), die für eine Entität vorhanden sind, bevor ein Anomaliemodell dafür erstellt wird. Wenn die Zahl unter dem Schwellenwert liegt, wird die Entität als zu neu und instabil betrachtet. Der Standardwert ist 20. | |
zScoreThreshEntity- | real |
Der Mindestschwellenwert für die Z-Bewertung auf Entitätsebene (Anzahl der Standardabweichungen über dem Durchschnitt), die als Anomalie gekennzeichnet werden sollen. Bei der Auswahl höherer Werte werden nur signifikantere Anomalien erkannt. Der Standardwert ist 3,0. | |
qScoreThreshEntity | real |
Der Mindestschwellenwert für Q-Score auf Entitätsebene (Anzahl der interquantile Bereiche über hohem Quantile), die als Anomalie gekennzeichnet werden sollen. Bei der Auswahl höherer Werte werden nur signifikantere Anomalien erkannt. Der Standardwert ist 2,0. | |
minNumValueThreshEntity- | long |
Der Mindestschwellenwert für die numerische Variable, die als Anomalie für eine Entität gekennzeichnet werden soll. Dies ist nützlich für filterungsfälle, wenn ein Wert statistisch anomale (high Z-score und Q-score) ist, aber der Wert selbst ist zu klein, um interessant zu sein. Der Standardwert ist 0. | |
minSlicesPerScope- | int |
Der Mindestschwellenwert für "Segmente" (z. B. Tage), die in einem Bereich vorhanden sind, bevor ein Anomaliemodell dafür erstellt wird. Wenn die Zahl unter dem Schwellenwert liegt, gilt der Bereich als zu neu und instabil. Der Standardwert ist 20. | |
zScoreThreshScope- | real |
Der Mindestschwellenwert für die Z-Bewertung auf Bereichsebene (Anzahl der Standardabweichungen über dem Durchschnitt), die als Anomalie gekennzeichnet werden sollen. Bei der Auswahl höherer Werte werden nur signifikantere Anomalien erkannt. Der Standardwert ist 3,0. | |
qScoreThreshScope- | real |
Der Mindestschwellenwert für die Q-Bewertung auf Bereichsebene (Anzahl der interquantile Bereiche über hoher Quantile), die als Anomalie gekennzeichnet werden sollen. Bei der Auswahl höherer Werte werden nur signifikantere Anomalien erkannt. Der Standardwert ist 2,0. | |
minNumValueThreshScope | long |
Der Mindestschwellenwert für eine numerische Variable, die als Anomalie für einen Bereich gekennzeichnet werden soll. Dies ist nützlich für filterungsfälle, wenn ein Wert statistisch anomale (high Z-score und Q-score) ist, aber der Wert selbst ist zu klein, um interessant zu sein. Der Standardwert ist 0. |
Funktionsdefinition
Sie können die Funktion definieren, indem Sie den Code entweder als abfragedefinierte Funktion einbetten oder wie folgt als gespeicherte Funktion in Ihrer Datenbank erstellen:
Definieren Sie die Funktion mithilfe der folgenden let-Anweisung. Es sind keine Berechtigungen erforderlich.
Wichtig
Eine anweisung zulassen, nicht eigenständig ausgeführt werden kann. Darauf muss eine tabellarische Ausdrucksanweisungfolgen. Informationen zum Ausführen eines funktionierenden Beispiels für detect_anomalous_spike_fl()
finden Sie unter Beispiel.
let detect_anomalous_spike_fl = (T:(*), numericColumnName:string, entityColumnName:string, scopeColumnName:string
, timeColumnName:string, startTraining:datetime, startDetection:datetime, endDetection:datetime, minTrainingDaysThresh:int = 14
, lowPercentileForQscore:real = 0.25, highPercentileForQscore:real = 0.9
, minSlicesPerEntity:int = 20, zScoreThreshEntity:real = 3.0, qScoreThreshEntity:real = 2.0, minNumValueThreshEntity:long = 0
, minSlicesPerScope:int = 20, zScoreThreshScope:real = 3.0, qScoreThreshScope:real = 2.0, minNumValueThreshScope:long = 0)
{
// pre-process the input data by adding standard column names and dividing to datasets
let timePeriodBinSize = 'day'; // we assume a reasonable bin for time is day
let processedData = (
T
| extend scope = column_ifexists(scopeColumnName, '')
| extend entity = column_ifexists(entityColumnName, '')
| extend numVec = tolong(column_ifexists(numericColumnName, 0))
| extend sliceTime = todatetime(column_ifexists(timeColumnName, ''))
| where isnotempty(scope) and isnotempty(sliceTime)
| extend dataSet = case((sliceTime >= startTraining and sliceTime < startDetection), 'trainSet'
, sliceTime >= startDetection and sliceTime <= endDetection, 'detectSet'
, 'other')
| where dataSet in ('trainSet', 'detectSet')
);
let aggregatedCandidateScopeData = (
processedData
| summarize firstSeenScope = min(sliceTime), lastSeenScope = max(sliceTime) by scope
| extend slicesInTrainingScope = datetime_diff(timePeriodBinSize, startDetection, firstSeenScope)
| where slicesInTrainingScope >= minTrainingDaysThresh and lastSeenScope >= startDetection
);
let entityModelData = (
processedData
| join kind = inner (aggregatedCandidateScopeData) on scope
| where dataSet == 'trainSet'
| summarize countSlicesEntity = dcount(sliceTime), avgNumEntity = avg(numVec), sdNumEntity = stdev(numVec)
, lowPrcNumEntity = percentile(numVec, lowPercentileForQscore), highPrcNumEntity = percentile(numVec, highPercentileForQscore)
, firstSeenEntity = min(sliceTime), lastSeenEntity = max(sliceTime)
by scope, entity
| extend slicesInTrainingEntity = datetime_diff(timePeriodBinSize, startDetection, firstSeenEntity)
);
let scopeModelData = (
processedData
| join kind = inner (aggregatedCandidateScopeData) on scope
| where dataSet == 'trainSet'
| summarize countSlicesScope = dcount(sliceTime), avgNumScope = avg(numVec), sdNumScope = stdev(numVec)
, lowPrcNumScope = percentile(numVec, lowPercentileForQscore), highPrcNumScope = percentile(numVec, highPercentileForQscore)
by scope
);
let resultsData = (
processedData
| where dataSet == 'detectSet'
| join kind = inner (aggregatedCandidateScopeData) on scope
| join kind = leftouter (entityModelData) on scope, entity
| join kind = leftouter (scopeModelData) on scope
| extend zScoreEntity = iff(countSlicesEntity >= minSlicesPerEntity, round((toreal(numVec) - avgNumEntity)/(sdNumEntity + 1), 2), 0.0)
, qScoreEntity = iff(countSlicesEntity >= minSlicesPerEntity, round((toreal(numVec) - highPrcNumEntity)/(highPrcNumEntity - lowPrcNumEntity + 1), 2), 0.0)
, zScoreScope = iff(countSlicesScope >= minSlicesPerScope, round((toreal(numVec) - avgNumScope)/(sdNumScope + 1), 2), 0.0)
, qScoreScope = iff(countSlicesScope >= minSlicesPerScope, round((toreal(numVec) - highPrcNumScope)/(highPrcNumScope - lowPrcNumScope + 1), 2), 0.0)
| extend isSpikeOnEntity = iff((slicesInTrainingEntity >= minTrainingDaysThresh and zScoreEntity > zScoreThreshEntity and qScoreEntity > qScoreThreshEntity and numVec >= minNumValueThreshEntity), 1, 0)
, entityHighBaseline= round(max_of((avgNumEntity + sdNumEntity), highPrcNumEntity), 2)
, isSpikeOnScope = iff((countSlicesScope >= minTrainingDaysThresh and zScoreScope > zScoreThreshScope and qScoreScope > qScoreThreshScope and numVec >= minNumValueThreshScope), 1, 0)
, scopeHighBaseline = round(max_of((avgNumEntity + 2 * sdNumEntity), highPrcNumScope), 2)
| extend entitySpikeAnomalyScore = iff(isSpikeOnEntity == 1, round(1.0 - 0.25/(max_of(zScoreEntity, qScoreEntity)),4), 0.00)
, scopeSpikeAnomalyScore = iff(isSpikeOnScope == 1, round(1.0 - 0.25/(max_of(zScoreScope, qScoreScope)), 4), 0.00)
| where isSpikeOnEntity == 1 or isSpikeOnScope == 1
| extend avgNumEntity = round(avgNumEntity, 2), sdNumEntity = round(sdNumEntity, 2)
, avgNumScope = round(avgNumScope, 2), sdNumScope = round(sdNumScope, 2)
| project-away entity1, scope1, scope2, scope3
| extend anomalyType = iff(isSpikeOnEntity == 1, strcat('spike_', entityColumnName), strcat('spike_', scopeColumnName)), anomalyScore = max_of(entitySpikeAnomalyScore, scopeSpikeAnomalyScore)
| extend anomalyExplainability = iff(isSpikeOnEntity == 1
, strcat('The value of numeric variable ', numericColumnName, ' for ', entityColumnName, ' ', entity, ' is ', numVec, ', which is abnormally high for this '
, entityColumnName, ' at this ', scopeColumnName
, '. Based on observations from last ' , slicesInTrainingEntity, ' ', timePeriodBinSize, 's, the expected baseline value is below ', entityHighBaseline, '.')
, strcat('The value of numeric variable ', numericColumnName, ' on ', scopeColumnName, ' ', scope, ' is ', numVec, ', which is abnormally high for this '
, scopeColumnName, '. Based on observations from last ' , slicesInTrainingScope, ' ', timePeriodBinSize, 's, the expected baseline value is below ', scopeHighBaseline, '.'))
| extend anomalyState = iff(isSpikeOnEntity == 1
, bag_pack('avg', avgNumEntity, 'stdev', sdNumEntity, strcat('percentile_', lowPercentileForQscore), lowPrcNumEntity, strcat('percentile_', highPercentileForQscore), highPrcNumEntity)
, bag_pack('avg', avgNumScope, 'stdev', sdNumScope, strcat('percentile_', lowPercentileForQscore), lowPrcNumScope, strcat('percentile_', highPercentileForQscore), highPrcNumScope))
| project-away lowPrcNumEntity, highPrcNumEntity, lowPrcNumScope, highPrcNumScope
);
resultsData
};
// Write your query to use the function here.
Beispiel
Im folgenden Beispiel wird der Aufrufoperator verwendet, um die Funktion auszuführen.
Um eine abfragedefinierte Funktion zu verwenden, rufen Sie sie nach der definition der eingebetteten Funktion auf.
let detect_anomalous_spike_fl = (T:(*), numericColumnName:string, entityColumnName:string, scopeColumnName:string
, timeColumnName:string, startTraining:datetime, startDetection:datetime, endDetection:datetime, minTrainingDaysThresh:int = 14
, lowPercentileForQscore:real = 0.25, highPercentileForQscore:real = 0.9
, minSlicesPerEntity:int = 20, zScoreThreshEntity:real = 3.0, qScoreThreshEntity:real = 2.0, minNumValueThreshEntity:long = 0
, minSlicesPerScope:int = 20, zScoreThreshScope:real = 3.0, qScoreThreshScope:real = 2.0, minNumValueThreshScope:long = 0)
{
// pre-process the input data by adding standard column names and dividing to datasets
let timePeriodBinSize = 'day'; // we assume a reasonable bin for time is day
let processedData = (
T
| extend scope = column_ifexists(scopeColumnName, '')
| extend entity = column_ifexists(entityColumnName, '')
| extend numVec = tolong(column_ifexists(numericColumnName, 0))
| extend sliceTime = todatetime(column_ifexists(timeColumnName, ''))
| where isnotempty(scope) and isnotempty(sliceTime)
| extend dataSet = case((sliceTime >= startTraining and sliceTime < startDetection), 'trainSet'
, sliceTime >= startDetection and sliceTime <= endDetection, 'detectSet'
, 'other')
| where dataSet in ('trainSet', 'detectSet')
);
let aggregatedCandidateScopeData = (
processedData
| summarize firstSeenScope = min(sliceTime), lastSeenScope = max(sliceTime) by scope
| extend slicesInTrainingScope = datetime_diff(timePeriodBinSize, startDetection, firstSeenScope)
| where slicesInTrainingScope >= minTrainingDaysThresh and lastSeenScope >= startDetection
);
let entityModelData = (
processedData
| join kind = inner (aggregatedCandidateScopeData) on scope
| where dataSet == 'trainSet'
| summarize countSlicesEntity = dcount(sliceTime), avgNumEntity = avg(numVec), sdNumEntity = stdev(numVec)
, lowPrcNumEntity = percentile(numVec, lowPercentileForQscore), highPrcNumEntity = percentile(numVec, highPercentileForQscore)
, firstSeenEntity = min(sliceTime), lastSeenEntity = max(sliceTime)
by scope, entity
| extend slicesInTrainingEntity = datetime_diff(timePeriodBinSize, startDetection, firstSeenEntity)
);
let scopeModelData = (
processedData
| join kind = inner (aggregatedCandidateScopeData) on scope
| where dataSet == 'trainSet'
| summarize countSlicesScope = dcount(sliceTime), avgNumScope = avg(numVec), sdNumScope = stdev(numVec)
, lowPrcNumScope = percentile(numVec, lowPercentileForQscore), highPrcNumScope = percentile(numVec, highPercentileForQscore)
by scope
);
let resultsData = (
processedData
| where dataSet == 'detectSet'
| join kind = inner (aggregatedCandidateScopeData) on scope
| join kind = leftouter (entityModelData) on scope, entity
| join kind = leftouter (scopeModelData) on scope
| extend zScoreEntity = iff(countSlicesEntity >= minSlicesPerEntity, round((toreal(numVec) - avgNumEntity)/(sdNumEntity + 1), 2), 0.0)
, qScoreEntity = iff(countSlicesEntity >= minSlicesPerEntity, round((toreal(numVec) - highPrcNumEntity)/(highPrcNumEntity - lowPrcNumEntity + 1), 2), 0.0)
, zScoreScope = iff(countSlicesScope >= minSlicesPerScope, round((toreal(numVec) - avgNumScope)/(sdNumScope + 1), 2), 0.0)
, qScoreScope = iff(countSlicesScope >= minSlicesPerScope, round((toreal(numVec) - highPrcNumScope)/(highPrcNumScope - lowPrcNumScope + 1), 2), 0.0)
| extend isSpikeOnEntity = iff((slicesInTrainingEntity >= minTrainingDaysThresh and zScoreEntity > zScoreThreshEntity and qScoreEntity > qScoreThreshEntity and numVec >= minNumValueThreshEntity), 1, 0)
, entityHighBaseline= round(max_of((avgNumEntity + sdNumEntity), highPrcNumEntity), 2)
, isSpikeOnScope = iff((countSlicesScope >= minTrainingDaysThresh and zScoreScope > zScoreThreshScope and qScoreScope > qScoreThreshScope and numVec >= minNumValueThreshScope), 1, 0)
, scopeHighBaseline = round(max_of((avgNumEntity + 2 * sdNumEntity), highPrcNumScope), 2)
| extend entitySpikeAnomalyScore = iff(isSpikeOnEntity == 1, round(1.0 - 0.25/(max_of(zScoreEntity, qScoreEntity)),4), 0.00)
, scopeSpikeAnomalyScore = iff(isSpikeOnScope == 1, round(1.0 - 0.25/(max_of(zScoreScope, qScoreScope)), 4), 0.00)
| where isSpikeOnEntity == 1 or isSpikeOnScope == 1
| extend avgNumEntity = round(avgNumEntity, 2), sdNumEntity = round(sdNumEntity, 2)
, avgNumScope = round(avgNumScope, 2), sdNumScope = round(sdNumScope, 2)
| project-away entity1, scope1, scope2, scope3
| extend anomalyType = iff(isSpikeOnEntity == 1, strcat('spike_', entityColumnName), strcat('spike_', scopeColumnName)), anomalyScore = max_of(entitySpikeAnomalyScore, scopeSpikeAnomalyScore)
| extend anomalyExplainability = iff(isSpikeOnEntity == 1
, strcat('The value of numeric variable ', numericColumnName, ' for ', entityColumnName, ' ', entity, ' is ', numVec, ', which is abnormally high for this '
, entityColumnName, ' at this ', scopeColumnName
, '. Based on observations from last ' , slicesInTrainingEntity, ' ', timePeriodBinSize, 's, the expected baseline value is below ', entityHighBaseline, '.')
, strcat('The value of numeric variable ', numericColumnName, ' on ', scopeColumnName, ' ', scope, ' is ', numVec, ', which is abnormally high for this '
, scopeColumnName, '. Based on observations from last ' , slicesInTrainingScope, ' ', timePeriodBinSize, 's, the expected baseline value is below ', scopeHighBaseline, '.'))
| extend anomalyState = iff(isSpikeOnEntity == 1
, bag_pack('avg', avgNumEntity, 'stdev', sdNumEntity, strcat('percentile_', lowPercentileForQscore), lowPrcNumEntity, strcat('percentile_', highPercentileForQscore), highPrcNumEntity)
, bag_pack('avg', avgNumScope, 'stdev', sdNumScope, strcat('percentile_', lowPercentileForQscore), lowPrcNumScope, strcat('percentile_', highPercentileForQscore), highPrcNumScope))
| project-away lowPrcNumEntity, highPrcNumEntity, lowPrcNumScope, highPrcNumScope
);
resultsData
};
let detectPeriodStart = datetime(2022-04-30 05:00:00.0000000);
let trainPeriodStart = datetime(2022-03-01 05:00);
let names = pack_array("Admin", "Dev1", "Dev2", "IT-support");
let countNames = array_length(names);
let testData = range t from 1 to 24*60 step 1
| extend timeSlice = trainPeriodStart + 1h * t
| extend countEvents = round(2*rand() + iff((t/24)%7>=5, 10.0, 15.0) - (((t%24)/10)*((t%24)/10)), 2) * 100
| extend userName = tostring(names[toint(rand(countNames))])
| extend deviceId = hash_md5(rand())
| extend accountName = iff(((rand() < 0.2) and (timeSlice < detectPeriodStart)), 'testEnvironment', 'prodEnvironment')
| extend userName = iff(timeSlice == detectPeriodStart, 'H4ck3r', userName)
| extend countEvents = iff(timeSlice == detectPeriodStart, 3*countEvents, countEvents)
| sort by timeSlice desc
;
testData
| invoke detect_anomalous_spike_fl(numericColumnName = 'countEvents'
, entityColumnName = 'userName'
, scopeColumnName = 'accountName'
, timeColumnName = 'timeSlice'
, startTraining = trainPeriodStart
, startDetection = detectPeriodStart
, endDetection = detectPeriodStart
)
Ausgabe-
t | timeSlice | countEvents | Nutzername | deviceId | accountName | Umfang | Entität | numVec | sliceTime | Dataset | firstSeenScope | lastSeenScope | slicesInTrainingScope | countSlicesEntity | avgNumEntity | sdNumEntity | firstSeenEntity | lastSeenEntity | slicesInTrainingEntity | countSlicesScope | avgNumScope | sdNumScope | zScoreEntity | qScoreEntity | zScoreScope | qScoreScope | isSpikeOnEntity | entityHighBaseline | isSpikeOnScope | scopeHighBaseline | entitySpikeAnomalyScore | scopeSpikeAnomalyScore | anomalyType | AnomalyScore | Anomalieexplainability | AnomalyState |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1440 | 2022-04-30 05:00:00.0000000 | 5079 | H4ck3r | 9e8e151aced5a64938b93e0c13fe940 | prodEnvironment | prodEnvironment | H4ck3r | 5079 | 2022-04-30 05:00:00.0000000 | detectSet | 2022-03-01 08:00:00.0000000 | 2022-04-30 05:00:00.0000000 | 60 | 1155 | 1363.22 | 267.51 | 0 | 0 | 13.84 | 185.46 | 0 | 1 | 628 | 0 | 0.9987 | spike_accountName | 0.9987 | Der Wert der numerischen Variablen countEvents für accountName prodEnvironment ist 5079, was für diesen AccountName ungewöhnlich hoch ist. Basierend auf Beobachtungen der letzten 60 Tage liegt der erwartete Basiswert unter 628,0. | {"avg": 1363.22,"stdev": 267.51,"percentile_0.25": 605,"percentile_0.9": 628} |
Die Ausgabe der Ausführung der Funktion ist die Zeilen im Erkennungsdatenset, die entweder auf Bereichs- oder Entitätsebenen als anomaliele Spitzen markiert wurden. Einige weitere Felder werden zur Übersichtlichkeit hinzugefügt:
-
dataSet
: aktuelles Dataset (ist immerdetectSet
). -
firstSeenScope
: Zeitstempel, als der Bereich zum ersten Mal angezeigt wurde. -
lastSeenScope
: Zeitstempel, zu dem der Bereich zuletzt gesehen wurde. -
slicesInTrainingScope
: Anzahl der Segmente (z. B. Tage), die im Schulungsdatensatz vorhanden sind. -
countSlicesEntity
: Anzahl der Segmente (z. B. Tage), die die Entität im Bereich vorhanden ist. -
avgNumEntity
: Mittelwert der numerischen Variablen im Schulungssatz pro Entität im Bereich. -
sdNumEntity
: Standardabweichung der numerischen Variablen im Schulungssatz pro Entität im Bereich. -
firstSeenEntity
: Zeitstempel, als die Entität zum ersten Mal im Bereich angezeigt wurde. -
lastSeenEntity
: Zeitstempel, als die Entität zuletzt im Bereich angezeigt wurde. -
slicesInTrainingEntity
: Anzahl der Segmente (z. B. Tage), die die Entität im Bereich des Schulungsdatensatzes vorhanden ist. -
countSlicesScope
: Anzahl der Segmente (z. B. Tage), die der Bereich vorhanden ist. -
avgNumScope
: Mittelwert der numerischen Variablen im Schulungssatz pro Bereich. -
sdNumScope
: Standardabweichung der numerischen Variablen im Schulungssatz pro Bereich. -
zScoreEntity
: Z-Score für den aktuellen Wert der numerischen Variablen basierend auf dem Entitätsmodell. -
qScoreEntity
: Q-Score für den aktuellen Wert der numerischen Variablen basierend auf dem Entitätsmodell. -
zScoreScope
: Z-Score für den aktuellen Wert einer numerischen Variablen basierend auf dem Bereichsmodell. -
qScoreScope
: Q-Score für den aktuellen Wert der numerischen Variablen basierend auf dem Bereichsmodell. -
isSpikeOnEntity
: binäre Kennzeichnung für anomaliele Spitzen basierend auf dem Entitätsmodell. -
entityHighBaseline
: Hohe Basislinie für numerische Variablenwerte basierend auf dem Entitätsmodell erwartet. -
isSpikeOnScope
: binäre Kennzeichnung für anomaliele Spitzen basierend auf dem Bereichsmodell. -
scopeHighBaseline
: Hohe Basislinie für numerische Variablenwerte basierend auf dem Bereichsmodell erwartet. -
entitySpikeAnomalyScore
: Anomaliebewertung für die Spitzen basierend auf dem Entitätsmodell; eine Zahl im Bereich [0,1], höhere Werte bedeuten eine Anomalie. -
scopeSpikeAnomalyScore
: Anomaliebewertung für die Spitzen basierend auf dem Bereichsmodell; eine Zahl im Bereich [0,1], höhere Werte bedeuten eine Anomalie. -
anomalyType
: zeigt den Typ der Anomalie an (hilfreich beim Ausführen mehrerer Anomalieerkennungslogiken). -
anomalyScore
: Anomaliebewertung für die Spitzen basierend auf dem ausgewählten Modell. -
anomalyExplainability
: Textwrapper für generierte Anomalien und deren Erklärung. -
anomalyState
: Beutel von Metriken aus dem ausgewählten Modell (Mittelwert, Standardabweichung und Quantile), die das Modell beschreiben.
Im obigen Beispiel erkennt das Ausführen dieser Funktion auf "countEvents"-Variable mithilfe von Benutzer als Entität und Konto als Bereich mit Standardparametern eine Spitze auf Bereichsebene. Da der Benutzer "H4ck3r" nicht über genügend Daten im Schulungszeitraum verfügt, wird die Anomalie nicht für Entitätsebene berechnet, und alle relevanten Felder sind leer. Die Anomalie der Bereichsebene weist eine Anomaliebewertung von 0,998 auf, was bedeutet, dass diese Spitze für den Bereich anomale ist.
Wenn wir einen der minimalen Schwellenwerte hoch genug erhöhen, wird keine Anomalie erkannt, da die Anforderungen zu hoch wären.
Die Ausgabe zeigt die Zeilen mit anomalen Spitzen zusammen mit Erklärungsfeldern im standardisierten Format an. Diese Felder eignen sich zum Untersuchen der Anomalien und zum Ausführen der Anomalienspitzenerkennung auf mehreren numerischen Variablen oder zum Gemeinsamen Ausführen anderer Algorithmen.
Die vorgeschlagene Verwendung im Cybersicherheitskontext führt die Funktion auf aussagekräftigen numerischen Variablen (Mengen von heruntergeladenen Daten, Anzahl der hochgeladenen Dateien oder fehlgeschlagenen Anmeldeversuchen) pro aussagekräftigen Bereichen (z. B. Abonnement für Konten) und Entitäten (z. B. Benutzer oder Geräte) aus. Eine erkannte anomaliele Spitzen bedeutet, dass der numerische Wert höher ist als erwartet in diesem Bereich oder dieser Entität und kann verdächtig sein.