赞
踩
1.异常值是指样本中的个别值,其数值明显偏离其余的观测值。异常值也称离群点,异常值的分析也称为离群点的分析
2.异常值的处理,先是辨别出哪些是异常值,再根据实际情况选择如何处理异常值。
3.异常值分析
4.异常值的处理方法
3σ原则是指若数据服从正态分布,异常值被定义为一组测定值与其平均值的差的绝对值超过3倍标准差值 → p(|x - μ| > 3σ) ≤ 0.003
但使用3σ原则需要先判断数据是否服从正态分布,服从正态分布才能使用该原则判断异常值
正态性检验是指利用观测数据判断总体是否服从正态分布的检验称为正态性检验,它是统计判决中重要的一种特殊的拟合优度假设检验
→ 正态性检验方法:KS检验
→KS检验理论简介:
- KS(Kolmogorov-Smirnov)检验用于检验数据是否符合某种分布,是比较一个频率分布f(x)与理论分布g(x)或者两个观测值分布的检验方法。
- 其原假设H0:两个数据分布一致或者数据符合理论分布。D=max| f(x)- g(x)|,当实际观测值D>D(n,α)则拒绝H0,否则则接受H0假设。KS检验与t-检验之类的其他方法不同,KS检验不需要知道数据的分布情况,可以算是一种非参数检验方法。
- 当然这样方便的代价就是当检验的数据分布符合特定的分布时,KS检验的灵敏度没有相应的检验来的高。在样本量比较小的时候,KS检验在为非参数检验在分析两组数据之间是否不同时,是相当常用。
- 虽然KS检验的定义中说检验的数据必须是连续的,若在非连续数据上用KS检验检验的显著性回下降,想要获得准确值就需要用其他检验,比如chi-square goodness-to-fit 但在实际操作中,如果离散分布的数据够多的话,用KS检验的显著性不会有太大影响,可以比较放心使用。
→ KS检验的参数解释:
- KS检验会返回两个值,D值和p值。
- D值:表示两个分布之间最大距离,即系D值越小,表示两个分布的差距越小,分布也就越一致。
- p值:表示假设检验中的p值,因为原假设为“待检验的两个数据的分布一致”,即系若p值>0.05(p值的设定取决于实际要求),那么就不能拒绝原假设,即系“待检验的两个数据分布一致”这个假设成立。
# 设置cell多行输出
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = 'all' #默认为'last'
# 导入相关库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import os
os.chdir(r'E:\python_learn\train')
# 读取数据
file_name = 'data_abnormal.csv'
data = pd.read_csv(file_name,usecols=['key1','key2','key3'])
print(data.head())
key1 key2 key3
0 171.478895 31.816106 -235.872855
1 38.145928 -44.222959 -45.868820
2 -14.594276 7.455609 -39.576063
3 118.362921 15.007191 83.177483
4 -5.589237 114.340285 135.983500
# 直接用算法做KS检验
from scipy import stats
# 创建函数
def f(x):
return stats.kstest(x,'norm',(x.mean(),x.std()))
# .kstest方法:KS检验,参数分别是:待检验的数据,检验方法(这里设置成norm正态分布),均值与标准差
data_stats = data.apply(f) # 将算法直接映射到每一列
data_stats.values
# 结果返回两个值:statistic → D值,pvalue → P值
# p值大于0.05,为正态分布
array([KstestResult(statistic=0.009734859311949784, pvalue=0.7305177443558707),
KstestResult(statistic=0.008796876410950949, pvalue=0.8338347831965152),
KstestResult(statistic=0.013374626202709239, pvalue=0.3327578473536996)],
dtype=object)
从所返回的D值和p值得出,数据集每列数据都符合正态分布的规律,因此可以使用3σ进行异常值检测。
公式: |x - μ| >3σ为异常值,也就是说一组测定值与其平均值的差的绝对值超过3倍标准差值即为异常值
# 数据缺失值查看
print(data.head())
data.isna().sum()
data.isna().sum().sum() # → 不存在缺失值
key1 key2 key3 0 171.478895 31.816106 -235.872855 1 38.145928 -44.222959 -45.868820 2 -14.594276 7.455609 -39.576063 3 118.362921 15.007191 83.177483 4 -5.589237 114.340285 135.983500 key1 0 key2 0 key3 0 dtype: int64 0
# 筛出异常值
df = data.copy() # 复制一份数据
lst = []
cols = df.columns
for col in cols:
df_col = df[col]
err = df_col[np.abs(df_col-df_col.mean())>3*df_col.std()] # 筛出异常数据
lst.append(err)
err_data = pd.concat(lst)
print('一共检测到异常值共:%i'%len(err_data),'\n')
print('异常值展示前10条:\n',err_data.head(10))
一共检测到异常值共:43
异常值展示前10条:
197 318.319213
1319 331.880033
2074 -416.500736
2109 300.174181
2922 -488.395881
3182 360.454103
3793 324.765684
3863 335.669291
4096 -307.131874
4272 -310.307727
dtype: float64
# 将异常值替换为NaN,并插补补全
normal = df[np.abs(df-df.mean())<3*df.std()] # 异常值是|x - μ| >3σ,反之小于3σ的值为正常
# 返回一个已用NaN替换掉异常值的DataFrame
normal.isna().sum() # 查看是否有空值 → 存在缺失值,表示已将异常值替换为NaN
normal.isna().sum().sum()
df_clean = normal.fillna(normal.median()) # 使用中位数插补
df_clean.isna().sum()
df_clean.isna().sum().sum() # 检查空值是否已处理
key1 11 key2 11 key3 21 dtype: int64 43 key1 0 key2 0 key3 0 dtype: int64 0
以上就是3σ原则检测异常值的操作过程
箱形图(Box-plot)又称为盒须图、盒式图或箱线图,是一种用作显示一组数据分散情况资料的统计图。
箱形图的六个数据节点:
箱形图的作用:
① 识别数据的异常值
② 易于发现数据的偏态和尾重
③ 能用于数据性探索分析,分析数据的形状
print(data.head()) # 原始数据展示
# 查看缺失值
data.isna().sum()
data.isna().sum().sum() # → 不存在缺失
key1 key2 key3 0 171.478895 31.816106 -235.872855 1 38.145928 -44.222959 -45.868820 2 -14.594276 7.455609 -39.576063 3 118.362921 15.007191 83.177483 4 -5.589237 114.340285 135.983500 key1 0 key2 0 key3 0 dtype: int64 0
# 箱型图查看数据
color = dict(boxes='DarkGreen', whiskers='DarkOrange', medians='DarkBlue', caps='Gray') # 颜色设置
box=df2.plot.box(figsize=(12,8),return_type='dict',color=color)
plt.title('异常值检测-箱型图',fontsize=14,pad=12)
从箱型图反映的情况可知,每列数据都存在异常值的情况。
# 筛出异常值 df2 = data.copy() # 复制一份数据 lst = [] cols = df2.columns for col in cols: df2_col = df2[col] q1 = df2_col.quantile(0.25) q3 = df2_col.quantile(0.75) iqr = q3-q1 ma = q3+iqr*1.5 mi = q1-iqr*1.5 error = df2_col[(df2_col>ma) | (df2_col<mi)] # 筛出异常 lst.append(error) err_data = pd.concat(lst) print('一共检测到异常值共:%i'%len(err_data),'\n') print('异常值展示前10条:\n',err_data.head(10))
一共检测到异常值共:130
异常值展示前10条:
85 -296.923702
197 318.319213
344 -268.979898
461 266.571340
609 -294.773187
615 -278.354103
819 293.908994
860 -275.333416
946 -269.933060
1232 278.143495
dtype: float64
# 处理异常值 → 替换为NaN,并以插值方法处理
Q1 = df2.quantile(0.25)
Q3 = df2.quantile(0.75)
IQR = Q3-Q1
Max = Q3+IQR*1.5
Min = Q1-IQR*1.5
data_nor = df2[(df2 >= Min) & (df2 <= Max)] # 将正常的数据按数据框形式筛选出来,返回一个已用NaN替换掉异常值的DataFrame
data_nor.isna().sum()
data_nor.isna().sum().sum()
# 插值处理NaN
data_clean = data_nor.fillna(data_nor.median())
data_clean.isna().sum() # 确认缺失值已处理
key1 45 key2 32 key3 53 dtype: int64 130 key1 0 key2 0 key3 0 dtype: int64
以上就是箱型图检测异常值的操作过程*
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。