目录

  • 前言
  • 异常分类
  • 实践案例
  • 建议
  • 参考文献

前言

很多数据算法工程师在做时间序列分析的时候都会去做时序的平稳性检测,从而获得ARIMA(p,d,q)中的参数d,然而, 还有一项工作比平稳性检测来得更前置,那就是时序的异常值检测。

异常分类

一个时间序列里可能包含各种各样的异常值,异常片段,归纳起来主要有2种类型的异常值检测。

  • 离群值检测

所谓离群多指离开其他同伴而孤立,故离群值检测就是从时序里面挑出那些众叛亲离的观测点,那些远离其他大多数观测值的观测点,离群值检测常常是把整个时序作为训练对象,这其中可能包含异常值,对整个时序进行无监督训练,得到一个异常值检测器,那些偏离大多数的观测点便是离群值。

  • 异常值检测

异常值检测常用一段被认为是“正常”的,不会受到异常值的污染的时序进行半监督训练,得到一个检测器,然后将这个检测器运用到新的数据上,假设正常的训练数据符合某个分布,而新的观测值不符合这个分布的则可以认为是异常值。

实践案例

我们以air_passenger数据集为对象进行auto_arima调参,先来看一下原数据长什么样子并对其进行可视化

import datetime
import time
import tsod
import pandas as pd
import pmdarima as pm
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import adfuller
from sklearn.metrics import mean_absolute_error
from tsod import RangeDetector,GradientDetector,ConstantGradientDetector,RollingStandardDeviationDetector,DiffDetectorair_passenger = pd.read_csv(r"D:\项目\时间序列\air_passenger.csv") #读取数据
air_passenger['date'] = pd.to_datetime(air_passenger['date']) #datetime格式化air_passenger.set_index("date", inplace = True) #设置date列为索引列
ts = air_passenger['passenger'] #乘客时序
print(ts.head(5)) #查看头5行
print(ts.tail(5)) #查看尾5行fig = plt.figure(figsize = (6,4)) #新建6*4的画布
ts.plot(label = 'ts_origin') #原时序图
plt.xticks(rotation =45) #横坐标逆时针倾斜45度
plt.legend()
plt.show()


原数据就2列,一列是date,一列是passenger,把date设置为索引正式得到passenger时间序列, 以date为横坐标,passenger为纵坐标,绘制出air_passenger的时序图,从air_passenger时序图我们看到序列的时间跨度是从2019年09月之前开始一直到2022年09月,中间有4段处于停飞状态,2020年05月到2020年09月中间有一段至暗时期,人数跌落到50人以下,姑且称为波谷,但是再2021年05月到2021年09月有一段高光时期,人数突破了200大关,暂称为波峰,除去这两段时期外,其余大部分位于150上下波动,且波动幅度不是特别大,那么我们可以预判这些为平稳时期表现,其余的如波峰,波谷,停飞期都可视为异常片段或者异常点,异常片段就是异常点形成聚集效果的时间段,现在要想办法将其甄别出来并适当剔除。

  • RangeDetector

范围检测可以根据业务经验和前置的观测结果给出一个范围,超过这个范围的一律被认为异常值,这对那些有额定值,如有额定座位的电影院上座率等时序比较友好,但是对随时间变化而形成趋势的时序不太友好。

from tsod import RangeDetectorprint(len(ts))
print(int(len(ts)*0.2))range_dector = RangeDetector(min_value=np.min(ts[-int(len(ts)*0.2):]), max_value=np.max(ts[-int(len(ts)*0.2):])) #以最近20%样例最大值最小值为范围
res = range_dector.detect(ts)plt.figure(figsize=(16,4)) #新建画布
plt.plot(ts, label = 'ts_origin') #原序列图
plt.plot(ts[res], 'ro', label='anomaly') #给异常值描红点
plt.plot(ts.index, [np.min(ts[-int(len(ts)*0.2):])]*len(ts)) #下界
plt.plot(ts.index, [np.max(ts[-int(len(ts)*0.2):])]*len(ts)) #上届
plt.xticks(rotation = 45)
plt.legend() #图例
plt.title("RangeDetector") #标题
plt.show()ts_1 = ts.drop(labels=ts[res].index) #drop掉极大极小值的时序
print("范围检测后长度", len(ts_1))

  • GradientDetector

