使用mvoutlier删除多变量异常值

时间:2017-07-24 20:10:35

标签: r k-means outliers

问题

我有一个由>组成的数据框。任何时候都有5个变量,我正在尝试做一个K-Means。因为K-Means受到异常值的影响很大,所以我一直试图寻找几个小时来计算和去除多变量异常值。大多数示例都有2个变量。


可能的解决方案

远远问题

关于 mvoutlier ,我无法生成结果,因为它注意到我的数据集中包含底片,因此无法生效。我不确定如何将我的数据改为正数,因为我需要在我正在使用的集合中使用。

关于另一种异常值检测方法我能够提出异常值列表,但不确定如何将它们从当前数据集中排除。另外,我知道这些计算是在K-Means之后完成的,因此我可能会在做K-Means之前应用数学。


最小可验证示例

不幸的是,我正在使用的数据集是禁止向任何人显示的,所以你需要的是任何包含3个以上变量的随机数据集。下面的代码是从另一个异常检测方法帖子转换的代码,用于处理我的数据。如果你有一个随机数据集,它应该动态工作。但它应该有足够的数据,其中群集中心数量应该可以用5。

clusterAmount <- 5
cluster <- kmeans(dataFrame, centers = clusterAmount, nstart = 20)
centers <- cluster$centers[cluster$cluster, ]
distances <- sqrt(rowSums(clusterDataFrame - centers)^2)
m <- tapply(distances, cluster$cluster, mean)
d <- distances/(m[cluster$cluster])

# 1% outliers
outliers <- d[order(d, decreasing = TRUE)][1:(nrow(clusterDataFrame) * .01)]

输出:我相信,离开他们居住的中心的距离排序的离群值列表。然后问题是将这些结果与数据框中的相应行配对并删除它们,以便我可以启动我的K-Means程序。 (注意,虽然在示例中我在删除异常值之前使用了K-Means,但我会确保采取必要的步骤并在K-Means解决之前删除异常值。)


问题

使用另一个异常值检测方法示例,如何将结果与当前数据框中的信息配对,以便在执行K-Means之前排除这些行?

1 个答案:

答案 0 :(得分:1)

我不知道这是否真的有用,但如果您的数据是多元正常的,您可能想尝试基于Wilks(1963)的方法。 Wilks表明,多变量正态数据的马哈拉诺比斯距离遵循Beta分布。我们可以利用这个(iris Sepal数据作为例子):

test.dat <- iris[,-c(1,2))]

Wilks.function <- function(dat){
  n <- nrow(dat)
  p <- ncol(dat)
  # beta distribution
  u <- n * mahalanobis(dat, center = colMeans(dat), cov = cov(dat))/(n-1)^2
  w <- 1 - u
  F.stat <- ((n-p-1)/p) * (1/w-1) # computing F statistic
  p <- 1 - round( pf(F.stat, p, n-p-1), 3) # p value for each row
  cbind(w, F.stat, p)
}

plot(test.dat, 
     col = "blue", 
     pch = c(15,16,17)[as.numeric(iris$Species)])

dat.rows <- Wilks.function(test.dat); head(dat.rows)
#                 w    F.stat     p
#[1,] 0.9888813 0.8264127 0.440
#[2,] 0.9907488 0.6863139 0.505
#[3,] 0.9869330 0.9731436 0.380
#[4,] 0.9847254 1.1400985 0.323
#[5,] 0.9843166 1.1710961 0.313
#[6,] 0.9740961 1.9545687 0.145

然后我们可以简单地找到我们的多变量数据的哪些行与β分布显着不同。

outliers <- which(dat.rows[,"p"] < 0.05)

points(test.dat[outliers,], 
       col = "red", 
       pch = c(15,16,17)[as.numeric(iris$Species[outliers])])

outliers