清理时间序列数据

数据挖掘 数据清理
2022-03-03 13:36:15

我有一个关于计算机程序日常使用的时间序列数据,这里是一个例子

  • 2017-11-10: 0
  • 2017-11-09: 14
  • 2017-11-08: 0
  • 2017-11-07: 6
  • 2017-11-06: 102
  • 2017-11-05: 0
  • 2017-11-04: 0

如您所见,11-06 在 102 处有一个峰值。由于我们收集此数据的方式,我们知道数据可能是错误的,并且根据其他值我们确信 102 是不正确的。

所以我们需要清理这些脏值。

有没有数学方法可以做到这一点?有python库来帮助我们吗?

4个回答

我认为你有几个选择:

  • 如果您有一个预先设定的规则来排除异常值,例如您知道数据不应超过的硬阈值 100,那么就x = [e for e in x if e < 100]可以做到这一点。
  • 如果您有一个参数信念,例如任何超出均值或四分位数标准差的任何观察结果都是异常值;然后您可以实施已经提到的其他答案。
  • 否则,您可以采用聚类方法。在这里,我相信您的第一个镜头应该是 k-means 聚类。这非常容易构建和解释。请参阅下面的代码。

    x = [0,14,0,6,102,0,0] from sklearn.cluster import KMeans kmeans = KMeans(n_clusters=2).fit(np.array(x).reshape(-1, 1))

    #First cluster: np.array(x)[np.where(kmeans.labels_ == 0)]

    #Second cluster (outliers): np.array(x)[np.where(kmeans.labels_ == 1)]

  • 众所周知,K-means 对异常值很敏感,因此您尝试过的更强大的方法(例如 MeanShift)是 k-means 的一个很好的竞争对手。我会同时运行两者,并坚持对我更有意义的结果。

希望这可以帮助!

一种解决方案是使用meanvariance检测时间序列中的异常值。例如:

>> data=np.array([0,0,102,6,0,14,0])
>> c = 1
>> abs(data - np.mean(data)) < c * np.std(data)
Output: array([ True,  True, False,  True,  True,  True,  True], dtype=bool)
>> clean_data= data[abs(data - np.mean(data)) < c * np.std(data)]
Output: array([ 0,  0,  6,  0, 14,  0])

c你可以根据你的要求玩。

此外,您可以分别对时间序列的每个部分(例如每 30 天)使用此方法,而不是使用所有数据的均值和方差。因为在不同的时间间隔内可能会有不同的行为。

这是我正在使用的:

import numpy as np
from sklearn.cluster import MeanShift, estimate_bandwidth

x = [0,14,0,6,102,0,0]

X = list(zip(x,np.zeros(len(x))))
bandwidth = estimate_bandwidth(X, quantile=0.2)
ms = MeanShift(bandwidth=bandwidth, bin_seeding=True)
ms.fit(X)
labels = ms.labels_
cluster_centers = ms.cluster_centers_

labels_unique = np.unique(labels)
n_clusters_ = len(labels_unique)

X = np.array(X)
for k in range(n_clusters_):
    my_members = labels == k
    print(k, X[my_members, 0])

来源:http ://scikit-learn.org/stable/auto_examples/cluster/plot_mean_shift.html

我会使用四分位数范围(IQR),其中异常值是大于Q3+1.5×IQR,并且值小于Q11.5×IQR, 在哪里Q1Q3分别是第一和第三四分位数。是一个很好的例子。