设为首页|收藏本站|
开启左侧

[问答] 有哪些比较好的做异常值检测的方法?

[复制链接]
42166 5
ben007 发表于 2022-8-13 15:43:40 | 只看该作者 打印 上一主题 下一主题
 
数据预处理的好坏,很大程度上决定了模型分析结果的好坏。(Garbage In  Garbage Out!)

其中,异常值(outliers)检测是整个数据预处理过程中,十分重要的一环。方法也是多种多样。比如有基于经典统计的方法——三倍于标准差之上的数据为异常值等等。

由于异常值检验,和去重、缺失值处理不同,它带有一定的主观性。所以,想请问一下各位大牛,平时你们更愿意相信哪种或哪几种异常值检测的方法。

谢谢!~


上一篇:敏感时刻,白宫官员重申美政府支持「一中政策」,「我们不 ...
下一篇:回看马航MH370事故,60多位芯片专家丧生,这是谁布下的 ...
@



1.西兔生活网 CTLIVES 内容全部来自网络;
2.版权归原网站或原作者所有;
3.内容与本站立场无关;
4.若涉及侵权或有疑义,请点击“举报”按钮,其他联系方式或无法及时处理。
 

精彩评论5

正序浏览
跳转到指定楼层
沙发
kyu_bobo 发表于 2022-8-13 15:44:10 | 只看该作者
 
lrhao:时间序列中的异常检测&孤立森林&异常可视化介绍

指标值的突然上升或下降是一种异常行为,这两种情况都需要注意。如果我们在建模之前就有异常行为的信息,那么异常检测可以通过监督学习算法来解决,但在没有反馈的情况下,最初很难识别这些点。因此,我们可以使用孤立森林(Isolation Forest)、支持向量机和LSTM等算法将其建模为一个无监督问题。下面使用孤立森林识别异常点。
# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to load in

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)

# Input data files are available in the "../input/" directory.
# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory
import warnings  
warnings.filterwarnings('ignore')
import os
print(os.listdir("../input"))

# Any results you write to the current directory are saved as output.
这里的数据是一个用例(如收益、流量等),每天有12个指标。我们必须首先确定在用例级别上是否存在异常。然后,为了获得更好的可操作性,我们深入到单个指标,并识别其中的异常情况。
df=pd.read_csv("../input/metric_data.csv")
df.head()

 第1张图片
现在在数据框中做一个透视,来创建一个数据框,在一个日期级别上包含所有指标。
metrics_df=pd.pivot_table(df,values='actuals',index='load_date',columns='metric_name')
metrics_df.head()

 第2张图片
将数据框展平,并填充nan值为0
metrics_df.reset_index(inplace=True)
metrics_df.fillna(0,inplace=True)
metrics_df.head()

 第3张图片
定义孤立森林并指定参数:
隔离森林试图分离数据中的每个点。在2D的情况下,它随机创建一条线,并试图选出一个点。在这种情况下,一个异常点只需几步就可以分离出来,而距离较近的正常点则需要相当多的步骤才能分离出来。
这里举例几个重要的参数。Contamination在这里是一个重要的参数,但是没有为它指定任何值,因为它是无监督的,我们没有关于异常值百分比的信息。
这里还可以通过在2D绘图中使用离群值验证其结果时的试错来指定它,或者如果数据是有监督的,则使用该信息来指定它,代表数据中离群点的百分比。
这里使用sklearn中自带的孤立森林,因为它是一个只有几个月数据的小数据集,而最近h2o的孤立森林也可用,它在高容量数据集上更可扩展,值得探索。
这个算法的更多细节可以参考这篇论文:https://cs.nju.edu.cn/zhouzh/zhouzh.files/publication/icdm08b.pdf
h2o孤立森林更多细节可以参考这个github链接:https://github.com/h2oai/h2o-tutorials/tree/master/tutorials/isolation-forest
metrics_df.columns

Index(['load_date', 'metric_1', 'metric_10', 'metric_11', 'metric_12',
       'metric_2', 'metric_3', 'metric_4', 'metric_5', 'metric_6', 'metric_7',
       'metric_8', 'metric_9'],
      dtype='object', name='metric_name')

