本文介绍异常检测算法的概念和时序异常检测的语法。
引擎与版本
时序异常检测仅支持时序引擎。无版本要求。
使用限制
时序异常检测必须和SAMPLE BY
语句搭配使用。
功能简介
时序异常检测用于检测指定时间线上异常点的值,支持阿里达摩院自研的在线异常检测算法。异常检测算法在检测过程中持续学习时序数据的特征(例如数据趋势或者周期),从而完成对新插入时序点的检测。例如新插入的时序数据有一个非常大的尖刺,检测结果可能为异常。
时序异常检测搭配SAMPLE BY
语句可以实现以下功能:
语法
select_sample_by_statement ::= SELECT ( select_clause )
FROM table_identifier
WHERE where_clause
SAMPLE BY 0
select_clause ::= selector [ AS identifier ] ( ',' selector [ AS identifier ] )
selector ::= tag_identifier, | time | anomaly_detect '(' field_identifier ',' algo_identifier | model_identifier [ ',' options] ')'
where_clause ::= relation ( AND relation )* (OR relation)*
relation ::= ( field_identifier| tag_identifier, ) operator term
operator ::= '=' | '<' | '>' | '<=' | '>=' | '!=' | IN | CONTAINS | CONTAINS KEY
anomaly_detect
代表时序异常检测函数,相关参数说明如下:
参数 | 描述 |
field_identifier | Field列名。 说明 Field列的类型不能是VARCHAR和BOOLEAN类型。 |
algo_identifier | 异常检测算法名称。支持阿里达摩院自研在线异常检测算法。
说明 algo_identifer参数适用于未开通数据库内机器学习功能,但有使用时序异常检测需求的场景。 |
model_identifier | 模型名称。 说明
|
options | 调整异常检测算法的检测效果。可选参数。格式为: |
算法分类
时序引擎支持以下异常检测算法,算法名称和适用场景如下表:
算法名称 | 适用场景 |
esd |
|
nsigma |
说明 不建议在数据点中有少量显著离群点的场景中使用,因为这种情况下计算的检测值不准确可能导致检测结果误报。 |
ttest |
|
Incremental STL with ESD(简称istl-esd) | 适用于周期性信号。istl-esd算法属于达摩院自研OneShot STL(也称Incremental STL)算法。Incremental STL是可以实时增量地将周期信号分解成周期项、趋势项和残余项的算法,需要对4个周期的信号进行初始化。此检测算法中包含Incremental STL算法和esd算法,先用Incremental STL对信号进行实时增量分解,再对残余项使用esd算法检测异常。通过对残余项进行esd算法检测,可以检测到非周期性尖刺。 |
Incremental STL with Nsigma(简称istl-nsigma) | 适用于周期性信号。Incremental STL是可以实时增量地将周期信号分解成周期项、趋势项和残余项的算法,需要对4个周期的信号进行初始化。此检测算法中包含Incremental STL算法和nsigma算法,先用Incremental STL对信号进行实时增量分解,再对残余项用nsigma检测异常。通过对残余项进行nsigma检测,可以检测到非周期性尖刺。 |
算法适用场景的曲线图如下:
esd算法:用于检测每个时序点,适用于相对稳定的信号中出现少量异常值的场景。
nsigma算法:用于检测每个时序点,适用于异常点相对于历史平均值有较大差异(通过算法的参数n来调节)的场景。
ttest算法:用于检测一段时间窗口内的时序数据。适用于以下两个连续时间段内均值变化异常的场景。
istl-esd算法:Incremental STL算法用于检测带周期性信号的时序数据。Incremental STL算法会在去除原始数据的周期趋势量后,对残余项使用esd算法进行检测。适用于相对稳定的周期信号中出现少量异常值的场景。
istl-nsigma算法:Incremental STL算法用于检测带周期性信号的时序数据。Incremental STL算法会在去除原始数据的周期趋势量后,对残余项使用nsigma算法进行检测。适用于异常点相对于历史平均值有较大差异的场景。
参数说明
公共参数
通用的公共参数控制检测过程中的调试诊断和行为,可以使用到所有的异常检测算法中。公共参数说明如下表:
参数名称 | 类型 | 默认值 | 说明 |
verbose | BOOLEAN | FALSE | 是否返回更多详细信息,并标识目标列是否异常。具体返回的信息由各算法决定。取值如下:
取值为 |
adhoc_state | BOOLEAN | FALSE | 是否将算法的异常检测状态限制在本次查询检测中,有关异常检测状态的描述请参见异常检测状态。 |
direction | VARCHAR | UP | 检测异常的方向。取值如下:
|
训练参数
使用异常检测算法时,指定算法名称和训练参数会确定一个具体的异常检测算法模型。训练参数在Lindorm时序引擎重启后会失效,需要重新对数据点进行训练(训练的操作是检测过程中实时适应时序数据的特性)。
配置训练参数时需要注意以下几点:
参数名称不区分大小写。
参数值的类型支持数值、布尔和字符串,不支持NULL等特殊值。
参数值必须在指定的取值范围内。
算法名称 | 参数名称 | 类型 | 取值 | 说明 |
esd | compression | INTEGER | 正整数,默认值为100,取值范围为 | 算法中数据结构的空间复杂度。参数值越大算法在运行过程中越占用内存,但是算法结果越准确。 |
lenHistoryWindow | INTEGER | 正整数,默认值为null,取值≥20。 | 算法参考的时间窗口长度。如果时间窗口长度比较短,计算过程中只会将最近的数据点作为参考值。当lenHistoryWindow=null时,表示没有指定参考的时间窗口长度,此时会用第一次检测以来的所有时间点作为参考的时间窗口长度。 | |
nsigma | lenHistoryWindow | INTEGER | 正整数,默认值为null,取值≥20。 | 算法参考的时间窗口长度。如果时间窗口长度比较短只会参考最近的数据点作为参考值。当lenHistoryWindow=null时,表示没有指定参考的时间窗口长度,此时会用第一次检测以来的所有时间点作为参考的时间窗口长度。 |
ttest | lenDetectWindow | INTEGER | 正整数,默认值为10。 | 待检测的最近的时间窗口的长度。 |
lenHistoryWindow | INTEGER | 正整数,默认值为100,取值≥20。 | 算法参考的时间窗口长度。如果时间窗口长度比较短,计算过程中只会将最近的数据点作为参考值。当 说明 此参数值必须大于lenDetectWindow参数值。 | |
istl-esd | frequency | VARCHAR | 用数字和时间单位表示的字符串。例如5M、24H、1D。 表示时间单位的有效取值及含义:
| 时间序列的采集频率。例如每小时一个点则 重要
|
periods | VARCHAR | 用数字和时间单位表示的字符串。例如5M、24H、1D。 表示时间单位的有效取值及含义如下:
| 周期信号的所有周期长度。可以通过索引符传递多个周期长度。例如: 说明 如果未设置该参数,算法会自动检测周期。 | |
esd.* | 不涉及 | 定义esd算法所需的训练参数,请参考esd算法的训练参数。使用时通过添加esd.前缀进行关联到esd算法参数。例如: | ||
istl-nsigma | frequency | VARCHAR | 用数字和时间单位表示的字符串。例如5M、24H、1D。 表示时间单位的有效取值及含义如下:
| 时间序列的采集频率。例如 重要
|
periods | VARCHAR | 用数字和时间单位表示的字符串。例如5M、24H、1D。 表示时间单位的有效取值及含义如下:
| 周期信号的所有周期长度。可以通过索引符传递多个周期长度。例如: 说明 如果未设置该参数,算法会自动检测周期。 | |
nsigma.* | 不涉及 | 定义nsigma算法所需的训练参数,请参考nsigma算法的训练参数。使用时通过添加nsigma.前缀进行关联到nsigma算法参数。例如: |
推理参数
推理参数只在检测时起作用,且参数名称大小写不敏感。
算法名称 | 参数名称 | 类型 | 取值 | 说明 |
esd | alpha | DOUBLE | 默认值为0.1,取值范围为 | 异常检测的敏感程度。参数值越大,对异常检测越敏感,会报出比较多的异常。 |
direction | VARCHAR | 默认值为Up。 | 检测异常的方向。
| |
maxAnomalyRatio | DOUBLE | 默认值为0.3,取值范围为 | 最大的异常比例。例如:当maxAnomalyRatio=0.3并且direction=Up时,表示值小于第70百分位数的点不会被认为是异常。
| |
warmupCount | INTEGER | 正整数,默认值为20。 | 至少需要多少个点才会开始报异常。例如:warmupCount=20表示数据点小于20个不会报异常。 | |
nsigma | n | DOUBLE | 非零浮点数,默认值为3.0。 |
|
warmupCount | INTEGER | 正整数,默认值为20。 | 至少需要多少个点才会报异常。例如:warmupCount=20表示数据点小于20个不会报异常。 | |
ttest | alpha | DOUBLE | 默认值为0.05,取值范围为 | 异常检测的敏感程度。参数值越大,对异常检测越敏感,会报出比较多的异常。 |
direction | VARCHAR | 默认为Up。 | 检测异常的方向。
| |
istl-esd | esd.* | 不涉及 | 定义esd算法所需的推理参数,请参考esd算法的推理参数。使用时通过 | |
istl-nsigma | nsigma.* | 不涉及 | 定义nsigma算法所需的推理参数,请参考nsigma算法的推理参数。使用时通过 |
示例
示例1:对时序数据表sensor中指定时间范围的温度使用esd算法进行时序异常检测。
SELECT device_id, region, time, anomaly_detect(temperature, 'esd') AS detect_result FROM sensor WHERE time >= '2022-01-01 00:00:00' and time < '2022-01-01 00:01:00' SAMPLE BY 0;
返回结果如下:
+-----------+----------+---------------------------+---------------+ | device_id | region | time | detect_result | +-----------+----------+---------------------------+---------------+ | F07A1260 | north-cn | 2022-01-01T00:00:00+08:00 | true | | F07A1260 | north-cn | 2022-01-01T00:00:01+08:00 | false | | F07A1260 | north-cn | 2022-01-01T00:00:02+08:00 | true | | F07A1261 | south-cn | 2022-01-01T00:00:00+08:00 | false | | F07A1261 | south-cn | 2022-01-01T00:00:01+08:00 | false | | F07A1261 | south-cn | 2022-01-01T00:00:02+08:00 | false | | F07A1261 | south-cn | 2022-01-01T00:00:03+08:00 | false | +-----------+----------+---------------------------+---------------+
示例2:对时序数据表sensor中F07A1260设备指定时间范围的温度使用esd算法进行时序异常检测。
SELECT device_id, region, time, anomaly_detect(temperature, 'esd') AS detect_result FROM sensor WHERE device_id in ('F07A1260') and time >= '2022-01-01 00:00:00' and time < '2022-01-01 00:01:00' SAMPLE BY 0;
返回结果如下:
+-----------+----------+---------------------------+---------------+ | device_id | region | time | detect_result | +-----------+----------+---------------------------+---------------+ | F07A1260 | north-cn | 2022-01-01T00:00:00+08:00 | true | | F07A1260 | north-cn | 2022-01-01T00:00:01+08:00 | false | | F07A1260 | north-cn | 2022-01-01T00:00:02+08:00 | true | +-----------+----------+---------------------------+---------------+
示例3:对时序数据表sensor中F07A1260设备指定时间范围的温度使用esd算法进行时序异常检测,同时指定算法参数。
SELECT device_id, region, time, anomaly_detect(temperature, 'esd', 'lenHistoryWindow=30,maxAnomalyRatio=0.1') AS detect_result FROM sensor WHERE device_id in ('F07A1260') and time >= '2022-01-01 00:00:00' and time < '2022-01-01 00:01:00' SAMPLE BY 0;
返回结果如下:
+-----------+----------+---------------------------+---------------+ | device_id | region | time | detect_result | +-----------+----------+---------------------------+---------------+ | F07A1260 | north-cn | 2022-01-01T00:00:00+08:00 | false | | F07A1260 | north-cn | 2022-01-01T00:00:01+08:00 | false | | F07A1260 | north-cn | 2022-01-01T00:00:02+08:00 | true | +-----------+----------+---------------------------+---------------+
示例4:与降采样算子MAX嵌套使用,降采样粒度为1分钟。
SELECT time, anomaly_detect(max(temperature), 'esd') AS ad_result, max(temperature) AS rawVal FROM sensor SAMPLE BY 1m;
返回结果如下:
+---------------------------+-----------+-------------+ | time | ad_result | rawVal | +---------------------------+-----------+-------------+ | 2022-04-12T06:00:00+08:00 | null | 923091.3175 | | 2022-04-11T08:00:00+08:00 | null | 8035700 | | 2022-04-11T09:00:00+08:00 | null | 8035690.25 | | 2022-04-11T10:00:00+08:00 | null | 3306277.545 | | 2022-04-11T11:00:00+08:00 | null | 5921167.787 | | 2022-04-11T12:00:00+08:00 | null | 833541.304 | +---------------------------+-----------+-------------+
示例5:与非降采样算子LATEST嵌套使用,降采样粒度为0。
SELECT time, anomaly_detect(latest(temperature), 'esd') AS ad_result, latest(temperature) AS latestVal FROM sensor SAMPLE BY 0;
返回结果如下:
+---------------------------+-----------+-------------+ | time | ad_result | latestVal | +---------------------------+-----------+-------------+ | 2022-04-12T06:00:00+08:00 | false | 923091.3175 | | 2022-04-13T07:00:00+08:00 | false | 8037506.75 | | 2022-04-13T07:00:00+08:00 | false | 50490.2 | +---------------------------+-----------+-------------+