首页 > 解决方案 > 与从数据集中移除异常值相关的问题 (R)

问题描述

我在 R 中制作的函数有一些问题(我是这种语言的初学者)。这是一个删除数据集中异常值的函数:

removalOutlier <- function(data){
  q1 <- 0
  q2 <- 0
  q3 <- 0

 for(j in 1:(ncol(data)-1)){
   m <- length(data[,j])

   J<-0
   data<-data[order(data[,j]),]
   data<-as.matrix(data)
   print(data)
   q2 <- median(data[,j])

if((m %% 2) != 0){     
  q1 <- median(data[1:(((m+1)/2)-1),j]) #m dispari
  q3 <- median(data[(((m+1)/2)+1):m,j])
   } else {  
   q1 <- median(data[1:(m/2),j]) #m pari
   q3 <- median(data[(m+2)/2:m,j])     
  }

    iqr = q3-q1

    for(k in 1:(length(data[,j]))){
    print(data[k,j])

    if((data[k,j] > (q3+(1.5*iqr))) | (data[k,j] < (q1-(1.5*iqr))))

    {
     J[k]<-k
     data <- as.matrix(data) 
     }
     else 
     {J[k]<-0}        
   }

 data <- as.data.frame(data)

  for(z in 1:length(J)){
    if(J[z]!=0){

    data<-data.frame(data[-J[z],])
    } 
  }
 print (data)

}
data 
}

这是与数据集第一列相关的有序输出。将数据集的第一列分成四分位数,我发现:Q1-1.5*IQR=117 和 Q3+1.5*IQR=3609。由于我有这些结果,函数应该删除以下列表的最后三个样本:

     V1 V2     V3
45  852  2 179900
32 1000  1 169900
26 1100  3 249900
44 1200  3 299000
47 1203  3 239500
18 1236  3 199900
37 1239  3 229900
15 1268  3 259900
17 1320  2 299900
9  1380  3 212000
4  1416  2 232000
8  1427  3 198999
36 1437  3 249900
27 1458  3 464500
10 1494  3 242500
7  1534  3 314900
2  1600  3 329900
23 1604  3 242900
41 1664  2 368500
21 1767  3 252900
35 1811  4 285900
31 1839  2 349900
46 1852  4 299900
22 1888  2 255000
13 1890  3 329999
11 1940  4 239999
24 1962  4 259900
6  1985  4 299900
12 2000  3 347000
33 2040  4 314900
1  2104  3 399900
38 2132  4 345000
40 2162  4 287000
29 2200  3 475000
42 2238  3 329900
16 2300  4 449900
3  2400  3 369000
28 2526  3 469000
43 2567  4 314000
19 2609  4 499998
30 2637  3 299900
5  3000  4 539900
20 3031  4 599000
34 3137  3 579900
25 3890  3 573900
14 4478  5 699900
39 4515  4 549000

但它删除:

25 3890  3 573900
39 4515  4 549000

并不是 :

14 4478  5 699900

我不明白为什么。当我通过检查第二列中是否存在异常值时,我找到它们并毫无问题地删除它们。

标签: rmachine-learningoutliers

解决方案


此代码将根据您的 IQR 逻辑删除最后 3 行

bound <- quantile(df$V1, c(.25, .75)) + c(-1, 1)*1.5*IQR(df$V1)
out <- subset(df, V1 > bound[1] & V1 < bound[2])

检查结果:

nrow(df) - nrow(out)
# [1] 3

data.table::fsetdiff(df, out)
#      V1 V2     V3
# 1: 3890  3 573900
# 2: 4478  5 699900
# 3: 4515  4 549000

使用的数据:

df <- data.table::fread('
     V1 V2     V3
45  852  2 179900
32 1000  1 169900
26 1100  3 249900
44 1200  3 299000
47 1203  3 239500
18 1236  3 199900
37 1239  3 229900
15 1268  3 259900
17 1320  2 299900
9  1380  3 212000
4  1416  2 232000
8  1427  3 198999
36 1437  3 249900
27 1458  3 464500
10 1494  3 242500
7  1534  3 314900
2  1600  3 329900
23 1604  3 242900
41 1664  2 368500
21 1767  3 252900
35 1811  4 285900
31 1839  2 349900
46 1852  4 299900
22 1888  2 255000
13 1890  3 329999
11 1940  4 239999
24 1962  4 259900
6  1985  4 299900
12 2000  3 347000
33 2040  4 314900
1  2104  3 399900
38 2132  4 345000
40 2162  4 287000
29 2200  3 475000
42 2238  3 329900
16 2300  4 449900
3  2400  3 369000
28 2526  3 469000
43 2567  4 314000
19 2609  4 499998
30 2637  3 299900
5  3000  4 539900
20 3031  4 599000
34 3137  3 579900
25 3890  3 573900
14 4478  5 699900
39 4515  4 549000
')[, -1]

推荐阅读