基于Python的时间序列异常值检测

news2025/1/12 15:55:44

 

今天我们介绍一下使用python做时间序列数据分析和预测中异常值检测的方法,常用的异常值检测方法有以下几种:

  • 3sigma: 基于正太分布,当数据值超过±3个标准差(3sigma)时为异常值。
  • z-score : z标准分数,它测量数据值到平均值的距离,当数据与平均值相差2个标准差时z-score为2,如果将z-score为3作为异常值判断标准时,便相当于3sigma。
  • 箱体法(box): 它基于数据的四分位值来判断异常值。
  • 多维度异常值判断法,通过数据特征的多个维度综合判断数据是否为异常值。

注:3sigma,z-score,箱体法(box)都是从数据值本身的单一维度去分析和判断异常值,从而有一定的局限性, 然而多维度异常值判断法更注重从数据特征的各个维度去分析和判断异常值,显然多维度异常值判断法更为科学和精准。

导入时间序列数据

我们的数据来自于某商业零售门店的每日客流量数据,客流量数据直接关系到门店销售业绩,所以有必要对客流量数据进行分析。

数据中的 y 列代表了客流量,这里数据的时间范围为2020.1至2023.1 ,接下来我们查看数据的趋势图。

plt.figure(figsize=(10,4),dpi=100)
plt.plot(df)
plt.title("客流量趋势")
plt.show()

 

 下面我们查看客流量数据的热力图分布:

calplot.calplot(df.y,suptitle='客流量分布',cmap='YlGn');

 从热力图的颜色深浅变化,我们也能发现客流量逐年在减少,这可能和疫情持续有关。

3sigma

依据正太分布异常值分布在3个标准差以外的位置,如下图所示:

下面我们来计算数据的±3个标准以外的位置,落在这两个位置内的数据点即为异常值:

# 3sigma
def three_sigma(df):
    mean=df.y.mean()
    std=df.y.std()
    upper_limit=mean+3*std
    lower_limit=mean-3*std
    df['anomaly']=df.y.apply(lambda x: 1 if (x>upper_limit )
                              or (x<lower_limit) else 0)
    return df
df1 = three_sigma(df.copy())
df1[df1.anomaly==1]

fig, ax = plt.subplots(figsize=(10,4))
a = df1.loc[df1['anomaly'] == 1, ['y']] #anomaly
ax.plot(df.index, df['y'], color='blue', label='正常值')
ax.scatter(a.index,a['y'], color='red', label='异常值')
plt.title(f'3sigma')
plt.xlabel('date')
plt.ylabel('y')
plt.legend()
plt.show();

 z-score

z-score测量数据值到平均值的距离,异常值的判断依据为给定的距离阈值,一般情况下阈值可以设置在大于2个标准差的任意位置(依据业务和经验来确定阈值)。如果将z-score为3作为异常值判定的阈值时,便相当于3sigma。

 

# Z-Score
def z_score(df,threshold):
    mean=df.y.mean()
    std=df.y.std()
    df['z_score']=df.y.apply(lambda x:abs(x-mean)/std)
    df['anomaly']=df.z_score.apply(lambda x: 1 if x>threshold else 0)
    return df

#设置阈值为2或3,当阈值为3时便相当于3sigma
threshold=2
df2 = z_score(df.copy(),threshold)
df2[df2.anomaly==1]

fig, ax = plt.subplots(figsize=(10,4))
a = df2.loc[df2['anomaly'] == 1, ['y']] 
ax.plot(df.index, df['y'], color='blue', label='正常值')
ax.scatter(a.index,a['y'], color='red', label='异常值')
plt.title(f'Z-score, {threshold=}')
plt.xlabel('date')
plt.ylabel('y')
plt.legend()
plt.show();

箱体法(box)

 箱体法(box)基于数据的四分位值来判断异常值。异常值>Q3+1.5*IQR 或者 异常值<Q1-1.5*IQR