梯度本是数学上一个专业术语,是一个向量,既有大小又有方向,表示函数在该点的方向导数取得最大值,放在时序里面可以认为是那些变化很大的样本,主要是指那些陡降陡升的观测样本

g_dector = GradientDetector().fit(ts[-int(len(ts)*0.2):]) #以近14期为训练样本异常梯度检测
res = g_dector.detect(ts)plt.figure(figsize=(16,4))
plt.plot(ts, label = 'ts_origin') #原序列图
plt.plot(ts[res], 'ro', label='anomaly') #给异常值描红点
plt.xticks(rotation = 45)
plt.legend()
plt.title("GradientDetector")
plt.show()
ts_2 = ts.drop(labels=ts[res].index)#drop掉梯度异常值的时序
print("异方差检测后长度",len(ts_2))

  • ConstantGradientDetector

常数梯度检测是检测那些梯度为常数的观测点,这些点随时间变化而没有产生变化,对于检测线性插值特别友好,比如我前面进行了频率设定和插值处理,那么在后续的常数梯度检测中是能够发现的。

......
air_passenger = air_passenger.asfreq("D") #设置频率
air_passenger = air_passenger.interpolate(method='linear', axis=0) #插值
......rstd_dector = ConstantGradientDetector().fit(ts) #滚动标准差异常检测,最近20%作为时序作为训练集
res = rstd_dector.detect(ts) #二进制plt.figure(figsize=(16,4))
plt.plot(ts, label = 'ts_origin') #原序列图
plt.plot(ts[res], 'ro', label='anomaly') #给异常值描红点
plt.xticks(rotation = 45)
plt.legend()
plt.title("RollingStandardDeviationDetector")
plt.show()
ts_3 = ts.drop(labels=ts[res].index) #过滤掉异常的时序
print("滚动标准差检测后长度", len(ts_3))

  • RollingStandardDeviationDetector

滚动标准差检测是以某个固定的滚动窗口进行向前滚动统计其均值和标准差,在符合均值上下的几个标准差范围里可以认为是正常的,超出这个范围就是异常的,她与RangeDector最大的区别是这个范围是随时间变化的。

rstd_dector = RollingStandardDeviationDetector(window_size=7, center=True).fit(ts[-int(len(ts)*0.2):]) #滚动标准差异常检测,最近20%作为时序作为训练集
res = rstd_dector.detect(ts) #二进制plt.figure(figsize=(16,4))
plt.plot(ts, label = 'ts_origin') #原序列图
plt.plot(ts[res], 'ro', label='anomaly') #给异常值描红点
plt.xticks(rotation = 45)
plt.legend()
plt.title("RollingStandardDeviationDetector")
plt.show()
ts_3 = ts.drop(labels=ts[res].index) #过滤掉异常的时序
print("滚动标准差检测后长度", len(ts_3))

  • DiffDetector

差分检测是对时序进行一阶差分,然后挑出那些差分值特别大或者特别小的观测点。

diff_dector = DiffDetector().fit(ts[-int(len(ts)*0.2):]) #差分异常检测,最近20%作为时序作为训练集
res = diff_dector.detect(ts) #二进制plt.figure(figsize=(16,4))
plt.plot(ts, label = 'ts_origin') #原序列图
plt.plot(ts[res], 'ro', label='anomaly') #给异常值描红点
plt.xticks(rotation = 45)
plt.legend()
plt.title("DiffDetector")
plt.show()
ts_4 = ts.drop(labels=ts[res].index) #过滤掉异常的时序
print("差分检测后长度",len(ts_4))

建议

在具体实践中,往往不是每一步都与原序列进行对比的,而是有先后顺序,先进行某一项检测,再进行下一项检测,后一项检测依赖于上一项检测结果,也就是说各项检测是串联的,上面的ts_origin, ts_1, ts_2, ts_3, ts_4都是有先后顺序的,可以根据业务经验决定先进行哪一项检测再进行哪一项检测并在具体实践中调整顺序,亦可以根据业务需要多项检测结合使用。。

参考文献

1,https://blog.csdn.net/Datawhale/article/details/115743840
2,https://github.com/DHI/tsod

