Прежде всего, чтобы получить нормализованный коэффициент (такой, что при отставании 0 мы получаем корреляцию Пирсона):
- разделить оба сигнала на их стандартное отклонение
- масштабировать по длине сигнала, по которому выполняется свертка (самый короткий сигнал)
out = correlate(x/std(x), y/std(y), 'full') / min(len(x), len(y))
Теперь о лагах из официальной документации correlate
< /a> можно прочитать, что полный результат кросс-корреляции определяется следующим образом:
z[k] = (x * y)(k - N + 1)
= \sum_{l=0}^{||x||-1}x_l y_{l-k+N-1}^{*}\]
Где *
обозначает свертку, а k идет от 0 до ||x|| + ||y|| - 2
точно. N равно max(len(x), len(y))
.
Лаги обозначены выше как аргумент свертки (x * y)
, поэтому они варьируются от 0 - N + 1
до ||x|| + ||y|| - 2 - N + 1
, что равно n - 1
с n=min(len(x), len(y))
.
Кроме того, бегло взглянув на исходный код, я думаю, что они иногда меняют местами x
и y
, если это удобно... (отсюда и min(len(x), len(y))
в приведенной выше нормализации. Однако это подразумевает изменение начала наших лагов, поэтому:
N = max(len(x), len(y))
n = min(len(x), len(y))
# if len(x) < (len(y):
lags = np.arange(-N + 1, n)
# else:
lags = np.arange(-n + 1, N)
Резюме
Проверьте этот код на двух временных рядах, для которых вы хотите построить взаимную корреляцию:
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import correlate
def plot_xcorr(x, y):
"Plot cross-correlation (full) between two signals."
N = max(len(x), len(y))
n = min(len(x), len(y))
if N == len(y):
lags = np.arange(-N + 1, n)
else:
lags = np.arange(-n + 1, N)
c = correlate(x / std(x), y / std(y), 'full')
plt.plot(lags, c / n)
plt.show()
person
H. Rev.
schedule
29.09.2020
s1
иs2
и показать, что они возвращают, а также то, что вы ожидаете. - person Bill   schedule 20.07.2020