想象你是一名社区人气调查员,任务是找出社区里“社交异常”的住户。社区里有热闹的广场舞区,也有安静的读书角。如果只按“朋友总数”排名,你会把所有读书角的居民都列为可疑——但他们只是圈子小,活得并不反常。聪明的做法是“参照朋友圈”:看一个人认识几个朋友,再对比他的朋友们平均认识多少人。如果他的朋友个个都认识一两百人,他却只有两三个朋友,这种密度反差才是真正的异常信号。 这就是 LOF(Local Outlier Factor,局部异常因子)算法的核心直觉:异常不是孤立的“绝对稀少”,而是与左邻右舍相比的“密度断崖”。它把每个样本放进自己的 k 近邻圈子里,用局部密度之比打分,分数越高越可疑。本文将带你以调查员的视角,一步步看懂 LOF 的原理、公式、调参、数据适配、高维困境,以及它在风控、故障检测、网络入侵中的真实用法。

岗位关联

掌握 LOF 原理与调参,你就能在欺诈、故障、入侵等无标注数据中精准揪出异常样本,让 AI 从业者的异常检测技术选型不再凭感觉。

目录
  1. 可视化演示
  2. 局部密度理念
  3. 关键概念定义
  4. 算法计算流程
  5. 参数调优指南
  6. 数据分布适配
  7. 高维维度挑战
  8. 风控应用场景
  9. 实战编程实现
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

动态演示LOF局部异常因子检测算法的核心机制,通过源头/管道/节点/终端四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

LOF局部异常因子检测算法:局部异常 局部异常与全局异常区别 k近邻与可达距离 核心机制可视化 LOF局部异常因子检测算法整体架构与关键组件

局部密度理念

调查员的第一课是理解“为什么不能只看朋友总数”。社区人口普查显示,广场舞区的张大妈认识 200 人,读书角的李老师认识 5 人。若按绝对数量排名,李老师必然被列为“社交异常”——但事实是他和读书角的朋友们都只有五六个好友,他在自己的圈子里很自在。异常与否,必须放进“朋友圈”里比较才有意义。

在异常检测里,这种思路对应“局部密度”与“全局密度”的分野。全局方法(如 Z-score)把全社区的平均值当成基准,稀疏区域的正常点全被误判。LOF 的做法是给每个点划定一个 k 近邻的局部视野,比较“自己视野里的密集程度”与“邻居们视野里的密集程度”,用比值定量刻画反差:

所以李老师不是异常——他的朋友也各自冷清,分子分母差不多,LOF 接近 1。真正可疑的,是那个“朋友个个百人好友、自己却形单影只”的住户。

LOFk(p)≈1k∑o∈Nk(p)lrdk(o)lrdk(p)\displaystyle \text{LOF}_k(p) \approx \frac{\frac{1}{k}\sum_{o \in N_k(p)} \text{lrd}_k(o)}{\text{lrd}_k(p)}
LOF 约等于 1,说明你和邻居一样“热闹”;明显大于 1,说明你被热闹的朋友们包围却形单影只,异常嫌疑随之上升。
  1. 分子-朋友圈人气把 p 的 k 个邻居各自的局部密度求平均,衡量“邻居们通常多热闹”。
    1k∑o∈Nk(p)lrdk(o)\displaystyle \frac{1}{k}\sum_{o \in N_k(p)} \text{lrd}_k(o)
  2. 分母-自己人气p 自身的局部密度,衡量“自己的圈子多冷清”。
    lrdk(p)\displaystyle \text{lrd}_k(p)
  3. 比值-密度反差分子比分母大得越多,说明 p 与朋友圈反差越大,越可能是异常点。
    LOFk(p)≈邻居平均密度自身密度\displaystyle \text{LOF}_k(p) \approx \frac{\text{邻居平均密度}}{\text{自身密度}}

关键概念定义

调查员需要两件趁手的工具:一是“朋友圈”的边界怎么画,二是“人与人之间的距离”怎么算。k 近邻就是“与你关系最近的前 k 个人”,k 距离则是“第 k 近的朋友离你有多远”,它定义了朋友圈的半径。

