2014-12-18 7 views
9

Plamuję autokorelację z pythonem. Użyłem trzech sposobów, aby to zrobić: 1. pandy, 2. matplotlib, 3. statmodels. Zauważyłem, że wykres, który otrzymałem od matplotlib, nie jest zgodny z pozostałymi dwoma. Kod jest:Błąd wykresu autokorelacji w plt.acorr matplotlib'a?

from statsmodels.graphics.tsaplots import * 
# print out data 
print mydata.values 

#1. pandas 
p=autocorrelation_plot(mydata) 
plt.title('mydata') 

#2. matplotlib 
fig=plt.figure() 
plt.acorr(mydata,maxlags=150) 
plt.title('mydata') 

#3. statsmodels.graphics.tsaplots.plot_acf 
plot_acf(mydata) 
plt.title('mydata') 

wykres jest tutaj: http://quant365.com/viewtopic.php?f=4&t=33

+1

To pytanie wydaje się być nie na temat, ponieważ jest to raport o błędzie –

+2

Nie tylko raporty o błędach nie należą na SO, ale twoja przykład nie jest możliwy do przeprowadzenia ('mydata' jest niezdefiniowany i brakuje importu) a twoje wykresy są chronione hasłem. Nie wiesz, jakiego rodzaju odpowiedzi oczekujesz. Jeśli chcesz poprawić to pytanie, zalecam skupienie się na pytaniu, co właściwie robi konkretna funkcja. Istnieje szansa, że ​​matplotlib przyjmuje inne, ale równie odpowiednie podejście. –

+0

Teraz powinno być dobrze. Nie mogę tu umieścić wykresu, ponieważ obraz jest podobny do http://quant365.com/download/file.php?id=5, którego nie można tutaj opublikować. –

Odpowiedz

31

Wynika to z różnych wspólnych definicji między statystyk i przetwarzania sygnału. Zasadniczo definicja przetwarzania sygnału zakłada, że ​​będziesz obsługiwać odrywanie. Definicja statystyczna zakłada, że ​​odjęcie średniej to całkowite odejście, które zrobisz, i robi to za ciebie.

Po pierwsze, niech wykazać problem z samodzielnym przykład:

import numpy as np 
import matplotlib.pyplot as plt 

import pandas as pd 
from statsmodels.graphics import tsaplots 

def label(ax, string): 
    ax.annotate(string, (1, 1), xytext=(-8, -8), ha='right', va='top', 
       size=14, xycoords='axes fraction', textcoords='offset points') 

np.random.seed(1977) 
data = np.random.normal(0, 1, 100).cumsum() 

fig, axes = plt.subplots(nrows=4, figsize=(8, 12)) 
fig.tight_layout() 

axes[0].plot(data) 
label(axes[0], 'Raw Data') 

axes[1].acorr(data, maxlags=data.size-1) 
label(axes[1], 'Matplotlib Autocorrelation') 

tsaplots.plot_acf(data, axes[2]) 
label(axes[2], 'Statsmodels Autocorrelation') 

pd.tools.plotting.autocorrelation_plot(data, ax=axes[3]) 
label(axes[3], 'Pandas Autocorrelation') 

# Remove some of the titles and labels that were automatically added 
for ax in axes.flat: 
    ax.set(title='', xlabel='') 
plt.show() 

enter image description here

Więc dlaczego do cholery ja mówię, że są one poprawne? Są wyraźnie różne!

Załóżmy napisać własną funkcję autokorelacji wykazać co plt.acorr robi:

def acorr(x, ax=None): 
    if ax is None: 
     ax = plt.gca() 
    autocorr = np.correlate(x, x, mode='full') 
    autocorr /= autocorr.max() 

    return ax.stem(autocorr) 

Gdybyśmy działki to z naszych danych, będziemy mieć bardziej lub mniej identyczny wynik plt.acorr (jestem pozostawiając prawidłowo oznakowania LGD, po prostu dlatego, że jestem leniwy):

fig, ax = plt.subplots() 
acorr(data) 
plt.show() 

enter image description here

jest to doskonale val id autokorelacja. Wszystko zależy od tego, czy twoje tło jest przetwarzaniem sygnału, czy statystyką.

Jest to definicja używana w przetwarzaniu sygnału. Założono, że poradzisz sobie z detekcją danych (zanotuj numer detrend kwarg w plt.acorr). Jeśli chcesz go odrzucić, zdecydowanie go poprosisz (i prawdopodobnie zrobisz coś lepszego niż odjęcie średniej), a inaczej nie należy zakładać.

W statystykach przyjmuje się po prostu, że odjęcie średniej jest tym, co chcemy zrobić dla oderwania.

Wszystkie pozostałe funkcje są odjęcie średniej z danych przed korelacji, podobnego do tego:

def acorr(x, ax=None): 
    if ax is None: 
     ax = plt.gca() 

    x = x - x.mean() 

    autocorr = np.correlate(x, x, mode='full') 
    autocorr /= autocorr.max() 

    return ax.stem(autocorr) 

fig, ax = plt.subplots() 
acorr(data) 
plt.show() 

enter image description here

Jednak wciąż mamy jedną dużą różnicę. Ta jest czysto spiskowa.

W większości podręczników do przetwarzania sygnałów (które widziałem, tak), wyświetlana jest "pełna" autokorelacja, tak że zerowe opóźnienie znajduje się pośrodku, a wynik jest symetryczny z każdej strony. Z drugiej strony R ma bardzo rozsądną konwencję do wyświetlania tylko jednej strony. (Wszakże druga strona jest całkowicie zbędna.) Funkcje statystyczne funkcji kreślenia są zgodne z konwencją R, i plt.acorr następuje po tym, co robi Matlab, który jest przeciwną konwencją.

zasadzie, że chcesz to:

def acorr(x, ax=None): 
    if ax is None: 
     ax = plt.gca() 

    x = x - x.mean() 

    autocorr = np.correlate(x, x, mode='full') 
    autocorr = autocorr[x.size:] 
    autocorr /= autocorr.max() 

    return ax.stem(autocorr) 

fig, ax = plt.subplots() 
acorr(data) 
plt.show() 

enter image description here

+1

Dzięki Wciąż mam jedno niezbyt jasne. "Jednak wciąż mamy jedną dużą różnicę, ta jest czysto spiskowa." Czy mogę wiedzieć, co to jest konwencja spiskowania? Pochodzę ze statystyki i nie mam wiedzy na temat przetwarzania sygnałów. Dlaczego Python nie zapewnia jednolitej wersji? I właśnie stwierdziłem, że nie ma częściowej autokorelacji w pandach, co jest rozczarowujące. –

+0

Dlaczego na moim wykresie autokorelacja przy opóźnieniu 0 wynosi 0,5? To jest złe, tak jak powinno być 1! Ale myślę, że użyłem tej funkcji poprawnie. Czy też coś mi umknęło? –

+0

@WuFuheng - konwencja kreślenia jest różnicą między dwiema ostatnimi cyframi: to, czy pokazana jest pełna, symetryczna autokorelacja, czy tylko jedna jej połowa. Jeśli chodzi o to, dlaczego Twoje wykresy mają 0,5 w przypadku opóźnienia 0, nie mam pojęcia. Otrzymuję autokorelację wynoszącą 1 przy opóźnieniu 0 z dokładnie tymi samymi funkcjami. –

Powiązane problemy