【免责声明:用于教学资料整理】

目录:

一. 用箱线图检测异常值

二. 使用局部异常因子法(LOF法)检测异常值

三. 用聚类方法检测异常值

四. 检测时间序列数据中的异常值

五. 基于稳健马氏距离检测异常值

正文:

异常值,是指测量数据中的随机错误或偏差,包括错误值或偏离均值的孤立点值。在数据处理中,异常值会极大的影响回归或分类的效果。

为了避免异常值造成的损失,需要在数据预处理阶段进行异常值检测。另外,某些情况下,异常值检测也可能是研究的目的,例如,数据造假的发现、电脑入侵的检测等。

一、用箱线图检测异常值

在一条数轴上,以数据的上下四分位数(Q1-Q3)为界画一个矩形盒子(中间50%的数据落在盒内);在数据的中位数位置画一条线段为中位线;用◇标记数据的均值;默认延长线不超过盒长的1.5倍,之外的点认为是异常值(用○标记)。

盒形图的主要应用就是,剔除数据的异常值、判断数据的偏态和尾重。

R语言实现,使用函数boxplot.stats(),基本格式为:

[stats, n, conf, out]=

boxplot.stats(x, coef=1.5, do.conf=TRUE, do.out=TRUE)

其中,x为数值向量(NA、NaN值将被忽略);coef为盒须的长度为几倍的IQR(盒长),默认为1.5;do.conf和do.out设置是否输出conf和out

返回值:stats返回5个元素的向量值,包括盒须最小值、盒最小值、中位数、盒最大值、盒须最大值;n返回非缺失值的个数;conf返回中位数的95%置信区间;out返回异常值。

单变量异常值检测

set.seed(2016)

x<-rnorm(100) #生成100个服从N(0,1)的随机数

summary(x) #x的汇总信息

Min. 1st Qu. Median Mean 3rd Qu. Max.

-2.7910 -0.7173 -0.2662 -0.1131 0.5917 2.1940

boxplot.stats(x) #用箱线图检测x中的异常值

$stats

[1] -2.5153136 -0.7326879 -0.2662071 0.5929206 2.1942200

$n

[1] 100

$conf

[1] -0.47565320 -0.05676092

$out

[1] -2.791471

boxplot(x) #绘制箱线图

多变量异常值检测

x<-rnorm(100)

y<-rnorm(100)

df<-data.frame(x,y) #用x,y生成两列的数据框

head(df)

x y

1 0.41452353 0.4852268

2 -0.47471847 0.6967688

3 0.06599349 0.1855139

4 -0.50247778 0.7007335

5 -0.82599859 0.3116810

6 0.16698928 0.7604624

#寻找x为异常值的坐标位置

a<-which(x %in% boxplot.stats(x)$out)

a

[1] 78 81 92

#寻找y为异常值的坐标位置

b<-which(y %in% boxplot.stats(y)$out)

b

[1] 27 37

intersect(a,b) #寻找变量x,y都为异常值的坐标位置

integer(0)

plot(df) #绘制x, y的散点图

p2<-union(a,b) #寻找变量x或y为异常值的坐标位置

[1] 78 81 92 27 37

points(df[p2,],col="red",pch="x",cex=2) #标记异常值

二、使用局部异常因子法(LOF法)检测异常值

局部异常因子法(LOF法),是一种基于概率密度函数识别异常值的算法。LOF算法只对数值型数据有效。

算法原理:将一个点的局部密度与其周围的点的密度相比较,若前者明显的比后者小(LOF值大于1),则该点相对于周围的点来说就处于一个相对比较稀疏的区域,这就表明该点是一个异常值。

R语言实现:使用DMwR或dprep包中的函数lofactor(),基本格式为:

lofactor(data, k)

其中,data为数值型数据集;k为用于计算局部异常因子的邻居数量。

library(DMwR)

iris2<-iris[,1:4] #只选数值型的前4列

head(iris2)

Sepal.Length Sepal.Width Petal.Length Petal.Width

1 5.1 3.5 1.4 0.2

2 4.9 3.0 1.4 0.2

3 4.7 3.2 1.3 0.2

4 4.6 3.1 1.5 0.2

5 5.0 3.6 1.4 0.2

6 5.4 3.9 1.7 0.4

out.scores<-lofactor(iris2,k=10) #计算每个样本的LOF值

plot(density(out.scores)) #绘制LOF值的概率密度图

#LOF值排前5的数据作为异常值,提取其样本号

