Próbuję obliczyć odległości parami między wieloma szeregami czasowymi zawartymi w tablicy numpy. Proszę zobaczyć poniższy kodEfektywne obliczanie parami DTW przy użyciu numpy lub cython
print(type(sales))
print(sales.shape)
<class 'numpy.ndarray'>
(687, 157)
Więc sales
zawiera 687 szeregów czasowych o długości 157. Korzystanie pdist do obliczenia odległości pomiędzy Detroit szeregów czasowych.
import fastdtw
import scipy.spatial.distance as sd
def my_fastdtw(sales1, sales2):
return fastdtw.fastdtw(sales1,sales2)[0]
distance_matrix = sd.pdist(sales, my_fastdtw)
--- EDIT: Próbowałem to robić bez pdist()
-----
distance_matrix = []
m = len(sales)
for i in range(0, m - 1):
for j in range(i + 1, m):
distance_matrix.append(fastdtw.fastdtw(sales[i], sales[j]))
--- EDIT: parallelizing wewnętrzna pętla for -----
from joblib import Parallel, delayed
import multiprocessing
import fastdtw
num_cores = multiprocessing.cpu_count() - 1
N = 687
def my_fastdtw(sales1, sales2):
return fastdtw.fastdtw(sales1,sales2)[0]
results = [[] for i in range(N)]
for i in range(0, N- 1):
results[i] = Parallel(n_jobs=num_cores)(delayed(my_fastdtw) (sales[i],sales[j]) for j in range(i + 1, N))
Wszystkie metody są bardzo powolne. Metoda równoległa trwa około 12 minut. Czy ktoś może zaproponować skuteczny sposób?
--- EDIT: Następujące kroki opisane w poniższej odpowiedzi ---
Oto jak folder lib wygląda następująco:
VirtualBox:~/anaconda3/lib/python3.6/site-packages/fastdtw-0.3.2-py3.6- linux-x86_64.egg/fastdtw$ ls
_fastdtw.cpython-36m-x86_64-linux-gnu.so fastdtw.py __pycache__
_fastdtw.py __init__.py
Tak, istnieje wersja z fastdtw w Cython tam. Podczas instalacji nie otrzymałem żadnych błędów. Nawet teraz, kiedy wciśnięty CTRL-C
podczas mojego wykonywania programu, widzę, że czysta wersja Pythona jest używany (fastdtw.py
):
/home/vishal/anaconda3/lib/python3.6/site-packages/fastdtw/fastdtw.py in fastdtw(x, y, radius, dist)
/home/vishal/anaconda3/lib/python3.6/site-packages/fastdtw/fastdtw.py in __fastdtw(x, y, radius, dist)
Kod pozostaje wolna jak przedtem.
Przeczytaj, co' pdist' mówi o dostarczaniu twojej własnej funkcji. Zauważ, ile razy to nazywa. Co produkuje 'fastdtw'? Jakie są pozycje w 'dm'? Myślę, że 'pdist' oczekuje prostej liczby od funkcji odległości. – hpaulj
@hpaulj, masz rację, każde wywołanie 'fastdtw' powoduje' float', który jest odległością wymaganą przez pdist, a także zwraca ścieżkę. Zobacz mój zaktualizowany wpis. – user1274878
Wygląda na to, że 'pdist' wykonuje ten sam rodzaj iteracji, gdy jest podana funkcja Pythona. Jest to szybsze, gdy używasz jednego ze swoich skompilowanych danych. Każda poprawa szybkości musi pochodzić z końca 'fastdtw'. – hpaulj