lof异常点检测算法

一、背景

Local Outlier Factor(LOF)是基于密度的经典算法(Breuning et. al. 2000), 文章发表于SIGMOD 2000, 到目前已经有 3000+ 的引用。

在 LOF 之前的异常检测算法大多是基于统计方法的,或者是借用了一些聚类算法用于异常点的识别(比如 DBSCAN,OPTICS)。这些方法都有一些不完美的地方:

  • 基于统计的方法:通常需要假设数据服从特定的概率分布,这个假设往往是不成立的。
  • 聚类方法:通常只能给出 0/1 的判断(即:是不是异常点),不能量化每个数据点的异常程度。

相比较而言,基于密度的LOF算法要更简单、直观。它不需要对数据的分布做太多要求,还能量化每个数据点的异常程度(outlierness)。

下面开始正式介绍LOF算法。

二、LOF 算法

首先,基于密度的离群点检测方法有一个基本假设:非离群点对象周围的密度与其邻域周围的密度类似,而离群点对象周围的密度显著不同于其邻域周围的密度。

什么意思呢?看下面图片感受下。

 

 集群 C1 包含了 400 多个点,集群 C2 包含 100 个点。C1 和 C2 都是一类集群点,区别是 C1 位置比较集中,或者说密度比较大。而像 o1o2点均为异常点,因为基于我们的假设,这两个点周围的密度显著不同于周围点的密度。

LOF 就是基于密度来判断异常点的,通过给每个数据点都分配一个依赖于邻域密度的离群因子LOF,进而判断该数据点是否为离群点。 如果LOF>=1 ,则该点为离群点,如果LOF≈1 ,则该点为正常数据点。

那什么是LOF呢?

了解LOF前,必须先知道一下3个基本概念,因为LOF是基于这几个概念而来的。

 

 

 

 

 

 

四、LOF优缺点

优点

LOF 的一个优点是它同时考虑了数据集的局部和全局属性。异常值不是按绝对值确定的,而是相对于它们的邻域点密度确定的。当数据集中存在不同密度的不同集群时,LOF表现良好,比较适用于中等高维的数据集。

缺点

LOF算法中关于局部可达密度的定义其实暗含了一个假设,即:不存在大于等于 k 个重复的点。

当这样的重复点存在的时候,这些点的平均可达距离为零,局部可达密度就变为无穷大,会给计算带来一些麻烦。在实际应用时,为了避免这样的情况出现,可以把 k-distance 改为 k-distinct-distance,不考虑重复的情况。或者,还可以考虑给可达距离都加一个很小的值,避免可达距离等于零。

另外,LOF 算法需要计算数据点两两之间的距离,造成整个算法时间复杂度为 O(n2) 。为了提高算法效率,后续有算法尝试改进。FastLOF (Goldstein,2012)先将整个数据随机的分成多个子集,然后在每个子集里计算 LOF 值。对于那些 LOF 异常得分小于等于 1 的,从数据集里剔除,剩下的在下一轮寻找更合适的 nearest-neighbor,并更新 LOF 值。

五、Python 实现 LOF

有两个库可以计算LOF,分别是PyODSklearn,下面分别介绍。

使用pyod自带的方法生成200个训练样本和100个测试样本的数据集。正态样本由多元高斯分布生成,异常样本是使用均匀分布生成的。

训练和测试数据集都有 5 个特征,10% 的行被标记为异常。并且在数据中添加了一些随机噪声,让完美分离正常点和异常点变得稍微困难一些。

from pyod.utils.data import generate_data
import numpy as np
X_train, y_train, X_test, y_test = \
        generate_data(n_train=200,
                      n_test=100,
                      n_features=5,
                      contamination=0.1,
                      random_state=3) 
X_train = X_train * np.random.uniform(0, 1, size=X_train.shape)
X_test = X_test * np.random.uniform(0,1, size=X_test.shape)

PyOD

下面将训练数据拟合了 LOF 模型并将其应用于合成测试数据。

在 PyOD 中,有两个关键方法:decision_function 和 predict

  • decision_function:返回每一行的异常分数
  • predict:返回一个由 0 和 1 组成的数组,指示每一行被预测为正常 (0) 还是异常值 (1)
    from pyod.models.lof import LOF
    clf_name = 'LOF'
    clf = LOF()
    clf.fit(X_train)
    
    test_scores = clf.decision_function(X_test)
    
    roc = round(roc_auc_score(y_test, test_scores), ndigits=4)
    prn = round(precision_n_scores(y_test, test_scores), ndigits=4)
    
    print(f'{clf_name} ROC:{roc}, precision @ rank n:{prn}')
    >> LOF ROC:0.9656, precision @ rank n:0.8

 可以通过 LOF 模型方法查看 LOF 分数的分布。在下图中看到正常数据(蓝色)的分数聚集在 1.0 左右。离群数据点(橙色)的得分均大于 1.0,一般高于正常数据。

