本节摘要:异常(Anomaly)又称离群点(Outlier),指时间序列中与绝大多数数据模式显著不同的数据点或数据段。本节先梳理"异常"的四种定义框架(统计、距离、密度、模型),再详解最常用的三分类:点异常、上下文异常、集体异常,每个类型给出判定规则与真实案例。异常的分类直接决定检测方法的选择,是本教程后续所有方法的坐标系。
阅读完本节,你应当能够:
深夜的网约车平台后台,风控系统盯着一笔订单愣住:深夜两点,一位乘客从市中心打了一辆车,三公里路程,车费 45 元。单看价格,45 元在正常范围;单看时间,深夜订单也不算稀奇。但把两者合起来看——深夜、短途、从商圈出发、开往住宅区,这套组合是典型的"代叫"行为,骗子常这样把账号借出去或骗接单奖励。
这就是异常检测最微妙的地方:有些异常,单独看任何数据点都"正常";异常藏在数据的组合关系里。 如果你只会"值超过某个阈值就报警",那这笔订单永远不会被拦下。
异常还有一个更麻烦的性质:定义是相对场景的。 一笔 5 万元的大额转账,放在普通用户身上是强烈异常信号;但同一个用户如果昨天刚卖了一套房,这笔钱可能完全合理。夏季冰淇淋销量 3 万支是正常高峰,冬季同样 3 万支就是晴天霹雳。这意味着,做异常检测的人必须先回答一个前置问题:对这条数据、这个业务而言,"正常"到底是什么?
这一节我们先不急着讲算法,而是把"异常"这个模糊的日常词,拆成可以用代码和规则表达的结构化定义。分清楚你要找的是哪一种异常,后面的方法选择才有的放矢。
异常不是一个绝对概念,它可以按四种视角定义,每种视角对应一类算法族:
| 定义视角 | 核心表述 | 对应方法族 | 前提假设 |
|---|---|---|---|
| 统计定义 | 偏离统计分布的点,如均值外若干标准差 | Z-score、正态假设方法 | 数据服从某分布 |
| 距离定义 | 与大多数点距离较远的点 | KNN、距离类方法 | 正常点彼此接近 |
| 密度定义 | 位于低密度区域的点 | LOF、DBSCAN | 正常点聚集、异常点孤立 |
| 模型定义 | 不符合预先学习到的数据模式 | 预测残差、重构误差 | 异常会破坏模式一致性 |
四种定义不矛盾,它们是同一件事在不同透镜下的投影。实际项目里常结合多种定义——先用统计方法粗筛,再用密度方法复核,最后用模型方法补漏。选哪种定义取决于数据性质:分布清晰用统计,形状任意用密度,模式复杂用模型。
点异常指单个数据点的值显著偏离预期,与其他数据点无关——把它孤立地拿出来看,它自己就是异常。
判定规则很直接:这个点的值,远超该位置"应该有的水平"。
真实案例:
点异常通常最容易抓:Z-score、箱线图、固定阈值、Isolation Forest 都能对付。但要注意,点异常最容易抓,也最容易抓错——它和"正常波动中的极端值"长得几乎一样。怎么区分?看是否符合业务逻辑:促销日销量高是正常的,非促销日突然翻倍才可疑。
上下文异常指数据点本身的值在全局范围内"正常",但在特定的时间上下文(时段、季节、前后关系)中被判定为异常。
判定规则:这个点的值,结合它所在的"时间位置"看才异常。值本身不是关键,值和时间上下文的组合才是。
真实案例:
上下文异常是自动检测里最难缠的一类,因为它要求模型知道"当前时刻正常应该是什么样"。解法通常分两路:一路是季节性感知——STL 分解后,只看残差是否偏离"同时刻的正常残差分布";另一路是预测残差——用模型预测此刻应有的值,再比较。如果模型不理解"工作日和周末是两套正常"这个背景,上下文异常会全线漏报。
集体异常指一组数据点作为一个整体偏离正常模式,即便其中任何一个点单独看都完全正常。
判定规则:这串点"一起出现的方式"不符合正常模式——注意,是组合方式异常,不是单个值异常。
真实案例:
集体异常适合用序列模式挖掘、基于窗口的方法或深度学习去抓。它的难点在于把"一串点"当成一个整体来评分,而不是逐点打分后简单相加。简单相加的问题在于:单点都"轻微异常"时,累加可能不超阈值;但真正的集体异常恰恰是"多个轻微偏差协同出现"。

