问题

我有一个随时由> 5个变量组成的数据框,并且正在尝试对其进行K均值。由于K-Means受离群值的影响很大,因此我一直试图寻找几个小时来计算和删除多元离群值。演示的大多数示例都带有2个变量。


探索了可能的解决方案


mvoutlier-此处的一位用户指出,我可能需要mvoutlier。
Another Outlier Detection Method-此处的发布者使用R函数进行了注释,以生成异常值的有序列表。




到目前为止的问题

关于mvoutlier,我无法生成结果,因为它指出我的数据集包含负数,因此无法运行。我不确定如何将数据更改为仅正数,因为我需要使用正负数。

关于另一种离群值检测方法,我能够提出一个离群值列表,但是不确定如何从当前数据集中排除它们。另外,我确实知道这些计算是在K均值之后进行的,因此我很可能会在进行K均值之前应用数学。



最小的可验证示例

不幸的是,我正在使用的数据集是禁止显示给任何人的,因此您需要的是任何具有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均值之前将结果与当前数据帧中的信息配对以排除那些行?

最佳答案

我不知道这是否真的有用,但是如果您的数据是多元正态的,您可能想尝试一种基于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


然后,我们可以简单地找到多元数据的哪些行与Beta分布明显不同。

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

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


r - 使用mvoutlier移除多元离群值-LMLPHP

07-24 13:58