Press "Enter" to skip to content

使用多变量高斯分布进行异常检测的基础知识

异常检测概述,多元高斯分布回顾以及在Python中实现基本异常检测算法的两个示例

我们天生具备识别模式的能力,这使得我们能够利用这种技能来填补空缺或者预测接下来会发生的事情。然而,偶尔会发生一些不符合我们期望且不符合我们对模式的感知的事件。我们称这样的事件为异常。如果我们正在尝试预测某件事情,我们可能希望从我们的训练数据中排除异常。或者也许我们希望识别异常以帮助改善我们的生活。无论哪种情况,异常检测技术在大多数行业和领域都可以证明是有用和适用的。

本文将指导您了解异常检测的基础知识以及实现统计异常检测模型。

什么是异常检测?

一般来说,异常检测是指识别超出正常范围的现象的过程。异常检测的目标是识别与我们的期望不符且不符合某种潜在模式的事件、发生、数据点或结果。因此,实现异常检测的关键是了解预期事件的潜在模式。如果我们知道预期的模式,我们可以使用它来映射前所未见的数据点;如果我们的映射不成功,并且我们的新数据点落在我们预期的模式之外,那么很可能我们已经找到了异常。

通常会发生三种类型的异常。第一种类型包括在整个数据集中被认为是异常的个别实例(例如,高速公路上行驶的一辆汽车以非常低的速度行驶,与所有高速公路交通相比是异常的)。第二种类型包括在特定上下文中是异常的实例(例如,与所有信用卡交易相比看起来还好,但与特定个体的消费模式相比是异常的信用卡交易)。第三种类型的异常是集体的 – 即使每个实例本身都符合某种期望,但一组实例可能被认为是异常的(例如,在亚马逊上的单笔欺诈信用卡交易可能看起来并不寻常,但在短时间内连续发生的一组交易是可疑的)[1]。

异常检测技术分为三类:

  1. 有监督检测需要数据集中的正常和异常标签。可以应用有监督学习算法(如神经网络或提升森林)将数据点分类为预期/异常类别。不幸的是,异常数据集往往非常不平衡,通常没有足够的训练样本来允许上采样或下采样技术辅助有监督学习。
  2. 半监督检测处理部分标记的数据。半监督技术假设输入数据仅包含正实例,并且输入数据遵循预期模式。这些技术试图学习正例的分布,以便能够生成正实例。在测试过程中,该算法将评估异常实例可能由模型生成的概率,并使用此概率来预测异常情况。[2]
  3. 无监督检测使用完全未标记的数据来创建期望的边界,任何落在此边界之外的都被视为异常。

异常检测技术可以应用于任何数据,数据格式会影响哪种算法最有用。数据类型包括序列(时间序列、链表、语言、声音)、表格(例如,引擎传感器数据)、图像(例如,X射线图像)和图形(例如,工作流程或过程)。

在胸部X射线图像中检测异常的示例 [4]

由于问题和技术的多样性,异常检测实际上是数据科学中的一个广阔领域,具有许多应用。其中一些应用包括:欺诈检测、网络安全应用、销售或交易数据分析、罕见疾病的识别、制造过程监控、外行星搜索、机器学习预处理等等。因此,获得强大且高性能的算法有潜力在许多领域产生重大影响。

让我们来看看最基本的用于检测异常的算法。

高斯分布用于异常检测

基本的异常检测技术之一是利用高斯(即正态)分布的能力来识别异常值。

高斯分布由卡尔·弗里德里希·高斯发现,它模拟了许多自然现象,因此在对数据集的特征建模时是一个常用选择。该分布的概率密度函数是一个以算术平均值为中心的钟形曲线,曲线的宽度由数据集的方差定义。由于大多数情况都在中心附近,概率密度函数的两端呈现出两个延长的尾巴。实例越稀有——离中心越远——越有可能是异常值或异常。我们可以利用这个概念来对数据集中的异常进行建模。

概率密度函数定义为 f(x),用于衡量数据集中某个结果 x 的概率。形式上,:

使用多变量高斯分布进行异常检测的基础知识 四海 第2张

假设我们的数据集只有一个特征,并且该特征遵循正态分布,那么我们可以使用上述的 f(x) 来建立我们的异常检测算法。然后,我们可以设置一些阈值 epsilon,用于确定一个案例是否是异常值。阈值 epsilon 应该根据使用情况和对异常的偏好进行启发式设置。

