如何比较不同的时间序列数据集

数据挖掘 Python 聚类 时间序列 异常检测
2021-09-17 13:01:33

我正在尝试使用 Python 和 sklearn 在 time#series 之间进行一些异常检测(但绝对欢迎其他软件包建议!)。

我有一组 10 个时间序列;每个时间序列都包含从轮胎的扭矩值收集的数据(总共 10 个轮胎),并且集合可能包含不同数量的数据点(集合大小不同)每个时间序列数据几乎只是轮胎 ID、时间戳和 sig_value(来自信号或传感器的值)。一个时间序列的样本数据如下所示:

tire_id        timestamp        sig_value
tire_1           23:06.1            12.75
tire_1           23:07.5                0
tire_1           23:09.0            -10.5

现在我有 10 个,其中 2 个表现得很奇怪。我知道这是一个异常检测问题,但我在网上阅读的大多数文章都是在同一时间序列内检测异常点(也就是说,如果在某些时候该轮胎的扭矩值不正常)。

为了检测哪两个轮胎表现异常,我尝试使用聚类方法,基本上是 k-means 聚类(因为它是无监督的)。

为了准备数据以输入 k-means 聚类,对于每个时间序列(也就是每个轮胎),我计算了:

  1. 前 3 组相邻的局部最大值和幅度最大的局部最小值(差值)
  2. 扭矩值的平均值
  3. 扭矩值的标准偏差

我还将集群的数量设置为只有 2,所以集群 1 或 2。

所以我的最终结果(分配集群后)如下所示:

        amplitude  local maxima  local minima  sig_value_std  \
tire_0     558.50        437.75       -120.75      77.538645   
tire_0     532.75        433.75        -99.00      77.538645   
tire_0     526.25        438.00        -88.25      77.538645   
tire_1     552.50       -116.50        436.00      71.125912   
tire_1     542.75        439.25       -103.50      71.125912   

        sig_value_average  cluster  
tire_0          12.816990        0  
tire_0          12.816990        0  
tire_0          12.816990        0  
tire_1          11.588038        1  
tire_1          11.588038        0 

现在我有一个关于如何处理这个结果的问题......所以每个轮胎都有 3 行数据,因为我选择了前 3 对具有 3 个最大幅度的局部最大值/最小值,这意味着每一行都可以分配到一个集群,有时甚至为 1 个轮胎分配到不同的集群。此外,集群大小通常大于 2。

我的问题是:

  1. 如何对“时间序列集”进行异常检测,而不仅仅是单个数据点?
  2. 我的方法合理/合乎逻辑吗?如果是,我怎样才能清理我的结果以获得我想要的?如果没有,我能做些什么来改进?
1个回答

很有趣的问题!

首先看看我的编辑,因为根据标准术语,您的问题有点不清楚。您有一组时间序列,并且想要检测异常值(异常)。

  1. 您的方法非常清晰和合乎逻辑,并显示出对问题和解决方案的理解。关键在于您选择应用它的方式。
  2. K-means 不是最好的方法。我想指出,在这里选择 2 个集群非常聪明,因为您希望集群是基于正常/异常结构形成的。如果您从时间序列中提取的特征没有抑制异常行为,那么它在实践中就不能很好地工作。
  3. 我认为嵌入算法是正确的方法。如果你应用一个简单的 PCA,你很可能会在比其他地方更远的地方看到异常的时间序列。下面我写代码。如果它不起作用,请尝试并给我留言,以便我寻求更复杂的解决方案(例如,您可以构建一个相空间并在那里查看您的数据或监控时间序列的重现等)
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt

pca = PCA(n_components=2)
X_new = pca.fit_transform(X)
plt.figure(figsize=(10,10))
plt.plot(X_new[:,0],X_new[:,1],"*")
plt.show()

其中 X 是一个 10xN 矩阵,其中每一行是一个时间序列。

您可以为 PCA 选择更多组件并检查不同的 PC。

无论如何,这个问题并不难,如果它不起作用,我会用另一个解决方案更新我的答案。

希望它有所帮助,祝你好运!