homework-jianmu/docs/zh/06-advanced/06-TDgpt/06-dev/03-ad.md

77 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "异常检测"
sidebar_label: "异常检测"
---
### 输入约定
`execute` 是算法处理的核心方法。框架调用该方法之前,在对象属性参数 `self.list` 中已经设置完毕用于异常检测的时间序列数据。
### 输出约定
`execute` 方法执行完成后的返回值是长度与 `self.list` 相同的数组,数组位置 -1 的标识异常值点。
> 例如:对于输入测量值序列 $[2, 2, 2, 2, 100]$ 假设 100 是异常点,那么方法返回的结果数组则为 $[1, 1, 1, 1, -1]$。
### 示例代码
下面我们开发一个示例异常检测算法,在异常检测中,将输入时间序列值的最后一个值设置为异常值,并返回结果。
```python
import numpy as np
from service import AbstractAnomalyDetectionService
# 算法实现类名称 需要以下划线 "_" 开始,并以 Service 结束
class _MyAnomalyDetectionService(AbstractAnomalyDetectionService):
""" 定义类,从 AbstractAnomalyDetectionService 继承,并实现 AbstractAnomalyDetectionService 类的抽象方法 """
# 定义算法调用关键词全小写ASCII码
name = 'myad'
# 该算法的描述信息(建议添加)
desc = """return the last value as the anomaly data"""
def __init__(self):
"""类初始化方法"""
super().__init__()
def execute(self):
""" 算法逻辑的核心实现"""
"""创建一个长度为 len(self.list),全部值为 1 的结果数组,然后将最后一个值设置为 -1表示最后一个值是异常值"""
res = [1] * len(self.list)
res[-1] = -1
"""返回结果数组"""
return res
def set_params(self, params):
"""该算法无需任何输入参数,直接重载父类该函数,不处理算法参数设置逻辑"""
pass
```
将该文件保存在 `./taosanalytics/algo/ad/` 目录下,然后重启 taosanode 服务。在 TDengine 命令行接口 taos 中执行 `SHOW ANODES FULL` 就能够看到新加入的算法,然后应用就可以通过 SQL 语句调用该检测算法。
```SQL
--- 对 col 列进行异常检测,通过指定 algo 参数为 myad 来调用新添加的异常检测类
SELECT COUNT(*) FROM foo ANOMALY_WINDOW(col, 'algo=myad')
```
如果是第一次启动该 Anode, 请按照 [TDgpt 安装部署](../../management/) 里的步骤先将该 Anode 添加到 TDengine 系统中。
### 单元测试
在测试目录`taosanalytics/test`中的 anomaly_test.py 中增加单元测试用例或添加新的测试文件。框架中使用了 Python Unit test 包。
```python
def test_myad(self):
""" 测试 _IqrService 类 """
s = loader.get_service("myad")
# 设置需要进行检测的输入数据
s.set_input_list(AnomalyDetectionTest.input_list)
r = s.execute()
# 最后一个点是异常点
self.assertEqual(r[-1], -1)
self.assertEqual(len(r), len(AnomalyDetectionTest.input_list))
```