#specify the 12 metrics column names to be modelled
to_model_columns=metrics_df.columns[1:13]

from sklearn.ensemble import IsolationForest
clf=IsolationForest(n_estimators=100, max_samples='auto', \
                        max_features=1.0, bootstrap=False, n_jobs=-1, random_state=42, verbose=0)
clf.fit(metrics_df[to_model_columns])

IsolationForest(behaviour='old', bootstrap=False, contamination='legacy',
        max_features=1.0, max_samples='auto', n_estimators=100, n_jobs=-1,
        random_state=42, verbose=0)

pred = clf.predict(metrics_df[to_model_columns])
metrics_df['anomaly']=pred
outliers=metrics_df.loc[metrics_df['anomaly']==-1]
outlier_index=list(outliers.index)
#print(outlier_index)
#Find the number of anomalies and normal points here points classified -1 are anomalous
print(metrics_df['anomaly'].value_counts())

1    109
-1     12
Name: anomaly, dtype: int64
/opt/conda/lib/python3.6/site-packages/sklearn/ensemble/iforest.py:417: DeprecationWarning: threshold_ attribute is deprecated in 0.20 and will be removed in 0.22.
  " be removed in 0.22.", DeprecationWarning)
现在我们有了12个指标根据孤立森林的情况对异常情况进行了分类。我们将尝试将结果可视化,并检查分类是否有意义。
将指标归一化并拟合到PCA上,以减少维数,然后以3D方式将其绘制出来,突出显示异常。
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from mpl_toolkits.mplot3d import Axes3D
pca = PCA(n_components=3)  # Reduce to k=3 dimensions
scaler = StandardScaler()
#normalize the metrics
X = scaler.fit_transform(metrics_df[to_model_columns])
X_reduce = pca.fit_transform(X)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_zlabel("x_composite_3")

# Plot the compressed data points
ax.scatter(X_reduce[:, 0], X_reduce[:, 1], zs=X_reduce[:, 2], s=4, lw=1, label="inliers",c="green")

# Plot x's for the ground truth outliers
ax.scatter(X_reduce[outlier_index,0],X_reduce[outlier_index,1], X_reduce[outlier_index,2],
           lw=2, s=60, marker="x", c="red", label="outliers")
ax.legend()
plt.show()

 第4张图片
我们可以看到3D点,异常点大多是集群正常点,但一个2D点将帮助我们更好地判断。接下来,我们试着把同样的绘制成缩小到二维的主成分分析。
from sklearn.decomposition import PCA
pca = PCA(2)
pca.fit(metrics_df[to_model_columns])


res=pd.DataFrame(pca.transform(metrics_df[to_model_columns]))

Z = np.array(res)
figsize=(12, 7)
plt.figure(figsize=figsize)
plt.title("IsolationForest")
plt.contourf( Z, cmap=plt.cm.Blues_r)

b1 = plt.scatter(res[0], res[1], c='blue',
                 s=40,label="normal points")

b1 = plt.scatter(res.iloc[outlier_index,0],res.iloc[outlier_index,1], c='red',
                 s=40,  edgecolor="red",label="predicted outliers")
plt.legend(loc="upper right")
plt.show()

 第5张图片