时间序列分析|异常值检测相关推荐

  1. 时间序列分析 lstm_LSTM —时间序列分析

    时间序列分析 lstm Neural networks can be a hard concept to wrap your head around. I think this is mostly d ...

  2. 大图和时间序列分析工具集Spartan2——Dense subgraph检测实践

    大图和时间序列分析工具集-Spartan2 先上Github链接!!!:Welcome to spartan2 1 简介 大图和时间序列是用户在线行为(例如社交媒体.购物.应用程序).金融(例如股票交 ...

  3. 【机器学习】数据挖掘实战:金融贷款分类模型和时间序列分析

    今天给大家带来一个企业级数据挖掘实战项目,金融贷款分类模型和时间序列分析,文章较长,建议收藏! 如果本文对你有所帮助,记得文末点赞和在看,也可分享给你需要的朋友- 项目背景 银行和其他金融贷款机构经常 ...

  4. 浅尝辄止_数学建模(笔记_时间序列分析及其SPSS实现)

    本文多是广泛的概念和SPSS运用,没有具体的推导过程和深入的探究 文章目录 一.时间序列分析 1.具体步骤: 二.基本知识 1.时间序列数据 2.时间序列的基本概念 3.时间序列分解 4.叠加模型和乘 ...

  5. 数学建模学习笔记(15)时间序列分析

    时间序列分析 时间序列分析概述和数据预处理 时间序列分解模型 指数平滑模型 ARIMA模型 SPSS专家建模器的使用步骤 时间序列分析概述和数据预处理 时间序列的概念:也称为动态序列,是指将某种现象的 ...

  6. Genome Biology:人体各部位微生物组时间序列分析Moving Pictures

    人体各部位微生物组初探 Moving pictures of the human microbiome Genome Biology, [14.028] 2011-05-30  Articles DO ...

  7. Genome Biology:人体各部位微生物组时间序列分析

    文章目录 人体各部位微生物组初探 摘要 背景 结果 结论 点评 主要结果 图1. 基于无权重UniFrac距离的PCoA 图2. 时间上的核心微生物组 图3. 群落中的成员关联 猜你喜欢 写在后面 人 ...

  8. 终于把时间序列分析的关键点全讲清楚了!

    来源:深度学习爱好者 本文约3200字,建议阅读10分钟本文与你分享时间序列分析的基础知识. 时间序列的定义 一个时间序列过程(time series process)定义为一个随机过程,这是一个按时 ...

  9. 独家 | Python时间序列分析:一项基于案例的全面指南

    作者: Selva Prabhakaran 翻译:陈超校对:王可汗本文约7500字,建议阅读20+分钟本文介绍了时间序列的定义.特征并结合实例给出了时间序列在Python中评价指标和方法. 时间序列是 ...

最新文章

  1. RabbitMQ 实战(四)消费者 ack 以及 生产者 confirms
  2. leetcode位运算的题
  3. 常用的6款Java开源报表制作工具
  4. 第八周项目四-角色有多样武器
  5. openCV—Python(6)—— 图像算数与逻辑运算
  6. windows server2012
  7. 【DBMS 数据库管理系统】OLTP 联机事务处理 与 OLAP 联机分析处理 ( 数据仓库 与 OLAP | OLAP 联机分析处理 | OLTP 与 OLAP 区别 )
  8. 中国高性能计算机TOP100出炉 曙光联想并列第一
  9. USACO3.15stamps(dp)
  10. 网线接法:交叉线、直通线的网线水晶头图解
  11. Python3笔记——IDE的选择
  12. c盘local文件太大_win7 c盘清理的方法教程
  13. 软件项目管理课程设计-数字化校园学工信息系统
  14. 苹果cms插件_苹果cms v10 站群插件修复版
  15. 【stm32】单片机学习——小车的开环控制
  16. 中国IT咨询公司的机会在哪里?
  17. 从“零”开始的C语言
  18. 马士兵python_马士兵:python学习(一)
  19. 一个葫芦娃的小程序,爷青回!
  20. html css js题目

热门文章

  1. 区块链开发之生成12个助记词
  2. 登录页面带验证码html,使用H5+css3+js实现带验证码的登录页面
  3. 遇见一个合适且长久的人有多难?
  4. oracle 10g expdp导出报错ora-4031的解决方法
  5. 【蓝桥真题6】三十块的蓝桥省赛模拟真题,做的大一都直呼上当(文末PDF原题)
  6. 5.STC15W408AS单片机按键输入
  7. 职场如战场,待看招聘网站风云
  8. ​用树莓派(Raspberry Pi)和机器学习制作一个DIY车牌阅读器
  9. 一些关于Java课程学习下来的心得
  10. UI --- Xcode7 模拟器运行时崩溃解决方法