时序异常检测
本文介绍异常检测算法的概念和时序异常检测的语法。
使用限制
时序异常检测必须和
SAMPLE BY 0
同时使用,表示检测每条时间线上的异常点的值。时序异常检测不支持与其他函数组合使用,例如:RATE、DELTA、MAX、MIN等函数。
功能简介
时序异常检测用于检测指定时间线上异常点的值,支持阿里达摩院自研的在线异常检测算法。异常检测算法在检测过程中持续学习时序数据的特征(例如数据趋势或者周期),从而完成对新插入时序点的检测。例如新插入的时序数据有一个非常大的尖刺,检测结果可能为异常。
语法
select_sample_by_statement ::= SELECT ( select_clause )
FROM table_name
WHERE where_clause
SAMPLE BY 0
select_clause ::= selector [ AS identifier ] ( ',' selector [ AS identifier ] )
selector ::= tag_name | time | anomaly_detect '(' field_name ',' algo_name | model_name [ ',' options] ')'
where_clause ::= relation ( AND relation )* (OR relation)*
relation ::= ( field_name | tag_name ) operator term
operator ::= '=' | '<' | '>' | '<=' | '>=' | '!=' | IN | CONTAINS | CONTAINS KEY
anomaly_detect
代表时序异常检测函数,相关参数说明如下:
参数 | 描述 |
field_name | Field列名。 说明 Field列的类型不能是VARCHAR和BOOLEAN类型。 |
algo_name | 异常检测算法名称。支持阿里达摩院自研在线异常检测算法。
说明 algo_name参数适用于未开通数据库内机器学习功能,但有使用时序异常检测需求的场景。 |
model_name | 模型名称。 说明
|
options | 调整异常检测算法的检测效果。可选参数。格式为: |
算法分类
时序引擎支持以下异常检测算法,算法名称和适用场景如下表:
算法名称 | 适用场景 |
esd |
|
nsigma |
说明 不建议在数据点中有少量显著离群点的场景中使用,因为这种情况下计算的检测值不准确可能导致检测结果误报。 |
ttest |
|
Online STL with ESD(简称ostl-esd) | 适用于周期性信号。ostl-esd算法属于达摩院自研Online STL算法。Online STL是可以实时将周期性信号分解成周期项、趋势项和残余项的算法,需要对4个周期的信号进行初始化。周期分解的作用是避免周期性的尖刺(通常为周期性的业务需求)被误判为异常。此检测算法中包含Online STL算法和esd算法,先用Online STL算法对周期信号进行分解,然后对残余项用esd算法检测异常。 |
Incremental STL with ESD(简称istl-esd) | 适用于周期性信号。istl-esd算法属于达摩院自研OneShot STL(也称Incremental STL)算法。Incremental STL是可以实时增量地将周期信号分解成周期项、趋势项和残余项的算法。此检测算法中包含Incremental STL算法和esd算法,先用Incremental STL对信号进行实时增量分解,再对残余项使用esd算法检测异常。通过对残余项进行esd算法检测,可以检测到非周期性尖刺。 |
参数说明
异常检测算法支持配置算法参数,包括公共参数、训练参数和推理参数。您可以通过调整可选参数options来实现不同的异常检测效果。
公共参数、训练参数和推理参数实际传参时都是在同一个列表内指定。以ttest为例,传参时可以指定为:lenDetectWindow=100,adhoc_stat=true
。
公共参数
通用的公共参数控制检测过程中的调试诊断和行为,可以使用到所有的异常检测算法中。公共参数说明如下表:
参数名称 | 类型 | 默认值 | 说明 |
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。 | 算法参考的时间窗口长度。如果时间窗口长度比较短,计算过程中只会将最近的数据点作为参考值。当lenHistoryWindow=null时,表示没有指定参考的时间窗口长度,此时会用第一次检测以来的所有时间点作为参考的时间窗口长度。 说明 此参数值必须大于lenDetectWindow参数值。 | |
ostl-esd | alphaStl | DOUBLE | 默认值为0.35,取值范围为 | 用于周期滤波的平滑参数。 |
periods | INT[] | 正整数,默认值为[1440]。 | 周期性信号的所有周期长度,也就是点的数目。可以通过索引符传递多个周期长度。 例如:periods[0]=1440;periods[1]=1880。 | |
esd.* | 不涉及 | 定义esd算法所需的训练参数,请参考esd算法的训练参数。使用时通过 | ||
istl-esd | frequency | VARCHAR | 用数字和时间单位表示的字符串。例如5M、24H、1D。 表示时间单位的有效取值及含义:
| 时间序列的采集频率。例如每小时一个点则 重要
|
periods | VARCHAR | 用数字和时间单位表示的字符串。例如5M、24H、1D。 表示时间单位的有效取值及含义如下:
| 周期信号的所有周期长度。 说明 如果未设置该参数,算法会自动检测周期。 | |
esd.* | 不涉及 | 定义esd算法所需的训练参数,请参考esd算法的训练参数。使用时通过添加esd.前缀进行关联到esd算法参数。例如: |
推理参数
推理参数只在检测时起作用,且参数名称大小写不敏感。
算法名称 | 参数名称 | 类型 | 取值 | 说明 |
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。 | 检测异常的方向。
| |
ostl-esd | esd.* | 不涉及 | 定义esd算法所需的推理参数,请参考esd算法的推理参数。使用时通过 | |
istl-esd | esd.* | 不涉及 | 定义esd算法所需的推理参数,请参考esd算法的推理参数。使用时通过 |
示例
示例一:对时序数据表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 | +-----------+----------+---------------------------+---------------+
示例二:对时序数据表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 | +-----------+----------+---------------------------+---------------+
示例三:对时序数据表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 | +-----------+----------+---------------------------+---------------+