异常检测基础概念:点异常、上下文异常、集体异常
做异常检测这些年,我遇到过不少新人一上来就问“什么是异常”。
其实异常本身不难理解——就是那些跟大多数数据不太一样的家伙。
但真正落地的时候,你会发现异常是有“形态”的。怎么分?
业内一般把这东西分成三类:点异常、上下文异常、集体异常。
说白了,就是单个“刺头”、不合时宜的“刺头”、一群扎堆的“刺头”。
下面我一个一个讲,顺便说说项目里踩过的坑。
点异常(Point Anomaly)
点异常是最好理解的。
单个数据点跟整体分布差太多,它就是异常。
举个例子:你家电表平时一天走5度电,突然有一天显示500度。那就很可能是点异常——要么电表坏了,要么有人偷电。
我在做服务器监控时遇到过类似情况:某台机器的CPU使用率常年稳定在30%左右,有一天突然飙到99%持续了30秒。那就是典型的点异常。
检测点异常最常用的手段就是统计方法:Z-score、IQR、高斯分布拟合。
不过要记住:点异常的定义依赖于“全局”视角。也就是说,你得先知道“正常”长什么样。
上下文异常(Contextual Anomaly)
这东西就有点意思了。
一个数据点本身可能完全正常,但放到它所在的那个“上下文”里看,它就不对了。
举个典型场景:北京冬天室外温度零下5摄氏度,正常;夏天35摄氏度,也正常。但如果7月份出现零下5摄氏度,那就是上下文异常。
为什么?因为温度值本身在全局分布中并不极端,但它在“7月”这个时间上下文里极其罕见。
我在做流量异常检测时吃过这样的亏:某个接口凌晨3点的请求量是1000次,看起来不高,但那个接口凌晨3点历史均值只有50次,1000就是20倍异常。如果不加时间上下文,1000次在全天来看只是中等水平,完全不会被识别出来。
上下文异常通常出现在时序数据中,常见的检测手段包括:
- 滑动窗口统计(移动平均、标准差)
- 季节性分解(STL、Prophet)
- 基于残差的异常评分
记得一定要做周期性对齐——比如流量数据,工作日和周末的基线完全不一样。我曾经因为没做周末/工作日分离,把周末的正常低流量全标成了异常,闹了笑话。
集体异常(Collective Anomaly)
最后一个是集体异常,也是最考验建模能力的。
单个数据点单独看都是正常的,但把它们放在一起,作为一个整体,就展现出异常行为。
想象这么一个场景:你的日志里连续出现10条“登录成功”记录,每一条单独看都是正常操作。但如果你发现这10条记录来自同一个IP,每30秒一次,持续5分钟——那很可能是暴力破解后的成功登录,是典型的集体异常。
我在金融风控项目里遇到过一个案例:用户A连续5笔交易,每笔金额都在1000-2000元之间,收款方分别是不同的个人账户。单笔交易金额正常,收款账户也没有黑名单记录。但5笔交易在30分钟内完成,且收款方账户均为新注册账户——这就是集体异常,最后确认是洗钱行为。
集体异常检测比前两类难得多,因为它需要捕捉数据之间的关联结构。常用的方法有:
- 序列模式挖掘(如GSP、PrefixSpan)
- 基于滑动窗口的频繁子序列异常检测
- 图结构中的社区异常检测(如ODD、SCAN)
嗯,这里要注意:集体异常对数据采样率很敏感。采样率太低,可能会把连续的异常行为拆散,变成孤立的点异常,从而漏报。我建议做集体异常检测时,先确定事件之间的“最大合理间隔”,把间隔内的行为合并为一个sequence来处理。
三种异常的对比
把这三个概念放一起看,你可能会更清楚它们的差异。下面这个表是我经常贴在工位上的:
| 类型 | 判断依据 | 典型场景 | 检测难度 |
|---|---|---|---|
| 点异常 | 单个点的全局分布偏离 | 传感器跳变、错误交易 | 低 |
| 上下文异常 | 单个点在特定上下文中的偏离 | 时间序列中的季节异常 | 中 |
| 集体异常 | 一组点的联合行为偏离 | 连续欺诈、网络攻击序列 | 高 |
当然,实际项目中这三种异常经常混合出现。比如一次DDoS攻击,单个请求是正常的点异常?不是。大量请求短时间内集中出现,是集体异常。而每个请求的时间戳相对于该IP的正常访问时间窗口来说,又是上下文异常。所以不要死板地只选一类,要根据业务灵活组合。
知识结构一览
下面这张图是我对本章内容的总结,你可以把它当作一个快速检索目录。三种异常之间用虚线关联,表示它们在实际数据中经常交织。
看到这里,你应该对三种异常有了比较清晰的认识。我个人觉得,这就像写代码时的异常处理——先分清类型,才能对症下药。点异常用“阈值”,上下文异常用“窗口”,集体异常用“模式”。记住这个口诀,能少走很多弯路。