scientific-agent-skills 中的 Aeon 异常检测:集合级与序列级检测器选型、STOMP 快速上手与 Range 评估指标全解
【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills
本文以 scientific-agent-skills 仓库中skills/aeon技能为蓝本,围绕其异常检测参考文档展开,完整覆盖 Aeon 提供的集合级(Collection)与序列级(Series)两类异常检测器目录、STOMP 矩阵谱快速上手代码、点异常/子序列异常/集体异常的区分方法,以及range_precision等窗口感知评估指标的使用方式。读完后你可以按数据形态(单条长序列、时间序列集合、流式数据、多维信号)直接选型算法,并复现一套可运行的异常检测与评估流程。
1. 背景:aeon 技能中的异常检测定位与版本前提
skills/aeon是仓库中面向"时间序列机器学习"的 Agent 技能,其入口文件 SKILL.md 声明该技能适用于时间序列分类、回归、聚类、预测、异常检测、分割与相似性搜索等任务,核心能力是提供scikit-learn 兼容接口(fit / predict / transform 一致 API)的时间序列专用算法库。异常检测是其中 7 大能力模块之一,详细目录即本文主体来源 references/anomaly_detection.md。
在动手之前,需要先确认三条适用前提(均来自 SKILL.md):
- 运行环境:要求 Python 3.10+(推荐 3.11+),通过
uv pip install "aeon>=1.4,<2"安装 1.x 稳定版本;深度学习和扩展估计器需aeon[all_extras]>=1.4,<2; - 实验性模块警告:上游将
forecasting、anomaly_detection、segmentation、similarity_search、visualisation列为实验性(experimental)模块,接口可能在次版本间变动。因此生产管道应优先使用稳定模块,除非你的任务就是异常检测——本文场景恰好属于后者,但升级 aeon 小版本时需注意接口兼容性; - 示例版本基线:技能文档明确示例针对aeon 1.x(v1.4.0,2026 年 3 月稳定文档)。v1.0 重写了预测与变换模块的导入路径,aeon 0.x / sktime 时代的旧代码导入路径不同,直接套用旧博客代码容易踩坑。
从仓库的测试基建看,tests/skill-requirements.toml 中为 aeon 技能单独声明了隔离测试环境:
[skills.aeon] packages = ["aeon", "matplotlib", "numpy", "scikit-learn"]也就是说,运行本文所有示例只需aeon + matplotlib + numpy + scikit-learn四件套;仓库通过 tests/run_all.py 的--isolated模式为每个技能构建一次性 uv 环境来验证技能可用性,aeon 技能与其他技能(如 opentrons、molfeat 等有冲突依赖的技能)互不干扰。
2. 集合级异常检测器(Collection Anomaly Detectors)
Aeon 把"异常"分两个层级:在时间序列集合中找出异常的那条序列,以及在单条时间序列内部找出异常的点或子序列。前者的两个适配器如下(引自 anomaly_detection.md):
ClassificationAdapter:分类器即异常检测器
- 作用:把标准分类器改造成异常检测器——只用正常数据训练,在预测阶段把被判为"非常规类"的样本标记为异常;
- 适用场景:手里有标注好的正常数据,想走分类路线。其本质是单类学习思路:训练集只喂正常样本,预测时分类器的输出置信度(或被判到少数类/拒绝类)作为异常信号。这种方式的好处是可以直接复用 Aeon 分类模块中全部算法(ROCKET 系、距离系、深度网络系),把"分类精度"转化为"异常分数"。
OutlierDetectionAdapter:桥接 sklearn 离群点检测器
- 作用:包装 scikit-learn 的离群检测器,使其能作用于时间序列集合;
- 支持算法:
IsolationForest、LOF(Local Outlier Factor)、OneClassSVM; - 适用场景:想直接把 sklearn 生态的成熟异常检测器用在时间序列集合上。由于 sklearn 原生只懂二维表格数据,该适配器负责把时间序列"摊平"为样本特征,再交给 sklearn 检测器,预测阶段反向映射回序列级别。
从源码结构看(依据技能文档的目录组织),这两个适配器与序列级检测器并列于aeon.anomaly_detection命名空间下,共享同一套 scikit-learn 风格的估计器 API,可以无缝放进sklearn.pipeline.Pipeline——这与 SKILL.md 中"分类管道"工作流展示的组合方式一致。
3. 序列级异常检测器:按方法论划分的完整目录
序列级检测的目标是找出单条时间序列内部的异常点或异常子序列。文档按方法论分为四类,选型时先定"异常长什么样",再定"数据有什么特点"。
3.1 距离类方法(Distance-Based)
利用相似度/距离度量识别异常:
| 检测器 | 原理 | 适用场景(Use when) |
|---|---|---|
CBLOF | 基于聚类的局部离群因子:先聚类,再依据簇的属性(半径、密度)识别离群者 | 异常点自身形成了稀疏簇 |
KMeansAD | K-means 距离法:样本到最近簇中心的距离即为异常度 | 正常模式聚集良好(簇结构清晰) |
LeftSTAMPi | 左半 STAMP 增量矩阵谱,支持在线计算 | 流式数据、需要在线检测 |
STOMP | 可扩展矩阵谱算法(STOMP),计算子序列的矩阵谱 | 失配(discord)发现、基序(motif)检测 |
MERLIN | 矩阵谱的高效变体 | 大型时间序列、追求可扩展性 |
LOF | 面向时间序列适配的局部离群因子,基于密度判断 | 异常落在低密度区域 |
ROCKAD | 基于 ROCKET 特征的半监督检测 | 有部分标注数据、想用特征化路线 |
其中矩阵谱三兄弟(STOMP / MERLIN / LeftSTAMPi)的原理值得单独展开,见第 5 节。
3.2 分布类方法(Distribution-Based)
分析统计分布形态:
COPOD(Copula-Based Outlier Detection):分别建模边际分布与联合分布,把两者信息融合成离群分数。适用场景:多维时间序列、变量间存在复杂依赖关系。它是目录中少数能天然处理多通道信号的点级方法;DWT_MLEAD(Discrete Wavelet Transform Multi-Level Anomaly Detection):用离散小波变换把序列分解到多个频带,在各层级上识别异常。适用场景:异常集中在特定频率成分(例如传感器在某一频段出现毛刺)。
3.3 孤立类方法(Isolation-Based)
利用"异常更容易被隔离"的原则:
IsolationForest:随机森林式随机切分,异常点路径更短、更易孤立。适用场景:高维数据、且对数据分布形态无假设——是无监督场景下的稳健默认项;OneClassSVM:学习一个包住正常数据边界的超平面,界外即异常。适用场景:正常区域边界定义清晰、需要鲁棒的边界刻画(半监督/单类学习);STRAY:面向流式的鲁棒异常检测,对数据分布漂移不敏感。适用场景:流式数据 + 分布随时间变化(如漂移的传感器读数)。
3.4 外部库桥接:PyODAdapter
PyODAdapter:把 PyOD 生态接入 Aeon 估计器体系,一次性获得 40+ 个 PyOD 异常检测算法,且仍保持 fit/predict 风格 API。适用场景:需要某个特定的 PyOD 算法,同时不想脱离 Aeon 的接口约定。
选型速查(继承自原文档 "Algorithm Selection" 小节):
| 优先目标 | 推荐算法 |
|---|---|
| 速度优先 | KMeansAD、IsolationForest |
| 精度优先 | STOMP、COPOD |
| 流式数据 | LeftSTAMPi、STRAY |
| Discord 发现 | STOMP、MERLIN |
| 多维数据 | COPOD、PyODAdapter |
| 半监督 | ROCKAD、OneClassSVM |
| 无训练数据 | IsolationForest、STOMP |
4. 快速上手:完整复现 STOMP 示例并可视化
4.1 最小可运行示例
以下代码完整继承自 anomaly_detection.md 的 Quick Start,构造一条含单点尖峰异常的正弦序列并用 STOMP 检测。逐行注释如下:
from aeon.anomaly_detection import STOMP import numpy as np # 构造含异常的时间序列:两段正弦中间插一个 5.0 的尖峰 y = np.concatenate([ np.sin(np.linspace(0, 10, 100)), [5.0], # 人为注入的异常尖峰 np.sin(np.linspace(10, 20, 100)) ]) # 实例化 STOMP:window_size 即矩阵谱滑窗长度(关键超参数) detector = STOMP(window_size=10) anomaly_scores = detector.fit_predict(y) # 分数越高越异常;这里用 95 分位数作为经验阈值 threshold = np.percentile(anomaly_scores, 95) anomalies = anomaly_scores > threshold参数要点说明:
window_size:STOMP 的滑窗长度。窗口太小会捕捉噪声,太大则错过细粒度模式;参考 references/similarity_search.md 的经验法则,可取序列长度的 10%–20%。示例中序列长 201,窗口取 10 恰好是"短窗口对长序列"的保守配置,能把尖峰附近的局部失配放大为高分;fit_predict(y):输入 1-D 数组即单条序列(Aeon 约定:集合为(n_cases, n_channels, n_timepoints),单序列为(n_channels, n_timepoints),1-D 可视为单通道特例);- 阈值策略:示例采用95 分位数这一基于分位数的经验阈值。若领域内对异常率有先验(如"异常占比不超过 1%"),应改用分领域阈值而非固定分位数。
4.2 加上可视化验证
SKILL.md 的 "Anomaly Detection with Visualization" 工作流给出了标准双图验证法(上图原序列、下图异常分数 + 阈值线):
from aeon.anomaly_detection import STOMP import matplotlib.pyplot as plt import numpy as np detector = STOMP(window_size=50) scores = detector.fit_predict(y) plt.figure(figsize=(15, 5)) plt.subplot(2, 1, 1) plt.plot(y, label='Time Series') plt.subplot(2, 1, 2) plt.plot(scores, label='Anomaly Scores', color='red') plt.axhline(np.percentile(scores, 95), color='k', linestyle='--') plt.show()这一步对应原文档最佳实践第 4 条"可视化验证检测结果是否有意义"——矩阵谱方法输出的高分位置应对应图中肉眼可见的形态突变,否则大概率是窗口参数或归一化出了问题。
5. 原理纵深:STOMP 为什么能检测异常——矩阵谱(Matrix Profile)
STOMP、MERLIN、LeftSTAMPi 共享同一数学基础。references/similarity_search.md 对矩阵谱数据结构有权威定义,可直接作为异常检测的理论注脚:
- Distance Profile(距离谱):一个查询子序列到其余所有子序列的距离曲线;
- Matrix Profile(矩阵谱):每个子序列到"任意其他子序列"的最近邻距离,构成一条与序列等长的距离曲线;
- Motif(基序):距离最小的子序列对——即重复出现的模式;
- Discord(失配):距离最大的子序列——即异常。
关键洞察在此:在矩阵谱语境下,异常检测与基序发现是同一枚硬币的两面。Motif 找的是argmin(profile),Discord 找的是argmax(profile)。相似性搜索参考文档给出了同一数据的基序侧用法:
from aeon.similarity_search import StompMotif mp = StompMotif(window_size=50) mp.fit(y) # 访问矩阵谱及其最近邻索引 profile = mp.matrix_profile_ profile_indices = mp.matrix_profile_index_ # 找失配(异常):距离谱的最大值位置 discord_idx = np.argmax(profile)也就是说,异常检测侧的STOMP与相似性搜索侧的StompMotif底层都是矩阵谱计算:前者把矩阵谱值直接当作异常分数输出(分数越高,该窗口越"找不到邻居",即越异常),后者把矩阵谱最小值当作基序对。理解了这一点,就能解释第 3.1 节中 STOMP/MERLIN 被同时列入"Discord 发现"和"精度优先"两个选型档次的理由。STOMP 名字中的 "Scalable Time series Ordered-search Matrix Profile" 指其用有序搜索 + 傅里叶加速把朴素 O(n²) 的矩阵谱计算大幅压缩,这正是 MERLIN(同属矩阵谱家族的高效变体)面向"大型时间序列、追求可扩展性"场景存在的原因;而 LeftSTAMPi 的 "Left" 与 "incremental" 后缀则对应只做左半距离谱、支持增量更新,从而适应流式场景。
6. 三种异常形态:点、子序列、集体
选算法前先判断异常属于哪种形态,原文档给出了清晰的三分法与对应算法:
- 点异常(Point anomalies):单个异常取值。典型表现是传感器瞬时毛刺。推荐:
COPOD、DWT_MLEAD、IsolationForest——这些都是逐点评分的方法,且对"单点偏离"敏感; - 子序列异常(Subsequence anomalies / discords):一段不寻常的模式。典型表现是设备进入短暂异常工况后恢复。推荐:
STOMP、LeftSTAMPi、MERLIN——矩阵谱方法天然是滑窗粒度评分,输出的 discord 就是"整段不对劲"; - 集体异常(Collective anomalies):一组点共同构成反常形态(如本该平滑的曲线出现整段平台)。推荐:矩阵谱方法 + 聚类类方法(如
CBLOF、KMeansAD)联合使用——前者定位失配窗口,后者刻画"整体偏离正常簇"的集体行为。
这个区分直接决定阈值语义:点异常场景下"超过阈值的点数"即异常量;子序列场景下应把相邻高分窗口合并成区间再评估(这也引出下文的 range 指标)。
7. 评估指标:窗口感知的 range 指标族
异常检测评估不同于分类:真实异常往往是一段区间,预测也往往是一段区间,逐点比对会高估或低估性能。Aeon 在aeon.benchmarking.metrics.anomaly_detection下提供了专为窗口检测设计的指标族。
7.1 基本用法
完整继承自原文档:
from aeon.benchmarking.metrics.anomaly_detection import ( range_precision, range_recall, range_f_score, roc_auc_score ) # range 系列指标考虑窗口重叠(alpha 为重叠容忍度) precision = range_precision(y_true, y_pred, alpha=0.5) recall = range_recall(y_true, y_pred, alpha=0.5) f1 = range_f_score(y_true, y_pred, alpha=0.5)alpha=0.5的含义是:预测区间与真实区间重叠达到一半即计为命中——这正是"区间级"评估与逐点 F1 的本质区别。
7.2 补充:AUC 与真实数据集
仓库内 references/datasets_benchmarking.md 给出了同一指标族的另一种导入,其中 AUC 变体的完整名为range_roc_auc_score:
from aeon.benchmarking.metrics.anomaly_detection import ( range_precision, range_recall, range_f_score, range_roc_auc_score ) auc = range_roc_auc_score(y_true, y_scores) # 注意传入的是连续分数注意区分两个输入:range_precision/recall/f_score 接收二值化后的预测(第 4 节阈值化后的结果),AUC 类指标接收连续异常分数(第 4 节阈值化之前的结果)。若你在不同文档间核对导入名,roc_auc_score与range_roc_auc_score分别出现在两份参考文档中,建议以你实际安装的 aeon 1.x 版本的 API 为准做from aeon.benchmarking.metrics.anomaly_detection import ...验证。
要拿真实标注数据做评估,同一个 benchmarking 参考文档记录了异常检测专用数据集加载器:
from aeon.datasets import load_anomaly_detection X, y = load_anomaly_detection("NAB_realKnownCause")即 NAB(Nist Anomaly Detection Benchmark)realKnownCause 数据集:加载后把第 4 节的检测流程跑在X上、用y标注做 range 指标评估,就构成一条完整的"检测 + 评估"闭环。
8. 五条最佳实践(含参数依据)
原文档 Best Practices 的五条建议,逐条补充了可操作的落地细节:
- 归一化数据:多数方法对尺度敏感。矩阵谱方法内部对子序列做 z 归一化(关注形状而非幅值),但 COPOD、DWT_MLEAD、IsolationForest 等逐点/逐特征方法不会替你归一化,输入前应统一量纲;
- 选对窗口大小:对矩阵谱方法,
window_size是最关键超参数——太小捕捉噪声、太大错过细节,经验值取序列长度的 10%–20%(出自相似性搜索参考文档的窗口选型经验);对非窗口方法(如KMeansAD),则关注簇数与距离核; - 设置阈值:二选一——基于分位数(如 95/99 分位)适合无先验的探索期;基于领域知识的固定阈值适合生产期,此时应同时报告 range 指标防止"阈值漂移";
- 验证结果:用第 4.2 节的双图法目视检查,检测位置必须对应肉眼可辨的形态变化,否则回到第 2 条调参;
- 处理季节性:有强季节成分(日周期、年周期)的序列,先做去趋势/去季节化再检测,否则季节重复形态会被矩阵谱误判为"正常基序",真正的异常反而淹没在季节波动里。
9. 延伸阅读:技能内的完整能力地图
本文聚焦异常检测,但 skills/aeon/SKILL.md 把异常检测放在更大的能力矩阵中:分类(RocketClassifier等)、回归、聚类(TimeSeriesKMeans)、预测(NaiveForecaster、ARIMA)、分割(ClaSPSegmenter)、相似性搜索(StompMotif)共享同一套 scikit-learn 风格 API 与数据格式约定,references/目录下每类任务都有对应的算法目录文档。典型组合场景:用相似性搜索的StompMotif找基序、用本文的STOMP找失配、用load_anomaly_detection+ range 指标评估——三者共同构成 Aeon 在"模式发现 + 异常定位 + 量化评估"上的完整工具链。
最后重申适用限制:aeon 上游将anomaly_detection标记为实验性模块,本文所有示例与 API 均以aeon 1.x(1.4 基线)为准;在跨版本迁移代码或把检测器投入生产管道前,应先在你锁定的版本上跑通第 4 节的快速示例与第 7 节的评估代码,确认接口未被变动。
【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考