博客专栏

EEPW首页>博客> 14种异常检测方法汇总(附代码)!(1)

14种异常检测方法汇总(附代码)!(1)

发布人:计算机视觉工坊 时间:2022-09-26 来源:工程师 发布文章
作者丨Ai

来源丨尤而小屋编辑丨Peter

今天给大家分享一篇关于异常检测的文章,重点介绍了14种公开网络上一些常见的异常检测方法(附资料来源和代码)。

图片

一、基于分布的方法1. 3sigma

基于正态分布,3sigma准则认为超过3sigma的数据为异常点。图片图1: 3sigma

defthree_sigma(s):
mu, std = np.mean(s), np.std(s)
lower, upper = mu-3*std, mu+3*std
returnlower, upper
2. Z-score

Z-score为标准分数,测量数据点和平均值的距离,若A与平均值相差2个标准差,Z-score为2。当把Z-score=3作为阈值去剔除异常点时,便相当于3sigma。

defz_score(s):
z_score = (s - np.mean(s)) / np.std(s)
returnz_score
3. boxplot

箱线图时基于四分位距(IQR)找异常点的。图片图2: boxplot

defboxplot(s):
q1, q3 = s.quantile(.25), s.quantile(.75)
iqr = q3 - q1
lower, upper = q1 -1.5*iqr, q3 +1.5*iqr
returnlower, upper
4. Grubbs假设检验

资料来源:

[1] 时序预测竞赛之异常检测算法综述 - 鱼遇雨欲语与余,知乎:https://zhuanlan.zhihu.com/p/336944097 [2] 剔除异常值栅格计算器_数据分析师所需的统计学:异常检测 - weixin_39974030,CSDN:https://blog.csdn.net/weixin_39974030/article/details/112569610

Grubbs’Test为一种假设检验的方法,常被用来检验服从正态分布的单变量数据集(univariate data set)Y中的单个异常值。若有异常值,则其必为数据集中的最大值或最小值。原假设与备择假设如下:

  • H0: 数据集中没有异常值

  • H1: 数据集中有一个异常值

使用Grubbs测试需要总体是正态分布的。算法流程:1. 样本从小到大排序2. 求样本的mean和dev3. 计算min/max与mean的差距,更大的那个为可疑值4. 求可疑值的z-score (standard score),如果大于Grubbs临界值,那么就是outlierGrubbs临界值可以查表得到,它由两个值决定:检出水平α(越严格越小),样本数量n,排除outlier,对剩余序列循环做 1-4 步骤 [1]。详细计算样例可以参考。

from outliersimportsmirnov_grubbs as grubbs
print(grubbs.test([8,9,10,1,9], alpha=0.05))
print(grubbs.min_test_outliers([8,9,10,1,9], alpha=0.05))
print(grubbs.max_test_outliers([8,9,10,1,9], alpha=0.05))
print(grubbs.max_test_indices([8,9,10,50,9], alpha=0.05))

局限:1、只能检测单维度数据2、无法精确的输出正常区间3、它的判断机制是“逐一剔除”,所以每个异常值都要单独计算整个步骤,数据量大吃不消。4、需假定数据服从正态分布或近正态分布

二、基于距离的方法1. KNN

资料来源:

[3] 异常检测算法之(KNN)-K Nearest Neighbors - 小伍哥聊风控,知乎:https://zhuanlan.zhihu.com/p/501691799

依次计算每个样本点与它最近的K个样本的平均距离,再利用计算的距离与阈值进行比较,如果大于阈值,则认为是异常点。优点是不需要假设数据的分布,缺点是仅可以找出全局异常点,无法找到局部异常点。

frompyod.models.knnimportKNN

# 初始化检测器clf
clf = KNN( method='mean', n_neighbors=3, )
clf.fit(X_train)
# 返回训练数据上的分类标签 (0: 正常值, 1: 异常值)
y_train_pred = clf.labels_
# 返回训练数据上的异常值 (分值越大越异常)
y_train_scores = clf.decision_scores_
三、基于密度的方法1. Local Outlier Factor (LOF)

资料来源:

[4] 一文读懂异常检测 LOF 算法(Python代码)- 东哥起飞,知乎:https://zhuanlan.zhihu.com/p/448276009

LOF是基于密度的经典算法(Breuning et. al. 2000),通过给每个数据点都分配一个依赖于邻域密度的离群因子 LOF,进而判断该数据点是否为离群点。它的好处在于可以量化每个数据点的异常程度(outlierness)。图片图3:LOF异常检测数据点的局部相对密度(局部异常因子)为点邻域内点的平均局部可达密度跟数据 点的局部可达密度的比值, 即:数据点P的局部可达密度=P最近邻的平均可达距离的倒数。距离越大,密度越小。点P到点O的第k可达距离=max(点O的k近邻距离,点P到点O的距离)。图片图4:可达距离点O的k近邻距离=第k个最近的点跟点O之间的距离。整体来说,LOF算法流程如下:

  • 对于每个数据点,计算它与其他所有点的距离,并按从近到远排序;

  • 对于每个数据点,找到它的K-Nearest-Neighbor,计算LOF得分。

fromsklearn.neighborsimportLocalOutlierFactorasLOF