### 回答1: LOF(Local Outlier Factor)异常检测算法是一种基于密度的异常检测方法。它通过计算每个数据点相对于其邻域点的密度比来判断其是否为异常点LOF算法的代码实现如下: 1. 首先,需要定义一个计算距离的函数,可以使用欧氏距离或者其他距离度量方法。 2. 然后,需要确定一个参数k,表示每个数据点的邻域大小。可以通过手动选择或者使用交叉验证等方法进行确定。 3. 对于每个数据点,计算其k个最近邻的距离,然后计算该数据点与其k个最近邻的平均距离。 4. 对于每个数据点,计算其邻域点的密度比,即该数据点周围数据点的平均距离与其k个最近邻的平均距离的比值。 5. 根据上述密度比的计算结果,可以将数据点分为异常点和正常点。对于具有较低密度比值的数据点,可以认为是异常点,而具有较高密度比值的数据点则认为是正常点。 LOF算法的时间复杂度为O(n^2),其中n是数据点的数量。对于大规模数据,可能需要引入近似算法或者其他优化方法来提高计算效率。 总结来说,LOF异常检测算法通过计算每个数据点相对于其邻域点的密度比,来判断其是否为异常点。通过一系列的计算步骤和参数设置,可以得到数据点的异常程度评估。 ### 回答2: LOF(局部离群因子)异常检测算法是一种用来识别数据集中离群点的算法。它基于一种理念:离群点的周围密度相对较低,而正常点的周围密度相对较高。 LOF算法的步骤如下: 首先,对于数据集中的每个点,计算该点与其邻居点的距离。邻居点是指这个点周围的其他点。 然后,计算局部可达密度(Local Reachability Density,LRD)值。对于每个点,LRD值是该点与其邻居点的平均可达距离的倒数。可达距离是指两个点之间需要经过的最短路径长度。 接下来,计算局部离群因子(Local Outlier Factor,LOF)值。对于每个点,LOF值是该点的邻居点的平均LRD值与该点的LRD值的比值。LOF值越大,表示该点越有可能是离群点。 最后,根据LOF值对所有点进行排序,选取具有较高LOF值的点作为离群点。 下面是一个简化的LOF异常检测算法的Python代码示例: ```python import numpy as np from sklearn.neighbors import LocalOutlierFactor # 加载数据 data = np.loadtxt('data.csv', delimiter=',') # 创建LOF模型 lof = LocalOutlierFactor(n_neighbors=20) # 训练模型并预测异常值 outliers = lof.fit_predict(data) # 输出异常值 print(data[outliers==-1]) ``` 上述代码中,我们首先加载数据集,然后创建了一个LOF模型。模型使用最近的20个邻居来计算LOF值。接着我们用数据来训练模型,并预测异常值。最后,我们将预测的异常值输出到控制台。 LOF算法是一种常用的异常检测算法,它能够在大多数情况下有效地检测出离群点。但是,在使用LOF算法之前,我们需要对数据集进行适当的预处理和参数调优,以提升算法的性能。 ### 回答3: LOF(Local Outlier Factor)异常检测算法是一种用于发现数据集中的异常点算法。它的基本思想是通过比较每个数据点与其周围数据点的密度来确定其异常程度。 下面是LOF异常检测算法的代码示例: 1. 导入所需的库: ``` import numpy as np from sklearn.neighbors import LocalOutlierFactor ``` 2. 准备数据集: ```` X = np.array([[1, 1], [1, 2], [2, 2], [2, 3], [8, 7], [8, 8], [25, 80], [80, 80]]) ``` 3. 创建LOF模型并进行训练: ``` lof = LocalOutlierFactor(n_neighbors=5) lof.fit(X) ``` 4. 预测数据集中的异常点: ``` y_pred = lof.predict(X) ``` 在这个例子中,我们创建了一个包含8个数据点的数据集。然后,我们使用`LocalOutlierFactor`类创建了LOF模型,并使用`fit`方法对数据进行训练。接下来,我们使用`predict`方法对数据集中的每个点进行预测,得到的结果是一个数组,其中1表示正常点,-1表示异常点LOF算法通过计算每个数据点与其最近邻点的密度比来判断其异常程度,密度比越小表示越异常。可以根据需要调整`n_neighbors`参数来控制最近邻点的数量,从而影响LOF算法的敏感度。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值