异常检测的阈值,你怎么选?给你整理好了...

异常值是指距离其他观测值非常遥远的点,但是我们应该如何度量这个距离的长度呢?同时异常值也可以被视为出现概率非常小的观测值,但是这也面临同样的问题——我们要如何度量这个概率的大小呢?


有许多用来识别异常值的参数和非参数方法,参数方法需要一些关于变量分布情况的假设条件,而非参数方法并不需要这些假设条件。此外,你还可以利用单变量分析和多变量分析的方法来识别异常值。


那么问题来了,哪个方法得到的结果才是正确的呢?不幸的是,实际上并不存在唯一的标准答案,结果的正确与否取决于你识别这些异常值的目的。你可能想要单独分析某个变量的情况,或者想利用这些变量构建预测模型。


让我们采用更直观的方法来识别异常值吧。


假设存在一个关于移动应用程序的数据集,其中包括操作系统、用户收入和设备情况三个变量,如下图所示:


640?wx_fmt=jpeg


我们应该如何识别出收入变量的异常值呢?


接下来我将尝试利用参数和非参数方法来检测异常值。


参数方法


640?wx_fmt=jpeg


如上图所示,x轴中的变量是收入,y轴代表收入值对应的概率密度值。图中粉色部分代表真实的样本数据,绿色部分表示正态分布数据,蓝色部分代表对数正态分布数据。其中正态分布和对数正态分布数据与实际样本数据具有相同的均值和方差。


我们可以通过计算观测值出现的概率或者计算观测值与均值之间的距离来判断异常值的情况。比如,正态分布情况下位于距均值三倍标准差范围外的观测值被视为异常值。


上述的例子中,如果我们假设原始数据服从正态分布,那么收入大于60,000元的数据都被视为异常值。从右图中可以看出,对数正态分布能更好地识别出真实的异常值,这是因为原始数据的分布近似于服从对数正态分布。但这并不是一个通用的方法,因为我们很难事先判断出数据潜在的分布情况。我们可以通过数据的拟合曲线来判断参数情况,但是如果原始的数据发生了变化,那么分布的参数也会随之发生改变。


640?wx_fmt=jpeg


上图展示了概率密度函数如何随参数的变化而发生改变,我们可以很明显地看出参数的变化会影响异常值的识别过程。


非参数方法


首先让我们来看一个识别异常值的简单的非参数方法——箱线图:

640?wx_fmt=jpeg


如上图所示,我们可以看出数据中存在 7 个显著的异常值(绿色标记的数据)。更多关于箱线图的内容请参考这篇文章。


上文提到的数据集中还存在一个分类变量——操作系统。如果我们根据操作系统将数据分组并绘制箱线图,那么我们是否能够识别出相同的异常值呢?


640?wx_fmt=jpeg


上图中,我们采用了多变量分析的方法。从图中我们可以看出,IOS 组中存在 3 个异常值,而安卓组则没有检测出异常值。这是因为安卓用户和 IOS 用户的收入分布情况不一致,所以如果只利用单变量分析方法的话,我们将会错误地识别出异常值。


结论


我们可以利用基于数据潜在分布情况的参数和非参数方法来检测异常值。在样本数据的均值十分贴近于分布函数的中心且数据集足够大的情况下,我们可以利用参数方法来识别异常值。如果中位数比均值更贴近于数据的分布中心,那么我们应该利用非参数的方法来识别异常值。


接下来我们将介绍如何利用聚类方法识别多变量情形中的异常值。


顾名思义,聚类方法就是将特征相似的样本聚集在同一个类别中,因此样本间的相似性是一个非常重要的概念,我们需要考虑如何量化样本间的相似情况。通常情况下,我们用样本之间的距离远近来衡量其相似度,不同的聚类方法采用不同的距离测度方式来实现聚类的目标。我们应该着重关注一个被广泛使用的聚类方法——K均值聚类算法。