因此,2D绘图为我们提供了一幅清晰的画面,表明算法正确地分类了用例中的异常点。
异常用红色边缘突出显示,正常点用绿色点表示。
在这里,Contamination参数起着很大的作用。我们的想法是捕获系统中所有的异常点。因此,最好是识别几个可能是正常的异常点(假阳性),但不要错过捕捉异常点(真阴性)。(所以我指定了12%作为Contamination,这取决于具体用例)
#Installing specific version of plotly to avoid Invalid property for color error in recent version which needs change in layout
!pip install plotly==2.7.0
现在我们已经发现了用例级别的异常行为。但是,要对异常采取行动,重要的是识别并提供信息,单独说明哪些指标标准是异常的。
当业务用户可以直观地看到(突然的下降/峰值)算法识别的异常时,就可以对其采取行动。所以在这个过程中,创造一个好的视觉效果也同样重要。
这个函数在时间序列上创建实际绘图,并在其上突出显示异常点。还有一个表,它提供了实际数据、更改和基于异常的条件格式化。
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
import plotly.plotly as py
import matplotlib.pyplot as plt
from matplotlib import pyplot
import plotly.graph_objs as go
init_notebook_mode(connected=True)
def plot_anomaly(df,metric_name):
    df.load_date = pd.to_datetime(df['load_date'].astype(str), format="%Y%m%d")
    dates = df.load_date
    #identify the anomaly points and create a array of its values for plot
    bool_array = (abs(df['anomaly']) > 0)
    actuals = df["actuals"][-len(bool_array):]
    anomaly_points = bool_array * actuals
    anomaly_points[anomaly_points == 0] = np.nan
    #A dictionary for conditional format table based on anomaly
    color_map = {0: "'rgba(228, 222, 249, 0.65)'", 1: "yellow", 2: "red"}
   
    #Table which includes Date,Actuals,Change occured from previous point
    table = go.Table(
        domain=dict(x=[0, 1],
                    y=[0, 0.3]),
        columnwidth=[1, 2],
        # columnorder=[0, 1, 2,],
        header=dict(height=20,
                    values=[['<b>Date</b>'], ['<b>Actual Values </b>'], ['<b>% Change </b>'],
                            ],
                    font=dict(color=['rgb(45, 45, 45)'] * 5, size=14),
                    fill=dict(color='#d562be')),
        cells=dict(values=[df.round(3)[k].tolist() for k in ['load_date', 'actuals', 'percentage_change']],
                   line=dict(color='#506784'),
                   align=['center'] * 5,
                   font=dict(color=['rgb(40, 40, 40)'] * 5, size=12),
                   # format = [None] + [",.4f"] + [',.4f'],
                   # suffix=[None] * 4,
                   suffix=[None] + [''] + [''] + ['%'] + [''],
                   height=27,
                   fill=dict(color=[test_df['anomaly_class'].map(color_map)],#map based on anomaly level from dictionary
                   )
                   ))
    #Plot the actuals points
    Actuals = go.Scatter(name='Actuals',
                         x=dates,
                         y=df['actuals'],
                         xaxis='x1', yaxis='y1',
                         mode='line',
                         marker=dict(size=12,
                                     line=dict(width=1),
                                     color="blue"))

    #Highlight the anomaly points
    anomalies_map = go.Scatter(name="Anomaly",
                               showlegend=True,
                               x=dates,
                               y=anomaly_points,
                               mode='markers',
                               xaxis='x1',
                               yaxis='y1',
                               marker=dict(color="red",
                                           size=11,
                                           line=dict(
                                               color="red",
                                               width=2)))


    axis = dict(
        showline=True,
        zeroline=False,
        showgrid=True,
        mirror=True,
        ticklen=4,
        gridcolor='#ffffff',
        tickfont=dict(size=10))

    layout = dict(
        width=1000,
        height=865,
        autosize=False,
        title=metric_name,
        margin=dict(t=75),
        showlegend=True,
        xaxis1=dict(axis, **dict(domain=[0, 1], anchor='y1', showticklabels=True)),
        yaxis1=dict(axis, **dict(domain=[2 * 0.21 + 0.20, 1], anchor='x1', hoverformat='.2f')))

    fig = go.Figure(data=[table, anomalies_map, Actuals], layout=layout)

    iplot(fig)
    pyplot.show()
    #return res
一个helper函数来查找百分比变化,根据严重程度对异常进行分类。
预测函数根据决策函数的结果,对数据进行异常分类。如果企业需要发现下一个可能产生影响的异常,可以使用这个来识别这些点。
前12个分位数为识别异常(高严重性),根据决策函数识别12-24个分位数点,将其分类为低严重性异常。
def classify_anomalies(df,metric_name):
    df['metric_name']=metric_name
    df = df.sort_values(by='load_date', ascending=False)
    #Shift actuals by one timestamp to find the percentage chage between current and previous data point
    df['shift'] = df['actuals'].shift(-1)
    df['percentage_change'] = ((df['actuals'] - df['shift']) / df['actuals']) * 100
    #Categorise anomalies as 0-no anomaly, 1- low anomaly , 2 - high anomaly
    df['anomaly'].loc[df['anomaly'] == 1] = 0
    df['anomaly'].loc[df['anomaly'] == -1] = 2
    df['anomaly_class'] = df['anomaly']
    max_anomaly_score = df['score'].loc[df['anomaly_class'] == 2].max()
    medium_percentile = df['score'].quantile(0.24)
    df['anomaly_class'].loc[(df['score'] > max_anomaly_score) & (df['score'] <= medium_percentile)] = 1
    return df