Graph depicting Normal Distribution [5]

在正态分布中,有 2.5% 的实例出现在均值的两个标准差以下。因此,如果我们将阈值设置为 0.054,那么我们数据集中约有 2.5% 的事件将被分类为异常值(2个标准差以下的累积分布函数为2.5,-2处的概率密度函数为0.054)。较低的阈值将导致较少的异常值被分类,而较高的阈值将导致较低的敏感性。

在现实世界中,可能存在一种权衡,因为一些正例可能低于阈值,而一些异常值可能高于阈值。在确定最适合的阈值之前,有必要了解使用情况并测试不同的 epsilon 值。

如果我们有多个特征,那么一个单特征的例子是简单的 —— 如果特征完全独立,我们实际上可以取特征概率密度函数的乘积来分类异常值。

使用多变量高斯分布进行异常检测的基础知识 四海 第4张

对于两个不相关的特征的情况,这变为:

使用多变量高斯分布进行异常检测的基础知识 四海 第5张

实质上,特征概率的乘积可以确保如果至少一个特征具有异常值,我们可以检测到异常值(在我们的 epsilon 足够高的情况下);如果我们的实例在多个特征中都具有异常值,我们的概率将更小(因为我们的总概率值是分数的乘积),该值更有可能是异常值。

然而,我们不能假设我们的特征是独立的。这就是多元概率密度函数的作用。在多元情况下,我们构建一个协方差矩阵(用 Σ 表示)来捕捉特征之间的关系。然后,我们可以使用协方差矩阵来避免“重复计算”特征之间的关系(这是一种非常简单的说法,实际上发生的情况更加复杂)。多元分布的概率密度函数公式如下所示,杜克大学的这些幻灯片对公式的推导做得很好。

使用多变量高斯分布进行异常检测的基础知识 四海 第6张

这里,x 是一个输入向量,μ 是特征均值向量,Σ 是特征之间的协方差矩阵。

为了简化我们的生活,我们可以使用 scipy 库来实现这个函数:scipy.stats.multivariate_normal 接受特征均值和标准差的向量作为输入,并具有 .pdf 方法来返回给定一组点的概率密度。

让我们在一个实际例子中尝试这个实现。

Python中的双特征模型实现

首先,让我们观察一个双特征的例子,这将使我们能够在欧几里得空间中可视化异常值。对于这个例子,我使用从正态分布中抽取的100个样本生成了两个特征(这些是正样本)。我计算了特征的均值和标准差,并使用scipy.stats库中的多元正态模型拟合了分布信息。需要注意的是:我只用正样本来拟合我的模型。在实际数据中,我们希望清理我们的数据集,确保特征遵循正态分布,不包含异常值或奇怪的值——这将提高模型定位异常值的能力(特别是因为它将有助于确保特征的正态分布要求)。最后,我在数据集中添加了5个异常样本,并使用.pdf方法报告概率。

下面的散点图显示了结果:x1特征绘制在x轴上,x2特征绘制在y轴上,异常值被注释,颜色代表多元概率密度函数的概率。

显示正样本和异常点的散点图[5]

一旦我们将阈值设置得足够低,我们就能够区分异常值和预期值。下面的两个图表比较了1×10^-7和1×10^-9之间的epsilon值。epsilon值为1×10^-9更能够捕捉到我们预期的异常值,而1×10^-7将一些正样本标识为异常值。

高和低epsilon值的识别异常值的散点图比较[5]

在这个例子中,很容易确定epsilon值,因为我们可以通过可视化表示和识别异常值并分析我们的结果。让我们看看在一个具有更多特征的例子中,这种情况会如何改变。

Python中的多元模型实现

对于这个例子,我将使用ODDS库中的葡萄酒数据集[3]。这个数据集包含13个数值特征和129个实例。这些特征捕捉了关于葡萄酒的信息,原始数据集用于基于葡萄酒分析的分类任务。为了进行异常检测,其中一个目标类别被下采样并作为异常值呈现。在129个实例中,总共有10个异常值(约8%)。我们使用的是一个相当干净的数据集,没有缺失值。

