异常值的处理

异常值是指观测数据中存在的过大或过小的值。它可能只是数据中内在的随机变异性的一种极端的表现,也可能是因为试验过程中出现操作错误或条件改变所导致。对于前一种异常值,必须予以保留并与其他数据一起参与统计过程,对于后一种数据,必须舍弃或修正。因此,一个过大或过小的值是否是真正意义上的异常值,需要先进行判别。判别的方法是检验。如果数据服从正态分布(需要先检验数据是否符合正态分布),检验的方法有奈尔检验、格拉布斯检验和狄克逊检验等。[大谦MATLAB,dqmatlab点com]

发现异常值

在MATLAB中,可以使用isoutlier函数或箱形图发现异常值。

isoutlier函数

该函数的调用格式为:

TF = isoutlier(A) 返回一个逻辑数组,当在A的元素中检测到异常值时,该数组中与之对应的元素为true。默认情况下,异常值是指与中位数相差超过三倍经过换算的中位数绝对偏差(MAD)的值。如果A是矩阵或表,则isoutlier分别对每一列进行运算。如果A是多维数组,则isoutlier沿大小不等于1的第一个维度进行运算。

TF = isoutlier(A,method) 指定确定异常值的方法。例如,isoutlier(A,'mean')对偏离均值超过三个标准差的所有元素返回true。

TF = isoutlier(A,movmethod,window) 指定根据window定义的窗口长度确定局部异常值的移动方法。例如,isoutlier(A,'movmedian',5)对包含五个元素的滑动窗口内偏离局部中位数超过三倍局部换算MAD的所有元素返回true。

对于上述任何语法,TF = isoutlier(___,dim) 将沿A的维度dim运算。例如,isoutlier(A,2)沿矩阵A的每一行运算。

TF = isoutlier(___,Name,Value) 使用一个或多个名称-值对组参数指定用于检测异常值的其他参数。例如,isoutlier(A,'SamplePoints',t)相对于时间向量t中的对应元素检测A中的异常值。

[TF,lower,upper,center] = isoutlier(___) 还会返回异常值检测方法所用的下阈值和上阈值以及中心值。

isoutlier函数采用5种方法进行异常值判断,如表1-8所示。

表1-8 isoutlier函数进行异常值判断的方法

方 法 说 明
'median' 对偏离中位数超过三倍MAD的元素返回true。MAD定义为 c*median(abs(A-median(A))),其中c=-1/(sqrt(2)*erfcinv(3/2))。
'mean' 对偏离均值超过三倍标准差的元素返回true。此方法比'median'快,但没有它可靠。
'quartiles' 对高于上四分位数或低于下四分位数超过1.5倍四分位极差的元素返回true。当A中的数据不是正态分布时,此方法很有用。
'grubbs' 应用Grubbs检验检测异常值,即基于假设检验以迭代方式每次迭代删除一个异常值。此方法假设A中的数据呈正态分布。
'gesd' 应用广义极端学生化偏差检验检测异常值。此迭代方法与'grubbs'类似,但当有多个异常值出现屏蔽效应时,此方法的执行效果更好。

下面根据给定的数据判断异常值。在命令窗口键入:

code.matlab
>> A = [1 62 63 74 55 236 77 68 59 10];
>> TF = isoutlier(A,'quartiles')
TF =
   1   0   0   0   0   1   0   0   0   1

TF变量中,判断为异常值的位置的值为1,其它为0。

箱形图

箱形图可以比较清晰地表示数据的分布特征。它由5个部分组成:

  • 箱形上、下的横线为样本的25%和75%分位数,箱形顶部和底部的差值为内四分极值;
  • 箱形中间的横线为样本的中位数。若该横线没在箱形中央,则说明存在偏度;
  • 箱形向上或向下延伸的直线称为“触须”,若没有异常值,样本的最大值为上触须的顶部,样本最小值为下触须的底部。默认情况下,距离箱形顶部或底部大于1.5倍内四分极值的值称为异常值;
  • 图中顶部的加号表示该处数据为一异常值。该值的异常可能是输入错误、测量失误或系统误差引起的;
  • 箱形两侧的V形槽口对应于样本中位数的置信区间。默认情况下,箱形图没有V形槽口。

用boxplot函数生成数据样本的箱形图,其调用格式如下:

