Кластеризация похожих временных рядов? - PullRequest
5 голосов
/ 12 октября 2019

У меня где-то 10–20 тысяч различных временных рядов (24-мерные данные - столбец для каждого часа дня), и меня интересует кластеризация временных рядов, которые демонстрируют примерно одинаковые модели активности.

Изначально я начал реализовывать динамическую деформацию времени (DTW), потому что:

  1. Не все мои временные ряды идеально выровнены
  2. Два слегка смещенных временных ряда длямои цели следует считать схожими
  3. Два временных ряда с одинаковой формой, но разными масштабами следует считать схожими

Единственная проблема, с которой я столкнулся с DTW, заключалась в том, что она не появляласьдля хорошего масштабирования - fastdtw на матрице расстояний 500x500 заняло ~ 30 минут.

Какие существуют другие методы, которые помогли бы мне выполнить условия 2 и 3?

1 Ответ

5 голосов
/ 14 октября 2019

ARIMA может выполнить эту работу, если вы разбиваете временные ряды на тренды, сезонность и остатки. После этого используйте алгоритм K-Nearest Neighbor. Однако вычислительные затраты могут быть дорогими, в основном из-за ARIMA.

В ARIMA:

from statsmodels.tsa.arima_model import ARIMA

model0 = ARIMA(X, dates=None,order=(2,1,0))
model1 = model0.fit(disp=1)

decomposition = seasonal_decompose(np.array(X).reshape(len(X),),freq=100)
### insert your data seasonality in 'freq'

trend = decomposition.trend
seasonal = decomposition.seasonal
residual = decomposition.resid

В качестве дополнения к комментарию @Sushant вы разбираете временные ряды и можете проверить сходство водин или все из 4 графиков: данные, сезонность, тренд и остатки.

ARIMA

Затем пример данных:

import numpy as np
import matplotlib.pyplot as plt
sin1=[np.sin(x)+x/7 for x in np.linspace(0,30*3,14*2,1)]
sin2=[np.sin(0.8*x)+x/5 for x in np.linspace(0,30*3,14*2,1)]
sin3=[np.sin(1.3*x)+x/5 for x in np.linspace(0,30*3,14*2,1)]
plt.plot(sin1,label='sin1')
plt.plot(sin2,label='sin2')
plt.plot(sin3,label='sin3')
plt.legend(loc=2)
plt.show()

Sine

X=np.array([sin1,sin2,sin3])

from sklearn.neighbors import NearestNeighbors
nbrs = NearestNeighbors(n_neighbors=2, algorithm='ball_tree').fit(X)
distances, indices = nbrs.kneighbors(X)
distances

Вы получите сходство:

array([[ 0.        , 16.39833107],
       [ 0.        ,  5.2312092 ],
       [ 0.        ,  5.2312092 ]])
...