• 时间序列分析|异常值检测


    前言

    很多数据算法工程师在做时间序列分析的时候都会去做时序的平稳性检测,从而获得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 matplotlib.pyplot as plt
    from statsmodels.tsa.stattools import adfuller
    from sklearn.metrics import mean_absolute_error 
    from tsod import RangeDetector,GradientDetector,RollingStandardDeviationDetector,DiffDetector
    
    air_passenger = pd.read_csv(r"D:\项目\时间序列\air_passenger.csv") #读取数据
    air_passenger['month'] = pd.to_datetime(air_passenger['month']) #datetime格式化
    
    air_passenger.set_index("month", inplace = True) #设置time列为索引列
    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 = 'origin ts') #原时序图
    plt.xticks(rotation =45) #横坐标逆时针倾斜45度
    plt.legend() 
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    原始时序

    • RangeDetector

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

    range_dector = RangeDetector(min_value=np.min(ts)*1.1, max_value=np.max(ts)*0.9) #以最近20%样例最大值最小值为范围
    res = range_dector.detect(ts)
    plt.figure(figsize=(16,4))
    plt.plot(ts, label = 'origin ts') #原序列图
    plt.plot(ts[res], 'ro', label='anomaly') #给异常值描红点
    plt.xticks(rotation = 45)
    plt.legend()
    plt.title("RangeDetector")
    plt.show()
    ts = ts.drop(labels=ts[res].index) #过滤掉极大极小值的时序
    print("范围检测后长度", len(ts))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    RangeDetector

    • GradientDetector

    梯度检测主要是指那些陡降陡升的观测值

    g_dector = GradientDetector().fit(ts[-14:]) #以近14期为训练集训练异常梯度检测
    res = g_dector.detect(ts) 
    plt.figure(figsize=(16,4))
    plt.plot(ts, label = 'origin ts') #原序列图
    plt.plot(ts[res], 'ro', label='anomaly') #给异常值描红点
    plt.xticks(rotation = 45)
    plt.legend()
    plt.title("GradientDetector")
    plt.show()
    ts = ts.drop(labels=ts[res].index)
    print("异方差检测后长度",len(ts))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    GradientDetector

    • RollingStandardDeviationDetector

    滚动标准差检测是以某个固定的滚动窗口而进行标准差的检测

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

    RollingStandardDeviationDetector

    • DiffDetector
      差分检测是对那些异常差分进行检测
    diff_dector = DiffDetector().fit(ts[-14:]) #差分异常检测
    res = diff_dector.detect(ts) #二进制
    plt.figure(figsize=(16,4))
    plt.plot(ts, label = 'origin ts') #原序列图
    plt.plot(ts[res], 'ro', label='anomaly') #给异常值描红点
    plt.xticks(rotation = 45)
    plt.legend()
    plt.title("DiffDetector")
    plt.show()
    ts = ts.drop(labels=ts[res].index) #过滤掉异常的时序
    print("差分检测后长度",len(ts))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    DiffDetector

    参考文献

    1,https://blog.csdn.net/Datawhale/article/details/115743840
    2,tsod,时序异常检测

  • 相关阅读:
    【✨十五天搞定电工基础】正弦交流电路的分析
    HTML中华传统文化题材网页《中国民间年画》HTML+CSS+JavaScript
    2022年面试天花板,Java岗史上最全八股文面试真题汇总
    变电站指针式仪表示数识别方法研究
    Linux 网络编程 TCP/UDP编程
    vue中父子组件之间的访问方式-$children-$refs-$parent
    开源办公OA开发平台使用说明:用车管理应用
    【一周安全资讯1007】多项信息安全国家标准10月1日起实施;GitLab发布紧急安全补丁修复高危漏洞
    分享一个逻辑题_一眼望去无法下手
    Java 获得applet参数学习笔记
  • 原文地址:https://blog.csdn.net/zengbowengood/article/details/125876495