X = [[-1.1], [0.2], [100.1], [0.3]]
clf = LOF(n_neighbors=2)
res = clf.fit_predict(X)
print(res)
print(clf.negative_outlier_factor_)
2. Connectivity-Based Outlier Factor (COF)

资料来源:

[5] Nowak-Brzezińska, A., & Horyń, C. (2020). Outliers in rules-the comparision of LOF, COF and KMEANS algorithms. *Procedia Computer Science*, *176*, 1420-1429. [6] 機器學習_學習筆記系列(98):基於連接異常因子分析(Connectivity-Based Outlier Factor) - 劉智皓 (Chih-Hao Liu)

COF是LOF的变种,相比于LOF,COF可以处理低密度下的异常值,COF的局部密度是基于平均链式距离计算得到。在一开始的时候我们一样会先计算出每个点的k-nearest neighbor。而接下来我们会计算每个点的Set based nearest Path,如下图:图片图5:Set based nearest Path假使我们今天我们的k=5,所以F的neighbor为B、C、D、E、G。而对于F离他最近的点为E,所以SBN Path的第一个元素是F、第二个是E。离E最近的点为D所以第三个元素为D,接下来离D最近的点为C和G,所以第四和五个元素为C和G,最后离C最近的点为B,第六个元素为B。所以整个流程下来,F的SBN Path为{F, E, D, C, G, C, B}。而对于SBN Path所对应的距离e={e1, e2, e3,…,ek},依照上面的例子e={3,2,1,1,1}。所以我们可以说假使我们想计算p点的SBN Path,我们只要直接计算p点和其neighbor所有点所构成的graph的minimum spanning tree,之后我们再以p点为起点执行shortest path算法,就可以得到我们的SBN Path。而接下来我们有了SBN Path我们就会接着计算,p点的链式距离:有了ac_distance后,我们就可以计算COF:

# https://zhuanlan.zhihu.com/p/362358580
frompyod.models.cofimportCOF
cof = COF(contamination =0.06,## 异常值所占的比例
n_neighbors =20,## 近邻数量
)
cof_label = cof.fit_predict(iris.values)# 鸢尾花数据
print("检测出的异常值数量为:",np.sum(cof_label ==1))
3. Stochastic Outlier Selection (SOS)

资料来源:

[7] 异常检测之SOS算法 - 呼广跃,知乎:https://zhuanlan.zhihu.com/p/34438518

将特征矩阵(feature martrix)或者相异度矩阵(dissimilarity matrix)输入给SOS算法,会返回一个异常概率值向量(每个点对应一个)。SOS的思想是:当一个点和其它所有点的关联度(affinity)都很小的时候,它就是一个异常点。图片图6:SOS计算流程SOS的流程:

  1. 计算相异度矩阵D;

  2. 计算关联度矩阵A;

  3. 计算关联概率矩阵B;

  4. 算出异常概率向量。

相异度矩阵D是各样本两两之间的度量距离, 比如欧式距离或汉明距离等。关联度矩阵反映的是 度量距离方差, 如图7, 点的密度最大, 方差最小;的密度最小, 方差最大。而关联概率 矩阵(binding probability matrix)就是把关联矩阵(affinity matrix)按行归一化得到的, 如图 8 所 示。图片图7:关联度矩阵中密度可视化图片图8:关联概率矩阵得到了binding probability matrix,每个点的异常概率值就用如下的公式计算,当一个点和其它所有点的关联度(affinity)都很小的时候,它就是一个异常点。

# Ref: https://github.com/jeroenjanssens/scikit-sos
importpandasaspd
fromsksosimportSOS
iris = pd.read_csv("http://bit.ly/iris-csv")
X = iris.drop("Name", axis=1).values
detector = SOS()
iris["score"] = detector.predict(X)
iris.sort_values("score", ascending=False).head(10)
四、基于聚类的方法1. DBSCAN

DBSCAN算法(Density-Based Spatial Clustering of Applications with Noise)的输入和输出如下,对于无法形成聚类簇的孤立点,即为异常点(噪声点)。

  • 输入:数据集,邻域半径Eps,邻域中数据对象数目阈值MinPts;

  • 输出:密度联通簇。

图片图9:DBSCAN处理流程如下:

  1. 从数据集中任意选取一个数据对象点p;

  2. 如果对于参数Eps和MinPts,所选取的数据对象点p为核心点,则找出所有从p密度可达的数据对象点,形成一个簇;

  3. 如果选取的数据对象点 p 是边缘点,选取另一个数据对象点;

  4. 重复以上2、3步,直到所有点被处理。

# Ref: https://zhuanlan.zhihu.com/p/515268801
fromsklearn.clusterimportDBSCAN
importnumpyasnp
X = np.array([[1,2], [2,2], [2,3],
[8,7], [8,8], [25,80]])
clustering = DBSCAN(eps=3, min_samples=2).fit(X)

clustering.labels_
array([0,0,0,1,1,-1])
# 0,,0,,0:表示前三个样本被分为了一个群
# 1, 1:中间两个被分为一个群
# -1:最后一个为异常点,不属于任何一个群


*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

物联网相关文章:物联网是什么




关键词:AI

相关推荐

技术专区

关闭