方法参考自https://blog.csdn.net/BulletTech2021/article/details/119080716 @BulletTech2021
使用与文中相同的 matrixprofile lib 计算异常数据位置
使用Fourier Transform计算周期,作为matrix profile计算过程中的window_size
准确率仅有50%, 达不到文中88%的准确率
计算周期函数如下:
def getWindowSize(timeseries, n=5, fmin=0.02):
yf = abs(fft(timeseries)) # 取绝对值
yfnormlize = yf / len(timeseries) # 归一化处理
yfhalf = yfnormlize[range(int(len(timeseries) / 2))] # 由于对称性,只取一半区间
yfhalf = yfhalf * 2 # y 归一化
xf = np.arange(len(timeseries)) # 频率
xhalf = xf[range(int(len(timeseries) / 2))] # 取一半区间
fwbest = yfhalf[signal.argrelextrema(yfhalf, np.greater)]
xwbest = signal.argrelextrema(yfhalf, np.greater)
xorder = np.argsort(-fwbest)
xworder = list()
xworder.append(xwbest[x] for x in xorder)
fworder = list()
fworder.append(fwbest[x] for x in xorder)
if len(fwbest) <= n:
fwbest = fwbest[fwbest >= fmin].copy()
x = len(timeseries)/xwbest[0][:len(fwbest)]
y = fwbest
else:
fwbest = fwbest[fwbest >= fmin].copy()
x = len(timeseries)/xwbest[0][:len(fwbest)]
y = fwbest
res_x = -1
max_y = -1
for i in range(len(x)):
if y[i] > max_y:
max_y = y[i]
res_x = x[i]
return int(res_x)