我们必须做的第一件事是确保我们的特征遵循高斯分布。在可能的情况下,我们应该去除异常值,并使用一种归一化策略将分布归一化。在这个数据集中,4个特征已经遵循正态分布(酒精、灰分、灰分碱度和非黄烷酚类酚)。还有4个特征可以通过取对数来归一化(总类酚、原花青素、颜色强度和色调)。虽然对于剩余的特征存在更好的策略,但为了这个例子的目的,我简单地从训练数据集中删除了它们。最后,我通过排除所有包含至少一个特征值在均值加减2个标准差之外的行来除去异常值。代码的其余部分与上面的例子相同。

与上述部分的双特征例子不同,不再可行在二维平面上可视化结果,但我们可以使用混淆矩阵指标(包括召回率和精确率)和ROC曲线下面积来帮助我们找到正确的epsilon值。

由于精确率和召回率之间通常存在着权衡,epsilon的设置取决于我们用例的敏感性要求。对于这个例子,我寻找最大化曲线下面积的epsilon。有些用例可能需要尽可能多地找到异常值(以包括正值为代价),而其他用例可能只在绝对确定的情况下检测到异常值(以漏掉一些异常值为代价)。我计算了几个不同epsilon值的评估指标。

通过epsilon值比较评估指标的线图[5]

随着epsilon的增加,召回率也增加。在所提出的epsilon值范围内,精确度相对较低,但在大约0.0035和0.0065附近达到峰值。AUC试图在精确度和召回率之间取得平衡,在大约0.0065附近达到峰值。让我们来看一下混淆矩阵。

表格描述混淆矩阵[5]

我们的模型在找到所有异常值方面表现得非常好,只错过了一个。考虑到我排除了三分之一的特征,这是一个很棒的结果。不幸的是,我们的模型还将40个正例识别为异常值,这意味着如果我们将该模型用于异常检测,我们将不得不手动检查一半的正例,以确定它们是否真的异常。

为了改进这个模型,我们可以进一步设计剩余的特征,并找到一个对异常值不太敏感的epsilon值。这个问题的其余部分是微不足道的,留给读者自己去解决。你可以在这里找到源代码。

Gaussian异常检测的潜在缺陷

多元高斯分布是一种用于异常检测的优秀模型——它简单、快速且易于执行。然而,它的缺点可能会阻止它在许多用例中的应用。

首先,多元分布可能会产生相当低的概率密度值。一般来说,现代计算机处理这个问题不是什么问题。但在某些情况下,这些值可能太低,以至于计算机无法有效处理。

其次,我们必须确保我们的特征遵循正态分布。如果花费时间和精力进行正确的特征工程和数据操作,这可能不是一个太大的问题,但投入工作是有风险的,因为在我们完成工作之前,我们不会知道回报。

第三,这个模型不能处理分类特征,如果我们的数据集包含分类特征,我们必须为每个分类特征的组合创建一个单独的模型(这可能需要很多工作)。

最后,该模型假设所有特征具有相同的相关性,并且特征之间没有复杂的关系。解决这个问题的一个方法是从头开始实现多元分布的概率密度函数,并包含一些参数来帮助处理特征的重要性。为了解决特征之间的关系问题,我们可以进行更多的特征工程和创建新的特征,但这个过程可能会很困难、耗时并且有风险(从回报的角度来看)。

尽管如此,对于表格异常检测问题,使用多元高斯分布是一个很好的第一步。它可以用于建立基准,或者被证明是一个在数据集中捕捉异常的完美工具,并为我们提供了一种直观的理解异常检测的方式。

感谢阅读!在不久的将来,我希望能够对异常检测进行一个完整的系列报道,所以如果你对这个主题感兴趣,请继续关注。

参考资料:

  1. https://www.kaggle.com/code/matheusfacure/semi-supervised-anomaly-detection-survey
  2. https://ai.googleblog.com/2023/02/unsupervised-and-semi-supervised.html
  3. Saket Sathe和Charu C. Aggarwal. LODES: Local Density meets Spectral Outlier Detection. SIAM Conference on Data Mining, 2016.
  4. Nakao, T., Hanaoka, S., Nomura, Y. et al. Unsupervised Deep Anomaly Detection in Chest Radiographs. J Digit Imaging 34 , 418–427 (2021). https://doi.org/10.1007/s10278-020-00413-2
  5. https://github.com/viyaleta/Anomaly-Detection/blob/main/Examples/1%20Anomaly%20Detection%20with%20Guassian%20Distribution.ipynb

数学排版由Codecogs在线LaTeX编辑器提供。

包含示例的Jupyter Notebook可以在这里找到。

Leave a Reply

Your email address will not be published. Required fields are marked *