| 异常类型 | 判断单位 | 核心特征 | 典型案例 | 推荐检测思路 |
|---|---|---|---|---|
| 点异常 | 单个点 | 孤立、值显著偏离 | CPU 瞬间飙到 100% | Z-score、阈值、Isolation Forest |
| 上下文异常 | 单个点+时间背景 | 依赖上下文、值本身正常 | 冬季冰淇淋销量异常高 | STL 残差、季节感知、预测残差 |
| 集体异常 | 一串点 | 整体性、反映系统变化 | 连续多日同向下跌 | 窗口评分、序列模式、深度学习 |
选方法的第一原则不是"哪个算法强",而是"你要抓哪类异常":
很多项目一上来就急着问"什么算法能自动识别异常",但忽略了一个前置事实:你没有异常的定义,就没有标注标准,也就没有训练数据和评估基准。 第 7 章会系统讲标签获取的挑战,这里先提醒一句:先把异常的分类想清楚(尤其是"上下文异常,正常窗口是什么"),再谈算法,否则后面每一步都在打地基不稳的房子。
⚠️ 常见坑:上下文异常与"业务正常波动"傻傻分不清。 冬季冰淇淋销量高是异常,但如果今年该品牌新进了商场铺位、铺货渠道翻倍,那这个"异常"可能就是"业务扩张的正常结果"。判断上下文异常之前,务必确认"背景"本身没有发生变化——背景变了,参照系就要重建。
💡 关键直觉:把异常分类当作给检测系统画"工作边界"。 明确告诉系统"你只管抓这类异常,其他情况放行",系统的虚警率会大幅下降。很多监控系统虚警多,不是算法不行,而是根本没有声明自己到底在找什么。
判断一个候选异常属于哪一类,最快的办法是把它画在图上:单点突刺 → 点异常;值没突变但"放错时段" → 上下文异常;整段形态改变 → 集体异常。视觉诊断配合三分类框架,五分钟就能给检测系统定好方向。 如果自己画图看不出名堂,多半是数据还没处理好(趋势没剥离、噪声太大),回到第 2 章的预处理流程。
某新能源场站监控到一段风机功率曲线:凌晨两点功率从 1800 千瓦跌到 400 千瓦,持续 40 分钟后恢复。按三分类排查——单点看,400 千瓦这个值在"低风速夜段"不算离谱;但放在"凌晨两点、全场 40 台风机仅这一台下跌"的上下文里,它既不像正常停机(停机前会有明显的功率缓降与偏航动作),也不像电网限电(限电通常全场同步)。结合"仅单机异常"这个集体特征,判断倾向为叶片结冰或变桨故障这一类集体性故障信号——单点数据正常,组合模式反常。这个判例说明:三分类不是死板的标签,而是排查的思维脚手架。
标准是"符不符合正常的数据来源机制"。物理上不可能的值(温度负 300 度、传感器量程外)先当脏数据;物理上可能但罕见的值,留作待检异常。真实业务里两者界限模糊,建议清洗阶段先粗筛物理不可能值,把"可疑但可能"的留给检测系统。
会。一个持续多日的"集体异常",单看其中某一天可能只是"上下文异常";而某一天的"上下文异常"如果只持续一两个点,看起来又像"点异常"。分类的粒度随观察窗口变化,检测系统要明确自己的窗口粒度,否则分类会漂移。
按"分层检测"处理:先分解剥离趋势季节(清掉大部分上下文异常),再对残差用统计/密度方法抓点异常,最后对连续段做窗口评分抓集体异常。三类不是三选一,而是三层流水线。
下一节我们从一个具体场景的代价出发——异常检测到底在哪些行业值回票价,不同场景对"漏报"和"误报"的容忍度差异,决定了整个检测系统的设计取向。