Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 什么';熊猫ACF和StatsModelACF有什么区别?_Python_Pandas_Statsmodels - Fatal编程技术网

Python 什么';熊猫ACF和StatsModelACF有什么区别?

Python 什么';熊猫ACF和StatsModelACF有什么区别?,python,pandas,statsmodels,Python,Pandas,Statsmodels,我在计算股票收益的自相关函数。为此,我测试了两个函数,Pandas内置的autocorr函数和statsmodels.tsa提供的acf函数。这在以下MWE中完成: import pandas as pd from pandas_datareader import data import matplotlib.pyplot as plt import datetime from dateutil.relativedelta import relativedelta from statsmodel

我在计算股票收益的自相关函数。为此,我测试了两个函数,Pandas内置的
autocorr
函数和
statsmodels.tsa
提供的
acf
函数。这在以下MWE中完成:

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')
我注意到他们预测的值不一样:


是什么导致了这种差异,以及应该使用哪些值?

正如评论中所建议的,通过向
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

Pandas和Statsmodels版本之间的差异在于均值减法和归一化/方差除法:

  • autocorr
    只是将原始序列的子序列传递给
    np.corrcoef
    。在该方法中,这些子系列的样本均值和样本方差用于确定相关系数
  • acf
    ,相反,使用总体序列样本平均值和样本方差来确定相关系数
时间序列越长,差异越小,但时间序列越短,差异就越大

与Matlab相比,Pandas
autocorr
函数可能对应于对(滞后)序列本身进行Matlabs
xcorr
(交叉corr),而不是Matlab的
autocorr
,后者计算样本自相关性(从文档中猜测;我无法验证这一点,因为我无法访问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()


Statsmodels使用
np.correlate
来优化它,但它基本上就是这样工作的。

在下面的示例中,Pandas
autocorr()
函数给出了预期的结果,而statmodels
acf()
函数没有

考虑以下系列:

将熊猫作为pd导入
s=pd.系列(范围(10))
我们期望这个序列和它的任何滞后序列之间都有完美的相关性,这实际上是我们通过
autocorr()
函数得到的

[s.autocorr(滞后=i)用于范围(10)内的i]
#[0.999999999999,1.0,1.0,1.0,1.0,1.0,0.999999999999999,1.0,1.0,0.999999999999,nan]
但是使用
acf()
我们得到了不同的结果:

从statsmodels.tsa.stattools导入acf
机场核心设施(s)
# [ 1.          0.7         0.41212121  0.14848485 -0.07878788 
#  -0.25757576 -0.37575758 -0.42121212 -0.38181818 -0.24545455]
如果我们尝试使用
adjusted=True
进行
acf
,结果会更加意外,因为对于某些滞后,结果小于-1(注意相关性必须在[-1,1])

acf(s,adjusted=True)#“unbiased”不推荐使用,应改用“adjusted”
# [ 1.          0.77777778  0.51515152  0.21212121 -0.13131313 
#  -0.51515152 -0.93939394 -1.4040404  -1.90909091 -2.45454545]

查看文档,pandas版本的默认滞后时间为
1
,statsmodelTry的默认滞后时间为
40
,statsmodelTry的默认滞后时间为
unbiased=True
作为statsmodels版本的选项。您在绘图中反转了标签,我认为
unbiased=True
应该使自相关系数更大。
autocorr
from
pandas
正在调用,而
acf
from
statsmodels
正在调用。我认为深入研究这些问题有助于找到产出差异的根源。这里的第一条评论是对这个问题的回答吗?这是伟大的解决这个问题,但哪2种方式计算自相关是更好的/正确的?我认为“代码> StassMasks<代码>方式是显而易见的。作为参考,这也是本文中指出的方法。要检查像熊猫一样使用互相关是否也是一个有效的估计,需要查阅文献。仅供参考:虽然statsmodels的这一估计被认为是“无偏的”,因为我们使用了
n-k
而不是
n
,但根据维基百科,它仍然是有偏的,因为我们使用样本平均值和样本协方差进行计算。