matplotlib的plt.acorr中的自相关图缺陷?

2024-10-17 12:19:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用python绘制自相关。我用了三种方法:1。熊猫,2。matplotlib,3号。斯塔茨模型。我发现从matplotlib得到的图形与另外两个不一致。代码是:

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

图表在这里:http://quant365.com/viewtopic.php?f=4&t=33


Tags: 方法代码模型图形plottitlematplotlib绘制
1条回答
网友
1楼 · 发布于 2024-10-17 12:19:41

这是统计和信号处理之间不同的共同定义的结果。基本上,信号处理定义假定您要处理去趋势化。统计定义假设减去平均值就是你将要做的所有改变,并且是为你做的。

首先,让我们用一个独立的例子来演示这个问题:

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

所以,为什么我说他们都是对的?他们明显不同!

让我们编写自己的自相关函数来演示plt.acorr在做什么:

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)

如果我们用我们的数据来绘制这个图,我们将得到与plt.acorr大致相同的结果(我没有适当地标记延迟,只是因为我很懒):

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

enter image description here

这是一个完全有效的自相关。这都是你的背景是信号处理还是统计的问题。

这是信号处理中使用的定义。假设您要处理数据的格式转换(注意detrend中的plt.acorrkwarg)。如果你想取消渲染,你会明确地要求它(并且可能做一些比仅仅减去平均值更好的事情),否则就不应该假设它。

在统计学中,简单地减去平均值被认为是你想要做的。

所有其他函数都是在相关之前减去数据的平均值,类似于:

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

然而,我们仍然有一个很大的区别。这纯粹是一个阴谋约定。

在大多数信号处理教科书中(我已经看到过了),显示的是“完全”自相关,这样零滞后在中心,结果在每一边都是对称的。R、 另一方面,有一个非常合理的惯例,只展示它的一面。(毕竟,另一方面是完全冗余的)统计绘图函数遵循R对流,而plt.acorr遵循Matlab所做的,这是相反的约定。

基本上,你会想要这个:

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

相关问题 更多 >