假设我有一组包含至少三个变量的多变量数据。如何找到异常值?成对散点图将不起作用,因为离群值可能存在于3维中,而不是任何二维子空间中的离群值。
我不是在考虑回归问题,而是真正的多元数据。因此,涉及稳健回归或计算杠杆的答案无济于事。
一种可能是计算主成分分数,并在前两个分数的双变量散点图中寻找离群值。这样可以保证工作吗?有更好的方法吗?
假设我有一组包含至少三个变量的多变量数据。如何找到异常值?成对散点图将不起作用,因为离群值可能存在于3维中,而不是任何二维子空间中的离群值。
我不是在考虑回归问题,而是真正的多元数据。因此,涉及稳健回归或计算杠杆的答案无济于事。
一种可能是计算主成分分数,并在前两个分数的双变量散点图中寻找离群值。这样可以保证工作吗?有更好的方法吗?
Answers:
看看mvoutlier软件包,它依赖于有序的稳健的马哈拉诺比斯距离,如@drknexus所建议。
我认为罗宾·吉拉德(Robin Girard)的答案在3维甚至4维上都可以很好地工作,但是维的诅咒将阻止它在此范围之外的工作。但是,他的建议使我想到了一种相关的方法,该方法是将交叉验证的内核密度估计应用于前三个主成分评分。然后,仍然可以很好地处理非常高维的数据集。
总之,对于i = 1到n
结束于
对Li进行排序(对于i = 1,..,n),离群值是那些似然度低于某个阈值的离群值。我不确定什么门槛会很好-我会把这个留给任何为此撰写论文的人!一种可能性是对log(Li)值进行箱线图绘制,并查看在负端检测到哪些异常值。
您可以在(1)中找到各种方法的教学摘要。
对于此处列出的各种方法的一些近期数值比较,可以检查 (2)和(3)。
有许多较旧的(且较不详尽)的数值比较,通常在书籍中找到。例如,您会在(4)的第142-143页上找到一个。
请注意,这里讨论的所有方法都有一个开源R实现,主要是通过rrcov 包实现的。
我会做某种“留下一个测试算法”(n是数据数量):
对于i = 1到n
结束于
如果n足够大,这将起作用...您还可以使用“离开k策略”,当您有“异常值”组时可能会更加放松...
我没有看到有人提到影响功能。我首先在Gnanadesikan的多元书中看到了这个想法。
在一个维度上,离群值是非常大或非常小的值。在多变量分析中,这是从大量数据中删除的观察结果。但是,我们应该使用什么指标来定义异常值呢?有很多选择。马氏距离仅是一。我认为寻找每种异常值都是徒劳的,适得其反。我想问一下你为什么在乎离群值?在估计均值时,他们可以对该估计产生很大影响。稳健的估算器可以减轻重量并容纳离群值,但他们并未对其进行正式测试。现在进行回归分析,离群点(如杠杆点)可能会对模型中的斜率参数产生很大影响。对于双变量数据,它们可能不适当地影响估计的相关系数,并且在三个或更多个维度上会影响多个相关系数。
Hampel引入影响功能作为一种可靠的估计工具,Mallows撰写了一篇不错的未发表论文,主张使用它们。影响函数是您在n维空间中所处的点和参数的函数。它实质上测量参数估计值与计算中的点与遗漏的点之间的差异。不必费心计算两个估计并求出差,您通常可以为其得出一个公式。然后,恒定影响的轮廓会告诉您相对于此参数的估计而言极端的方向,从而告诉您在n维空间中何处寻找离群值。
有关更多信息,请查看我在1983年发表在《美国数学与管理科学杂志》上的论文“影响函数及其在数据验证中的应用”。在数据验证中,我们希望查找影响数据预期用途的异常值。我的感觉是,您应该将注意力转移到离群值上,这些离点值会极大地影响您想要估算的参数,而不是那么在乎那些不需要的参数。
这可能是一个过冲,但是您可以对数据进行无监督的随机森林训练,并使用对象接近度度量来检测离群值。更多细节在这里。
对于中等尺寸(如3),那么其他地方建议的某种内核交叉验证技术似乎是合理的,并且是我能想到的最好的方法。
对于较大的尺寸,我不确定该问题是否可以解决。它正好落在“三维诅咒”的领域。问题在于,随着维数(包括从分布派生的距离)的增加,距离函数趋于非常快地收敛到非常大的值。如果您将离群值定义为“相对于其他点具有相对较大的距离函数的点”,并且您的所有距离函数都开始收敛,因为您处于高维空间中,那么,您很麻烦。
如果没有某种可以使您将其转变为概率分类问题的分布假设,或者至少没有某种旋转可以使您将空间分为“噪声维”和“信息维”,我认为高维空间的几何形状将禁止对异常值的任何简单(或至少可靠)识别。
我的第一个回答是,如果您可以对数据进行多元回归,则可以使用该回归中的残差来发现异常值。(我知道您说这不是回归问题,所以这可能对您没有帮助,对不起!)
我要从我之前回答的Stackoverflow问题中复制一些内容,其中包含一些R代码示例
首先,我们将创建一些数据,然后使用异常值对其进行污染;
> testout<-data.frame(X1=rnorm(50,mean=50,sd=10),X2=rnorm(50,mean=5,sd=1.5),Y=rnorm(50,mean=200,sd=25))
> #Taint the Data
> testout$X1[10]<-5
> testout$X2[10]<-5
> testout$Y[10]<-530
> testout
X1 X2 Y
1 44.20043 1.5259458 169.3296
2 40.46721 5.8437076 200.9038
3 48.20571 3.8243373 189.4652
4 60.09808 4.6609190 177.5159
5 50.23627 2.6193455 210.4360
6 43.50972 5.8212863 203.8361
7 44.95626 7.8368405 236.5821
8 66.14391 3.6828843 171.9624
9 45.53040 4.8311616 187.0553
10 5.00000 5.0000000 530.0000
11 64.71719 6.4007245 164.8052
12 54.43665 7.8695891 192.8824
13 45.78278 4.9921489 182.2957
14 49.59998 4.7716099 146.3090
<snip>
48 26.55487 5.8082497 189.7901
49 45.28317 5.0219647 208.1318
50 44.84145 3.6252663 251.5620
通常,以图形方式检查数据最有用(与数学相比,大脑更容易发现异常值)
> #Use Boxplot to Review the Data
> boxplot(testout$X1, ylab="X1")
> boxplot(testout$X2, ylab="X2")
> boxplot(testout$Y, ylab="Y")
然后,您可以使用统计信息计算临界值,在这里使用Lund测试(请参阅Lund,RE 1975,“线性模型中离群值的近似测试表”,Technometrics,第17卷,第4期,第473页) -476。和Prescott,第1975年,“线性模型中离群值的近似测试”,技术计量学,第17卷,第1期,第129-132页。)
> #Alternative approach using Lund Test
> lundcrit<-function(a, n, q) {
+ # Calculates a Critical value for Outlier Test according to Lund
+ # See Lund, R. E. 1975, "Tables for An Approximate Test for Outliers in Linear Models", Technometrics, vol. 17, no. 4, pp. 473-476.
+ # and Prescott, P. 1975, "An Approximate Test for Outliers in Linear Models", Technometrics, vol. 17, no. 1, pp. 129-132.
+ # a = alpha
+ # n = Number of data elements
+ # q = Number of independent Variables (including intercept)
+ F<-qf(c(1-(a/n)),df1=1,df2=n-q-1,lower.tail=TRUE)
+ crit<-((n-q)*F/(n-q-1+F))^0.5
+ crit
+ }
> testoutlm<-lm(Y~X1+X2,data=testout)
> testout$fitted<-fitted(testoutlm)
> testout$residual<-residuals(testoutlm)
> testout$standardresid<-rstandard(testoutlm)
> n<-nrow(testout)
> q<-length(testoutlm$coefficients)
> crit<-lundcrit(0.1,n,q)
> testout$Ynew<-ifelse(testout$standardresid>crit,NA,testout$Y)
> testout
X1 X2 Y newX1 fitted residual standardresid
1 44.20043 1.5259458 169.3296 44.20043 209.8467 -40.5171222 -1.009507695
2 40.46721 5.8437076 200.9038 40.46721 231.9221 -31.0183107 -0.747624895
3 48.20571 3.8243373 189.4652 48.20571 203.4786 -14.0134646 -0.335955648
4 60.09808 4.6609190 177.5159 60.09808 169.6108 7.9050960 0.190908291
5 50.23627 2.6193455 210.4360 50.23627 194.3285 16.1075799 0.391537883
6 43.50972 5.8212863 203.8361 43.50972 222.6667 -18.8306252 -0.452070155
7 44.95626 7.8368405 236.5821 44.95626 223.3287 13.2534226 0.326339981
8 66.14391 3.6828843 171.9624 66.14391 148.8870 23.0754677 0.568829360
9 45.53040 4.8311616 187.0553 45.53040 214.0832 -27.0279262 -0.646090667
10 5.00000 5.0000000 530.0000 NA 337.0535 192.9465135 5.714275585
11 64.71719 6.4007245 164.8052 64.71719 159.9911 4.8141018 0.118618011
12 54.43665 7.8695891 192.8824 54.43665 194.7454 -1.8630426 -0.046004311
13 45.78278 4.9921489 182.2957 45.78278 213.7223 -31.4266180 -0.751115595
14 49.59998 4.7716099 146.3090 49.59998 201.6296 -55.3205552 -1.321042392
15 45.07720 4.2355525 192.9041 45.07720 213.9655 -21.0613819 -0.504406009
16 62.27717 7.1518606 186.6482 62.27717 169.2455 17.4027250 0.430262983
17 48.50446 3.0712422 228.3253 48.50446 200.6938 27.6314695 0.667366651
18 65.49983 5.4609713 184.8983 65.49983 155.2768 29.6214506 0.726319931
19 44.38387 4.9305222 213.9378 44.38387 217.7981 -3.8603382 -0.092354925
20 43.52883 8.3777627 203.5657 43.52883 228.9961 -25.4303732 -0.634725264
<snip>
49 45.28317 5.0219647 208.1318 45.28317 215.3075 -7.1756966 -0.171560291
50 44.84145 3.6252663 251.5620 44.84145 213.1535 38.4084869 0.923804784
Ynew
1 169.3296
2 200.9038
3 189.4652
4 177.5159
5 210.4360
6 203.8361
7 236.5821
8 171.9624
9 187.0553
10 NA
11 164.8052
12 192.8824
13 182.2957
14 146.3090
15 192.9041
16 186.6482
17 228.3253
18 184.8983
19 213.9378
20 203.5657
<snip>
49 208.1318
50 251.5620
显然,除了隆德检验(格鲁布斯涌现出来)之外,还有其他异常检验,但是我不确定哪种检验更适合多元数据。
vw-top-errors
@ goo.gl/l7SLlB上的github页面 (请注意,那里的示例碰巧有一个Y,但是我使用相同的技术,通过固定Y也非常成功地解决了无监督问题。)