1、概述
统计学方法对数据的正常性做出假定。**它们假定正常的数据对象由一个统计模型产生,而不遵守该模型的数据是异常点。**统计学方法的有效性高度依赖于对给定数据所做的统计模型假定是否成立。
异常检测的统计学方法的一般思想是:学习一个拟合给定数据集的生成模型,然后识别该模型低概率区域中的对象,把它们作为异常点。
即利用统计学方法建立一个模型,然后考虑对象有多大可能符合该模型。
根据如何指定和学习模型,异常检测的统计学方法可以划分为两个主要类型:参数方法和非参数方法。
参数方法假定正常的数据对象被一个以为参数的参数分布产生。该参数分布的概率密度函数给出对象被该分布产生的概率。该值越小,越可能是异常点。
非参数方法并不假定先验统计模型,而是试图从输入数据确定模型。非参数方法通常假定参数的个数和性质都是灵活的,不预先确定(所以非参数方法并不是说模型是完全无参的,完全无参的情况下从数据学习模型是不可能的)。
2、参数方法
2.1 Z-score
Z-score适用于正态分布单变量参数的场景,Z-score表示的是一个数据点距离其他数据群有多远。例如Z-score=2表示数据点距离均值2倍标准差远。
使用Z-score方法时只需使用所有数据计算求出均值和标准差,再对观测点求出Z-score即可。
2.2 Modified Z-score
上节Z-score方法虽然简单好用,仍然有两个缺陷,即不适用于数据非正态分布或是数据量很小的情况。
一个重要的原因是Z-score方法对极端值敏感,为了解决这一问题,对Z-score算法进行改良。
具体操作是:
- 用中位数代替均值
- 用中位数绝对偏差(MAD)代替标准差
- 为了和使用标准差的形式在结果上等同,需要乘以额外的系数
2.3 箱线图和IQR
箱线图可以展示数据的分布情况,也能用来筛选异常点。
其中IQR等于数据集的75%分位值Q3和25分位值Q1的差值,一般我们将小于Q1-1.5IQR或大于Q3+1.5IQR的数据定义为异常点。
2.4 多元高斯分布
以上的方法都是针对单一变量的情况,但有时对单一变量分别考量时不属于异常的数据点在考虑多维分布时反而是异常点,原因是变量之间存在交互作用。
因此对于多变量的数据集,要从考虑单变量数据集的均值和标准差转变为均值和协方差。
实际上,多元高斯分布可以看做多个独立的一元高斯模型的集合,后者是前者的一个特例形式。
多元高斯分布的优点是模型会自动构建交互特征,但缺点是协方差矩阵的计算耗时巨大,效率较低。
2.5 基于回归模型
基于回归模型是另一类参数统计学方法。
一个用于异常检测的基本回归模型分为两步:
- 使用数据集构建回归模型
- 对于每个数据点,基于模型得到残差,残差也就是不能被回归模型解释的部分,因此可以用来确定异常分数值
3、非参数方法
非参数方法中最常见的方法是基于直方图的算法,这种算法使用直方图获得正常数据的轮廓,也被认为是基于频率或基于计数的方法。
例子:使用直方图检测异常点。
直方图是一种频繁使用的非参数统计模型,可以用来检测异常点。该过程包括如下两步:
步骤1:构造直方图。使用输入数据(训练数据)构造一个直方图。该直方图可以是一元的,或者多元的(如果输入数据是多维的)。
尽管非参数方法并不假定任何先验统计模型,但是通常确实要求用户提供参数,以便由数据学习。例如,用户必须指定直方图的类型(等宽的或等深的)和其他参数(直方图中的箱数或每个箱的大小等)。与参数方法不同,这些参数并不指定数据分布的类型。
步骤2:检测异常点。为了确定一个对象是否是异常点,可以对照直方图检查它。在最简单的方法中,如果该对象落入直方图的一个箱中,则该对象被看作正常的,否则被认为是异常点。
对于更复杂的方法,可以使用直方图赋予每个对象一个异常点得分。例如令对象的异常点得分为该对象落入的箱的容积的倒数。
使用直方图作为异常点检测的非参数模型的一个缺点是,很难选择一个合适的箱尺寸。一方面,如果箱尺寸太小,则许多正常对象都会落入空的或稀疏的箱中,因而被误识别为异常点。另一方面,如果箱尺寸太大,则异常点对象可能渗入某些频繁的箱中,因而“假扮”成正常的。
3.1 HBOS
在这类直方图方法中,有一个经典的算法叫做Histogram-based Outlier Score (HBOS)。它的思路是假定每个维度之间相互独立,分别计算每个维度的概率密度,最后合并成总体的概率密度,再根据概率密度计算异常分数值。
具体步骤如下:
- 对每个维度d单独绘制直方图
- 对于类别变量,按照类别分箱
- 对于数值变量,静态分箱(每个箱子等宽)或动态分箱(每个箱子等频)
- 根据频率计算得到概率密度
- 计算每个数据点p的异常分数值
HBOS方法的优势是计算速度较快,对大数据集友好。
3.2 基于角度的方法
基于角度的方法的主要思想是:数据边界上的数据很可能将整个数据包围在一个较小的角度内,而内部的数据点则可能以不同的角度围绕着他们。如下图所示,其中点A是一个异常点,点B位于数据内部。
如果数据点与其余点离得较远,则潜在角度可能越小。因此,具有较小角度谱的数据点是异常值,而具有较大角度谱的数据点不是异常值。
考虑三个点X,Y,Z。如果对于任意不同的点Y,Z,有:
其中代表L2范数 , 代表点积。
这是一个加权余弦,因为分母包含L2-范数,其通过距离的逆加权进一步减小了异常点的加权角,这也对角谱产生了影响。然后,通过改变数据点Y和Z,保持X的值不变计算所有角度的方法。相应地,数据点X的基于角度的异常分数(ABOF)∈ D为:
4、统计学方法的优缺点
优势:
- 如果统计假定成立,这种方法会非常有效
- 统计方法的置信区间可以作为额外的信息帮助决策
劣势
- 这类方法严重依赖数据集的分布假定
5、Python代码相关
运用pyod包的HBOS模块。
5.1 基线模型
from pyod.models.hbos import HBOS
from pyod.utils.data import generate_data
from pyod.utils.data import evaluate_print
from pyod.utils.example import visualize
contamination = 0.1 # percentage of outliers
n_train = 200 # number of training points
n_test = 100 # number of testing points
# 生成虚拟数据
X_train, y_train, X_test, y_test = \
generate_data(n_train=n_train,
n_test=n_test,
n_features=2,
contamination=contamination,
random_state=42)
# 训练KNN模型
clf_name = 'HBOS'
clf = HBOS()
clf.fit(X_train) # 注意训练模型的时候,不需要输入y参数
# 得到训练标签和训练分数
y_train_pred = clf.labels_ # 0正常,1异常
y_train_scores = clf.decision_scores_ # 数值越大越异常
# 用训练好的模型预测测试数据的标签和分数
y_test_pred = clf.predict(X_test)
y_test_scores = clf.decision_function(X_test)
# 评估并打印结果
print("\nOn Training Data:")
evaluate_print(clf_name, y_train, y_train_scores)
print("\nOn Test Data:")
evaluate_print(clf_name, y_test, y_test_scores)
# 可视化模型效果
visualize(clf_name, X_train, y_train, X_test, y_test, y_train_pred,
y_test_pred, show_figure=True, save_figure=True)
模型评估结果与可视化结果
5.2 模型调参
发现使用默认参数的模型效果在测试集上不是特别理想,那么让我们来看一下HBOS方法中有哪些参数可以调整。
HBOS(n_bins=10, alpha=0.1, tol=0.5, contamination=0.1)
其中这四个参数分别表示:
- n_bins:分箱的数量
- alpha:用于防止边缘溢出的正则项
- tol:用于设置当数据点落在箱子外时的宽容度
- contamination:用于设置异常点的比例
通过观察可视化结果,问题在于中心圆簇周围有些数据点被分错了,考虑到该玩具数据集分布较为简单,因此确定了两种调参思路:
- 减少n_bins数量
- 减少alpha的正则项值