如何使用互相关找到两个时间序列之间的滞后
How to find the lag between two time series using cross-correlation
假设这两个系列是:
x = [4,4,4,4,6,8,10,8,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4]
y = [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,6,8,10,8,6,4,4]
系列 x 明显滞后于 y 12 个时间段。
但是,使用 Python cross correlation 中建议的以下代码:
import numpy as np
c = np.correlate(x, y, "full")
lag = np.argmax(c) - c.size/2
导致 -0.5 的错误滞后。
这里有什么问题?
如果你想以简单的方式做到这一点,你应该简单地使用 scipy correlation_lags
此外,请记住从输入中减去平均值。
import numpy as np
from scipy import signal
x = [4,4,4,4,6,8,10,8,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4]
y = [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,6,8,10,8,6,4,4]
correlation = signal.correlate(x-np.mean(x), y - np.mean(y), mode="full")
lags = signal.correlation_lags(len(x), len(y), mode="full")
lag = lags[np.argmax(abs(correlation))]
这给出 lag=-12
,即 x
和 y
中前六个索引之间的差异,如果交换输入,它给出 +12
编辑
为什么要减去均值
如果信号具有非零值,则相关性中心的项将变得更大,因为那里有更大的支持样本来计算相关性。此外,对于非常大的数据,减去平均值可以使计算更准确。
这里我举例说明如果不减去平均值会发生什么。
plt.plot(abs(correlation))
plt.plot(abs(signal.correlate(x, y, mode="full")))
plt.plot(abs(signal.correlate(np.ones_like(x)*np.mean(x), np.ones_like(y)*np.mean(y))))
plt.legend(['subtracting mean', 'constant signal', 'keeping the mean'])
请注意蓝色曲线上的最大值(10)与橙色曲线上的最大值不重合。
假设这两个系列是:
x = [4,4,4,4,6,8,10,8,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4]
y = [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,6,8,10,8,6,4,4]
系列 x 明显滞后于 y 12 个时间段。 但是,使用 Python cross correlation 中建议的以下代码:
import numpy as np
c = np.correlate(x, y, "full")
lag = np.argmax(c) - c.size/2
导致 -0.5 的错误滞后。
这里有什么问题?
如果你想以简单的方式做到这一点,你应该简单地使用 scipy correlation_lags
此外,请记住从输入中减去平均值。
import numpy as np
from scipy import signal
x = [4,4,4,4,6,8,10,8,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4]
y = [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,6,8,10,8,6,4,4]
correlation = signal.correlate(x-np.mean(x), y - np.mean(y), mode="full")
lags = signal.correlation_lags(len(x), len(y), mode="full")
lag = lags[np.argmax(abs(correlation))]
这给出 lag=-12
,即 x
和 y
中前六个索引之间的差异,如果交换输入,它给出 +12
编辑
为什么要减去均值
如果信号具有非零值,则相关性中心的项将变得更大,因为那里有更大的支持样本来计算相关性。此外,对于非常大的数据,减去平均值可以使计算更准确。
这里我举例说明如果不减去平均值会发生什么。
plt.plot(abs(correlation))
plt.plot(abs(signal.correlate(x, y, mode="full")))
plt.plot(abs(signal.correlate(np.ones_like(x)*np.mean(x), np.ones_like(y)*np.mean(y))))
plt.legend(['subtracting mean', 'constant signal', 'keeping the mean'])
请注意蓝色曲线上的最大值(10)与橙色曲线上的最大值不重合。