def box_plot(df):
    q1=np.nanpercentile(df.y,25)
    q3=np.nanpercentile(df.y,75)
    iqr=q3-q1
    lower_limit=q1-1.5*iqr
    upper_limit=q3+1.5*iqr
    df['anomaly']=df.y.apply(lambda x: 1 if x<lower_limit or x>upper_limit  
                             else 0)
    return df
df3 = box_plot(df.copy())
df3[df3.anomaly==1]

fig, ax = plt.subplots(figsize=(10,4))
a = df3.loc[df3['anomaly'] == 1, ['y']] 
ax.plot(df.index, df['y'], color='blue', label='正常值')
ax.scatter(a.index,a['y'], color='red', label='异常值')
plt.title(f'Box-plot')
plt.xlabel('date')
plt.ylabel('y')
plt.legend()
plt.show();

 多维度异常检测法PyOD

异常检测算法工具库(PyOD) 可以从数据的多个特征维度来检测异常值,所以我们可以将时间序列数据的日期特征分解成多个和时间相关的其它特征,同时我们还需要设置一个异常值比例,一般情况下我们设置异常值比例在5%以下。这里我们使用的是Pycaret的异常值检测模型,该模型是对PyOD进行了再次包装,使之调用更为简单,感兴趣的朋友可以去查看Pycaret和PyOD的相关文档。这里我们首先将日期字段进行分解,从原始的日期字段中我们可以拆分出年,月,日,星期,季度等和时间相关的特征:

from pycaret.anomaly import AnomalyExperiment
# 分解日期特征
def create_features(df):        
    df['year'] = df.index.year #年 
    df['month'] = df.index.month #月
    df['dayofmonth'] = df.index.day #日
    df['dayofweek'] = df.index.dayofweek #星期
    df['quarter'] = df.index.quarter #季度
    df['weekend'] = df.dayofweek.apply(lambda x: 1 if x > 5 else 0) #是否周末
    df['dayofyear'] = df.index.dayofyear   #年中第几天
    df['weekofyear'] = df.index.weekofyear #年中第几月
    df['is_month_start']=df.index.is_month_start
    df['is_month_end']=df.index.is_month_end
    return df
#创建特征
df4 = create_features(df.copy())
df4

 接下来我们使用Pycaret的anomaly模型对新数据集进行建模和预测,同时我们仍然需要设置一个异常值比例的阈值fraction:

#异常值算法:'knn','cluster','iforest','svm'等。
alg='knn'#异常值算法
fraction=0.02 #异常值比例 0.02,0.03,0.04,0.05
#创建异常值模型
exp = AnomalyExperiment()
r = exp.setup(df4.copy(), session_id = 123,verbose=False)
model = exp.create_model(alg, fraction=fraction,verbose=False)
model_results = exp.assign_model(model,verbose=False)
#获取检测结果
df5 = pd.merge(df.reset_index(),model_results[['Anomaly']],
               left_index=True, right_index=True)
df5.set_index('date',inplace=True)

fig, ax = plt.subplots(figsize=(10,4))
a = df5.loc[df5['Anomaly'] == 1, ['y']] 
ax.plot(df5.index, df5['y'], color='blue', label='正常值')
ax.scatter(a.index,a['y'], color='red', label='异常值')
plt.title(f'Pycaret.anomaly {fraction=}')
plt.xlabel('date')
plt.ylabel('y')
plt.legend()
plt.show();

 

 

 

 这里我们还有多种异常值算法可以选择,有兴趣的朋友可以自己去尝试不同的异常值算法:

 总结

今天我们介绍几种常用的异常值检测方法,其中3sigma,z-score,箱体法(box)都是从数据值本身的单一维度去分析和判断异常值,从而有一定的局限性, 而多维度异常值判断法更注重从数据特征的各个维度去分析和判断异常值,显然多维度异常值判断法更为科学和精准。

参考资料

Pycaret 文档

PyOD文档

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/379649.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pandas对某一列的种类编码

文章目录背景实现背景 如果某一列的种类特别多&#xff0c;想要通过映射来编码&#xff0c;这样非常麻烦&#xff0c;所以可以对一个列全部一次性进行编码。 例如我的数据如下&#xff1a; 我需要编码专业这个列&#xff0c;我们可以看到这一列很多&#xff1a; 实现 使用…

