问题
我有一个随时由 > 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 均值过程。 (请注意,虽然在示例中我在删除异常值之前使用了 K 均值,但在解决方案时,我将确保在使用 K 均值之前采取必要的步骤并删除异常值)。
问题
使用另一种离群值检测方法示例后,如何将结果与当前数据框中的信息配对,以在执行 K 均值之前排除这些行?
最佳答案
我不知道这是否完全有帮助,但如果您的数据是多元正态的,您可能想尝试基于 Wilks (1963) 的方法。 Wilks 证明多元正态数据的马哈拉诺比斯距离遵循 Beta 分布。我们可以利用这一点(以鸢尾花萼片数据为例):
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])])
关于使用 mvoutlier 删除多元异常值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45289225/