boxplot(X) 为X矩阵的每一列生成一个箱形图。箱形上、下四分位数和中位数处有一条线段,箱形末端延伸出去的直线称为触须,表示数据向极大和极小方向延伸的程度。触须末端以外的数据为异常值,如果在触须外没有数据,则底部触须有一点,点的颜色与触须的颜色相同。

boxplot(X, notch) 当notch = 1时,生成一个带刻槽的箱形图。刻槽用图形表示箱形比较中均值不确定性的稳健性估计。默认时notch = 0,生成一个矩形箱形图。

boxplot(X, notch, 'sym') 其中,'sym'为一图形标记,允许控制异常值的标记(默认时标记符号为'+')。

boxplot(X, notch, 'sym', vert) 当vert = 0时,箱形水平(默认时,vert=1,箱形垂直)。

boxplot(X, notch, 'sym', vert, whis) 可以指定'whiskers'的长度。whis参数用内四分极差(IQR)的函数来定义触须的长度。默认时,该函数为1.5*IQR。若whis=0,则用图形标记'sym'来显示所有箱形以外的数据值。

下面根据给定的随机数绘箱形图。

code.matlab
>> A = [1 62 63 74 55 236 77 68 59 10];
>> boxplot(A)

生成图如图1-4所示。其中红色加号表示的值即为异常值。

Document Image
\[\]

图1-4 箱形图

处理异常值

用filloutliers函数可以检测和替换异常值。该函数的调用格式为:

B = filloutliers(A,fillmethod) 查找A中的异常值并根据fillmethod替换它们。例如,filloutliers(A,'previous')将异常值替换为上一个非异常值元素。默认情况下,异常值是指与中位数相差超过三倍经过换算的中位数绝对偏差(MAD)的值。如果A是矩阵或表,则filloutliers分别对每一列进行运算。如果A是多维数组,则filloutliers沿大小不等于1的第一个维度进行运算。

B = filloutliers(A,fillmethod,findmethod) 指定确定异常值的方法。例如,filloutliers(A,'previous','mean')将A中与均值相差超过三倍标准差的元素定义为异常值。

B = filloutliers(A,fillmethod,movmethod,window) 指定根据window定义的窗口长度确定局部异常值的移动方法。例如,filloutliers(A,'previous','movmean',5) 将包含五个元素的窗口中与局部均值相差超过三倍局部标准差的元素标识为异常值。

对于上述任何语法,B= filloutliers(___,dim) 将沿A的维度dim运算。例如,filloutliers(A,'linear',2)沿矩阵A的每一行运算。

B = filloutliers(___,Name,Value) 使用一个或多个名称-值对组参数指定用来检测和替换异常值的其他参数。例如,filloutliers(A,'previous','SamplePoints',t) 基于时间向量t的对应元素检测A中的异常值。

[B,TF,lower,upper,center] = filloutliers(___) 还返回检测方法计算的异常值和阈值的位置信息。TF是一个逻辑数组,指示A中的异常值的位置。lower、upper和center参数表示异常值检测方法使用的阈值下限、阈值上限和中心值。

filloutliers函数检测异常值的方法与isoutliers函数的相同,如表1-8所示。该函数替换异常值的方法如表1-9所示。

表1-9 替换异常值

替换方法 说 明
数值标量 使用指定的标量值进行填充
'center' 使用由findmethod决定的中心值进行填充
'clip' 对于比findmethod决定的下阈值还小的元素,用下阈值填充。对于比findmethod决定的上阈值还大的元素,用上阈值填充
'previous' 使用上一个非异常值进行填充
'next' 使用下一个非异常值进行填充
'nearest' 使用最接近的非异常值进行填充
'linear' 使用相邻的非异常值的线性插值进行填充
'spline' 使用分段三次样条插值进行填充
'pchip' 使用保形分段三次样条插值进行填充

下面创建一个包含异常值的向量,使用filloutliers函数,用quartiles方法判断异常值,用nearest方法替换异常值。

code.matlab
>> A = [1 62 63 74 55 236 77 68 59 10];
>> B = filloutliers(A,'nearest','quartiles')
B =
    62    62    63    74    55    77    77    68    59    59

绘制处理前后数据的图形:

code.matlab
>> plot(1:10,A,1:10,B,'o')
>> legend('原数据','处理后数据')

生成图1-5。图中小圆圈没在曲线上的点为异常点,已经用最近点进行了替换。

Document Image
\[\]

图1-5 替换异常值

使用rmoutliers函数,可以删除异常值。