K均值聚类算法主要是基于两两样本之间的欧式距离,欧式距离是两点之间的直线距离。我们还可以采用其他方法——比如马氏距离,闵式距离和切比雪夫距离——来度量样板间的相似性,但是这些方法的缺点是计算量大、收敛速度较慢。


给定一组样本x1,x2,…,xn,其中每个观测值都是一个d维的向量,K均值算法的目标是在最小化类内离差的前提下将这n个观测值分成 k(<=n) 组(S={S1,S2,…,Sk})。换句话说,该算法的目标函数如下所示:


640?wx_fmt=png


其中μi表示第 i 组样本的均值。


借助上面这个目标函数,我们可以更加直观地介绍K均值算法的计算过程。


K均值算法的基本步骤


步骤一:聚类数目


选择类别数目k。这是一个循环迭代的过程,我们无法提前知道应该选择聚成几个类别。我们将用一个例子来说明如何选择类别数目。


步骤二:聚类中心


从样本中随机抽取出k个点,并将其定义为k个组的中心。


步骤三:计算距离


分别计算所有观测值到聚类中心的欧式距离,并将其归到距离最近的中心类别中。假设我们有一个包含100个观测值的数据集,我们的目标是将其聚成5类。首先我们需要计算每个观测值到5个中心点的距离,然后从5个距离中筛选出距离最小值,并将该样本归到对应的类别中。


步骤四:重新计算类中心


接下来我们需要重新计算各个类别的中心值。某个类的中心值等于该类别中所有样本点的均值。因此,如果某个类别中的样本点由于步骤三的计算导致了重分配,那么相应的类中心也会随之改变。


步骤五:迭代过程


重复步骤三和步骤四直到类别中心不再改变为止。


640?wx_fmt=jpeg


拟合K均值算法前需要记住一个要点——对变量进行标准化处理。比如,你的数据集中包含年龄、身高、体重、收入等无法直接比拟的变量,我们需要将其标准化到同一量纲中。如果数据集中的变量单位一致但方差不同,我们也需要事先将其标准化。数据集中的变量方差不相等,这相当于对方差小的变量赋予了一个更大的权重,因此该算法倾向于对方差大的变量进行划分。标准化处理可以保证K均值算法同等对待所有的变量。一个常用的标准化方法是——所有的观测值减去均值然后除以标准差。


接下来,让我们利用K均值聚类算法来识别数据集中的异常值。假设数据集中某一个类别的特征完全不同于其他类别,如下表所示:


640?wx_fmt=jpeg


上表是某个 app 的部分用户数据。表中有 5 个变量,其中 3 个数值变量,2 个分类变量。分析过程中,我们将忽略第一列变量。通常情况下,我们将 OS 变量中的 Android 赋值为 0,iOS 赋值为1。但是从理论上来说,我们并不建议这样做,因为拟合K均值模型需要计算样本之间的欧式距离,我们无法很好地量化 Android 用户和 iOS 用户之间的距离。


举个例子,如果点 A 和点 B 之间的欧式距离等于 30,点 A 和点 C 之间的欧式距离等于 8,那么我们可以推出点 A 和点 C 更相似。但分类变量不是由数值构成的,而是由枚举的方式展现出来,比如“香蕉”、“苹果”和“橙子”,我们无法计算这些水果之间的欧式距离,所以我们无法判断橙子和香蕉哪个与苹果更相近。基于这个原因,我们应该采用K众数算法来处理分类变量问题,而不是K均值算法。


获取聚类数目是一个反复迭代的过程。为了获取最佳类别数目,我们可以尝试对所有的样本分别拟合 2-20 个类别的模型,然后通过评估统计量的表现情况来选取最佳类别数目。作为一名分析师,拟合多少个类别的模型都是由你决定的。但需要注意的是,你必须在建模前标准化处理数据。


我们可以利用一些统计量来评估最佳类别数目,比如类内平方和,类间平方和,方差贡献比和统计差异值。本文中主要采用类内平方和来选择最佳类别数目。