【Unity】P3 基础设定

Unity基础设定父子关系InspectorTransformMesh FilterMesh Rendener第二种常用的父子操作Global 与 Local 模式Pivot 与 Center 模式声音组件创建多场景Asset 资源商店前言 上一篇博文主要围绕Unity的静态基础操作部分&#xff0c;从创建好的一个小方块cube开始&#xff0c;到对…

Selenium基于POM的自动化测试实践

什么是Page Object模式 Page Object 见名知意&#xff0c;就是页面对象&#xff0c;并将页面元素定位方法和元素操作进行分离。在实际自动化测试实战过程中&#xff0c;我们一般对脚本的实现分为三层&#xff1a; (1)对象层&#xff1a; 用于存放页面元素定位和控件操作 (2)逻…

《Nacos(3) - 集群搭建(详细)》

《Nacos(3) - 集群搭建》 提示: 本材料只做个人学习参考,不作为系统的学习流程,请注意识别!!! 《Nacos3 - 集群搭建》《Nacos(3) - 集群搭建》1.集群结构图2.搭建集群2.1.初始化数据库2.2.下载nacos2.3.配置Nacos2.4.启动2.5.nginx反向代理2.6.优化1.集群结构图 官方给出的Na…

【JavaSE】对象的比较

哈喽&#xff0c;大家好&#xff01;我是保护小周ღ&#xff0c;本期为大家带来的是Java中自定义类型&#xff08;对象&#xff09;的三种比较方式&#xff0c;equals 方法, Comparable 泛型接口, Comparator 泛型接口 。在日常编程中&#xff0c;我们常常会需要比较的问题&…

cuda版本,pytorch(GPU)版本的选择和下载

cuda版本&#xff1a; 1.Nvidia控制面板里的cuda版本, 或使用nvidia-smi命令显示的cuda版本 是cuda的driver api版本 2.nvcc -V中的cuda版本&#xff0c;是cuda的runtime api版本&#xff0c;即cudatoolkit的版本 cudatoolkit的版本不能高于cuda driver api的版本&#xff…

23.2.28 Staffing System

员工管理系统功能介绍&#xff1a; 1&#xff09;服务器负责管理所有员工表单&#xff08;以数据库形式&#xff09;&#xff0c;其他客户端可通过网络连接服务器来查询员工表单。 2&#xff09;需要账号密码登陆&#xff0c;其中需要区分管理员账号还是普通用户账号。 3&am…

聚观早报 | 苹果2024年放弃高通;腾讯回应进军类 ChatGPT

今日要闻&#xff1a;苹果2024年放弃高通&#xff1b;腾讯回应进军类 ChatGPT&#xff1b;小米发布无线AR眼镜探索版&#xff1b;50%的美国企业已在使用ChatGPT&#xff1b;Snap推出ChatGPT驱动的聊天机器人 苹果2024年放弃高通 高通公司 CEO 兼总裁克里斯蒂亚诺・安蒙&#xf…

Node.js 是个啥?

趣学 Node.js - 死月 - 掘金小册带你重新体悟 Node.js 之美。「趣学 Node.js」由死月撰写&#xff0c;1923人购买https://s.juejin.cn/ds/SYVvuDw/ 在这里&#xff0c;我们先装作对 Node.js 不了解&#xff0c;从头来过吧。你有没有假装不了解 Node.js 我不知道&#xff0c;但…

界面开发(2)--- 使用PyQt5制作用户登陆界面

使用PyQt5制作用户登陆界面 上篇文章已经介绍了如何配置PyQt5环境&#xff0c;这篇文章在此基础上展开&#xff0c;主要记录一下如何使用 PyQt5 制作用户登陆界面&#xff0c;并对一些基础操作进行介绍。 下面是具体步骤&#xff0c;一起来看看吧&#xff01; 1. 打开 Pychar…

【IoT】2023裁员潮还在继续,构建规划能力也许是一剂良方