在数学上,先计算所有样本两两之间的欧氏距离,对每个点 p 圈定 k 个最近邻居组成集合 \(N_k(p)\)。但邻居所在圈子的疏密不同,直接拿绝对距离比较会不公平——稀疏区里“隔两条街”就算近,热闹区里“楼下”才算近。因此引入“可达距离”(Reachability Distance):当 p 离 o 很近时,按实际距离算;当 p 离 o 较远时,以“o 的 k 距离”作为保底门槛:

有了“可达距离”这把尺子,侦探就能公平地测量疏密不一的街区,不会因为读书角本身冷清,就冤枉其中的住户。

rdk(p,o)=max⁡{dk(o), d(p,o)}\displaystyle \text{rd}_k(p, o) = \max \{ d_k(o),\ d(p, o) \}
可达距离像“去朋友家的路程费”:朋友若在闹市,至少得跨过他的街区半径;朋友若在隔壁,则按实际距离算。
  1. k 距离-圈子半径邻居 o 到它自己第 k 个朋友的距离,代表“o 所在圈子的密度尺寸”。
    dk(o)=max⁡{d(o,q)∣q∈Nk(o)}\displaystyle d_k(o) = \max \{ d(o, q) \mid q \in N_k(o) \}
  2. 实际距离-两人远近p 与 o 的欧氏距离,代表“两人的关系有多近”。
    d(p,o)=∑i=1d(pi−oi)2\displaystyle d(p, o) = \sqrt{\sum_{i=1}^{d}(p_i - o_i)^2}
  3. 取较大者-公平保底p 离 o 近时按实际距离,p 离 o 远时按 o 的圈子半径,避免稀疏区被“绝对距离”带偏。
    max⁡{dk(o), d(p,o)}\displaystyle \max \{ d_k(o),\ d(p, o) \}

算法计算流程

调查员的办案手册共四步:先绘制全社区地图,再圈定每个人的朋友圈,然后估算每个小圈子的人气,最后对照人气反差打分。这四步正是 LOF 算法的完整推理链。

局部可达密度(LRD)是“平均可达距离”的倒数——平均可达距离越小,说明这个点周围越密集,人气指数越高。最后,LOF 是“朋友们的平均人气”与自己人气之比:

四步办完,侦探手里就有了一份“人气反差榜”,分数越高越可疑。

lrdk(p)=k∑o∈Nk(p)rdk(p,o),LOFk(p)=∑o∈Nk(p)lrdk(o)k×lrdk(p)\displaystyle \text{lrd}_k(p) = \frac{k}{\sum_{o \in N_k(p)} \text{rd}_k(p, o)}, \qquad\displaystyle \text{LOF}_k(p) = \frac{\sum_{o \in N_k(p)} \text{lrd}_k(o)}{k \times \text{lrd}_k(p)}
LRD 是“人气指数”,可达距离平均越小越热闹;LOF 则是“朋友人气相对自己人气的倍率”。
  1. LRD-人气指数分母是所有邻居可达距离之和除以 k,取倒数后值越大说明越热闹。
    lrdk(p)=(1k∑o∈Nk(p)rdk(p,o))−1\displaystyle \text{lrd}_k(p) = \left( \frac{1}{k} \sum_{o \in N_k(p)} \text{rd}_k(p, o) \right)^{-1}
  2. 分子-朋友人气总和把 k 个朋友的 LRD 加起来,朋友圈越热闹,分子越大。
    ∑o∈Nk(p)lrdk(o)\displaystyle \sum_{o \in N_k(p)} \text{lrd}_k(o)
  3. LOF-人气反差分子比自己 LRD 的 k 倍大很多时,LOF 远超 1,异常信号明显。
    LOFk(p)=∑o∈Nk(p)lrdk(o)k⋅lrdk(p)\displaystyle \text{LOF}_k(p) = \frac{\sum_{o \in N_k(p)} \text{lrd}_k(o)}{k \cdot \text{lrd}_k(p)}

参数调优指南

k 值就像侦探的“观察视野”:看得太小,只抓住身边两三个人的情绪波动,满城都是嫌疑犯;看得太大,把大半个城区都当朋友圈,真正的孤立者反而被淹没。调参的本质,是在敏感与迟钝之间找平衡。