类内平方和(wss)


类内平方和主要反映同一类别中样本的同质性,该统计量通过计算类中所有点与类中心之间的距离平方和来刻画聚类效果。加总所有类的类内平方和得到所有样本的总离差平方和(Total wss)。


上述指标是个相对指标而不是绝对指标,也就是说我们需要结合类别数目来进一步判断最佳类别数目。如果我们的最佳类别数目在 2 和 20 之间,那么我们倾向于选择具有最小 twss 的类别数目。


640?wx_fmt=jpeg


上图展现了 twss 随类别数目变化的趋势图,从图中可以看出:当类别数目大于4时,twss的下降率大大降低。理论上来说,你会倾向于选择最小twss所对应的类别数目,但在实际应用中这并不是一个好的方案;虽然将样本聚成 19 类时具有最小的 twss,但是分析这么多类的数据非常麻烦,我们无法达到聚类的基本要求——类内差异小,类间差异大。综合多方面信息,本例中我们应该选择的最佳类别数目为 4。你甚至可以比较不同类别数目模型之间的差异,然后再选取出最佳类别数目。




640?wx_fmt=jpeg


上图中不同颜色的点代表不同类别中的样本。其中第 4 类不同于其他三个类,它的标记颜色为蓝色。


聚类特征


640?wx_fmt=jpeg


上表给出了每个类别中观测值的数量,其中类别 4 占比最小,仅为 3.7%。


接下来让我们看看每个类别各自的一些特征:


640?wx_fmt=jpeg


上表不仅给出了每个类别中各个变量的均值以及样本的总体均值和标准差,同时还提供了一个用于衡量类均值与总体均值之间差异的统计量 Z-score:


640?wx_fmt=png

其中μ代表总体均值,σ代表总体标准差。


对每个数值型变量来说,标准差越小,对应的 Z-score 越大。Z-score 的符号代表类均值高于或低于总体均值。


第 4 类的变量值与其他三个类别相差甚远,比如较低的样本个数,较高的访问量、交易值和 Z-score。


让我们也来看看不同类别中分类变量 OS 的差异情况:


640?wx_fmt=jpeg


从上表中可以看出,第 4 类中 iOS用户的比例远高于其他三组,因此我们可以认为第 4 类为异常值。作为一名分析师,我们需要进一步探索第 4 类的详细情况,以便于更好地了解异常值的情况。


总之,我们可以利用聚类方法来识别多变量情形中的异常值。除了K均值算法外还有许多聚类算法可以用于检测异常值,但这些已经超出了本文的讨论范围。

640?wx_fmt=png