识别单个指标的异常并绘制结果。
X轴-日期,Y轴-实际值和异常点。
指标的实际值显示在蓝线中,异常点以红点突出显示。在表中,背景红色表示高异常,黄色表示低异常。
import warnings  
warnings.filterwarnings('ignore')
for i in range(1,len(metrics_df.columns)-1):
    clf.fit(metrics_df.iloc[:,i:i+1])
    pred = clf.predict(metrics_df.iloc[:,i:i+1])
    test_df=pd.DataFrame()
    test_df['load_date']=metrics_df['load_date']
    #Find decision function to find the score and classify anomalies
    test_df['score']=clf.decision_function(metrics_df.iloc[:,i:i+1])
    test_df['actuals']=metrics_df.iloc[:,i:i+1]
    test_df['anomaly']=pred
    #Get the indexes of outliers in order to compare the metrics with use case anomalies if required
    outliers=test_df.loc[test_df['anomaly']==-1]
    outlier_index=list(outliers.index)
    test_df=classify_anomalies(test_df,metrics_df.columns)
    plot_anomaly(test_df,metrics_df.columns)

 第6张图片

 第7张图片

 第8张图片

 第9张图片

 第10张图片

 第11张图片

 第12张图片

 第13张图片

 第14张图片

 第15张图片

 第16张图片

 第17张图片
从图中,我们能够捕捉到指标的突然峰值和低谷,并将它们投射出来。
此外,条件格式的表(可以运行代码获取,这里太占用篇幅没有展现)还可以让我们了解一些情况,比如数据不存在(值为零),这可能是数据处理过程中pipeline破裂的潜在结果,需要修复,并突出显示高级别和低级别异常。
如何使用呢?


  • 如果当前时间戳对于用例来说是异常的,那么深入到指标,找出时间戳中有高度异常的指标集,以便在其上执行PCA。
  • 此外,业务用户的反馈可以更新回数据中,这将有助于将其转换为监督/半监督学习问题,并比较其结果。
  • 这里的一种增强是将不断发生的反常行为结合起来。如,大促销日(游戏绑定:可能会导致数天内的指标飙升)可以显示为单一行为。
如果这对你有用,点赞关注一键三连呀,支持我的工作。
回复 支持 反对

使用道具 举报

 
板凳
小长弓 发表于 2022-8-13 15:44:21 | 只看该作者
 
检测异常值的方法有很多,选择哪种方法需要具体问题具体分析,下面罗列一些常用的方法。


统计学方法:

1、  一维数据的异常值检测

假设我们的数据(一维)服从正态分布,我们可以通过极大似然法估计出均值$\mu$ 和标准差$\sigma$,然后根据$3\sigma$准则:有99.7%的数据会落入区域$\mu\pm3\sigma$中。一般情况下,我们认为在区域$\mu\pm3\sigma$外的点为异常值。

一种更加简便易操作的方法是利用箱线图方法,我们先求出一维数据的第一个四分位数$Q_1$和第三个四分位数$Q_3$,定义$IQR=Q_3-Q_1$,那么对于小于$Q_1-1.5\times IQR$或大于$Q_3+1.5\times IQR$的值认为是异常值。理由和$3\sigma$准则类似,有99.3%的数据会包含在$Q_1-1.5\times IQR$和$Q_3+1.5\times IQR$之间。

还有一种方法是最大标准残差检验法(Grubb检验),也是假设数据服从正态分布。该方法是先对数据集中每一个元素计算$z-score$:$$z=\frac{|x-\mu|}{\sigma}$$,其中$\bar{x}$为数据集的均值,$\sigma$为数据集的标准差。如果$z\ge\frac{N-1}{\sqrt{n}}\sqrt{\frac{t_{\alpha/(2N),N-2}^2}{N-2+t_{\alpha/(2N),N-2}^2}}$,那么$x$维异常值。公式中$N$是数据集中点的个数,$t_{\alpha/(2N),N-2}$是显著水平$\alpha/(2N)$下的$t-$分布的值。

