【问题标题】:outlier detection for a grouped (clustered) data分组(集群)数据的异常值检测
【发布时间】:2021-10-22 18:18:09
【问题描述】:

我想找出异常值并在我的数据中消除它们(名为“df”):

> head(df)

  cluster machine.code age Good.Times repair.price
1       1     13010132  23      58.54    198170000
2       1     13010129  23     105.25    390847500
3       1     13010131  23      20.50     20701747
4       1     13010072  18      14.30     22340000
5       1     13010101  18      57.63     13220000
6       1     13010106  27      49.96    254450000

我的数据有 65 个集群,我想分别在每个集群中运行异常值检测, 我之前使用下面的代码对一个集群进行异常值检测,这很好:

library("ggstatsplot")
df<- read.csv("C:/Users/gadmin/Desktop/dataE.csv",header = TRUE)
  ggbetweenstats(df,cluster, repair.price , outlier.tagging = TRUE)
  Q <- quantile(df$repair.price, probs=c(.25, .75), na.rm = FALSE)
  iqr <- IQR(df$repair.price)
  up <-  Q[2]+1.5*iqr # Upper Range  
  low<- Q[1]-1.5*iqr # Lower Range
  eliminated<- subset(df, df$repair.price > (Q[1] - 1.5*iqr) & df$repair.price < (Q[2]+1.5*iqr))
  ggbetweenstats(eliminated, cluster, repair.price, outlier.tagging = TRUE)

现在我想使用“for”对所有 65 个集群做同样的事情:

 for(i in 1:length(unique(df$cluster))) {
   ...   
    }

但我不知道怎么办? (我的意思是在异常值检测到第一个集群之后,应该如何替换它(子集)并继续处理到另一个集群)

【问题讨论】:

  • “我想找到异常值并在我的数据中消除它们”异常值只是具有您所拥有的信息无法解释的特征的案例。是什么让他们成为异常值?如果存在数据输入错误并且绝对没有理由相信该信息,那么当然 - 删除它们。但是,如果它们的特征是准确的,那么删除它们就是一种伤害。
  • 由于数据收集过程,数据异常值很可能是真正的异常值,需要删除

标签: r outliers


【解决方案1】:

核心问题

有多种方法可以检测异常值。至于您问题的核心,我将其理解为“如何对数据进行子集化,以便我可以应用 for-loop 来删除每个集群的异常值?”

# maybe insert a column id that assigns an id (identical to the row number) to identify individual entries
df$id <- seq(1, nrow(df))
# make a list to store the outlier ids for each cluster
outlrs <- list()

# loop through the clusters
for(clust in unique(df$cluster)){
subset <- df[df$cluster == clust,]
outlrs[[clust]] <- [INSERT YOUR OUTLIER DETECTION FUNCTION HERE*]
}

# remove the outliers
outliers <- do.call(rbind, outlrs)
df <- df[-outliers, ]

* 你使用的异常值检测函数最终应该输出包含异常值的行的id。这部分必须适应您的异常值识别方法。

我没有测试它,因为我没有足够的数据。你可以使用例如dput(df) 输出您可以复制和粘贴的数据版本,以供想要测试他们提出的解决方案的人访问。

编辑:一种(多种)替代方法

或者,您可以将问题中包含的函数应用于循环内的数据子集,存储清理后的输出,例如作为列表,然后将do.call(rbind.data.frame, your_list) 应用于列表。

注意

正如 Phil 指出的那样,是否应该删除异常值是值得怀疑的,尤其是当您只是应用一个“处理它们”的循环时。虽然我们可以提供以编程方式删除“异常值”的方法,但在给定情况下是否应该实际删除这些异常值的问题是另一个问题(在CrossValidated 上可能更合适)。还应该注意的是,有许多算法可以确定哪些值与大部分值“显着”不同,并且“显着”和不显着之间的边界是任意的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 2019-08-19
    • 2019-12-10
    • 2013-12-21
    • 1970-01-01
    • 2018-03-04
    • 2011-08-26
    相关资源
    最近更新 更多