2.7. 新颖性和异常值检测#

许多应用程序需要能够确定新观测是否属于与现有观测相同的分布(它是一个 inlier ),或者应该认为不同(它是一个 outlier ).通常,这种能力用于清理真实数据集。必须做出两个重要的区分:

离群点检测:

训练数据包含异常值,这些异常值被定义为远离其他观测值的观测值。因此,离群值检测估计器试图适应训练数据最集中的区域,忽略异常观察。

新奇检测:

训练数据没有被离群值污染,我们感兴趣的是检测是否存在异常值。 new 观察结果是异常值。在这种情况下,异常值也被称为新奇物。

异常值检测和新颖性检测都用于异常检测,其中人们对检测异常或异常观察感兴趣。离群点检测也称为无监督异常检测,新奇性检测称为半监督异常检测。在异常值检测的背景下,异常值/异常无法形成密集集群,因为可用的估计器假设异常值/异常位于低密度区域。相反,在新奇检测的背景下,新奇/异常只要位于训练数据的低密度区域,就可以形成密集集群,在这种背景下被认为是正常的。

scikit-learn项目提供了一套机器学习工具,可用于新奇或异常值检测。该策略是通过以无监督的方式从数据中进行对象学习来实现的::

estimator.fit(X_train)

然后,新的观察可以排序为内值或异常值, predict 方法:

estimator.predict(X_test)

离群值标记为1,离群值标记为-1。预测方法利用估计器计算的原始评分函数上的阈值。此评分功能可通过 score_samples 方法,而阈值可以通过 contamination 参数.

decision_function 方法还从评分函数中定义,负值是离群值,非负值是内值::

estimator.decision_function(X_test)

注意 neighbors.LocalOutlierFactor 不支持 predict , decision_functionscore_samples 默认情况下方法,但只有一个 fit_predict 方法,因为该估计器最初旨在应用于离群值检测。训练样本的异常评分可通过 negative_outlier_factor_ 属性

如果你想使用 neighbors.LocalOutlierFactor 对于新颖性检测,即预测标签或计算新的未见数据的异常性分数,您可以使用 novelty 参数设置为 True 在匹配估计器之前。在这种情况下, fit_predict 不可用.

警告

Novelty detection with Local Outlier Factor

novelty 设置为 True 请注意您只能使用 predict , decision_functionscore_samples 基于新的未见数据,而不是训练样本,因为这会导致错误的结果。即,的结果 predict 不会和 fit_predict .训练样本的异常评分始终可以通过 negative_outlier_factor_ 属性

的行为 neighbors.LocalOutlierFactor 总结在下表中。

方法

离群点检测

新奇检测

fit_predict

OK

不可用

predict

不可用

仅用于新数据

decision_function

不可用

仅用于新数据

score_samples

使用 negative_outlier_factor_

仅用于新数据

negative_outlier_factor_

OK

OK

2.7.1. 异常值检测方法概述#

scikit-learn中异常值检测算法的比较。局部异常值因子(LOF)不会以黑色显示决策边界,因为当它用于异常值检测时,它没有可应用于新数据的预测方法。

../_images/sphx_glr_plot_anomaly_comparison_001.png

ensemble.IsolationForestneighbors.LocalOutlierFactor 在这里考虑的数据集上表现相当好。的 svm.OneClassSVM 已知对异常值敏感,因此对于异常值检测表现不佳。话虽如此,在高维度中检测异常值,或者在不对内部数据的分布进行任何假设的情况下检测异常值是非常具有挑战性的。 svm.OneClassSVM 仍然可以与异常值检测一起使用,但需要对其超参数进行微调 nu 以处理异常值并防止过度匹配。 linear_model.SGDOneClassSVM 提供了样本数量具有线性复杂性的线性单类支持者的实现。此实现与内核逼近技术一起使用,以获得类似的结果 svm.OneClassSVM 默认情况下使用高斯核。最后, covariance.EllipticEnvelope 假设数据是高斯数据并学习椭圆。有关不同估计量的更多详细信息,请参阅示例 比较玩具数据集异常值检测的异常检测算法 以及以下各节。

示例

2.7.2. 新奇检测#

考虑一个数据集 \(n\) 来自相同分布的观察结果, \(p\) 功能. 现在考虑我们向该数据集添加一个观察结果。新的观察结果与其他观察结果如此不同,以至于我们可以怀疑它是有规律的吗?(i.e.它是否来自同一个分布?)或者相反,它与另一个如此相似,以至于我们无法将其与原始观察区分开来?这是新颖性检测工具和方法所解决的问题。

一般来说,它即将学习一个粗略、紧密的边界,该边界划定了初始观测值分布的轮廓,并在嵌入中绘制 \(p\) - 维度空间。然后,如果进一步的观测位于边界界限的子空间内,则它们被认为来自与初始观测相同的种群。否则,如果它们位于边境之外,我们可以在对我们的评估有一定的信心的情况下说它们是异常的。

Schölkopf等人为此引入了单类支持机,并在 支持向量机 模块在 svm.OneClassSVM object.它需要选择一个内核和一个纯量参数来定义边界。 尽管没有确切的公式或算法来设置其带宽参数,但通常会选择RBS核。这是scikit-learn实现中的默认值。的 nu 参数,也称为一类支持者的裕度,对应于在边界外找到新的、但定期的观察的概率。

引用

示例

../_images/sphx_glr_plot_oneclass_001.png

2.7.2.1. 扩大一类支持者的规模#

One-Class Support的在线线性版本在中实现 linear_model.SGDOneClassSVM .此实现随样本数量线性扩展,并且可以与核逼近一起使用来逼近核化的解 svm.OneClassSVM 其复杂性充其量是样本数量的二次。见章节 在线一类支持者 了解更多详细信息。

