LOF详解

局部离群因子LOF

基于密度的离群点检测方法的关键步骤在于给每个数据点都分配一个离散度,其主要思想是:
针对给定的数据集,对其中的任意一个数据点,如果在其局部邻域内的点都很密集,那么认为此数据点为正常数据点

而离群点则是距离正常数据点最近邻的点都比较远的数据点。通常有阈值进行界定距离的远近。在基于密度的离群点检测方法中,最具有代表性的方法是局部离群因子检测方法 (Local Outlier Factor, LOF)。

  • 核心:样本点跟周围邻居的密度对比

LOF通过计算一个数值score来反映一个样本的异常程度。这个数值的大致意思是:一个样本点周围的样本点所处位置的平均密度比上该样本点所在位置的密度。比值越大于1,则该点所在位置的密度越小于其周围样本所在位置的密度,这个点就越有可能是异常点。

逐步公式理解

第k距离

d k ( p ) = d ( p , o ) d_k(p) = d(p,o) dk(p)=d(p,o)

意思是离p点第k远的点

第k距离领域

  • 意思是离p点第k远的点,以p为圆心,到第k远的点的距离为半径,画圆,这个圆就是第k距离领域
    在这里插入图片描述
    这个圆很重要
  1. 如果数据点密,这个圆的半径就小
  2. 如果数据点稀疏,这个圆的半径就很大
  3. 由于圆的大小不同,所以在算距离的时候,有不同的结果

第k可达距离

r e a c h − d i s t a n c e ( A , B ) = m a x { d i s t a n c e k ( B ) , d i s t a n c e ( A , B ) } reach-distance(A,B) = max\{distance_k(B),distance(A,B)\} reachdistance(A,B)=max{distancek(B),distance(A,B)}

在这里插入图片描述

  1. 数据点p落在o2的第k距离领域内,那么o2到p的距离等于o2的第k距离。也就是说,距离o2点最近的k个点,它们到o2点的距离被认为是相当的,等于 D k ( o 2 ) D_k(o_2) Dko2,即都等于o2的第k距离
  2. 数据点p落在第k距离领域范围外, 那么o1到p的距离等于o1到p的直接距离 D ( o 1 , p ) D(o_1,p) Do1p

局部可达密度

l r d k ( p ) = 1 ∑ o > N k ( p ) d i a t a n c e k ( p , o ) / N k ( p ) lrd_k(p) = \frac{1}{\sum{_{o>N_k(p)}}diatance_k(p,o)/N_k(p)} lrdk(p)=o>Nk(p)diatancek(p,o)/Nk(p)1

N k ( p ) N_k(p) Nkp是p点的k距离邻域, 也就是要计算p点与第k距离邻域内每一个点的距离,按照上述的两种情况计算(圈内还是圈外)

∑ o > N k ( p ) d i a t a n c e k ( p , o ) / N k ( p ) {\sum{_{o>N_k(p)}}diatance_k(p,o)/N_k(p)} o>Nk(p)diatancek(p,o)/Nk(p) : 在p的第k距离邻域内,所有领域内点到p的可达距离的和

N k ( p ) N_k(p) Nk(p) : 第k距离邻域内的所有点的个数

  • 表示的意义是:p点的k距离邻域内的点到p点的平均可达距离

局部离群因子

在这里插入图片描述

∑ B > N k ( A ) l r d ( B ) l r d ( A ) \sum_{B>N_k(A)}\frac{lrd(B)}{lrd(A)} B>Nk(A)lrd(A)lrd(B) : 在A点的第k邻域Nk(A)中,所有的点的局部可达密度与A点的局部可达密度之比,再求平均


结果分析

给每个数据点都分配一个依赖于邻域密度的离群因子 LOF,进而判断该数据点是否为离群点。

  • 若异常分数 LOF 接近1,则说明样本点p的局部密度跟邻居的接近。
  • 若异常分数 LOF 小于1,表明p处于一个相对密集的区域,不像一个异常点。
  • ​ 若异常分数 LOF 远大于1,表明p跟其他点比较疏远,很可能是一个异常点

代码:

import pandas as pd
from sklearn.neighbors import LocalOutlierFactor
def lof(data, predict=None, k=5, method=1, plot=False):
    
    # 判断是否传入测试数据,若没有传入则测试数据赋值为训练数据
    try:
        if predict == None:
            predict = data.copy()
    except Exception:
        pass
    predict = pd.DataFrame(predict)
    # 计算 LOF 离群因子
    clf = LocalOutlierFactor(n_neighbors=k + 1, algorithm='auto', contamination=0.1, n_jobs=-1)
    clf.fit(data)
    # 记录 k 邻域距离
    predict['k distances'] = clf.kneighbors(predict)[0].max(axis=1)
    # 记录 LOF 离群因子,做相反数处理
    predict['local outlier factor'] = -clf._decision_function(predict.iloc[:, :-1])
    # 根据阈值划分离群点与正常点
    outliers = predict[predict['local outlier factor'] > method].sort_values(by='local outlier factor')
    inliers = predict[predict['local outlier factor'] <= method].sort_values(by='local outlier factor')
    return outliers, inliers
clf.fit(data)

#获取第 k 距离邻域内的每一个点到中心点的距离
clf.kneighbors(data)

#获取每一个样本点的 LOF 值,该函数范围 LOF 值的相反数,需要取反号
-clf._decision_function(data)

clf._predict(data) 则按照原先设置的 contamination 输出判断结果(按比例给出判断结果,异常点返回-1,非异常点返回1

致命缺点:

  • 必须不存在大于等于 k 个重复的点。当这样的重复点存在的时候,这些点的平均可达距离为零,局部可达密度就变为无穷大
  • 所有k diantance计算要去重
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值