Scikit Learn 异常检测
在这里,我们将了解什么是 Sklearn 中的异常检测以及如何使用它来识别数据点。
异常检测是一种用于识别数据集中与其余数据不匹配的数据点的技术。它在商业中有许多应用,例如欺诈检测、入侵检测、系统健康监控、监视和预测性维护。异常,也称为异常值,可分为以下三类:
点异常: 当单个数据实例被认为与其余数据异常时,就会发生这种情况。
上下文异常: 这种异常是上下文特定的。如果数据实例在特定上下文中异常,则会发生这种情况。
集合异常: 当相关数据实例的集合与整个数据集而不是单个值异常时,就会发生这种情况。
方法
两种方法即异常检测和新奇检测可用于异常检测,下面看到它们之间的区别。
异常值检测
训练数据包含与其余数据相去甚远的异常值,此类异常值被定义为观测值,这就是为什么异常检测估计器总是试图拟合训练数据最集中的区域,而忽略异常观察,它也被称为无监督异常检测。
新奇检测
它涉及在未包含在训练数据中的新观察中检测未观察到的模式,在这里,训练数据没有被异常值污染,它也被称为半监督异常检测。
scikit-learn 提供了一组 ML 工具,可用于异常值检测和新颖性检测,这些工具首先通过使用 fit() 方法在无监督中从数据中实现对象学习,如下所示:
estimator.fit(X_train)
现在,通过使用predict()方法,新的观察值将被排序为异常值(标记为1) 或 离群值(标记为-1),如下所示:
estimator.fit(X_test)
估算器将首先计算出原始评分函数,然后预测方法将利用该原始评分函数的阈值。我们可以在score_sample方法的帮助下访问这个原始评分函数,并可以通过 contamination 参数控制阈值。
我们还可以定义decision_function方法,将异常值定义为负值,将异常值定义为非负值。
estimator.decision_function(X_test)
用于异常值检测的 Sklearn 算法
让我们首先了解什么是椭圆包络。
拟合椭圆包络
这个算法假设常规数据来自一个已知的分布,如高斯分布。对于离群点检测,Scikit-learn提供了一个名为covariance.EllipticEnvelop的对象。
该对象对数据进行了稳健的协方差估计,因此将椭圆拟合到中心数据点,它忽略中心模式之外的点。
参数
下表是sklearn.covariance.EllipticEnvelop方法使用的参数:
序号 | 参数及说明 |
---|---|
1 | store_precision: bool,optional,默认 = True 如果存储了估计的精度,我们可以指定它。 |
2 | assume_centered: bool,optional,默认 = False 如果我们将其设置为 False,它将直接借助 FastMCD 算法计算鲁棒位置和协方差。另一方面,如果设置为 True,它将计算稳健位置和协方差的支持。 |
3 | support_fraction: float in (0., 1.), optional,默认= None 该参数告诉方法在原始 MCD 估计的支持中要包含多少点比例。 |
4 | contamination: float in (0., 1.), optional,默认= 0.1 它提供了数据集中异常值的比例。 |
5 | random_state: int, RandomState instance或None,可选,默认= none 此参数表示在混洗数据时使用的生成的伪随机数的种子。以下是选项:
|
属性
下表由sklearn.covariance.EllipticEnvelop方法使用的属性:
序号 | 属性和描述 |
---|---|
1 | support_: array-like,形状(n_samples,) 它表示用于计算位置和形状的稳健估计的观察掩码。 |
2 | location_:array-like,形状(n_features) 它返回估计的稳健位置。 |
3 | covariance_:array-like,形状(n_features, n_features) 它返回估计的稳健协方差矩阵。 |
4 | precision_:array-like,形状(n_features, n_features) 它返回估计的伪逆矩阵。 |
5 | offset_: float 它用于根据原始分数定义决策函数,decision_function = score_samples -offset_ |
示例
import numpy as np^M from sklearn.covariance import EllipticEnvelope^M true_cov = np.array([[.5, .6],[.6, .4]]) X = np.random.RandomState(0).multivariate_normal(mean = [0, 0], cov=true_cov,size=500) cov = EllipticEnvelope(random_state = 0).fit(X)^M # Now we can use predict method. It will return 1 for an inlier and -1 for an outlier. cov.predict([[0, 0],[2, 2]])
array([ 1, -1])
隔离林
在高维数据集的情况下,检测离群点的一个有效方法是使用随机森林。scikit-learn提供了ensemble.IsolationForest方法,它通过随机选择一个特征来隔离观测值。之后,它在所选特征的最大值和最小值之间随机选择一个值。
这里,隔离样本所需的分裂次数等于从根节点到终止节点的路径长度。
参数
下表是sklearn.ensemble.IsolationForest方法使用的参数:
序号 | 参数及说明 |
---|---|
1 | n_estimators: int, optional, 默认= 100 它表示集成中基估计器的数量。 |
2 | max_samples: int 或 float,optional,默认 = “auto” 它表示要从 X 中抽取以训练每个基估计器的样本数。如果我们选择 int 作为它的值,它将绘制 max_samples 个样本。如果我们选择 float 作为其值,它将绘制 max_samples ∗ ?.shape[0] 样本。而且,如果我们选择 auto 作为其值,它将绘制 max_samples = min(256,n_samples)。 |
3 | support_fraction: float in (0., 1.), optional,默认= None 该参数告诉方法在原始 MCD 估计的支持中要包含多少点比例。 |
4 | contamination: auto 或 float,optional,默认 = auto 它提供了数据集中异常值的比例。如果我们将其设置为默认值,即自动,它将确定原始论文中的阈值。如果设置为浮动,则污染范围将在 [0,0.5] 范围内。 |
5 | random_state: int, RandomState instance或None,optional,默认= none 此参数表示在混洗数据时使用的生成的伪随机数的种子。以下是选项:
|
6 | max_features: int 或 float,optional,默认 = 1.0 它表示要从 X 中提取以训练每个基本估计器的特征数量。如果我们选择 int 作为它的值,它将绘制 max_features 个特征。如果我们选择 float 作为其值,它将绘制 max_features * X.shape[?] 样本。 |
7 | bootstrap: bool, optional,默认 = False 它的默认选项是 False,这意味着将在没有替换的情况下执行采样。而另一方面,如果设置为 True,则意味着单个树适合用替换采样的训练数据的随机子集。 |
8 | n_jobs: int 或 None,optional,默认 = None 它表示fit()和predict()方法要并行运行的作业数量。 |
9 | verbose: int, optional,默认 = 0 此参数控制树构建过程的详细程度。 |
10 | warm_start: bool,optional,默认=False 如果warm_start = true,我们可以重用之前的调用解决方案来拟合,并且可以向集成中添加更多的估计器。但是如果设置为false,我们需要适应一个全新的森林。 |
属性
下表由sklearn.ensemble.IsolationForest方法使用的属性:
序号 | 属性和描述 |
---|---|
1 | estimators_: DecisionTreeClassifier 列表 提供所有拟合子估计量的集合。 |
2 | max_samples_: 整数 它提供了实际使用的样本数。 |
3 | offset_: float 它用于根据原始分数定义决策函数。decision_function = score_samples -offset_ |
实现示例
下面的Python脚本将使用sklearn.ensemble.IsolationForest方法,在给定的数据上拟合10棵树:
from sklearn.ensemble import IsolationForest import numpy as np X = np.array([[-1, -2], [-3, -3], [-3, -4], [0, 0], [-50, 60]]) OUTDClf = IsolationForest(n_estimators = 10) OUTDclf.fit(X)
IsolationForest( behaviour = 'old', bootstrap = False, contamination='legacy', max_features = 1.0, max_samples = 'auto', n_estimators = 10, n_jobs=None, random_state = None, verbose = 0 )
局部异常因子
局部异常因子(LOF)算法是另一种在高维数据上进行离群检测的有效算法。scikit-learn提供的 neighbors.LocalOutlierFactor 方法可以计算出一个分数,称为局部异常因子,反映了观测值的不正常程度,这个算法的主要逻辑是检测那些密度大大低于其邻居的样本,这就是为什么它测量给定数据点相对于其邻居的局部密度偏差。
参数
下表是sklearn.neighbors.LocalOutlierFactor方法使用的参数:
序号 | 参数及说明 |
---|---|
1 | n_neighbors: int,optional,默认= 20 它表示默认情况下用于 kneighbors 查询的邻居数量。如果 . |
2 | algorithm: optional 用于计算最近邻的算法:
|
3 | leaf_size: int,optional,默认= 30 该参数的值会影响构建和查询的速度。它还影响存储树所需的内存。此参数传递给 BallTree 或 KdTree 算法。 |
4 | contamination : auto 或 float,optional,默认 = auto 它提供了数据集中异常值的比例。如果我们将其设置为默认值,即自动,它将确定原始论文中的阈值。如果设置为浮动,则污染范围将在 [0,0.5] 范围内。 |
5 | metric: string 或 callable 它表示用于距离计算的度量。 |
6 | P: int, optional,默认 = 2 它是 Minkowski 度量的参数。 P=1 等效于使用 manhattan_distance 即 L1,而 P=2 等效于使用 euclidean_distance 即 L2。 |
7 | novelty: bool,默认 = False 默认情况下,LOF 算法用于离群点检测,但如果我们设置 Novelty = true,它可以用于新颖性检测。 |
8 | n_jobs: int 或 None,optional,默认 = None 它表示 fit() 和 predict() 方法并行运行的作业数量。 |
属性
下表由sklearn.neighbors.LocalOutlierFactor方法使用的属性:
序号 | 属性和描述 |
---|---|
1 | negative_outlier_factor_: numpy array,形状(n_samples,) 提供训练样本的相反 LOF。 |
2 | n_neighbors_: int 它提供用于邻居查询的实际邻居数。 |
3 | offset_: float 它用于从原始分数定义二进制标签。 |
示例
下面给出的Python脚本将使用sklearn.neighbors.LocalOutlierFactor方法,从与我们的数据集对应的任何数组中构建NeighborsClassifier类。
from sklearn.neighbors import NearestNeighbors samples = [[0., 0., 0.], [0., .5, 0.], [1., 1., .5]] LOFneigh = NearestNeighbors(n_neighbors = 1, algorithm = "ball_tree",p=1) LOFneigh.fit(samples)
NearestNeighbors( algorithm = 'ball_tree', leaf_size = 30, metric='minkowski', metric_params = None, n_jobs = None, n_neighbors = 1, p = 1, radius = 1.0 )
现在,我们可以使用以下python脚本从这个构造的分类器中询问到[0.5, 1., 1.5]的壁橱点:
print(neigh.kneighbors([[.5, 1., 1.5]])
(array([[1.7]]), array([[1]], dtype = int64))
一类SVM
Schölkopf等人提出的单类SVM是无监督的Outlier检测,它在高维数据中也非常有效,可以估计高维分布的支持度,它在支持向量机模块的Sklearn.svm.OneClassSVM对象中实现,为了定义边界,它需要一个核(主要使用RBF)和一个标量参数。
为了更好地理解,让我们用svm.OneClassSVM对象来拟合我们的数据:
from sklearn.svm import OneClassSVM X = [[0], [0.89], [0.90], [0.91], [1]] OSVMclf = OneClassSVM(gamma = 'scale').fit(X)
现在,我们可以得到输入数据的 score_samples 如下:
OSVMclf.score_samples(X)
array([1.12218594, 1.58645126, 1.58673086, 1.58645127, 1.55713767])