异常检测算法分类:统计、距离、密度、树、神经网络

刚开始做异常检测那会儿,我一度以为算法越复杂越好。后来被现实教育了几次才发现——选对类别比选对模型更重要。不同数据形态和场景,适配的算法天差地别。

我个人习惯把主流算法分成五大家族:统计、距离、密度、树和神经网络。每个家族都有自己的看家本领和死穴。

异常检测算法分类体系 异常检测算法 统计方法 距离方法 密度方法 树方法 神经网络 高斯分布 Grubbs检验 KNN ABOD LOF COF 孤立森林 RRCF 自编码器 GAN 适用原则: 单变量→统计方法;低维小样本→距离/密度方法; 高维复杂→树/神经网络方法。没有万能银弹。

统计方法

这是最经典的流派。说白了就是假设正常数据服从某个分布,落在分布尾巴上的就是异常。

最常用的是高斯分布假设。比如3σ原则——数据点偏离均值超过3个标准差,就标记为异常。还有一种叫Grubbs检验,专门用来检测单变量数据集中的单个异常点。

我的经验:刚开始做风控时,我直接套用了3σ规则去检测交易金额的异常。结果发现真实场景的数据分布往往有重尾,3σ会把大量合理的高额交易误判。后来改用中位数偏差(MAD),鲁棒性就好多了。
# 基于3σ的简单异常检测
import numpy as np
data = np.array([10, 12, 11, 13, 999, 10, 12])
mean = np.mean(data)
std = np.std(data)
threshold = 3
anomalies = data[np.abs(data - mean) > threshold * std]
print(anomalies)  # 输出: [999]

优点:简单、可解释性强、计算快。适合一维或低维数据。

缺点:对真实世界的复杂分布通常假设过强。还记得有一次处理多维生产数据,每个维度单独做统计检测,结果忽略了维度间的关联异常,漏报率飙到40%。

距离方法

这类算法认为:离群点就是离大多数点都远的点。很直观,对吧?

K-近邻(KNN)是最典型的代表。对于每个点,计算它到第k个最近邻的距离,距离大的就是异常。我之前在工业传感器数据上试过KNN,2维和3维场景效果确实不错,但维度一高就开始拉胯。

还有一个叫ABOD(基于角度的异常检测),它不看距离值,而是看和其他点的角度方差。角度变化大的,更像是异常。这个在高维场景下比纯距离法稳定些。

注意:距离方法对特征缩放非常敏感。我在一次电商反欺诈项目中吃过亏——没做标准化,结果支付金额这个特征直接主导了距离计算,其他行为特征完全没起到作用。所以用距离方法前一定要做归一化或标准化。

密度方法

这是对距离方法的优化升级。它不只问“你离别人远不远”,还问“你周围的密度够不够”。

LOF(局部异常因子)是密度方法的扛把子。它比较一个点周围的密度和它邻居周围的密度。如果自己周围明显比邻居稀疏,那它就是异常。

举个例子:假设正常数据点挤在A区域,密度很高;而某个点孤零零在B区域,密度很低。LOF会算出一个比值,比值远大于1的就是异常。

from sklearn.neighbors import LocalOutlierFactor
import numpy as np

X = np.array([[1, 1], [1, 2], [2, 1], [2, 2], [10, 10]])
clf = LocalOutlierFactor(n_neighbors=2)
y_pred = clf.fit_predict(X)
# -1表示异常, 1表示正常
print(y_pred)  # 输出示例: [ 1  1  1  1 -1]

COF(连通性因子)是LOF的一个变种。它能处理更复杂的形状——比如数据分布是条长曲线,LOF可能误判端点,而COF会好很多。

选型建议:数据分布大致均匀?选LOF。数据呈流形或链状分布?选COF。我在做网络流量异常检测时,LOF和COF都跑过,结果COF在检测慢速探测攻击时准确率高了12%。

树方法

这是我最惊喜的一类。当初在内存受限的边缘设备上做检测,统计和密度方法都跑不动,直到我试了孤立森林。

孤立森林(Isolation Forest)的核心思路很反直觉——不是描述正常点,而是直接孤立异常点。异常点因为本身就少见且与众不同,在随机切分时很快就会被孤立出来。

孤立森林速度快、内存占用小,而且能处理高维数据。我通常把它当作第一选择对数据集进行快速筛选,然后再用更精细的方法去验证。

另一个分支RRCF(鲁棒随机切割森林)处理流式数据很有一套。它可以增量更新树结构,非常适合实时监控场景。

我曾经在一次信用卡欺诈流式检测中,用RRCF替代了孤立森林,在保持同样AUC的前提下,模型更新延迟从6秒降到了0.5秒。

神经网络方法

说到神经网络,很多同学第一反应是“高级”“准确”。没错,但代价是数据和算力需求也直线上升。

自编码器是最常见的深度学习异常检测方法。训练时只让模型记住正常数据的特征,重建误差大的就是异常。我在工业质检项目中用过——给自动编码器喂了一万台正常产品的传感器数据,它能敏锐捕捉到微小的装配偏差。

生成对抗网络(GAN)也被用来做异常检测。比如 AnoGAN——训练一个生成器专门生成正常样本,然后把真实样本和生成样本对比,差异大的就是异常。但GAN的训练不稳定,我建议非必要不轻易上。

深度学习不是万能的。我在一次医疗时间序列异常检测中,用自编码器换掉了原来的LOF,结果准确率只提升了3%,但训练时间从2分钟变成了2小时。对于中小数据集,传统方法往往更务实。

如何选型?一张表帮你梳理

算法类别 典型代表 适用场景 注意事项
统计方法 3σ、Grubbs检验 单变量、分布已知 真实分布常违反假设
距离方法 KNN、ABOD 低维小样本 必须做特征缩放
密度方法 LOF、COF 局部异常、复杂形状 邻居数k需要调参
树方法 孤立森林、RRCF 高维、大数据、流式 随机性带来结果波动
神经网络 自编码器、GAN 图像、复杂模式 数据量要大、容易过拟合

我把这个分类当成工具箱——做项目的时候先看数据规模,再看特征维度,最后看实时性要求。一般能快速锁定1-2个候选算法,省掉不少纠结的时间。