<think>好的,我现在需要帮助用户了解如何使用支持向量机(SVM)进行数据异常检测。首先,我得回顾一下SVM的基本原理,因为异常检测通常是基于分类或离群点检测的方法。SVM本身主要是用于分类任务,但如何应用到异常检测呢? 根据用户提供的引用,特别是引用[1]和[2],SVM的核心是找到一个超平面来最大化间隔,而核函数可以将数据映射到高维空间处理非线性问题。那异常检测可能和一分类SVM有关,或者使用支持向量数据描述(SVDD)?我需要确认这些方法。 首先,SVM在异常检测中的常见方法可能包括One-Class SVM,这是专门用于无监督异常检测的。它的原理是找到一个能够包含大部分正常数据的区域,而将边界的点视为异常。这需要用到核函数,如引用[2]提到的核技巧,处理非线性数据。 接下来,我需要整理步骤:数据预处理、模型选择、核函数调参、训练模型、异常判定。对于案例,可以引用用户提到的Scikit-learn库,因为引用[3]中有使用该库的示例。例如,使用OneClassSVM类,对合成数据进行训练,然后预测异常点。 然后,注意事项部分需要提到特征标准化,因为SVM对尺度敏感;样本不平衡可能需要调整nu参数;核函数的选择影响结果,比如RBF核适合非线性情况。这些点需要结合引用中的信息,确保正确性。 关于应用场景,可以举网络入侵检测、工业质检、金融欺诈等,这些都是常见的异常检测场景,用户可能感兴趣的实际例子。 可能还需要考虑如何评估模型效果,比如使用准确率、召回率等指标,但异常检测中常用F1分数或AUC,不过用户的问题可能更关注方法和案例,所以这部分可能不需要深入,除非用户后续提问。 现在,我需要验证这些思路是否正确。例如,One-Class SVM是否属于SVM的应用之一?是的,Scikit-learn中的确有此实现。另外,SVDD是另一种方法,但用户可能更熟悉One-Class SVM,所以重点放在这里。 然后,代码示例部分需要展示如何用Python实现,使用合成数据,预处理,训练模型,预测,并可视化结果。这能帮助用户直观理解。需要注意代码中的关键参数,比如kernel='rbf',nu=0.05等,解释它们的作用。 最后,生成相关问题需要考虑用户可能的后续疑问,比如参数调优、与其他算法比较、处理高维数据等。这些问题应基于当前回答的内容,引导用户进一步学习。 总结一下,我需要分步骤解释方法,提供案例代码,注意事项,应用场景,并生成相关问题。确保引用正确,比如引用[2]提到核函数的作用,引用[3]中的代码实例,但用户的问题是关于异常检测,所以可能需要调整引用部分,确保相关性。</think>### 使用支持向量机(SVM)进行数据异常检测的方法 #### 1. **核心原理** - **SVM异常检测**通常基于**One-Class SVM**(一分类支持向量机),其目标是找到一个超平面,将**正常数据**尽可能包含在高维空间的一个紧凑区域中,而将偏离该区域的样本视为异常[^1][^2]。 - 通过核函数(如RBF核)将数据映射到高维空间,解决非线性可分问题,增强对复杂数据分布的拟合能力。 #### 2. **实施步骤** 1. **数据预处理**:标准化或归一化数据(SVM对特征尺度敏感)。 2. **模型选择**:使用`OneClassSVM`(Scikit-learn实现),设定核函数和参数。 3. **训练模型**:仅用正常数据训练模型,学习正常数据的分布边界。 4. **异常判定**:通过`decision_function`或`predict`输出样本的异常得分,得分低于阈值的判为异常。 #### 3. **案例:工业质检异常检测** **代码示例**: ```python from sklearn.svm import OneClassSVM from sklearn.datasets import make_blobs import matplotlib.pyplot as plt import numpy as np # 生成合成数据(正常样本+少量异常) X, _ = make_blobs(n_samples=300, centers=1, cluster_std=0.5, random_state=42) X_outliers = np.random.uniform(low=-6, high=6, size=(20, 2)) X_total = np.vstack([X, X_outliers]) # 训练One-Class SVM model = OneClassSVM(kernel='rbf', nu=0.05) # nu控制异常点比例上限 model.fit(X_total) y_pred = model.predict(X_total) # 异常点返回-1 # 可视化结果 plt.scatter(X_total[:,0], X_total[:,1], c=y_pred, cmap='coolwarm') plt.title('One-Class SVM异常检测结果') plt.show() ``` #### 4. **关键参数与调优** - **`nu`**:控制异常点比例上限(取值0.01~0.5),值越小对异常越敏感。 - **`kernel`**:选择核函数(如`rbf`、`poly`),需通过交叉验证调整`gamma`或`degree`参数[^2]。 #### 5. **注意事项** - **特征工程**:需结合领域知识选择与异常相关的特征。 - **样本不平衡**:若异常样本极少,可结合过采样或半监督方法。 - **结果解释**:需结合实际场景分析异常原因,避免误判。 #### 6. **应用场景** - **网络入侵检测**:识别流量中的异常行为[^3]。 - **金融欺诈检测**:发现信用卡异常交易。 - **工业设备监控**:预测机械故障前的异常信号。 --- ###
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值