示例

2.7.3. 离群点检测#

离群值检测与新奇检测类似,因为目标是将定期观察的核心与一些污染观察分开,称为 outliers .然而,在离群值检测的情况下,我们没有一个干净的数据集来表示可用于训练任何工具的常规观测的总体。

2.7.3.1. 装配椭圆形信封#

执行异常值检测的一种常见方法是假设常规数据来自已知分布(例如数据是高斯分布的)。根据这个假设,我们通常会尝试定义数据的“形状”,并可以将离群观察定义为距离适合形状足够远的观察。

scikit-learn提供了一个对象 covariance.EllipticEnvelope 这将稳健的协方差估计与数据进行匹配,从而将椭圆与中心数据点进行匹配,忽略中心模式之外的点。

例如,假设内点数据是高斯分布的,它将以稳健的方式估计内点位置和协方差(即不受异常值的影响)。从此估计获得的马哈拉诺比斯距离用于推导离群度的测量。该策略如下所示。

../_images/sphx_glr_plot_mahalanobis_distances_001.png

示例

引用

  • 尤利西斯,PJ,Van Driessen,K.“最小协方差决定性估计器的快速算法”Technographics 41(3),212(1999)

2.7.3.2. 孤立森林#

在多维数据集中执行异常值检测的一种有效方法是使用随机森林。的 ensemble.IsolationForest 通过随机选择一个特征,然后随机选择所选特征的最大值和最小值之间的拆分值来“隔离”观察结果。

由于递归分割可以用树结构表示,因此隔离样本所需的分割次数等于从根节点到终止节点的路径长度。

这个路径长度在一片此类随机树的森林中平均,是正常性的衡量标准和我们的决策函数。

随机划分会显著缩短异常路径。因此,当随机树的森林共同产生特定样本的较短路径长度时,它们极有可能是异常。

执行 ensemble.IsolationForest 是基于一系列 tree.ExtraTreeRegressor .根据Isolation Forest原始论文,每棵树的最大深度设置为 \(\lceil \log_2(n) \rceil\) 哪里 \(n\) 是用于构建树的样本数量(参见(Liu等人,2008年)了解更多详细信息)。

该算法如下所示。

../_images/sphx_glr_plot_isolation_forest_003.png

ensemble.IsolationForest 支持 warm_start=True 这允许您将更多树木添加到已安装的模型中::

>>> from sklearn.ensemble import IsolationForest
>>> import numpy as np
>>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [0, 0], [-20, 50], [3, 5]])
>>> clf = IsolationForest(n_estimators=10, warm_start=True)
>>> clf.fit(X)  # fit 10 trees
>>> clf.set_params(n_estimators=20)  # add 10 more trees
>>> clf.fit(X)  # fit the added trees

示例

引用

  • 刘、飞托尼、丁、启明和周志华。“隔离森林。数据挖掘,2008年。ICDM'08。第八届IEEE国际会议。

2.7.3.3. 局部离群因子#

对中等维度数据集执行异常值检测的另一种有效方法是使用局部异常值因子(LOF)算法。

neighbors.LocalOutlierFactor (LOF)算法计算反映观察异常程度的分数(称为局部异常值因子)。它测量给定数据点相对于其邻居的局部密度偏差。其想法是检测密度远低于邻居的样本。

实际上,局部密度是从k近邻获得的。观察的LOF分数等于其k近邻的平均局部密度与其自身局部密度的比率:正常实例预计具有与其邻居相似的局部密度,而异常数据预计具有小得多的局部密度。

考虑的邻居数量k,(别名参数 n_neighbors )通常选择1)大于集群必须包含的对象的最小数量,以便其他对象可能是相对于此集群的局部异常值,以及2)小于可能是局部异常值的附近对象的最大数量。在实践中,此类信息通常是不可用的,并且采取 n_neighbors=20 似乎在一般情况下运作良好。当异常值的比例很高时(即大于10%,如下面的例子所示), n_neighbors 应当加强 (n_neighbors=35 在下面的例子中)。

LOF算法的优势在于它同时考虑了数据集的局部和全局属性:即使在异常样本具有不同基础密度的数据集中,它也可以表现良好。问题不在于样本的隔离程度如何,而在于它与周围社区的隔离程度如何。

When applying LOF for outlier detection, there are no predict, decision_function and score_samples methods but only a fit_predict method. The scores of abnormality of the training samples are accessible through the negative_outlier_factor_ attribute. Note that predict, decision_function and score_samples can be used on new unseen data when LOF is applied for novelty detection, i.e. when the novelty parameter is set to True, but the result of predict may differ from that of fit_predict. See 利用本地异常值因子进行新颖性检测.

该策略如下所示。

../_images/sphx_glr_plot_lof_outlier_detection_001.png

示例

引用

2.7.4. 利用本地异常值因子进行新颖性检测#

使用 neighbors.LocalOutlierFactor 对于新颖性检测,即预测标签或计算新的未见数据的异常性分数,您需要用 novelty 参数设置为 True 在匹配估计器之前::

lof = LocalOutlierFactor(novelty=True)
lof.fit(X_train)

注意 fit_predict 在这种情况下不可用,以避免不一致。

警告

Novelty detection with Local Outlier Factor

novelty 设置为 True 请注意您只能使用 predict , decision_functionscore_samples 基于新的未见数据,而不是训练样本,因为这会导致错误的结果。即,的结果 predict 不会和 fit_predict .训练样本的异常评分始终可以通过 negative_outlier_factor_ 属性

使用本地异常值因子进行新颖性检测如下所示。

../_images/sphx_glr_plot_lof_novelty_detection_001.png