R语言--异常值检测

自编函数,boxplot()原理

outlier.IQR <- function(x, multiple = 1.5, replace = FALSE, revalue = NA) { 
  q <- quantile(x, na.rm = TRUE) #四分位间距3倍间距以外的认为是离群值
  IQR <- q[4] - q[2]
  x1 <- which(x < q[2] - multiple * IQR | x > q[4] + multiple * IQR)
  x2 <- x[x1]
  if (length(x2) > 0) outlier <- data.frame(location = x1, value = x2)
  else outlier <- data.frame(location = 0, value = 0)
  if (replace == TRUE) {
    x[x1] <- revalue
  }
  return(list(new.value = x, outlier = outlier))
}

结果输出为列表,分别为 outlier.IQR()$new.valueoutlier.IQR()$outlier。前者为异常值替换后的新向量,后者为原向量中异常值及其所在位置。

异常检测,主要内容如下:

(1)单变量的异常检测

(2)使用LOF(local outlier factor,局部异常因子)进行异常检测

(3)通过聚类进行异常检测

(4)对时间序列进行异常检测

单变量异常检测

本部分展示了一个单变量异常检测的例子,并且演示了如何将这种方法应用在多元数据上。在该例中,单变量异常检测通过boxplot.stats()函数实现,并且返回产生箱线图的统计量。在返回的结果中,有一个部分是out,它结出了异常值的列表。更明确点,它列出了位于极值之外的胡须。参数coef可以控制胡须延伸到箱线图外的远近。在R中,运行?boxplot.stats可获取更详细的信息。

如图呈现了一个箱线图,其中有四个圈是异常值。

> set.seed(1234)
> x <- rnorm(1000)
> summary(x)
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
-3.39606 -0.67325 -0.03979 -0.02660  0.61582  3.19590 
> boxplot.stats(x)$out
 [1]  3.043766 -2.732220 -2.855759  2.919140 -3.233152 -2.651741
 [7] -3.396064  3.195901 -2.729680 -2.704203 -2.864347 -2.661346
[13]  2.705775 -2.906674 -2.874042 -2.757050 -2.739754
> y=rep(1,1000)
> z = data.frame(x,y)
> g <- ggplot(z,aes(y=x,x=y))
> g+geom_boxplot()

这里写图片描述

如上的单变量异常检测可以用来发现多元数据中的异常值,通过简单搭配的方式。在下例中,我们首先产生一个数据框df,它有两列x和y。之后,异常值分别从x和y检测出来。然后,我们获取两列都是异常值的数据作为异常数据。

在下图中,异常值用红色标记为”+”

> y = rnorm(1000)
> df <- data.frame(x,y)
> rm(x,y)
> head(df)
           x          y
1 -1.2070657 -1.2053334
2  0.2774292  0.3014667
3  1.0844412 -1.5391452
4 -2.3456977  0.6353707
5  0.4291247  0.7029518
6  0.5060559 -1.9058829

> attach(df)
> #find the index of outliers from x
> (a<- which(x  %in% boxplot.stats(x)$out))
 [1] 178 181 192 227 237 382 392 486 487 517 558 717 771 788 901 949
[17] 967
> 
> #find the index of outliers from y
> 
> (b <- which(y %in% boxplot.stats(y)$out))
[1] 121 233 317 359 517 660 815
> 

> detach(df)
> #outliers in both x and y
> (outlier.list1 <- intersect(a,b))
 [1] 517 
> 

plot(df)
points
  • 8
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值