2016-03-16 20 views
12

Bir hisse senedi iadesi için Otomatik İlişkilendirme İşlevini hesaplıyorum. Bunu yapmak için, iki işlevi test ettim, Pandalar'a yerleşik autocorr işlevi ve statsmodels.tsa tarafından sağlanan acf işlevi. Bu şu MWE yapılır: Fark nedirpanda ACF ve statsmodel ACF arasındaki fark nedir?

import pandas as pd 
from pandas_datareader import data 
import matplotlib.pyplot as plt 
import datetime 
from dateutil.relativedelta import relativedelta 
from statsmodels.tsa.stattools import acf, pacf 

ticker = 'AAPL' 
time_ago = datetime.datetime.today().date() - relativedelta(months = 6) 

ticker_data = data.get_data_yahoo(ticker, time_ago)['Adj Close'].pct_change().dropna() 
ticker_data_len = len(ticker_data) 

ticker_data_acf_1 = acf(ticker_data)[1:32] 
ticker_data_acf_2 = [ticker_data.autocorr(i) for i in range(1,32)] 

test_df = pd.DataFrame([ticker_data_acf_1, ticker_data_acf_2]).T 
test_df.columns = ['Pandas Autocorr', 'Statsmodels Autocorr'] 
test_df.index += 1 
test_df.plot(kind='bar') 

onlar tahmin değerleri özdeş değildi edildi: Hangi

enter image description here

Ne bu farkı dikkate ve kullanılmalıdır değerlerin?

+2

Dokümanlara bakarak varsayılan gecikmeler pandalar sürümü için 1'tir ve statsmodel – EdChum

+0

için '40', statsmodels sürümüne 'neutral = True' seçeneğini deneyin. – user333700

+0

Çizginizdeki etiketleri tersine çevirdiniz, bence 'yansız = Doğru' otokorelasyon katsayılarını daha büyük yapmalı. – user333700

cevap

4

ortalama çıkarma ve normalleşme/varyans bölümü Pandalar ve Statsmodels versiyonu yalan arasındaki fark:

  • autocorr başka bir şey yapar Orijinal dizinin alt bölümlerini np.corrcoef'a iletmekten daha fazla. Bu yöntemin içinde, bu alt bölümlerin örnek ortalaması ve örnek varyansı, korelasyon katsayısını belirlemek için korelasyon katsayısını
  • acf, tam tersine, genel seri örnek ortalaması ve örnek varyansını belirlemek için kullanılır.

Farklılıklar daha uzun zaman serileri için daha küçük olabilir, ancak kısa olanlar için oldukça büyük olabilir. Matlab karşılaştırıldığında

, panda autocorr fonksiyonu muhtemelen MATLABların durumu tekabül xcorr dokümanlardan tahmin örnek otokorelasyon (hesaplar (gecikmeli) seri kendisi (çapraz corr) yerine Matlab'ınkine autocorr; ı doğrulayamamaktadır çünkü Matlab'a erişimim yok).

import numpy as np 
import pandas as pd 
from statsmodels.tsa.stattools import acf 
import matplotlib.pyplot as plt 
plt.style.use("seaborn-colorblind") 

def autocorr_by_hand(x, lag): 
    # Slice the relevant subseries based on the lag 
    y1 = x[:(len(x)-lag)] 
    y2 = x[lag:] 
    # Subtract the subseries means 
    sum_product = np.sum((y1-np.mean(y1))*(y2-np.mean(y2))) 
    # Normalize with the subseries stds 
    return sum_product/((len(x) - lag) * np.std(y1) * np.std(y2)) 

def acf_by_hand(x, lag): 
    # Slice the relevant subseries based on the lag 
    y1 = x[:(len(x)-lag)] 
    y2 = x[lag:] 
    # Subtract the mean of the whole series x to calculate Cov 
    sum_product = np.sum((y1-np.mean(x))*(y2-np.mean(x))) 
    # Normalize with var of whole series 
    return sum_product/((len(x) - lag) * np.var(x)) 

x = np.linspace(0,100,101) 

results = {} 
nlags=10 
results["acf_by_hand"] = [acf_by_hand(x, lag) for lag in range(nlags)] 
results["autocorr_by_hand"] = [autocorr_by_hand(x, lag) for lag in range(nlags)] 
results["autocorr"] = [pd.Series(x).autocorr(lag) for lag in range(nlags)] 
results["acf"] = acf(x, unbiased=True, nlags=nlags-1) 

pd.DataFrame(results).plot(kind="bar", figsize=(10,5), grid=True) 
plt.xlabel("lag") 
plt.ylim([-1.2, 1.2]) 
plt.ylabel("value") 
plt.show() 

See this plot for the result

Statsmodels bu duruma getirmek için np.correlate kullanır, ancak nasıl çalıştığını bu temelde:

açıklama bu MWe bakınız.

0

Açıklamalarda önerildiği gibi, unbiased=True işlevini statsmodels işlevine ileterek sorun azaltılabilir, ancak tamamen çözülemez. rastgele girişini kullanma:

import statistics 

import numpy as np 
import pandas as pd 
from statsmodels.tsa.stattools import acf 

DATA_LEN = 100 
N_TESTS = 100 
N_LAGS = 32 

def test(unbiased): 
    data = pd.Series(np.random.random(DATA_LEN)) 
    data_acf_1 = acf(data, unbiased=unbiased, nlags=N_LAGS) 
    data_acf_2 = [data.autocorr(i) for i in range(N_LAGS+1)] 
    # return difference between results 
    return sum(abs(data_acf_1 - data_acf_2)) 

for value in (False, True): 
    diffs = [test(value) for _ in range(N_TESTS)] 
    print(value, statistics.mean(diffs)) 

Çıktı:

False 0.464562410987 
True 0.0820847168593