Muszę zrobić autokorelację zbioru liczb, co, jak rozumiem, jest po prostu korelacją zbioru ze sobą.
Wypróbowałem to za pomocą funkcji korelacji numpy, ale nie wierzę w wynik, ponieważ prawie zawsze daje wektor, w którym pierwsza liczba nie jest największa, jak powinna.
Tak więc to pytanie to tak naprawdę dwa pytania:
- Co dokładnie
numpy.correlate
robi? - Jak mogę tego użyć (lub czegoś innego) do wykonania autokorelacji?
Odpowiedzi:
Aby odpowiedzieć na pierwsze pytanie,
numpy.correlate(a, v, mode)
należy wykonać splota
z odwrotnościąv
i podać wyniki obcięte przez określony tryb. Definicji splotu c (t) = Ď -∞ <i <∞ i v t + i, gdzie -∞ <t <∞ pozwala na wyniki z -∞ do ∞, ale oczywiście nie można przechowywać nieskończenie długa szyk. Musi więc zostać przycięty i właśnie tam pojawia się tryb. Istnieją 3 różne tryby: pełny, taki sam i ważny:t
, w którym zarównoa
iv
pewne nakładanie.a
lubv
).a
iv
całkowicie zachodzą na siebie. Dokumentacja dlanumpy.convolve
daje więcej szczegółów na temat trybów.Na drugie pytanie, myślę, że
numpy.correlate
to daje autokorelacji, to jest po prostu daje trochę więcej, jak również. Autokorelacja służy do ustalenia, jak podobny jest do siebie sygnał lub funkcja przy określonej różnicy czasu. Przy różnicy czasu równej 0 autokorelacja powinna być najwyższa, ponieważ sygnał jest identyczny ze sobą, więc spodziewano się, że pierwszy element w tablicy wyników autokorelacji będzie największy. Jednak korelacja nie zaczyna się przy różnicy czasu równej 0. Zaczyna się od ujemnej różnicy czasu, zamyka się do 0, a następnie staje się dodatnia. Oznacza to, że spodziewałeś się:autokorelacja (a) = ∑ -∞ <i <∞ a i v t + i gdzie 0 <= t <∞
Ale otrzymałeś:
autokorelacja (a) = ∑ -∞ <i <∞ a i v t + i gdzie -∞ <t <∞
To, co musisz zrobić, to wziąć ostatnią połowę wyniku korelacji i to powinna być autokorelacja, której szukasz. Prosta funkcja w Pythonie do zrobienia to:
Będziesz oczywiście potrzebował sprawdzenia błędów, aby upewnić się, że
x
faktycznie jest to tablica 1-wymiarowa. Poza tym to wyjaśnienie prawdopodobnie nie jest najbardziej rygorystyczne matematycznie. Rzucałem się wokół nieskończoności, ponieważ definicja splotu używa ich, ale niekoniecznie dotyczy to autokorelacji. Zatem teoretyczna część tego wyjaśnienia może być nieco niepewna, ale miejmy nadzieję, że praktyczne wyniki będą pomocne. Te strony dotyczące autokorelacji są bardzo pomocne i mogą dać ci znacznie lepsze podstawy teoretyczne, jeśli nie masz nic przeciwko przebrnięciu przez notację i ciężkie koncepcje.źródło
return numpy.correlate(x, x, mode='same')
np.correlate(x,x,mode='full')[len(x)//2:] != np.correlate(x,x,mode='same')
. Na przykładx = [1,2,3,1,2]; np.correlate(x,x,mode='full');
{>>> array([ 2, 5, 11, 13, 19, 13, 11, 5, 2])
}np.correlate(x,x,mode='same');
{>>> array([11, 13, 19, 13, 11])
}. Prawidłowy to:np.correlate(x,x,mode='full')[len(x)-1:];
{>>> array([19, 13, 11, 5, 2])
} zobacz, że pierwsza pozycja jest największa .[len(x)-1:]
zaczyna się od 0-laga. Ponieważfull
tryb daje rozmiar wyniku2*len(x)-1
, wartość A. Levy'ego[result.size/2:]
jest taka sama jak[len(x)-1:]
. Lepiej jednak zrobić z tego intrygę, na przykład[result.size//2:]
.Autokorelacja występuje w dwóch wersjach: statystycznej i splotowej. Obaj robią to samo, z wyjątkiem małego szczegółu: Wersja statystyczna jest znormalizowana do przedziału [-1,1]. Oto przykład, jak wykonujesz statystyczny:
źródło
numpy.corrcoef[x:-i], x[i:])[0,1]
w drugim wierszu, ponieważ wartość zwracanacorrcoef
jest macierzą 2x2Użyj
numpy.corrcoef
funkcji zamiastnumpy.correlate
obliczyć korelację statystyczną dla opóźnienia t:źródło
Myślę, że są dwie rzeczy, które wprowadzają zamieszanie w tym temacie:
Stworzyłem 5 funkcji, które obliczają autokorelację tablicy 1d, z rozróżnieniami częściowymi i nie częściowymi. Niektórzy używają wzoru ze statystyk, inni używają korelacji w sensie przetwarzania sygnału, co można również zrobić za pomocą FFT. Ale wszystkie wyniki są autokorelacjami w definicji statystyki , więc ilustrują, w jaki sposób są ze sobą powiązane. Kod poniżej:
Oto liczba wyjściowa:
Nie widzimy wszystkich 5 linii, ponieważ 3 z nich nakładają się (na fioletowo). Wszystkie nakładające się elementy są nie częściowymi autokorelacjami. Dzieje się tak, ponieważ obliczenia z metod przetwarzania sygnału (
np.correlate
FFT) nie obliczają innej średniej / standardowej dla każdego nakładania się.Zauważ również, że wynik
fft, no padding, non-partial
(czerwona linia) jest inny, ponieważ nie dopełnił on szeregu czasowego zerami przed wykonaniem FFT, więc jest to cykliczna FFT. Nie potrafię szczegółowo wyjaśnić, dlaczego, tego nauczyłem się gdzie indziej.źródło
Ponieważ właśnie napotkałem ten sam problem, chciałbym podzielić się z wami kilkoma wierszami kodu. W rzeczywistości istnieje już kilka dość podobnych postów dotyczących autokorelacji w przepływie stosu. Jeśli zdefiniujesz autokorelację jako
a(x, L) = sum(k=0,N-L-1)((xk-xbar)*(x(k+L)-xbar))/sum(k=0,N-1)((xk-xbar)**2)
[jest to definicja podana w funkcji a_correlate IDL i zgadza się z tym, co widzę w odpowiedzi 2 na pytanie nr 12269834 ], to poniższe wydaje się dawać prawidłowe wyniki:Jak widać, przetestowałem to z krzywą grzechu i jednolitym losowym rozkładem i oba wyniki wyglądają tak, jakbym się ich spodziewał. Zauważ, że użyłem
mode="same"
zamiast tego,mode="full"
co zrobili inni.źródło
Twoje pytanie 1 zostało już obszernie omówione w kilku doskonałych odpowiedziach tutaj.
Pomyślałem, że podzielę się z wami kilkoma wierszami kodu, które pozwolą obliczyć autokorelację sygnału na podstawie wyłącznie matematycznych właściwości autokorelacji. Oznacza to, że autokorelację można obliczyć w następujący sposób:
odejmij średnią od sygnału i uzyskaj nieobciążony sygnał
obliczyć transformatę Fouriera nieobciążonego sygnału
obliczyć gęstość widmową mocy sygnału, biorąc normę kwadratową każdej wartości transformaty Fouriera nieobciążonego sygnału
obliczyć odwrotną transformatę Fouriera gęstości widmowej mocy
znormalizuj odwrotną transformatę Fouriera gęstości widmowej mocy przez sumę kwadratów nieobciążonego sygnału i weź tylko połowę wynikowego wektora
Kod służący do tego jest następujący:
źródło
p = np.abs(f)
?Jestem biologiem obliczeniowym i kiedy musiałem obliczyć korelacje auto / krzyżowe między parami szeregów czasowych procesów stochastycznych, zdałem sobie sprawę, że
np.correlate
nie spełniało to moich oczekiwań.Rzeczywiście, wydaje się, że brakuje
np.correlate
w nim uśredniania wszystkich możliwych par punktów czasowych na odległość 𝜏.Oto jak zdefiniowałem funkcję wykonującą to, czego potrzebowałem:
Wydaje mi się, że żadna z poprzednich odpowiedzi nie obejmuje tego przypadku korelacji automatycznej / krzyżowej: mam nadzieję, że ta odpowiedź może być przydatna dla kogoś, kto pracuje nad procesami stochastycznymi, tak jak ja.
źródło
Używam talib.CORREL do autokorelacji w ten sposób, podejrzewam, że możesz zrobić to samo z innymi pakietami:
źródło
Zastosowanie transformacji Fouriera i twierdzenia o splotach
Złożoność czasowa to N * log (N)
Oto znormalizowana i nieobciążona wersja, jest to również N * log (N)
Metoda dostarczona przez A. Levy'ego działa, ale przetestowałem ją na swoim komputerze, jej złożoność czasowa wydaje się być N * N
źródło
Alternatywa dla numpy.correlate jest dostępna w statsmodels.tsa.stattools.acf () . Daje to stale malejącą funkcję autokorelacji, taką jak ta opisana przez OP. Wdrożenie jest dość proste:
Domyślnym zachowaniem jest zatrzymanie przy 40 nlagach, ale można to dostosować za pomocą
nlag=
opcji dla konkretnej aplikacji. Na dole strony znajduje się cytat ze statystykami funkcji .źródło
Myślę, że prawdziwa odpowiedź na pytanie PO jest zwięźle zawarta w tym fragmencie dokumentacji Numpy.correlate:
Oznacza to, że gdy jest używana bez definicji „trybu”, funkcja Numpy.correlate zwróci wartość skalarną, gdy otrzyma ten sam wektor dla swoich dwóch argumentów wejściowych (tj. - gdy zostanie użyta do wykonania autokorelacji).
źródło
Proste rozwiązanie bez pand:
źródło
Wykreśl autokorelację statystyczną, biorąc pod uwagę dane pandy Seria zwrotów:
źródło
autocorrelation_plot()
w tym przypadku? (por. stats.stackexchange.com/questions/357300/… )