out<-order(out.scores,decreasing=TRUE)[1:5]

out

[1] 42 107 23 16 99

iris2[out,] #异常值数据

Sepal.Length Sepal.Width Petal.Length Petal.Width

42 4.5 2.3 1.3 0.3

107 4.9 2.5 4.5 1.7

23 4.6 3.6 1.0 0.2

16 5.7 4.4 1.5 0.4

99 5.1 2.5 3.0 1.1

对鸢尾花数据进行主成分分析,并利用产生的前两个主成分绘制成双标图来显示异常值:

n<-nrow(iris2) #样本数

n

[1] 150

labels<-1:n #用数字1-n标注

labels[-out]<-"." #非异常值用"."标注

biplot(prcomp(iris2),cex=0.8,xlabs=labels)

说明:函数prcomp()对数据集iris2做主成份分析,biplot()取主成份分析结果的前两列数据即前两个主成份绘制双标图。上图中,x轴和y轴分别代表第一、二主成份,箭头指向了原始变量名,其中5个异常值分别用对应的行号标注。

也可以通过函数pairs()绘制散点图矩阵来显示异常值,其中异常值用红色的"+"标注:

pchs<-rep(".",n)

pchs[out]="+"

cols<-rep("black",n)

cols[out]<-"red"

pairs(iris2,pch=pchs,col=cols)

:另外,Rlof包中函数lof()可实现相同的功能,并且支持并行计算和选择不同距离。

三、用聚类方法检测异常值

通过把数据聚成类,将那些不属于任何一类的数据作为异常值。比如,使用基于密度的聚类DBSCAN,如果对象在稠密区域紧密相连,则被分组到一类;那些不会被分到任何一类的对象就是异常值。

也可以用k-means算法来检测异常值:将数据分成k组,通过把它们分配到最近的聚类中心。然后,计算每个对象到聚类中心的距离(或相似性),并选择最大的距离作为异常值。

kmeans.result<-kmeans(iris2,centers=3) #kmeans聚类为3类

kmeans.result$centers #输出聚类中心

Sepal.Length Sepal.Width Petal.Length Petal.Width

1 5.901613 2.748387 4.393548 1.433871

2 5.006000 3.428000 1.462000 0.246000

3 6.850000 3.073684 5.742105 2.071053

kmeans.result$cluster #输出聚类结果

