异常监测——基于相似度的方法

本文详细探讨了异常检测中的两种核心方法:一是基于距离单元,通过计算k-距离和邻域密度来识别离群点;二是基于密度的LOF算法,通过局部异常因子来评估数据点的异常程度。通过实例演示,展示了如何在实际应用中利用这些技术进行异常值检测。
摘要由CSDN通过智能技术生成

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一、基于距离

基于距离的方法是一种常见的适用于各种数据域的异常检测算法,它基于最近邻距离来定义异常值。 此类方法不仅适用于多维数值数据,在其他许多领域,例如分类数据,文本数据,时间序列数据和序列数据等方面也有广泛的应用。   基于距离的异常检测有这样一个前提假设,即异常点的 k 近邻距离要远大于正常点。解决问题的最简单方法是使用嵌套循环。 第一层循环遍历每个数据,第二层循环进行异常判断,需要计算当前点与其他点的距离,一旦已识别出多于 k 个数据点与当前点的距离在 D 之内,则将该点自动标记为非异常值。 这样计算的时间复杂度为O(N^2),当数据量比较大时,这样计算是及不划算的。 因此,需要修剪方法以加快距离计算。

单元的方法

在基于单元格的技术中,数据空间被划分为单元格,单元格的宽度是阈值D和数据维数的函数。具体地说,每个维度被划分成宽度最多为 D/2⋅√ d的单元格。在给定的单元以及相邻的单元中存在的数据点满足某些特性,这些特性可以让数据被更有效的处理。
在这里插入图片描述
以二维情况为例,此时网格间的距离为D/2⋅√ d ,需要记住的一点是,网格单元的数量基于数据空间的分区,并且与数据点的数量无关。这是决定该方法在低维数据上的效率的重要因素,在这种情况下,网格单元的数量可能不多。 另一方面,此方法不适用于更高维度的数据。对于给定的单元格,其 L1 邻居被定义为通过最多1个单元间的边界可从该单元到达的单元格的集合。请注意,在一个角上接触的两个单元格也是 L1 邻居。 L2 邻居是通过跨越2个或3个边界而获得的那些单元格。 上图中显示了标记为 X的特定单元格及其 L1 和 L2 邻居集。 显然,内部单元具有8个 L1 邻居和40个 L2 邻居。
唯一无法直接得出结论的是 L2 中的单元格。 这表示特定单元中数据点的不确定性区域。 对于这些情况,需要明确执行距离计算。 同时,可以定义许多规则,以便立即将部分数据点确定为异常值或非异常值。
如果一个单元格中包含超过 k 个数据点及其 L1 邻居,那么这些数据点都不是异常值。如果单元 A 及其相邻 L1 和 L2 中包含少于 k 个数据点,则单元A中的所有点都是异常值。
1、利用规则1,标记非异常值;
2、利用规则2,标记异常值;
3、对于此时仍未标记为异常值或非异常值的单元格中的数据点需要明确计算其 k 最近邻距离。

二、基于密度

基于密度的算法主要有局部离群因子(LocalOutlierFactor,LOF),以及LOCI、CLOF等基于LOF的改进算法。下面我们以LOF为例来进行详细的介绍和实践。

基于距离的检测适用于各个集群的密度较为均匀的情况。在下图中,离群点B容易被检出,而若要检测出较为接近集群的离群点A,则可能会将一些集群边缘的点当作离群点丢弃。而LOF等基于密度的算法则可以较好地适应密度不同的集群情况。
在这里插入图片描述

第k距离

对于数据集D中的某一个对象o,与其距离最近的k个相邻点的最远距离表示为k-distance§,定义为给定点p和数据集D中对象o之间的距离d(p,o),满足:
在集合D中至少有k个点 o’,其中o′∈Dp,满足d(p,o′)≤d(p,o)
在集合D中最多有k-1个点o’,其中o′∈Dp,满足d(p,o;)<d(p,o)
在这里插入图片描述

距离的计算方式有如下几种常用形式:

距离的计算方式

欧式距离

在这里插入图片描述

马氏距离

在这里插入图片描述

k邻域

由k-距离,我们扩展到一个点的集合——到对象o的距离小于等于k-距离的所有点的集合,我们称之为k-邻域:
在这里插入图片描述
  在二维平面上展示出来的话,对象o的k-邻域实际上就是以对象o为圆心、k-距离为半径围成的圆形区域。就是说,k-邻域已经从“距离”这个概念延伸到“空间”了。

可达距离

有了邻域的概念,我们可以按照到对象o的距离远近,将数据集D内的点按照到o的距离分为两类:

若pi在对象o的k-邻域内,则可达距离就是给定点p关于对象o的k-距离;
若pi在对象o的k-邻域外,则可达距离就是给定点p关于对象o的实际距离。
给定点p关于对象o的可达距离用数学公式可以表示为:reach−distk(p,o)=maxk−distance(o),d(p,o) 。

这样的分类处理可以简化后续的计算,同时让得到的数值区分度更高。

局部可达密度

我们可以将“密度”直观地理解为点的聚集程度,就是说,点与点之间距离越短,则密度越大。在这里,我们使用数据集D中给定点p与对象o的k-邻域内所有点的可达距离平均值的倒数(注意,不是导数)来定义局部可达密度。
  给定点p的局部可达密度计算公式为:
  在这里插入图片描述
由公式可以看出,这里是对给定点p进行度量,计算其邻域内的所有对象o到给定点p的可达距离平均值。给定点p的局部可达密度越高,越可能与其邻域内的点 属于同一簇;密度越低,越可能是离群点。

局部异常因子

在这里插入图片描述
表示点p的邻域Nk§内其他点的局部可达密度与点p的局部可达密度之比的平均数。如果这个比值越接近1,说明o的邻域点密度差不多,o可能和邻域同属一簇;如果这个比值小于1,说明o的密度高于其邻域点密度,o为密集点;如果这个比值大于1,说明o的密度小于其邻域点密度,o可能是异常点。

最终得出的LOF数值,就是我们所需要的离群点分数。在sklearn中有LocalOutlierFactor库,可以直接调用。下面来直观感受一下LOF的图像呈现效果。

LocalOutlierFactor库可以用于对单个数据集进行无监督的离群检测,也可以基于已有的正常数据集对新数据集进行新颖性检测。在这里我们进行单个数据集的无监督离群检测。

代码如下(示例):

clf = LocalOutlierFactor(n_neighbors=20, contamination=0.1)
y_pred = clf.fit_predict(X)
n_errors = y_pred != ground_truth
X_pred = np.c_[X,n_errors]
X_scores = clf.negative_outlier_factor_
X_scores_nor = (X_scores.max() - X_scores) / (X_scores.max() - X_scores.min())
X_pred = np.c_[X_pred,X_scores_nor]
X_pred = pd.DataFrame(X_pred,columns=['x','y','pred','scores'])
X_pred_same = X_pred[X_pred['pred'] == False]
X_pred_different = X_pred[X_pred['pred'] == True]
X_pred
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值