>
>
>
>
一、问题
什么是异常值?如何检测异常值?请伙伴们思考或者留言讨论。
>>>>
二、解决方法
1. 单变量异常值检测
2. 使用局部异常因子进行异常值检测
3. 通过聚类的方法检验异常值
4. 检验时间序列数据里面的异常值
>>>>
三、R代码实现
1、单变量异常值检测
这一节主要讲单变量异常值检测,并演示如何将它应用到多元(多个自变量)数据中。使用函数boxplot.stats()实现单变量检测,该函数根据返回的统计数据生成箱线图。在上述函数的返回结果中,有一个参数out,它是由异常值组成的列表。更明确的说就是里面列出了箱线图中箱须线外面的数据点。其中参数coef可以控制箱须线从箱线盒上延伸出来的长度,关于该函数的更多细节可以通过输入‘?boxplot.ststs’查看。
画箱线图:
在一个应用中,如果有三个或者3个以上自变量,异常值最终的列表应该根据各个单变量异常检测到的异常数据的总体情况而产生。在现实应用中,要将理论和程序运行结果一起考虑从而检验出比较合适的异常值。
2、使用LOF(局部异常因子)检测异常值
LOF(局部异常因子)是一种基于密度识别异常值的算法。算法实现是:将一个点的局部密度与分布在它周围的点的密度相比较,如果前者明显的比后者小,那么这个点相对于周围的点来说就处于一个相对比较稀疏的区域,这就表明该点事一个异常值。LOF算法的缺点是它只对数值型数据有效。
使用包‘DMwR’和包‘dprep’中的lofactor()可以计算LOF算法中的局部异常因子。
接下来对鸢尾花数据进行主成分分析,并利用产生的前两个主成分绘制成双标图来显示异常值。
上面的代码中,prcomp()实现对数据集iris2的主成分分析,biplot()取主成分分析结果的前两列数据也就是前两个主成分绘制双标图。上图中,x轴和y轴分别代表第一、二主成分,箭头指向了原始变量名,其中5个异常值分别用对应的行号标注。
我们也可以通过pairs()函数绘制散点图矩阵来显示异常值,其中异常值用红色的'+'标注:
包Rlof提供函数lof()能并行实现LOF算法。它的用法类似于lofacotor(),但是lof()能实现两个额外的功能:k可以是一个向量以及选择多个距离侧度。下面是关于lof()函数实现的例子:
3、通过聚类检测异常值
检测异常值的另外一种方式就是聚类。先把数据聚成不同的类,选择不属于任何类的数据作为异常值。例如,基于密度的聚类DBSCAN算法的实现就是将与数据稠密区域紧密相连的数据对象划分为一个类,因此与其他对象分离的数据就会作为异常值。
也可以使用K均值算法实现异常值的检测。首先通过把数据划分为k组,划分方式是选择距离各自簇中心最近的点为一组;然后计算每个对象和对应的簇中心的距离(或者相似度),并挑出拥有最大的距离的点作为异常值。
使用鸢尾花数据集,结合k均值算法进行异常值检验的代码如下:
4、检测时间序列中的异常值
本节介绍如何从时间序列数据中检测出异常值。首先使用函数stl()对时间序列数据进行稳健回归方法分解,然后识别出异常值。实现代码如下:
5、思考
试着思考其他的异常值检验算法,并查询R中其他的包是否可以很好的检测到异常值。