2、多维数据的异常值检测

对于多维的数据,一种检测思想是转化成一维数据进行异常值检测。我们依然假设其服从多元正态分布。计算Mahalanobis距离:$MDist(x,\mu)=(x-\mu)^T\Sigma^{-1}(x-\mu)$,其中$\mu$是均值向量,$\Sigma$是协方差矩阵。$MDist(x,\mu)$服从自由度为$d$的$\chi^2$分布,$d$是数据维度。如果$MDist(x,\mu)>\chi_{d,0.975}^2$,则$x$为异常值。



基于密度的方法

局部异常因子检测算法是一种基于密度的算法,通过计算局部异常因子来判断异常值,计算公式如下:

*可达距离*(Reachability Distance):$RD_k(x, x')=\max(\|x-x^{(k)}\|, \|x-x'\|)$,其中$x^{(k)}$是训练样本中距$x$第$k$近的点

*局部可达密度*(Local Reachability Density):$LRD_k(x)=\big(\frac{1}{k}\sum_{i=1}^k RD_k(x^{(i)},x)\big)$

*局部异常因子*(Local Outlier Factor):$LOF_k(x)=\frac{\frac{1}{k}\sum_{i=1}^k LRD_k(x^{(i)})}{LRD_k(x)}$

从公式中可以看出:当$x^{(i)}$周围的密度比较高而$x$周围的密度比较低时,局部异常因子比较大,$x$就会被看作是异常值。



基于聚类的方法

基于聚类的方法是一类无监督的检测方法,通过考察数据点与簇之间的关系检测异常值。考虑数据样本中的数据点:

* 判断该数据点是否属于某个簇,如果不属于任何簇,则认为是异常值

* 计算该数据点与最近的簇之间的距离,如果距离很远,则认为是异常值

* 判断该数据点是否是小簇或者稀疏簇的一部分,如果是,则该簇中的所有点都是异常值。

上述三条中的第一条可以采用基于密度的聚类方法(如DBSCAN)进行计算。第二条可以采用k-means聚类方法。第三条寻找小簇和稀疏簇一般采用FindCBLOF算法,其方法为:

* 通过设置一个参数$\alpha(0\le\alpha\le1)$来区别大簇和小簇,至少包含数据集中数据点占比为$\alpha$的簇是大簇,其余的为小簇

* 对每个数据点计算基于簇的局部异常因子(CBLOF):对于大簇的点,CBLOF为簇的大小和该点与簇的相似性的乘积;对于小簇的点,CBLOF为小簇的大小和该点于最近的大簇的相似性的乘积。

点与簇的相似性代表了点属于簇的概率,因此CBLOF的值可以检测远离任何簇的异常值,具有最低CBLOF值的点被认为是异常值。



孤立森林

孤立森林(Isolation Forest)也是一种无监督的检测方法。假设一个空间中有很多点,我们用一个随机的超平面去分割这个空间,会得到两个子空间,再分别对每个子空间用一个随机的超平面去分割,如此循环下去,直到被划分出来的子空间只包含一个点停止。直觉上,如果一个点周围的密度很低,则会很早的停留到一个子空间中。这便是孤立森林的思想。

我们从样本集中随机选择$\psi$个数据作为子样本,在这个子样本上构建一棵iTree:随机选择一个特征,在这个特征上,随意选择一个属于特征取值范围内的值$p$,对子样本进行划分,在该特征上,取值小于$p$的点划分到左侧,取值大于等于$p$的点划分到右侧。按照这种方式继续对左右进行划分,直到满足下面两条中的一条则停止:1、只包含一个数据点,不可再分;2、树高达到$\log_2\psi$

重复$t$次,可构建$t$棵iTree,组成iForest。我们用这个iForest来检测异常值:对于一个数据点$x$,我们让它遍历每一棵iTree,计算在每棵iTree中的高度$h(x)$。然后计算异常分数:$s(x,\psi)=2^{-\frac{E(h(x))}{c(\psi)}}$,其中$c(\psi)=2H(\psi-1)-2(\psi-1)/n$,$H(n)=\ln n+\gamma$,$\gamma$为欧拉常数,约为0.5772156649。

