2016-03-16 13 views
12

私は、株式のリターンの自己相関関数を計算しています。これを行うために、私はautocorr関数をPandasに組み込み、acf関数はstatsmodels.tsaによって提供するという2つの関数をテストしました。これは、次のMWEで行われます。pandas ACFとstatsmodel ACFの違いは何ですか?

enter image description here

この違いを占め、かつその値が使用されるべきもの:

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') 

私は気づいた彼らは予測値が同じではありませんでしたでしたか?

+2

デフォルトの遅れはパンダのバージョンでは '1'、statsmodelでは' – EdChum

+0

'の場合は '40'です。統計モデルバージョンのオプションとして' unbiased = True'を試してみてください。 – user333700

+0

あなたはプロットのラベルを逆にしました。私は 'unbiased = True'は自己相関係数を大きくするべきだと思います。 – user333700

答えて

4

平均減算及び正規化/分散部門でパンダとStatsmodelsバージョン位置との差:

  • autocorrより何もしません元のシリーズのサブシリーズをnp.corrcoefに渡すよりもこの方法の中で、これらのサブシリーズのサンプル平均およびサンプル分散を用いて相関係数を決定する。
  • acf逆に、相関係数を決定するためにシリーズ全体のサンプル平均およびサンプル分散を使用する。

差は、より長い時系列では小さくなることがありますが、短いものではかなり大きくなります。 Matlabのに比べ

、パンダautocorr機能はおそらくドキュメントから推測(サンプル自己相関を計算する代わりに、MATLABのautocorrの、(遅れ)シリーズ自体とMatlabs xcorr(クロスCORR)を行うことに対応し、Iが検証できませんこれは私がMatlabにアクセスできないためです)。

明確化のため、このMWEを参照してください。

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はこれを最適化するためnp.correlateを使用していますが、これはそれがどのように動作するか基本的にあります。

0

コメントで示唆されているように、statsmodels機能にunbiased=Trueを指定することで、この問題は軽減できますが、完全には解決されません。ランダムな入力を使用して:

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)) 

出力:

False 0.464562410987 
True 0.0820847168593 
関連する問題