series_decompose_anomalies()

适用于:✅Azure 数据资源管理器Azure MonitorMicrosoft Sentinel

异常情况检测基于序列分解。 有关详细信息,请参阅 series_decompose()

此函数采用包含某个序列(动态数值数组)的表达式作为输入,并提取有分数的异常点。

语法

series_decompose_anomalies (系列, [阈值, 季节性 , 趋势, Test_points, AD_method, Seasonality_threshold ])

详细了解语法约定

参数

客户 类型​​ 必需 说明
系列 dynamic ✔️ 数值的数组,通常是 make-seriesmake_list 运算符生成的输出。
阈值 real 异常阈值。 默认值为 1.5(k 值),用于检测轻度异常或更严重的异常。
季节性 int 控制周期性分析。 可能的值为:

- -1:使用 series_periods_detect 自动检测周期性。 这是默认值。
- 整数时间段:一个正整数,指定箱数的预期周期。例如,如果系列位于 1h 箱中,则每周周期为 168 箱。
- 0:无周期性,因此请跳过提取此组件的操作。
趋势 string 控制趋势分析。 可能的值为:

- avg:将趋势组件定义为 average(x)。 这是默认值。
- linefit:使用线性回归提取趋势组件。
- none:无趋势,因此请跳过提取此组件的操作。
Test_points int 正整数,指定要从学习或回归过程中排除的序列末尾处的点的数目。 应当设置此参数,用于预测。 默认值为 0。
AD_method string 控制对残差时序的异常情况检测方法,其中包含以下值之一:

- ctukey:Tukey 的围栏测试,采用自定义的第 10 - 90 个百分位数范围。 这是默认值。
- tukey:Tukey 的围栏测试,采用标准的第 25 - 75 个百分位数范围。

有关残差时序的详细信息,请参阅 series_outliers
Seasonality_threshold real 当 Seasonality 设置为 autodetect 时周期性分数的阈值。 默认分数阈值为 0.6。

有关详细信息,请参阅 series_periods_detect

返回

该函数返回以下各个序列:

  • ad_flag:一个三元序列,其中包含 (+1, -1, 0),分别标记为正常/关闭/无异常
  • ad_score:异常分数
  • baseline:序列的预测值,通过分解获得

算法

此函数执行以下步骤:

  1. 使用相应的参数调用 series_decompose() 来创建基线和残差序列。
  2. 通过使用所选的异常情况检测方法对残差序列应用 series_outliers() 来计算 ad_score 序列。
  3. 通过对 ad_score 应用阈值来计算 ad_flag 序列,分别标记为正常/关闭/无异常。

示例

检测每周周期性中的异常

在下面的示例中,将生成一个包含每周周期性的序列,然后向其中添加一些离群值。 series_decompose_anomalies 会自动检测周期性并生成用于捕获重复模式的基线。 在 ad_score 组件中可以清楚地辨认出你添加的离群值。

let ts=range t from 1 to 24*7*5 step 1 
| extend Timestamp = datetime(2018-03-01 05:00) + 1h * t 
| extend y = 2*rand() + iff((t/24)%7>=5, 10.0, 15.0) - (((t%24)/10)*((t%24)/10)) // generate a series with weekly seasonality
| extend y=iff(t==150 or t==200 or t==780, y-8.0, y) // add some dip outliers
| extend y=iff(t==300 or t==400 or t==600, y+8.0, y) // add some spike outliers
| summarize Timestamp=make_list(Timestamp, 10000),y=make_list(y, 10000);
ts 
| extend series_decompose_anomalies(y)
| render timechart  

显示了基线和离群值的每周周期性。

检测具有趋势的每周周期性中的异常

在此示例中,将向上一示例中的序列添加趋势。 首先,使用默认参数运行 series_decompose_anomalies,其中的趋势 avg 默认值仅取平均值,不计算趋势。 与前面的示例相比,生成的基线不包含趋势,并且准确度更低。 因此,你在数据中插入的某些离群值会因为差异较大而不被检测到。

let ts=range t from 1 to 24*7*5 step 1 
| extend Timestamp = datetime(2018-03-01 05:00) + 1h * t 
| extend y = 2*rand() + iff((t/24)%7>=5, 5.0, 15.0) - (((t%24)/10)*((t%24)/10)) + t/72.0 // generate a series with weekly seasonality and ongoing trend
| extend y=iff(t==150 or t==200 or t==780, y-8.0, y) // add some dip outliers
| extend y=iff(t==300 or t==400 or t==600, y+8.0, y) // add some spike outliers
| summarize Timestamp=make_list(Timestamp, 10000),y=make_list(y, 10000);
ts 
| extend series_decompose_anomalies(y)
| extend series_decompose_anomalies_y_ad_flag = 
series_multiply(10, series_decompose_anomalies_y_ad_flag) // multiply by 10 for visualization purposes
| render timechart

包含趋势的每周周期性离群值。

接下来运行同一示例,但由于你预计序列中存在趋势,因此请在 trend 参数中指定 linefit。 你可以看到,基线更接近输入序列。 将会检测到所有插入的离群值,还会检测到一些误报。 请参阅接下来有关调整阈值的示例。

let ts=range t from 1 to 24*7*5 step 1 
| extend Timestamp = datetime(2018-03-01 05:00) + 1h * t 
| extend y = 2*rand() + iff((t/24)%7>=5, 5.0, 15.0) - (((t%24)/10)*((t%24)/10)) + t/72.0 // generate a series with weekly seasonality and ongoing trend
| extend y=iff(t==150 or t==200 or t==780, y-8.0, y) // add some dip outliers
| extend y=iff(t==300 or t==400 or t==600, y+8.0, y) // add some spike outliers
| summarize Timestamp=make_list(Timestamp, 10000),y=make_list(y, 10000);
ts 
| extend series_decompose_anomalies(y, 1.5, -1, 'linefit')
| extend series_decompose_anomalies_y_ad_flag = 
series_multiply(10, series_decompose_anomalies_y_ad_flag) // multiply by 10 for visualization purposes
| render timechart  

包含 linefit 趋势的每周周期性异常。

调整异常情况检测阈值

在上一示例中,一些干扰点被当作异常情况检测出来。 现在,将异常情况检测阈值从默认值 1.5 提高到 2.5。 使用此百分位距,将只会检测到更严重的异常。 现在,将只会检测到你在数据中插入的离群值。

let ts=range t from 1 to 24*7*5 step 1 
| extend Timestamp = datetime(2018-03-01 05:00) + 1h * t 
| extend y = 2*rand() + iff((t/24)%7>=5, 5.0, 15.0) - (((t%24)/10)*((t%24)/10)) + t/72.0 // generate a series with weekly seasonality and onlgoing trend
| extend y=iff(t==150 or t==200 or t==780, y-8.0, y) // add some dip outliers
| extend y=iff(t==300 or t==400 or t==600, y+8.0, y) // add some spike outliers
| summarize Timestamp=make_list(Timestamp, 10000),y=make_list(y, 10000);
ts 
| extend series_decompose_anomalies(y, 2.5, -1, 'linefit')
| extend series_decompose_anomalies_y_ad_flag = 
series_multiply(10, series_decompose_anomalies_y_ad_flag) // multiply by 10 for visualization purposes
| render timechart  

异常阈值较高的每周序列异常。