如果异常分数非常接近于1,则该点为异常值;如果异常分数比0.5小得多,则为正常值;如果异常分数在0.5附近,则整个样本没有明显的异常值。
回复 支持 反对

使用道具 举报

 
地板
butty护肤 发表于 2022-8-13 15:44:31 | 只看该作者
 
最近很多小伙伴都比较关注异常值检测的方法,接下来小编就为大家介绍几种,希望能帮到大家!!
摘要: 本文介绍了异常值检测的常见四种方法,分别为Numeric Outlier、Z-Score、DBSCA以及Isolation Forest
在训练机器学习算法或应用统计技术时,错误值或异常值可能是一个严重的问题,它们通常会造成测量误差或异常系统条件的结果,因此不具有描述底层系统的特征。实际上,最佳做法是在进行下一步分析之前,就应该进行异常值去除处理。
在某些情况下,异常值可以提供有关整个系统中局部异常的信息;因此,检测异常值是一个有价值的过程,因为在这个工程中,可以提供有关数据集的附加信息。
目前有许多技术可以检测异常值,并且可以自主选择是否从数据集中删除。在这篇博文中,将展示KNIME分析平台中四种最常用的异常值检测的技术。
数据集和异常值检测问题

本文用于测试和比较建议的离群值检测技术的数据集来源于航空公司数据集,该数据集包括2007年至2012年间美国国内航班的信息,例如出发时间、到达时间、起飞机场、目的地机场、播出时间、出发延误、航班延误、航班号等。其中一些列可能包含异常值。
从原始数据集中,随机提取了2007年和2008年从芝加哥奥黑尔机场(ORD)出发的1500次航班样本。
为了展示所选择的离群值检测技术是如何工作的,将专注于找出机场平均到达延误的异常值,这些异常值是在给定机场降落的所有航班上计算的。我们正在寻找那些显示不寻常的平均到达延迟时间的机场。
四种异常值检测技术

数字异常值|Numeric Outlier

数字异常值方法是一维特征空间中最简单的非参数异常值检测方法,异常值是通过IQR(InterQuartile Range)计算得的。
计算第一和第三四分位数(Q1、Q3),异常值是位于四分位数范围之外的数据点x i:

 第35张图片
使用四分位数乘数值k=1.5,范围限制是典型的上下晶须的盒子图。这种技术是使用KNIME Analytics Platform内置的工作流程中的Numeric Outliers节点实现的(见图1)。
Z-score

Z-score是一维或低维特征空间中的参数异常检测方法。该技术假定数据是高斯分布,异常值是分布尾部的数据点,因此远离数据的平均值。距离的远近取决于使用公式计算的归一化数据点z i的设定阈值Zthr:

 第36张图片
其中xi是一个数据点,μ是所有点xi的平均值,δ是所有点xi的标准偏差。
然后经过标准化处理后,异常值也进行标准化处理,其绝对值大于Zthr:

 第37张图片
Zthr值一般设置为2.5、3.0和3.5。该技术是使用KNIME工作流中的行过滤器节点实现的(见图1)。
DBSCAN

该技术基于DBSCAN聚类方法,DBSCAN是一维或多维特征空间中的非参数,基于密度的离群值检测方法。
在DBSCAN聚类技术中,所有数据点都被定义为核心点(Core Points)、边界点(Border Points)或噪声点(Noise Points)。

  • 核心点是在距离ℇ内至少具有最小包含点数(minPTs)的数据点;
  • 边界点是核心点的距离ℇ内邻近点,但包含的点数小于最小包含点数(minPTs);
  • 所有的其他数据点都是噪声点,也被标识为异常值;
从而,异常检测取决于所要求的最小包含点数、距离ℇ和所选择的距离度量,比如欧几里得或曼哈顿距离。该技术是使用图1中KNIME工作流中的DBSCAN节点实现的。
孤立森林|Isolation Forest