[1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2

[30] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 3 1 1 1 1 1

[59] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 1 1

[88] 1 1 1 1 1 1 1 1 1 1 1 1 1 3 1 3 3 3 3 1 3 3 3 3 3 3 1 1 3

[117] 3 3 3 1 3 1 3 1 3 3 1 1 3 3 3 3 3 1 3 3 3 3 1 3 3 3 1 3 3

[146] 3 1 3 3 1

#centers返回每个样本对应的聚类中心样本

centers <- kmeans.result$centers[kmeans.result$cluster, ]

#计算每个样本到其聚类中心的距离

distances<-sqrt(rowSums((iris2-centers)^2))

#找到距离最大的5个样本,认为是异常值

out<-order(distances,decreasing=TRUE)[1:5]

out #异常值的样本号

[1] 99 58 94 61 119

iris2[out,] #异常值

Sepal.Length Sepal.Width Petal.Length Petal.Width

99 5.1 2.5 3.0 1.1

58 4.9 2.4 3.3 1.0

94 5.0 2.3 3.3 1.0

61 5.0 2.0 3.5 1.0

119 7.7 2.6 6.9 2.3

#绘制聚类结果

plot(iris2[,c("Sepal.Length","Sepal.Width")],pch="o",col=kmeans.result$cluster,cex=0.3)

#聚类中心用"*"标记

points(kmeans.result$centers[,c("Sepal.Length", "Sepal.Width")], col=1:3, pch=8, cex=1.5)

#异常值用"+"标记

points(iris2[out,c("Sepal.Length", "Sepal.Width")], pch="+", col=4, cex=1.5)

四、检测时间序列数据中的异常值

对时间序列数据进行异常值检测,先用函数stl()进行稳健回归分解,再识别异常值。

函数stl(),基于局部加权回归散点平滑法(LOESS),对时间序列数据做稳健回归分解,分解为季节性、趋势性、不规则性三部分。

f<-stl(AirPassengers,"periodic",robust=TRUE)

#weights返回稳健性权重,以控制数据中异常值产生的影响

out<-which(f$weights < 1e-8) #找到异常值

out

[1] 79 91 92 102 103 104 114 115 116 126 127 128 138 139 140

#设置绘图布局的参数

op<-par(mar=c(0,4,0,3), oma=c(5,0,4,0), mfcol=c(4,1))

plot(f,set.pars=NULL)

#time.series返回分解为三部分的时间序列

> head(f$time.series,3)

seasonal trend remainder

[1,] -16.519819 123.1857 5.3341624

[2,] -27.337882 123.4214 21.9164399

[3,] 9.009778 123.6572 -0.6670047

sts<-f$time.series

#用红色"x"标记异常值

points(time(sts)[out], 0.8*sts[,"remainder"][out], pch="x", col="red")

par(op)

五、基于稳健马氏距离检测异常值

检验异常值的基本思路是观察各样本点到样本中心的距离,若某些样本点的距离太大,就可以判断是异常值。

若使用欧氏距离,则具有明显的缺点:将样本不同属性(即各指标变量)之间的差别等同看待。而马氏距离则不受量纲的影响,并且在多元条件下,还考虑到了变量之间的相关性。

对均值为μ,协方差矩阵为Σ的多变量向量,其马氏距离为

(x-μ)TΣ-1(x-μ)

但是传统的马氏距离检测方法是不稳定的,因为个别异常值会把均值向量和协方差矩阵向自己方向吸引,这就导致马氏距离起不了检测异常值的所用。解决方法是利用迭代思想构造一个稳健的均值和协方差矩阵估计量,然后计算稳健马氏距离,这样异常值就能正确地被识别出来。

用mvoutlier包实现,

library(mvoutlier)

set.seed(2016)

x<-cbind(rnorm(80),rnorm(80))

y<-cbind(rnorm(10,5,1), rnorm(10,5,1)) #噪声数据

z<-rbind(x,y)

res1<-uni.plot(z) #一维数据的异常值检验

#返回outliers标记各样本是否为异常值,md返回数据的稳健马氏距离

which(res1$outliers==TRUE) #返回异常值的样本号

[1] 81 82 83 84 85 86 87 88 89 90

res2<-aq.plot(z) #基于稳健马氏距离的多元异常值检验

which(res2$outliers==TRUE) #返回异常值的样本号

[1] 81 82 83 84 85 86 87 88 89 90

上图为在一维空间中观察样本数据。

说明:图1-1为原始数据;图1-2的X轴为各样本的稳健马氏距离排序,Y轴为距离的经验分布,红色曲线为卡方分布,蓝色垂线表示阀值,在阀值右侧的样本判断为异常值;图2-1和2-2均是用不同颜色来表示异常值,只是阀值略有不同。

若数据的维数过高,则上述距离不再有很大意义(例如基因数据有几千个变量,数据之间变得稀疏)。此时可以融合主成份降维的思路来进行异常值检验。mvoutlier包中提供了函数pcout()来对高维数据进行异常值检验。

data(swiss) #使用swiss数据集

res3<-pcout(swiss)

#返回wfinal01标记是否为异常值,0表示是

which(res3$wfinal01==0) #返回异常值的样本号

Delemont Franches-Mnt Porrentruy Broye

2 3 6 7

Glane Gruyere Sarine Veveyse

8 9 10 11

La Vallee Conthey Entremont Herens

19 31 32 33

Martigwy Monthey St Maurice Sierre

34 35 36 37

Sion V. De Geneve

38 45

:对于分类数据,一个快速稳定的异常检测的策略是AVF (Attribute Value Frequency)算法。

主要参考文献

《R语言-异常值处理1-3》,银河统计学,博客园

http://www.cnblogs.com/cloudtj/category/780800.html

剔除异常值栅格计算器_R语言系列 数据清洗3 异常值处理相关推荐

  1. 50万数据生成6位数不重复字符串_R语言系列3:高级数据管理

    R语言系列3:高级数据管理 此文内容为<R语言实战>的笔记,人民邮电出版社出版. 从高中电脑课学VB开始,大一课内开始学习C++,到后来大二为了数模学习Matlab,到大三为了搞深度学习自 ...

  2. 格兰杰因果关系检验r语言_R语言系列第四期:R语言单样本双样本差异性检验

    之前详细介绍了利用R语言进行统计描述,详情点击:R语言系列第三期:①R语言单组汇总及图形展示.R语言系列第三期:②R语言多组汇总及图形展示.R语言系列第三期:③R语言表格及其图形展示 从这个部分我们就 ...

  3. R count函数_R语言系列第二期:R变量、脚本、作图等模块介绍

    在上一篇文章里,给大家介绍了R语言的下载,界面操作,6个处理对象等等.R语言系列第一期(番外篇 ):R的6种对象-向量.矩阵.数组.因子.列表.数据框 在这些内容的基础上,我们在这个部分为大家介绍一些 ...

  4. 剔除异常值栅格计算器_基于数据流的异常检测: Random Cut Forest

    一.解决的问题 数据是实时产生的,对数据进行批处理所花费的成本太高了,数据产生的价值被低估 在高维数据下,如何能发现异常的维度? If my time-series data with 30 feat ...

  5. r语言 线性回归 相关系数_R语言系列第四期:R语言简单相关与回归

    这一系列里前面的三个部分都是用于比较组间差异的各种方法. 在这个部分里,我们会为大家介绍如何使用R进行基础回归和相关分析,以及模型作图.置信区间的预估和展示. A. 简单线性回归 我们使用数据集thu ...

  6. r语言 整理、处理数据步骤_R语言万能数据清洗整理包Tidyverse(一)

    数据整理和清洗是任何统计分析的前提,也是最为困难的一个环节,很多软件也提供了数据整理和清洗的功能.甚至连我们常用的EXCEL也可以做这个工作,但是效率很低,而且容易出错,且无法完整保存清洗过程.R语言 ...

  7. 语言时间序列年月日_R语言系列 时间序列分析

    [免责声明:本文用于教学] 时间序列分析 基础操作 数据输入 d <- c(10,15,10,10,12,10,7,7,10,14,8,17,14,18,3,9,11,10,6,12,14,10 ...

  8. r数据框计算字符出现次数_R语言系列第二期:①R变量、脚本、作图等模块介绍...

    在上一篇文章里,给大家介绍了R语言的下载,界面操作,6个处理对象等等. 在这些内容的基础上,我们在这个部分为大家介绍一些实用知识,包括描述工作区结构.图形设备以及它们的参数等问题,还有初级编程和数据输 ...

  9. r roc曲线 语言_R语言系列6:生存分析中多重时间依赖性ROC曲线绘制 timeROC

    上一篇文章,我们讲到R语言实现Cox回归生存预测模型构建,以及如何将Logistic回归中,多条ROC曲线绘制在一个图里 今天主要围绕生存分析中,预测模型验证部分,如何将多条time-depend e ...

最新文章

  1. 磁悬浮地球仪控制初步测试
  2. BUUCTF(pwn) ciscn_2019_s_3 [ 栈溢出SROP攻击]
  3. Python实现快速排序(非递归实现)
  4. html不可选择的按钮,HTML功能无法使用按钮
  5. css新奇技术及其未来发展
  6. 一个websocket 可以多个页面创建吗_实战分享|给我一个Puppeteer,没有爬不了的网站
  7. 如何抓取所有域用户的hash(win2008--win2012)
  8. RedHat7 Git 安装使用
  9. MESSAGE消息发送失败
  10. can't resolve symbol 'R' ...
  11. 东北大学linux程序设计考试,Linux认证考试试题及答案
  12. 示波器学习笔记(2)——模拟示波器
  13. xbox 手柄按键测试软件,unity中链接Xbox手柄设置及按键检测
  14. 回溯法求解TSP问题(旅行商问题)
  15. mysql学习心得总结
  16. 架构师必备!15个经典面试问题及回答思路
  17. 场景二:刮刮卡,大转盘等抽奖算法
  18. [Android]从canDrawOverlays权限获取错误说起
  19. android+4.4+打印功能,安卓android4.4新增打印支付功能
  20. 计算机英语boot,电脑开不了机显示英文boottmgr

热门文章

  1. %d 跟%i 的区别以及scanf和sscanf的用法
  2. #pragma pack(push,1) #pragma pack(pop)
  3. 计算机无法识别文件夹,电脑提示错误:此卷不包含可识别的文件系统的解决办法...
  4. C++ 标准库类型 stack
  5. 21-5-22校赛G 自行车调度
  6. 深度强化学习入门介绍
  7. 【竞赛经验分享】2020腾讯广告算法大赛:如何突破分数瓶颈?
  8. 重磅发布!吴恩达 AI 完整课程资源超级大汇总!
  9. ECCV 2018 | Bi-box行人检测:‘行人遮挡’为几何?
  10. WE CAN:全球智能路由网络 | 体验共享技术专题