机器学习数据分析之异常值检测

更新时间:2023-07-07 00:26:17 阅读: 评论:0

机器学习数据分析之异常值检测
⽂章⽬录
在检查异常值之前,可以将缺失值填充好。
异常值检验可以分为单变量异常值检验和多变量异常值检验,对于时间序列数据⽽⾔还有趋势预测的时间序列异常值检验。
1.基于统计学的单变量异常值检验
可以先采⽤统计学⽅法查看数据的描述性统计(均值、标准差、最⼩值、最⼤值等信息)
"""假设数据为dataframe"""
# 查看dataframe 的描述性统计
df .describe ()
1.1 3准则
这个原则有个条件:数据需要服从正态分布。在原则下,异常值如超过3倍标准差,那么可以将其视为异常值。正负的概率是
99.7%,那么距离平均值之外的值出现的概率为P(|x-u| > ) <= 0.003,属于极个别的⼩概率事件。如果数据不服从正态分布,也可以⽤远离平均值的多少倍标准差来描述。
数值分布在(μ-σ,μ+σ)中的概率为0.6827
数值分布在(μ-2σ,μ+2σ)中的概率为0.9545
数值分布在(μ-3σ,μ+3σ)中的概率为0.9973
σ3σ3σ3σ3σ
from scipy.stats import kstest
# 正态分布检验
def KsNormDetect(df):
# 计算均值
u = df['value'].mean()
# 计算标准差
std = df['value'].std()
# 计算P值
res=kstest(df,'norm',(u, std))[1]
# 判断p值是否服从正态分布,p<=0.05 则服从正态分布,否则不服从。
if res<=0.05:
print('该列数据服从正态分布------------')家里财神怎样摆放更能招财
print('均值为:%.3f,标准差为:%.3f'%(u, std))
print('------------------------------')
return1
el:
return0
爆炒羊羔肉
# 异常值检测并删除
def OutlierDetection(df, ks_res):
# 计算均值
u = df['value'].mean()
# 计算标准差
std = df['value'].std()
if ks_res==1:
# 定义3σ法则识别异常值
# 识别异常值
error = df[np.abs(df['value']- u)>3* std]
# 剔除异常值,保留正常的数据
data_c = df[np.abs(df['value']- u)<=3* std]
# 输出异常数据
print(error)
return error
el:
print('请先检测数据是否服从正态分布-----------')
21xxxreturn None
df = pd.DataFrame([111,333,12,290,265,152,222,1213,242467,114,231,122,33,2,1,5,22,44], columns=["value"])
ks_res = KsNormDetect(df)
result = OutlierDetection(df, ks_res)
print(result)
1.2 箱型图
这种⽅法是利⽤箱型图的四分位距(IQR)对异常值进⾏检测,也叫Tukey‘s test。
四分位距(IQR)就是上四分位与下四分位的差值。⽽我们通过IQR的1.5倍为标准,规定:超过(上四分位+1.5倍IQR距离,或者下四分位-1.5倍IQR距离)的点为异常值。
# 箱型图实现
def OutlierDetection(df):
揭竿而起# 计算下四分位数和上四分位
Q1 = df.quantile(q=0.25)
Q3 = df.quantile(q=0.75)
# 基于1.5倍的四分位差计算上下须对应的值
low_whisker = Q1 -1.5*(Q3 - Q1)
up_whisker = Q3 +1.5*(Q3 - Q1)
# 寻找异常点
kk = df[(df > up_whisker)|(df < low_whisker)]
data1 = pd.DataFrame({'id': kk.index,'异常值': kk})
return data1
# 创建数据
data =[1222,87,77,92,68,80,78,84,77,81,80,80,77,92,86,76,80,81,75,77,72,81,72,84,86,80,68,77,87,76,77,78,92,75,80,78,123,3, 1223,1232]
df = pd.DataFrame(data, columns=['value'])
df = df.iloc[:,0]
result = OutlierDetection(df)
print('箱线图检测到的异常值如下---------------------')
print(result)
# aborn可视化箱型图
f,ax=plt.subplots(figsize=(10,8))
sns.boxplot(data=df, ax=ax)
plt.show()
1.3 Grubbs检验
σ
夏威夷果怎么打开
3 准则的加强版,适合于近似正态分布数据的检验。
# pip3 install outlier_utils==0.0.3
from outlier import smirnov_grubbs as grubbs
# 默认双边检测,alpha是显著性,输出的结果会删除不满⾜要求的数据
data = pd.Series([1,8,9,10,9])
# 1    8
# 2    9
# 3    10
# 4    9
# dtype: int64
data = np.array([1,8,9,10,9])预制块
# 返回离群指数的单侧(最⼩)检验
grubbs.min_test_indices([8,9,10,1,9], alpha=0.05)#[3]
#返回异常值的单侧(max)测试
grubbs.max_test_outliers([8,9,10,1,9], alpha=0.05)#[]
grubbs.max_test_outliers([8,9,10,50,9], alpha=0.05)#[50]
1.4 ESD检验
适合多个异常值检验。预先设定异常值个数上限r,执⾏r轮单独的检验。
import math
import numpy as np
from scipy import stats
def get_r(arr):
m_arr = np.mean(arr)
d_arr =abs(arr - m_arr)
s = np.std(arr, ddof=1)# 样本标准差,注意分母n-1
out_ind = np.argmax(d_arr)
return np.max(d_arr)/ s, out_ind
def esd(data, alpha=0.05, max_anoms=0.10):
n =len(data)
if isinstance(max_anoms,float):
r = il(max_anoms * n)
el:
r = max_anoms
outliers =[]
for i in range(1, r +1):
p =1- alpha /(n - i +1)/2
拉小提琴用英语怎么说
t = ppf(p, n - i -1)# p分位点
_lambda =(n - i)* t / math.sqrt((n - i -1+ t **2)*(n - i +1))
arr = np.delete(data, outliers)
_r, out_ind = get_r(arr)
if _r > _lambda:# 超出临界值,视为异常点
outliers.append(out_ind)
el:
break
return np.delete(data, outliers), data[outliers]
1.5 Dixon检验
下⾯这篇博⽂写得很清楚了,就不搬了:
本节其他参考:
2. 时间序列数据的异常值检验
2.1 ADTK python模块
pip3 install adtk
时间序列的数据主要包括时间和相应的指标(如cpu,内存,数量等)。python中数据分析⼀般都是pandas的DataFrame,adtk要求输⼊数据的索引必须是DatetimeIndex。
pandas提供了时间序列的时间⽣成和处理⽅法。
# pd.date_range
stamps = pd.date_range("2012-10-08 18:15:05", periods=4, freq="D")
# DatetimeIndex(['2012-10-08 18:15:05', '2012-10-09 18:15:05',
# '2012-10-10 18:15:05', '2012-10-11 18:15:05'],
#  dtype='datetime64[ns]', freq='D')
# pd.Timestamp
tmp = pd.Timestamp("2018-01-05")+ pd.Timedelta("1 day")
print(tmp, tmp.timestamp(), tmp.strftime('%Y-%m-%d'))
# 2018-01-06 00:00:00 1515196800.0 2018-01-06
pd.Timestamp( tmp.timestamp(), unit='s', tz='Asia/Shanghai')
# Timestamp('2018-01-06 08:00:00+0800', tz='Asia/Shanghai')
<_datetime
adtk提供是validate_ries来验证时间序列数据的有效性,如是否按时间顺序:
import pandas as pd
from adtk.data import validate_ries
from adtk.visualization import plot
df = pd.read_csv('./data/nyc_taxi.csv', index_col="timestamp", par_dates=True)
df = validate_ries(df)
plot(df)
2.1.1 ThresholdAD
adtk.detector.ThresholdAD(low=None, high=None)
参数:
low:下限,⼩于此值,视为异常
high:上限,⼤于此值,视为异常
原理:通过认为设定上下限来识别异常
梦见坐大巴车
总结:固定阈值算法
from adtk.detector import ThresholdAD
threshold_ad = ThresholdAD(high=30, low=15)
anomalies = threshold_ad.detect(s)
2.1.2 QuantileAD
QuantileAD
adtk.detector.QuantileAD(low=None, high=None)
参数:
low:分位下限,范围(0,1),当low=0.25时,表⽰Q1
high:分位上限,范围(0,1),当low=0.25时,表⽰Q3
原理:通过历史数据计算出给定low与high对应的分位值Q_low,Q_high,⼩于Q_low或⼤于Q_high,视为异常总结:分位阈值算法
from adtk.detector import QuantileAD
quantile_ad = QuantileAD(high=0.99, low=0.01)
anomalies = quantile_ad.fit_detect(s)
2.1.3 InterQuartileRangeAD
InterQuartileRangeAD
adtk.detector.InterQuartileRangeAD(c=3.0)
参数:
c:分位距的系数,⽤来确定上下限,可为float,也可为(float,float)
原理:
当c为float时,通过历史数据计算出 Q3+c IQR 作为上限值,⼤于上限值视为异常
当c=(float1,float2)时,通过历史数据计算出 (Q1-c1IQR, Q3+c2*IQR) 作为正常范围,不在正常范围视为异常总结:箱线图算法

本文发布于:2023-07-07 00:26:17,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1082668.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数据   时间   标准差   正态分布
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图