局部异常因子(LOF)算法是一种无监督异常检测方法,它通过计算给定数据点与其邻居的局部密度偏差来识别异常值。在这种方法中,那些相对于其邻居具有显著低密度的样本被视为异常值。本文将展示如何在scikit-learn库中使用LOF进行异常检测,这是该估计器的默认用例。需要注意的是,当LOF用于异常检测时,它没有predict、decision_function和score_samples方法。有关异常检测和新颖性检测之间的区别以及如何使用LOF进行新颖性检测的详细信息,请参考用户指南。
通常,考虑的邻居数量(参数n_neighbors)应设置为:1)大于一个簇必须包含的最小样本数,以便其他样本可以相对于这个簇成为局部异常值;2)小于可能成为局部异常值的最近样本的最大数量。在实践中,通常没有这样的信息,而取n_neighbors=20通常效果不错。
以下是使用LOF进行异常检测的示例代码。首先,需要生成带有异常值的数据集。然后,将使用fit_predict方法来计算训练样本的预测标签(当LOF用于异常检测时,估计器没有predict、decision_function和score_samples方法)。
import numpy as np
np.random.seed(42)
X_inliers = 0.3 * np.random.randn(100, 2)
X_inliers = np.r_[X_inliers + 2, X_inliers - 2]
X_outliers = np.random.uniform(low=-4, high=4, size=(20, 2))
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
from sklearn.neighbors import LocalOutlierFactor
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_
接下来,将绘制结果。首先,需要导入matplotlib库。然后,将绘制数据点,并根据异常分数绘制半径成比例的圆圈。
import matplotlib.pyplot as plt
from matplotlib.legend_handler import HandlerPathCollection
def update_legend_marker_size(handle, orig):
"Customize size of the legend marker"
handle.update_from(orig)
handle.set_sizes([20])
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())
scatter = plt.scatter(X[:, 0], X[:, 1], s=1000 * radius, edgecolors="r", facecolors="none", label="Outlier scores")
plt.axis("tight")
plt.xlim((-5, 5))
plt.ylim((-5, 5))
plt.xlabel("prediction errors: %d" % (n_errors))
plt.legend(handler_map={scatter: HandlerPathCollection(update_func=update_legend_marker_size)})
plt.title("Local Outlier Factor (LOF)")
plt.show()