经验上,k 常取数据量 \(n\) 的平方根向上取整,起步值通常在 10 到 30 之间。同时,业务上还需要一条“分数线” \(\theta\):LOF 高于它才判定为异常。\(\theta\) 的取值可与预期异常比例对齐——先按 top \(\alpha\%\) 圈出嫌疑名单,再反推对应的 LOF 分位点:

视野太大看不到局部反差,视野太小满眼都是噪声——根号值起步,业务比例校准,侦探才不误伤良民。

k建议=⌈n⌉,判异常: LOFk(p)≥θ\displaystyle k_{\text{建议}} = \left\lceil \sqrt{n} \right\rceil, \qquad \text{判异常: } \text{LOF}_k(p) \ge \theta
根号 n 是 k 的经验起点,θ 是业务分数线,两者配合才能让 LOF 既不过敏也不迟钝。
  1. 根号 n-经验视野n 为样本量,开根号后向上取整,兼顾局部性与稳定性。
    ⌈n⌉\displaystyle \left\lceil \sqrt{n} \right\rceil
  2. θ-业务门槛θ 是判定异常的分值线,可根据漏报与误报的代价来回调整。
    LOFk(p)≥θ\displaystyle \text{LOF}_k(p) \ge \theta
  3. 异常比例-校准先按预期比例 α(如 2%)取排序后的 top 样本,再映射回 θ,让统计口径与业务口径对齐。
    α=预期异常数n\displaystyle \alpha = \frac{\text{预期异常数}}{n}

数据分布适配

社区里有热闹的广场舞区,也有安静的读书角。全局方法只盯全社区平均人气,会把读书角的居民一锅端;LOF 则尊重每个街区的“当地标准”——这就是它在多密度数据上的核心优势。

只要一个点与它的邻居密度相当,哪怕整片区域都很稀疏,LOF 也接近 1,不会误报;反之,跨簇的点、簇边缘的“游离者”能被人气反差揪出来。对比全局 Z-score 与局部 LOF 的公式,差异一目了然:

尊重当地标准的社区侦探,无论广场舞区还是读书角,都能精准揪出真正的“局外人”。

Z(p)=d(p,μ)σvsLOFk(p)=邻居平均密度自身密度\displaystyle Z(p) = \frac{d(p, \mu)}{\sigma} \qquad\text{vs}\qquad \text{LOF}_k(p) = \frac{\text{邻居平均密度}}{\text{自身密度}}
Z-score 拿全社区平均数做尺子,LOF 拿朋友圈做尺子,尺子不同,稀疏区的结论天差地别。
  1. Z-score-全局尺子p 离全局中心越远越异常,在密度不均时系统性地误判稀疏簇。
    d(p,μ)σ\displaystyle \frac{d(p, \mu)}{\sigma}
  2. LOF-局部尺子只关心 p 与邻居的相对密度差,不受远处簇的密度影响。
    邻居平均密度自身密度\displaystyle \frac{\text{邻居平均密度}}{\text{自身密度}}
  3. 场景选型-按密度决定密度均匀时全局方法省算力,密度不均时优先选 LOF。
    密度不均⇒LOF;密度均匀⇒全局方法\displaystyle \text{密度不均} \Rightarrow \text{LOF};\quad \text{密度均匀} \Rightarrow \text{全局方法}

高维维度挑战

当房间的维度从 2 维变成 100 维,一切都会变形。侦探发现一个诡异现象:在高维空间里,每个人到其他人的距离都差不多远,“远亲”和“近邻”变得难以分辨。这就是著名的“维度灾难”。

随着维度 \(d\) 增加,样本在空间中越来越稀疏,任意两点的距离分布趋同,k 近邻集合不再稳定,LOF 的分辨力急剧下降。数学上,若各维独立随机取值,最大距离与最小距离的差除以最小距离,会随维度增大而趋于 0:

不是 LOF 变笨了,而是高维空间把“远近”变得不再清晰。聪明的侦探先做减法,再亮出火眼金睛。

