获取数据,得到均值、方差,进行正态分布判断,如符合正态分布,则返回异常值和异常位置索引,并进行绘图。主要用到了numpy,matplotlib和scipy。下一步会考虑长尾分布数据的异常值检测。
代码语言:javascript复制# 根据4σ法则和正态分布,进行数据异常值判断和识别
# 如果数据服从正态分布,异常值被定义为一组测定值中与平均值的偏差超过3倍的值 → p(|x - μ| > 3σ) ≤ 0.003
# 数值分布在(μ-σ,μ σ)中的概率为0.6827
# 数值分布在(μ-2σ,μ 2σ)中的概率为0.9545
# 数值分布在(μ-3σ,μ 3σ)中的概率为0.9973
# 数值分布在(μ-4σ,μ 4σ)中的概率为0.999937
# 获取均值、标准方差,数据异常值索引,数据异常值
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
def getextredata(data,histnum=50,sigmanum=3):
#return Boolean,[],[]
#Boolean 数据是否满足正态分布要求
#extreindex 异常值所在的索引位置
#extremum 异常值的具体内容
dmean = data.mean()
dstd = data.std()
extreindex = np.append(np.where(data > dmean sigmanum * dstd), np.where(data < dmean - sigmanum * dstd))
extremum = data[extreindex]
# 进行KS检验,参数分别是:待检验的数据,检验方法(这里设置成norm正态分布),均值与标准差
D,p_value = stats.kstest(data, 'norm',(dmean,dstd))
if p_value < 0.05: return False,[],[]
#绘制数据直方图-正态分布
hist, bin_edges = np.histogram(data, histnum)
fig = plt.figure(figsize=(10, 6))
ax1 = fig.add_subplot(2, 1, 1)
plt.hist(data, bins=bin_edges) # 画直方图
plt.axvline(dmean sigmanum * dstd, hold=None, color='r', linestyle="--", alpha=0.8) # 添加3σ边界
plt.axvline(dmean - sigmanum * dstd, hold=None, color='r', linestyle="--", alpha=0.8) # 添加3σ边界
plt.title("data histogram")
plt.grid(True)
#绘制散点图-异常值
ax2 = fig.add_subplot(2, 1, 2)
plt.plot(extreindex,extremum, 'o')
plt.title("extredata point")
plt.show()
return True,extreindex,extremum
#生成符合正态分布的数组
data=np.random.normal(6,1,1000000)
# 添加异常值点
data=np.append(data,[1,1,1,2,2,2,2,3,3,3])
data=np.append(data,[9,9,9,10,10,10,10,11,11,11])
data.sort()
ifnorm,extreindex,extremum=getextredata(data,100,3)
print('异常数组索引=',extreindex)
print('异常数组内容=',extremum)