LOF通过比较数据点自身局部密度与其邻居平均局部密度的比值得出LOF score,该值显著大于1(即负值绝对值越大)表明该点密度显著低于邻域,从而识别为局部离群点;其核心是相对密度偏差而非绝对距离。

LocalOutlierFactor 怎么靠邻域密度对比识别离群点
LOF 不是看单个点离中心有多远,而是看「这个点所在位置的密度」和「它周围邻居所在位置的平均密度」谁更低。比值(LOF score)显著大于 1,就说明该点局部更稀疏——它被一群相对密集的点包围着,所以是局部离群点。
关键不是绝对距离,而是密度的相对偏差。这也是它能发现 a2 这类“在绿色簇边缘但不算全局最远”的局部异常点的原因。
-
fit_predict返回的是 -1(离群)或 1(正常),但内部计算出的negative_outlier_factor_才是真正的 LOF score(注意:它是负数,绝对值越大越异常) - 默认使用欧氏距离,高维稀疏数据建议先标准化,否则距离失效
-
n_neighbors太小(如 5)会让 LOF 对噪声敏感;太大(如 > len(X)//2)会模糊局部结构,导致所有点密度趋同
为什么 fit_predict 的输出是 -1/1,而真正判断依据是 negative_outlier_factor_
scikit-learn 的 LocalOutlierFactor 为兼容聚类接口,把异常检测包装成“两分类”形式:fit_predict 直接返回硬标签。但它底层没做阈值截断——negative_outlier_factor_ 是原始、连续的密度比值(取负号只为让异常点数值更小,方便用 argsort 排序)。
- 不要用
predict或fit_predict的 -1/1 做精细分析,它们只是基于默认阈值(contamination='auto'时按训练集离群比例估计)的粗略划分 - 真要看哪些点最可疑,排序
model.negative_outlier_factor_,取前 5% 或观察拐点(如从 -1.2 突降到 -2.8) - 若设了
contamination=0.1,模型会自动把 LOF score 最低的 10% 标为 -1,但这个分界线未必合理——尤其当异常程度呈长尾分布时
LocalOutlierFactor 的 n_neighbors 参数怎么选才不翻车
n_neighbors 决定了“谁算你的邻居”,直接影响密度估计的粒度。选错会导致两类典型失败:要么把正常波动当异常,要么漏掉紧凑簇内的局部离群点。
立即学习“Python免费学习笔记(深入)”;
- 经验下限:至少 > 2×维度(比如 10 维数据,
n_neighbors≥ 20),否则 k 距离不稳定,可达距离退化为普通距离 - 上限建议 ≤ min(20, len(X)//2),超大样本也不宜超过 50;否则局部性消失,LOF 退化成近似全局密度估计
- 调试技巧:画
negative_outlier_factor_的直方图,如果峰值集中在 -1.0 附近且拖一条极短左尾,大概率n_neighbors设太大了
LocalOutlierFactor 在时间序列上直接用会出什么问题
原生 LocalOutlierFactor 把每个时间点当作独立坐标点处理(例如把 [t₁, t₂, t₃] 当作三维空间中的一个点),完全忽略时序依赖和滑动窗口结构。这会导致两个后果:
- 趋势项或周期性变化会被误判为“密度突变”,比如上升期末尾几个点因值偏高而集体获得高 LOF score
- 突发脉冲(如单点尖峰)可能因邻域内其他点也处于高位而被平滑掉——它的局部密度未必比周围低
- 正确做法是先构造特征:用滑动窗口提取均值、标准差、一阶差分等统计量,再把每个窗口映射为一个特征向量,最后喂给
LocalOutlierFactor
真正容易被忽略的是:LOF 对输入尺度极度敏感,而时间序列原始值往往量纲混杂(温度 vs 订单量)。不做 StandardScaler 或 RobustScaler,negative_outlier_factor_ 的解释性基本归零。


















