Python实现基于3σ原则的异常值检测

Python实现基于3σ原则的异常值检测异常值是指样本中的个别值明显偏离其余的观测值

异常值是指样本中的个别值明显偏离其余的观测值。异常值的存在会对数据分析、建模产生干扰,因此需要对数据集进行异常值检测并进行异常值删除或修正,以便后续更好地进行数据分析和挖掘。对于异常值检测,有描述性统计、3σ原则方法、箱线图、基于聚类的方法等,而3σ原则是最常使用的异常值检测方法之一。在3σ原则下,一般认为数据的取值99.7%的概率集中在(μ-3σ,μ+3σ)区间内(μ为平均值,σ为标准差),超出这个范围的可能性仅占0.3%,属于极个别的小概率事件,因此将超出(μ-3σ,μ+3σ)范围的值认为是异常值。3σ原则要求数据服从正态或近似正态分布,且样本数据大于10。若数据不服从正态分布,也可以用远离平均值的多少倍标准差来描述。现利用Python实现基于3σ原则的异常值检测,并对从网络上查询的中国1952年-2018年中国GDP(亿)、GDP指数((上年=100)) 人均GDP()、GDP增长率(%)、第二产业增加值(亿) 、第三产业增加值(亿)等24个指标数据进行异常值检测。
在这里插入图片描述

#基于3sigma的异常值检测 #-*- coding: utf-8 -*- import numpy as np import pandas as pd import matplotlib.pyplot as plt #导入绘图库 3sigma原则 def threesigma(data,n): ''' data:表示时间序列,包括时间和数值两列; n:表示几倍的标准差 ''' data_x = data.ix[:,0].tolist() 获取时间序列的时间 #print (data_x) #print ("",j) mintime=data_x[0] 获取时间序列的起始年份 maxtime=data_x[-1] 获取时间序列的结束年份 data_y = data.ix[:,1].tolist() 获取时间序列数值 ymean = np.mean(data_y) 求时间序列平均值 ystd = np.std(data_y) 求时间序列标准差 down = ymean - n * ystd 计算下界 up = ymean + n * ystd 计算上界 outlier = [] #将异常值保存 outlier_x = [] for i in range(0, len(data_y)): if (data_y[i] < down)|(data_y[i] > up): outlier.append(data_y[i]) outlier_x.append(data_x[i]) else: continue return mintime,maxtime,outlier,outlier_x #设置列表,用于记录结果 indicator=[] 指标 flag=[] 是否为异常值 outlier_data=[] 异常值 outlier_time=[] 出现异常值的对应时间 max_time=[] 时间序列的开始时间 min_time=[] 时间序列的结束时间 time_flag=[] 异常值是否为起始时间 #读取数据 data = pd.read_csv( 'data.csv', index_col = False,encoding='gb18030') #读取数据 #print(data.head()) col_name=data.columns.tolist() #print (data.columns.tolist()) #设置参数 n = 3 # n*sigma print (":n=",n) 依次检测每一个指标 for j in col_name[1:]: indicator.append(j) temp_data=data.ix[:,['时间',j]] #print ("删除空值前",len(temp_data)) temp_data=temp_data.dropna() #删除空值 #print("删除空值后",len(temp_data)) temp_data=temp_data.sort_values(by = ['时间'],axis = 0,ascending = True) #按时间排序 #print (temp_data) mintime,maxtime,outlier,outlier_x=threesigma(temp_data,n) #调用3sigma函数 min_time.append(mintime) 获取时间序列的起始年份 max_time.append(maxtime) 获取时间序列的结束年份 outlier_data.append(outlier) outlier_time.append(outlier_x) if (maxtime in outlier_x) or (mintime in outlier_x): time_flag.append('异常值为起始端') #print (time_flag) else: time_flag.append("") if len(outlier)>0: flag.append('异常') print("*") print ("异常指标:",j) print('\n异常数据如下:',outlier,outlier_x) 画出存在异常值的时间序列的折线图,异常值处特殊标注 plt.figure(figsize=(12,5)) plt.plot(temp_data.ix[:,0], temp_data.ix[:,1]) plt.plot(outlier_x, outlier, 'ro') for j in range(len(outlier)): plt.annotate(outlier[j], xy=(outlier_x[j], outlier[j]), xytext=(outlier_x[j],outlier[j])) plt.show() else: flag.append('正常') result=pd.DataFrame() result['指标']=indicator result['开始时间']=min_time result['结束时间']=max_time result['是否异常']=flag result['异常数值']=outlier_data result['异常时间']=outlier_time result['异常值所处时间标识']=time_flag result 

在这里插入图片描述
对于抛出来的异常值要重点关注,并且结合实际的业务情况来判断数据是否真的存在异常,以及何种原因导致的异常,进而确定异常值的处理方式。

  • GDP指数(上年=100):1961年我国刚刚经过三年自然灾害,查询多方面资料证实数据没有问题,不作处理。
    在这里插入图片描述
  • 第三产业占GDP比重(%):查询多方面资料证实数据确实存在问题,进行修正。
    在这里插入图片描述
  • 第三产业增加值(亿):异常值出现在时间序列的起始端,通过折线图和多方面资料证实数据没有问题,不作处理。
    在这里插入图片描述
    附数据和源程序。链接:https://bianchenghao.cn/s/1RLC6769nJLKUG3woWsv17w 提取码:rmjc

ps:初衷是通过撰写博文记录自己所学所用,实现知识的梳理与积累;将其分享,希望能够帮到面临同样困惑的小伙伴儿。如发现博文中存在问题,欢迎随时交流~~

今天的文章 Python实现基于3σ原则的异常值检测分享到此就结束了,感谢您的阅读。
编程小号
上一篇 2024-12-16 07:33
下一篇 2024-12-16 07:30

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/88173.html