今天要分享的主题是华为的市场管理方法论。 市场管理这个词总体来说还是有些抽象&#xff0c;本质上来看或者说从个人的角度来看&#xff0c;其实就是一种规划的能力。 无论是创业&#xff0c;还是作为职场人&#xff0c;规划能力必将是你不可或缺的一种基础能力。 尤其是在这样…

Maven说明

目录 1.说明 2.详细说明 3.Maven模型 4.Maven常用的命令 5.Maven生命周期 6.Maven坐标 7.依赖管理与依赖范围 1.说明 Maven是专门用于管理和构建Java项目的工具&#xff0c;它是基于项目对象模型(POM)的概念&#xff0c;主要功能有&#xff1a; 提供了一套标准化的项目…

Ubuntu 下NGINX 的简单使用

1.NGINX的安装与卸载 1.1.安装NGINX apt-get install nginx1.2.NGINX操作命令 service nginx start #启动 service nginx reload #重新加载配置文件 service nginx restart #重启 service nginx status #查看运行状态 1.3.卸载NGINX apt-get remove nginx nginx-common #…

28 openEuler管理网络-配置主机名

文章目录28 openEuler管理网络-配置主机名28.1 简介28.2 使用hostnamectl配置主机名28.2.1 查看所有主机名28.2.2 设定所有主机名28.2.3 设定特定主机名28.2.4 清除特定主机名28.2.5 远程更改主机名28.3 使用nmcli配置主机名28 openEuler管理网络-配置主机名 28.1 简介 hostn…

XXL-JOB的基本使用

1、执行器 1.1下边配置执行器 下边配置执行器&#xff0c;执行器负责与调度中心通信接收调度中心发起的任务调度请求。 1、首先在媒资管理模块的service工程添加依赖&#xff0c;在项目的父工程已约定了版本2.3.1 XML <dependency><groupId>com.xuxueli</gro…

【Web安全社工篇】——水坑攻击

作者名&#xff1a;白昼安全主页面链接&#xff1a; 主页传送门创作初心&#xff1a; 以后赚大钱座右铭&#xff1a; 不要让时代的悲哀成为你的悲哀专研方向&#xff1a; web安全&#xff0c;后渗透技术每日鸡汤&#xff1a;努力赚钱不是因为爱钱“水坑攻击”&#xff0c;黑客攻…

CVPR 2023 接收结果出炉!再创历史新高!录用2360篇!(附10篇最新论文)

点击下方卡片&#xff0c;关注“CVer”公众号AI/CV重磅干货&#xff0c;第一时间送达点击进入—>【计算机视觉】微信技术交流群2023 年 2 月 28 日凌晨&#xff0c;CVPR 2023 顶会论文接收结果出炉&#xff01;这次没有先放出论文 ID List&#xff0c;而是直接 email 通知作…

【C语言】位段

位段 一.简介 位段和结构体很相似。不同的是&#xff1a; 位段的成员&#xff1a;成员名 : 数字且其成员必须是整型(char、int、unsigned int……) 示例&#xff1a; struct S {char a : 3;char b : 2;char c : 7; };S就是一个位段类型&#xff0c;其成员a为占3个比特位的…

【趣味学Python】Python基础语法讲解

目录 编码 标识符 python保留字 注释 实例(Python 3.0) 实例(Python 3.0) 行与缩进 实例(Python 3.0) 实例 多行语句 数字(Number)类型 字符串(String) 实例(Python 3.0) 空行 等待用户输入 实例(Python 3.0) 同一行显示多条语句 实例(Python 3.0) 多个语句构…

【Day02数据结构 空间复杂度】

最近太忙了都好久没有更新博客了,太难了,抽空水一篇文章,大佬们多多支持. 上篇:时间复杂度分析 目录 前言 一、空间复杂度概念&#xff1f; 二、实例展示 三、.有复杂度要求的算法题练习 1.题目链接&#xff1a;力扣--消失的数字 2.题目链接&#xff1a;力扣--旋转数组 总结: 1…