【问题标题】:SAX method: cut time series into subsequences then calculate distances (Python)SAX 方法:将时间序列切割成子序列,然后计算距离(Python)
【发布时间】:2020-11-05 08:59:31
【问题描述】:

我正在尝试应用 SAX(符号聚合近似)方法来检测我的时间序列数据中的异常值。基本上我需要将整个系列切割成等长的子系列,然后计算它们之间的距离。然后将top-K子系列标记为异常。

尝试了几个包:

  • pyts - 一开始不知道如何剪辑这个系列
  • This question 是相关的 - 在 python 中有没有更好的解决方案?
  • tslearn.metrics.dtw_path_from_metric - 看起来它正在计算两个系列之间的距离,但我错过了第一个“切割”部分。
  • 我还在考虑是否可以使用矩阵(将每个子系列作为行和列,然后在诊断中布置距离)

结果是 1)按周切系列; 2)计算每个子序列之间的距离; 3)用前k个最长距离的对它们进行排序。我知道这可能有很多问题,但任何建议都将不胜感激!

import datetime
import pandas as pd
import bumpy as np

rng = np.random.RandomState(0)
base = datetime.datetime.today()
dates = pd.date_range(start='1/1/2020', end='6/1/2020', freq='D')
df = pd.DataFrame(dates, columns=['date'])
df['sales'] = np.random.randint(0, 100, size=(len(dates)))

【问题讨论】:

    标签: python time-series outliers anomaly-detection


    【解决方案1】:

    对 1) 的答案是按周剪切系列

    虽然您可能只需要使用 df.groupby(pd.Grouper(key='date', freq='W')) 就可以侥幸,但也许更有用的是使用 week_number 和 week_date 属性填充到数据框。

    week = 1
    weekly_data = []
    week_data = []
    for data in df.groupby(pd.Grouper(key='date', freq='W')):
        week_date = data[0]
        week_dates = list(data[1]['date'])
        week_sales = list(data[1]['sales'])
        week_data_list = list(zip(week_dates, week_sales))
        for i in week_data_list:
            week_data.append([week, week_date, i[0], i[1]])
        weekly_data.append(week_data)
        week += 1
    df = pd.DataFrame(week_data, columns=['week_number', 'week_date', 'date', 'sales'])
    df
    

    这会产生一个形状的数据框:

        week_number week_date   date    sales
    0   1   2020-01-05  2020-01-01  57
    1   1   2020-01-05  2020-01-02  64
    2   1   2020-01-05  2020-01-03  51
    3   1   2020-01-05  2020-01-04  77
    4   1   2020-01-05  2020-01-05  69
    ... ... ... ... ...
    148 22  2020-05-31  2020-05-28  34
    149 22  2020-05-31  2020-05-29  51
    150 22  2020-05-31  2020-05-30  66
    151 22  2020-05-31  2020-05-31  77
    152 23  2020-06-07  2020-06-01  31
    153 rows × 4 columns
    

    您可以简单地选择或迭代您想要的维度,例如

    df.loc[weeks_df['week_number'] == 1]
    
        week_number week_date   date    sales
    0   1   2020-01-05  2020-01-01  57
    1   1   2020-01-05  2020-01-02  64
    2   1   2020-01-05  2020-01-03  51
    3   1   2020-01-05  2020-01-04  77
    4   1   2020-01-05  2020-01-05  69
    

    请注意,这不会为您提供每周相等长度的子序列,因为您的数据示例不允许这样做,第一周只有 5 个值,第 23 周只有 1 个。

    祝你好运 2) 和 3)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-20
      • 2018-01-31
      • 2012-02-21
      • 1970-01-01
      • 2018-07-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多