暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

机器学习丨离群点检测算法 LOF 及其 Python 实践

AISeer 2021-09-17
5256

背景

离群点检测算法具有非常强的实际意义和广泛的应用前景,包括欺诈检测、网络性能和活动监控等等。

📢 「离群点」「噪声」有区别:噪声是观测值的随机误差和方差;离群点属于观测值,可能是真实数据产生或者噪声产生,整体而言是和大部分观测值明显不同的观测值。

本文主要学习下「基于密度的离群点检测方法」中最具有代表性的算法:「局部离群因子检测算法」 (Local Outlier Factor, LOF) [^1]。

LOF 算法

基于密度的离群点检测方法基本假设:非离群点对象周围的密度与其邻域周围的密度类似,而离群点对象周围的密度显著不同于其邻域周围的密度。 如下图所示:

局部离群因子检测算法 LOF 是一种典型的基于密度的高精度离群点检测方法,通过给每个数据点都分配一个依赖于邻域密度的离群因子 ,进而判断该数据点是否为离群点。若 ,则该数据点为离群点;若 ,则该数据点为正常数据点。

假设当前的样本集合 包含 个数据点,其数据维度为 ,数据点表示为

LOF 算法需要度量不同数据点间的距离 ,至于距离度量可以采用欧式距离、汉明距离、马氏距离等等。为了简明仅给出欧式距离计算公式如下:

在介绍 LOF 算法前先引用几个重要的概念 ^2。

「第 距离」

定义:设 为数 的第 距离

即:点 是距离点 最近的第 个点。

距离邻域」

定义:设 为点 的第 距离邻域,满足条件

即: 中所有到点 距离不大于 的点集合。

「可达距离」

定义:以点 为中心,点 到点 的第 可达距离定义为

即:点 到点 的第 可达距离至少为 ,距离 最近的 个点到 的可达距离被认为是相等的为等于

「局部密度可达」

定义:局部密度可达为

即:点 的第 邻域内所有点到 的平均可达距离。如果 和周围邻域点是同一簇,那么可达距离越可能为较小的 ,导致可达距离之和越小,局部可达密度越大。如果 和周围邻域点较远,那么可达距离可能会取较大值 ,导致可达距离之和越大,局部可达密度越小。

📢 注意:关于局部可达密度的定义其实暗含假设,即:不存在大于等于 个重复的点,这些重复点的平均可达距离为零,局部可达密度就变为无穷大。解决方法是可以将可达距离加上非常小的值。

根据以上定义,LOF 计算公式如下

即:点 的邻域 内其他点的局部可达密度与点 的局部可达密度之比的平均数。如果这个比值越接近 1,说明 的邻域点密度差不多, 可能和邻域同属一簇;如果这个比值小于1,说明 的密度高于其邻域点密度为密集点;如果这个比值大于 1,说明 的密度小于其邻域点密度可能是异常点。

LOF 算法需要计算数据点对间的距离,整个算法时间复杂度为 。为了提高算法效率,FastLOF[^3] 算法对其进行改进。主要思路先将数据集划分为多个子集,再分别计算 LOF 分数,剔除异常分数小于 1 的再进行计算,详情可以参考原文。

Python 实践

为了方便此处直接采用 Scikit-learn 中提供的包测试算法效果。

采用人工生成的离群点数据测试,代码如下所示:

# Generate train data
X_inliers = 0.3 * np.random.randn(1002)
X_inliers = np.r_[X_inliers + 2, X_inliers - 2]

# Generate some outliers
X_outliers = np.random.uniform(low=-4, high=4, size=(202))
X = np.r_[X_inliers, X_outliers]

n_outliers = len(X_outliers)
ground_truth = np.ones(len(X), dtype=int)
ground_truth[-n_outliers:] = -1

clf = LocalOutlierFactor(n_neighbors=20, contamination=0.1)

y_pred = clf.fit_predict(X)
n_errors = (y_pred != ground_truth).sum()
X_scores = clf.negative_outlier_factor_

plt.title("Local Outlier Factor (LOF)")
plt.scatter(X[:, 0], X[:, 1], color="k", s=3.0, label="Data points")
# plot circles with radius proportional to the outlier scores
radius = (X_scores.max() - X_scores) / (X_scores.max() - X_scores.min())
plt.scatter(
    X[:, 0], X[:, 1], s=1000 * radius, edgecolors="r", facecolors="none", label="Outlier scores"
)
plt.axis("tight")
plt.xlim((-55))
plt.ylim((-55))
plt.xlabel("prediction errors: %d" % (n_errors))
legend = plt.legend(loc="upper left")
legend.legendHandles[0]._sizes = [10]
legend.legendHandles[1]._sizes = [20]
plt.show()


对应的实验结果如下:

[^1]: M. M. Breunig, H. P. Kriegel, R. T. Ng, J. Sander. LOF: Identifying Density-based Local Outliers SIGMOD, 2000.

[^3]: M. Goldstein. FastLOF: An Expectation-Maximization based Local Outlier detection algorithm. ICPR, 2012



 KDD 2021丨RANSynCoder:异步多变量时间序列异常检测与定位模型

● KDD 2020 | MTGNN: 基于图神经网络的多变量时间序列预测模型

● AAAI 2021 | 基于图神经网络的多变量时间序列异常检测

MTAD-GAT:基于图注意力网络的多变量时间序列异常检测模型


「阅读原文」留言哦!      

文章转载自AISeer,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论