lim⁡d→∞Dmax⁡−Dmin⁡Dmin⁡→0\displaystyle \lim_{d \to \infty} \frac{D_{\max} - D_{\min}}{D_{\min}} \to 0
维度越高,样本间的距离越挤在一起,“远近”失去意义,LOF 的邻域也就名存实亡。
  1. 距离跨度-远近可辨度样本间最大与最小距离的差,衡量“远近”是否分得开。
    Dmax⁡−Dmin⁡\displaystyle D_{\max} - D_{\min}
  2. 比值趋零-距离集中除以 \(D_{\min}\) 后随维度增大趋近 0,说明所有距离聚在同一量级。
    Dmax⁡−Dmin⁡Dmin⁡→0\displaystyle \frac{D_{\max} - D_{\min}}{D_{\min}} \to 0
  3. 应对策略-先降维用 PCA/UMAP 压到几十维,或先做特征选择剔除噪声维度,再跑 LOF。
    x′=fPCA(x),LOFk(x′)\displaystyle x' = f_{\text{PCA}}(x), \quad \text{LOF}_k(x')

风控应用场景

侦探终于上岗了。在银行反欺诈团队,他盯的是每一笔交易:正常客户的交易习惯形成密集的“朋友圈”,盗刷行为往往瞬间跳出这个圈子——这就是欺诈信号。

LOF 在风控场景的价值在于无需标注数据即可建立异常基线。实际落地时,对每个样本计算 LOF 分数,再依据业务风险偏好设定阈值 \(\theta\),把分数翻译成可执行的决策规则:

侦探的价值不止于发现嫌疑,更在于把嫌疑分翻译成业务能用的行动指令——拦截、复核、升级。