该方法是一维或多维特征空间中大数据集的非参数方法,其中的一个重要概念是孤立数。
孤立数是孤立数据点所需的拆分数。通过以下步骤确定此分割数:

  • 随机选择要分离的点“a”;
  • 选择在最小值和最大值之间的随机数据点“b”,并且与“a”不同;
  • 如果“b”的值低于“a”的值,则“b”的值变为新的下限;
  • 如果“b”的值大于“a”的值,则“b”的值变为新的上限;
  • 只要在上限和下限之间存在除“a”之外的数据点,就重复该过程;
与孤立非异常值相比,它需要更少的分裂来孤立异常值,即异常值与非异常点相比具有更低的孤立数。因此,如果数据点的孤立数低于阈值,则将数据点定义为异常值。
阈值是基于数据中异常值的估计百分比来定义的,这是异常值检测算法的起点。有关孤立森林技术图像的解释,可以在此找到详细资料。
通过在Python Script中使用几行Python代码就可以实现该技术。
from sklearn.ensemble import IsolationForest
import pandas as pd

clf = IsolationForest(max_samples=100, random_state=42)
table = pd.concat([input_table['Mean(ArrDelay)']], axis=1)
clf.fit(table)
output_table = pd.DataFrame(clf.predict(table))```python

Python Script节点是KNIME Python Integration的一部分,它允许我们将Python代码编写/导入到KNIME工作流程。
在KNIME工作流程中实施

KNIME Analytics Platform是一个用于数据科学的开源软件,涵盖从数据摄取和数据混合、数据可视化的所有数据需求,从机器学习算法到数据应用,从报告到部署等等。它基于用于可视化编程的图形用户界面,使其非常直观且易于使用,大大减少了学习时间。
此外,它被设计为对不同的数据格式、数据类型、数据源、数据平台以及外部工具(例如R和Python)开放,还包括许多用于分析非结构化数据的扩展,如文本、图像或图形。
KNIME Analytics Platform中的计算单元是小彩色块,名为“节点”。一个接一个地组装管道中的节点,实现数据处理应用程序。管道也被称为“工作流程”。
鉴于所有这些特性,本文选择它来实现上述的四种异常值检测技术。图1中展示了异常值检测技术的工作流程。工作流程:

  • 1.读取Read data metanode中的数据样本;
  • 2.进行数据预处理并计算Preproc元节点内每个机场的平均到达延迟;
  • 3.在下一个名为密度延迟的元节点中,对数据进行标准化,并将标准化平均到达延迟的密度与标准正态分布的密度进行对比;
  • 4.使用四种选定的技术检测异常值;
  • 5.使用KNIME与Open Street Maps的集成,在MapViz元节点中显示美国地图中的异常值机场。

 第38张图片

图1:实施四种离群值检测技术的工作流程:数字异常值、Z-score、DBSCAN以及孤立森林

检测到的异常值

在图2-5中,可以看到通过不同技术检测到的异常值机场。其中。蓝色圆圈表示没有异常行为的机场,而红色方块表示具有异常行为的机场。平均到达延迟时间定义的大小了记。
一些机场一直被四种技术确定为异常值:斯波坎国际机场(GEG)、伊利诺伊大学威拉德机场(CMI)和哥伦比亚大都会机场(CAE)。斯波坎国际机场(GEG)具有最大的异常值,平均到达时间非常长(180分钟)。然而,其他一些机场仅能通过一些技术来识别、例如路易斯阿姆斯特朗新奥尔良国际机场(MSY)仅被孤立森林和DBSCAN技术所发现。
对于此特定问题,Z-Score技术仅能识别最少数量的异常值,而DBSCAN技术能够识别最大数量的异常值机场。且只有DBSCAN方法(MinPts = 3/ℇ= 1.5,欧几里德距离测量)和孤立森林技术(异常值的估计百分比为10%)在早期到达方向发现异常值。

 第39张图片

图2:通过数字异常值技术检测到的异常值机场

 第40张图片

图3:通过z-score技术检测到的异常机场

 第41张图片

图4:DBSCAN技术检测到的异常机场

 第42张图片

图5:孤立森林技术检测到的异常机场

总结

本文在一维空间中描述并实施了四种不同的离群值检测技术:2007年至2008年间所有美国机场的平均到达延迟。研究的四种技术分别是Numeric Outlier、Z-Score、DBSCAN和Isolation Forest方法。其中一些用于一维特征空间、一些用于低维空间、一些用于高维空间、一些技术需要标准化和检查维度的高斯分布。而有些需要距离测量,有些需要计算平均值和标准偏差。有三个机场,所有异常值检测技术都能将其识别为异常值。但是,只有部分技术(比如,DBSCAN和孤立森林)可以识别分布左尾的异常值,即平均航班早于预定到达时间到达的那些机场。因此,应该根据具体问题选择合适的检测技术。
参考


  • Santoyo, Sergio. (2017, September 12). A Brief Overview of Outlier Detection Techniques;

以上为译文,由阿里云云栖社区组织翻译。
译文链接
本文为云栖社区原创内容,未经允许不得转载。
回复 支持 反对

使用道具 举报

 
5#
无敌小柠檬╯ 发表于 2022-8-13 15:44:46 | 只看该作者
 
1. 首先,你要明白什么是异常值,如何处理异常值
有时候数据集中会包含一个或多个数值异常大或异常小的值,这样的极端值称为异常值(outlier)。
对于异常值,我们该怎么办呢?

第1步,你需要采用一定的技术手段从大量数据中找出哪些数值可能是异常值。
第2步,然后对找到的这些异常值的准确性进行检查,以确定如何处理异常值

 第51张图片
处理异常值一般有3种办法:
1)异常值可能是一个被错误记录的数据值,如果是这样,就可以在进一步分析之前把它修正。
例如在全国人口系统中,出生了一个叫王思聪的婴儿,王健林前来登记,你手动将王思聪的性别错误输入成“女”。这种情况下的异常值,就需要进一步核实对应人把它修正。
2)异常值也可能是一个被错误包含在数据集总的值,如果是这样,则可以把它删除。
例如在全国人口系统中,你不小心把你家狗狗的姓名“王二狗”记录进去了,记录的年龄是10岁,身高是1米,这明显不符合正常情况下的10岁儿童身高,进一步识别出异常值后,进行核对,发现是错误数据,删掉。
3)异常值也可能是一个反常的数据值,它被正确记录并且属于数据集,这种情况下,它应该被保留。
例如你公司发布了一款吊炸天的产品,没想到全球用户都喜欢用,发布会当天销售量暴增。这时候的异常值代表了销售的实际数值,应该保留。
2. 如何自动识别出异常值
在了解了异常值和对异常值的处理知识后,可以用四分位数是自动识别出可能的异常值的。
这个方法叫Tukey‘s test方法,用于计算出数据集中最小估计值,和最大估计值。这样超出最小估计值和最大估计值范围的数值就可能是异常值了。如何计算呢?
最小估计值和最大估计值的计算公式如图中列出。可以根据不同的数据分析目对k取值。一般k=1.5,计算出的是中度异常的范围。
K=3计算出的是极度异常的范围。我们通过下面图片用图形的方式看下这个公式是如何计算出数值的范围的。

 第52张图片
下面图片红色是k=1.5时,计算出的是中度异常的范围。
蓝色是K=3计算出的是极度异常的范围。
超出这个范围的数值就有可能是异常值,这样我们就可以从大量数据中自动识别出异常值。

 第53张图片
我是猴子,中科院硕士/前IBM高级软件工程师/豆瓣8分《数据分析思维》作者,我和知乎联合出品的「数据分析训练营」即将开课,3天带你掌握数据分析实用技巧,包含课程+实战带练,工作提效、升职加薪必备神器!
报名还有独家Excel自学资料领取,点击开启数据分析升职加薪密码:
回复 支持 反对

使用道具 举报

 
6#
柚子绿茶控 发表于 2022-8-13 15:45:38 | 只看该作者
 
之前写过几篇文章:分别介绍了概率方法,矩阵分解,神经网络的方法。
(1)
异常点检测算法(一)(2)
异常值检测算法(二)
(3)
异常点检测算法(三)
(4)
异常点检测算法综述
回复 支持 反对

使用道具 举报

 
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

排行榜
活跃网友
返回顶部快速回复上一主题下一主题返回列表APP下载手机访问
Copyright © 2016-2028 CTLIVES.COM All Rights Reserved.  西兔生活网  小黑屋| GMT+8, 2024-7-13 13:58