y^i={1,LOFk(xi)≥θ0,LOFk(xi)<θ\displaystyle \hat y_i = \begin{cases} 1, & \text{LOF}_k(x_i) \ge \theta \\ 0, & \text{LOF}_k(x_i) < \theta \end{cases}
θ 的高低决定拦截松紧,可结合坏账损失与人工成本来定,分数越高越优先复核。
  1. 特征向量-单条样本一笔交易、一个设备读数或一条网络会话的 d 维特征。
    xi∈Rd\displaystyle x_i \in \mathbb{R}^d
  2. 嫌疑分-离群程度LOF 输出该样本的离群分数,越高说明与历史行为圈子越疏离。
    LOFk(xi)\displaystyle \text{LOF}_k(x_i)
  3. 决策规则-业务动作分数超过 θ 则判为异常并转人工或拦截,否则放行。
    y^i=1{LOFk(xi)≥θ}\displaystyle \hat y_i = \mathbb{1}\{ \text{LOF}_k(x_i) \ge \theta \}

实战编程实现

工欲善其事,必先利其器。Python 的 scikit-learn 已经帮侦探配好了装备:LocalOutlierFactor 一行代码即可完成训练与预测。实际工程中,我们会先造一批含异常点的数据,用“从零实现”与官方接口对照,验证理解正确。

核心是调用 fit_predict(),返回 -1 表示异常、1 表示正常;contamination 参数告诉模型预期的异常占比。上线前还要用精确率与召回率验收:

侦探不打无准备之仗。先用合成数据校准装备,再用精确率与召回率验收,最后才敢把 LOF 部署到真实流水线上。

Precision=TPTP+FP,Recall=TPTP+FN\displaystyle \text{Precision} = \frac{TP}{TP + FP}, \qquad \text{Recall} = \frac{TP}{TP + FN}
精确率高=别冤枉好人,召回率高=别放过坏人,上线前两个指标一起看。
  1. TP/FP-判定结果预测异常且真实异常记 TP,预测异常但实际正常记 FP,漏掉真实异常记 FN。
    TP=检出且真实,FP=检出但误报\displaystyle TP = \text{检出且真实}, \quad FP = \text{检出但误报}
  2. 精确率-省人力说有问题的样本里有多大比例真的有问题,越高越省审核人力。
    TPTP+FP\displaystyle \frac{TP}{TP + FP}
  3. 召回率-少漏网真的有问题的样本里有多少被检出来,越高越少漏网之鱼。
    TPTP+FN\displaystyle \frac{TP}{TP + FN}

AI 应用场景

信用卡反欺诈的离群交易识别

阶段:无监督异常检测

解决的问题:欺诈标注样本稀少、欺诈手法不断翻新,规则引擎只能拦截已知套路。LOF 用持卡人近 30 天的正常交易行为构建“朋友圈”,任何偏离自身交易习惯的离群交易都会得到高分。

具体案例:某支付平台对交易的金额、频次、时段、设备指纹等 20 维特征计算 LOF,取分数 top 1% 转人工复核,欺诈拦截率提升 23%,误报率远低于全局阈值方案。

工业设备故障的早期预警

阶段:预测性维护中的异常检测

解决的问题:故障样本少且故障形态未知,传统阈值报警频繁误报。LOF 在正常振动、温度、电流数据上建立局部密度基线,磨损初期的异常特征会以离群点形式提前显现。

具体案例:某风电场将轴承振动传感器数据接入 LOF 监测,提前 5 天发现早期磨损信号,安排停机检修,避免了传动轴断裂的高额损失。

网络入侵流量的异常发现

阶段:信息安全异常检测

解决的问题:攻击流量千变万化,特征库更新滞后。LOF 对正常网络会话的包长、连接时长、协议分布等特征建模,突发的扫描与渗透行为因密度孤立而现形。

具体案例:某安全团队对一周的流量会话计算 LOF 分数,在日志特征库尚未更新前,成功捕捉到一次新型端口扫描与横向移动。

Python 演示

python60 行
# -*- coding: utf-8 -*-"""LOF 局部异常因子算法: 从零实现并与 sklearn 对照"""import numpy as npfrom sklearn.datasets import make_blobsfrom sklearn.neighbors import LocalOutlierFactor  def lof_scratch(X, k=5):    """从零实现 LOF: 返回每个样本的 LOF 分数"""    n = X.shape[0]    # 第一步: 计算两两欧氏距离矩阵    diff = X[:, None, :] - X[None, :, :]    dist = np.sqrt((diff ** 2).sum(axis=2))    # 第二步: 求每个点的 k 近邻和 k 距离    order = np.argsort(dist, axis=1)    kd = np.array([dist[i, order[i, k]] for i in range(n)])    nb = order[:, 1:k + 1]    # 第三步: 算局部可达密度 lrd    lrd = np.zeros(n)    for i in range(n):        rd_sum = 0.0        for m in range(k):            j = nb[i, m]            rd_sum += max(kd[j], dist[i, j])        lrd[i] = 1.0 / (rd_sum / k)    # 第四步: 邻居 lrd 均值除以自己的 lrd 得到 LOF    lof = np.zeros(n)    for i in range(n):        lof[i] = np.mean([lrd[j] / lrd[i] for j in nb[i]])    return lof  def main():    # 造数据: 两个簇 80 个点 + 额外 4 个异常点    X, _ = make_blobs(n_samples=80, centers=2,                      cluster_std=0.6, random_state=42)    outliers = np.array([[0.0, 6.0], [6.0, 0.0],                         [5.0, 5.0], [-3.0, 1.0]])    X = np.vstack([X, outliers])     k = 5    lof = lof_scratch(X, k)    pred = (lof > 1.5).astype(int)     # sklearn 对照: contamination 设为真实异常占比    clf = LocalOutlierFactor(n_neighbors=k, contamination=4.0 / 84)    pred_sk = clf.fit_predict(X)    pred_sk = (pred_sk == -1).astype(int)     print("idx   LOF     from_scratch  sklearn")    for i in range(X.shape[0]):        if pred[i] == 1 or pred_sk[i] == 1:            print("%3d   %.3f      %d           %d"                  % (i, lof[i], pred[i], pred_sk[i]))    agree = np.mean(pred == pred_sk)    print("标记一致率: %.1f%%" % (agree * 100))  if __name__ == "__main__":    main()
目的:从零实现 LOF 算法并与 sklearn 官方接口对照,验证对可达距离、局部密度和 LOF 公式的理解正确性。
  1. diff = X[:, None, :] - X[None, :, :]用广播机制一次性算出所有样本两两之差,免写双重循环
  2. dist = np.sqrt((diff ** 2).sum(axis=2))对差值平方求和再开方,得到 n×n 的距离矩阵
  3. nb = order[:, 1:k + 1]排序后去掉自己(第 0 位),取前 k 个邻居的下标
  4. kd = np.array([dist[i, order[i, k]] for i in range(n)])每个点第 k 近的邻居距离,即圈子半径
  5. rd_sum += max(kd[j], dist[i, j])可达距离取“邻居的 k 距离”与“实际距离”中较大者
  6. lrd[i] = 1.0 / (rd_sum / k)局部可达密度是平均可达距离的倒数,人气的量化
  7. lof[i] = np.mean([lrd[j] / lrd[i] for j in nb[i]])邻居密度相对自己的平均倍率,大于 1 越可疑

常见误区

误区我以为只要 LOF 大于 1,这个点就一定是异常,于是把所有 LOF>1 的样本全删了,结果正常数据被误杀一大片。

正解LOF=1 只是表示样本密度与邻居相当,正常点也会在 1 附近波动。真正的异常通常在 1.5 甚至 2 以上。正确做法是画出 LOF 分布图找拐点,或按业务异常比例(如 1%~5%)反推阈值,而不是机械地把 1 当分界线。

为何常见:LOF 公式的比值天然以 1 为中心,初学者容易把“基准值”当成“判定线”,忽略了统计波动与业务口径。

误区我觉得 k 越大,见过的邻居越多,结果肯定越可靠,于是把 k 设成样本数的一半。

正解k 过大会让“局部”名存实亡:邻居圈子蔓延到整个簇,稀疏簇的边缘点被误判为正常,真正的局部离群点被正常点平均掉。k 过小又易受噪声干扰。常用 \(k \approx \sqrt{n}\) 起步,再结合业务数据多次试验。

为何常见:“更多信息=更好结果”的直觉在局部算法里不成立,视野被撑大就失去了“局部”的意义。

误区我觉得 LOF 用距离就能度量相似度,特征多点儿也不怕,于是直接把 500 维特征喂进去等待结果。

正解高维下距离趋于均匀,最近邻与最远邻相差无几,LOF 分辨力骤降。正确做法是先降维(PCA/UMAP)或做特征选择,压缩到几十维内再跑 LOF,否则算出的分数与随机猜没什么差别。

为何常见:低维散布图上 LOF 效果惊艳,让人误以为距离度量在高维依然有效,忽略了维度灾难。

误区我以为 LOF 是万能异常检测器,时间序列里的突刺、图像里的异物、全局偏移全都能交给它处理。

正解LOF 只擅长发现“密度型离群点”——局部密度明显低于邻居的点。全局偏移型异常适合 Z-score 或孤立森林,时间序列上下文异常需要专门方法。选型要看异常形态,不能一把 LOF 走天下。

为何常见:LOF 名气大、上手快,容易让人忽视它的适用边界,遇到任何异常都先套 LOF。

面试题

Q1. LOF 算法的核心思想是什么?

单选题 · easy

  • A.比较局部密度与邻居的差异← 正确答案
  • B.计算样本点到全局中心距离
  • C.统计每个样本出现的频次
  • D.求解样本间的最短路径

答案:A。LOF 的本质是把样本放进局部视野,与邻居的密度做对比,就像社区侦探不看你认识多少人,而看你与朋友圈的密度反差。全局中心距离是 Z-score 的思路,频次统计与最短路径都与此无关。

Q2. 一个点的 LOF 值约等于 1,最可能说明什么?

单选题 · easy

  • A.该点一定是全局最中心点
  • B.该点周围完全没有邻居点
  • C.该点局部密度与邻居相当← 正确答案
  • D.该点属于最大密度簇内部

答案:C。LOF≈1 表示自身密度与邻居密度相当,就像读书角的居民和朋友一样“冷清”,并不反常。完全没有邻居时 LOF 会因除零而异常,属于最大密度簇内部不一定 LOF 为 1,全局中心点更不是 LOF 的定义。

Q3. 关于可达距离 rd_k(p,o) 的定义,正确的是?

单选题 · mid

  • A.永远取两个距离中的较小值
  • B.求两个距离之间的平均值差
  • C.求两个距离之间的相乘结果
  • D.取两者距离中较大的数值← 正确答案

答案:D。可达距离定义为 max{邻居 o 的 k 距离,p 与 o 的实际距离},即“去朋友家的路程费”:朋友若在闹市,至少跨过他的街区半径;朋友若在隔壁,按实际距离算。取小值、平均值或相乘都不符合定义。

Q4. LOF 中 k 值设置过大,将导致什么后果?

单选题 · mid

  • A.局部视野过大,异常被平均掉← 正确答案
  • B.局部视野过小,噪声干扰大
  • C.距离矩阵计算量大幅增加
  • D.计算速度反而变得更快

答案:A。k 过大时邻居圈扩大成整个簇,局部异常被正常点“平均”稀释,就像侦探视野太大看不到单点反常。视野过小是 k 过小的后果,计算量增加不是“过大”的本质危害,计算速度更不会变快。

Q5. 与全局异常检测方法相比,LOF 的优势体现在哪些方面?

多选题 · mid

  • A.能适应多个密度不同的簇← 正确答案
  • B.不需要任何参数参与
  • C.稀疏区域的正常点不会被误杀← 正确答案
  • D.计算效率始终是最高的

答案:AC。LOF 尊重每个街区的“当地标准”,多密度簇与稀疏区域都能正确处理,读书角的居民不会被冤枉。但它需要 k 参数,且距离矩阵计算开销大,效率和“无参数”都不是优势。

Q6. 局部可达密度 LRD 越大,说明该点周围环境?

单选题 · easy

  • A.越稀疏,邻居越少且离得远
  • B.越密集,邻居平均可达距离越小← 正确答案
  • C.样本数量越多而且维度越高
  • D.数据噪声越大且分布越乱

答案:B。LRD 是平均可达距离的倒数,平均可达距离越小则 LRD 越大,说明该点被密集的邻居环绕。稀疏、高维、噪声大都会让可达距离变大,从而降低 LRD,而非升高。

Q7. 在高维数据上使用 LOF 之前,合理的做法包括?

多选题 · mid

  • A.先做 PCA 主成分降维处理← 正确答案
  • B.先用特征选择剔除噪声维度← 正确答案
  • C.把 k 值调大到样本总量
  • D.直接保留所有原始特征维度

答案:AB。高维下距离趋同,需要先降维或剔除噪声维度,恢复距离的区分度。把 k 调到样本总量等于放弃局部性,直接使用所有原始特征会加剧维度灾难,都不是合理做法。

Q8. 高维数据下 LOF 失效的根本原因是?

单选题 · extreme

  • A.距离矩阵存储开销过大
  • B.局部密度计算会溢出报错
  • C.距离趋同导致邻域失去区分← 正确答案
  • D.近邻集合大量重复和冗余

答案:C。高维空间中样本间距离趋于均匀,最近邻与最远邻难分彼此,邻域失去区分度,局部密度对比自然失效。存储开销、溢出、重复都是次要的工程问题,不是根本原因。

Q9. 关于 LOF 阈值的选取,以下哪种做法最合理?

单选题 · mid

  • A.机械地固定为 LOF 等于 1
  • B.结合异常占比与业务成本反推← 正确答案
  • C.直接取所有样本的最大 LOF
  • D.取 k 值与样本总量相等

答案:B。阈值应先定预期异常比例,再看 LOF 分布取对应分位点,最后用误报与漏报成本校准。固定为 1 没有考虑统计波动,直接取最大值会导致一个异常都检不出,调大 k 则是参数问题而非阈值问题。

Q10. 以下哪些场景适合使用 LOF 进行异常检测?

多选题 · hard

  • A.信用卡交易的离群行为识别← 正确答案
  • B.图像像素级别的语义分割
  • C.设备传感器突发性故障预警← 正确答案
  • D.网络流量中的基础设施攻击← 正确答案

答案:ACD。信用卡离群交易、设备传感器突变、网络流量中的扫描渗透都属于“密度型离群点”,是 LOF 的用武之地。图像语义分割是监督式稠密预测任务,需要标注与卷积结构,不是 LOF 的适用场景。