Мне нужно сделать автокорреляцию набора чисел, что, как я понимаю, просто корреляция набора с самим собой.
Я пробовал использовать функцию корреляции numpy, но я не верю результату, так как он почти всегда дает вектор, где первое число не самым большим, как должно быть.
Итак, это действительно два вопроса:
- Что именно
numpy.correlate
делает? - Как я могу использовать его (или что-то еще) для автокорреляции?
Ответы:
Чтобы ответить на ваш первый вопрос,
numpy.correlate(a, v, mode)
выполняет сверткуa
с обратнымv
и выдает результаты, обрезанные указанным режимом. Определение свертки , С (т) = Е -∞ <я <∞ я v т + я где -∞ <т <∞, позволяет сделать результаты от -∞ до ∞, но вы , очевидно , не может хранить бесконечно долго массив. Таким образом, он должен быть обрезан, и именно здесь вступает в силу режим. Есть 3 разных режима: полный, одинаковый и действительный:t
где обаa
иv
имеют некоторое перекрытие.a
илиv
).a
иv
полностью перекрывают друг друга. В документации дляnumpy.convolve
более подробно описаны режимы.Что касается вашего второго вопроса, я думаю, что
numpy.correlate
он дает вам автокорреляцию, он просто дает вам немного больше. Автокорреляция используется, чтобы определить, насколько сигнал или функция похож на сам себя в определенную разницу во времени. При разнице во времени, равной 0, автокорреляция должна быть максимальной, потому что сигнал идентичен самому себе, поэтому вы ожидали, что первый элемент в массиве результатов автокорреляции будет максимальным. Однако корреляция не начинается при разнице во времени, равной 0. Она начинается при отрицательной разнице во времени, закрывается до 0, а затем становится положительной. То есть вы ожидали:автокорреляция (a) = ∑ -∞ <i <∞ a i v t + i, где 0 <= t <∞
Но у вас было:
автокорреляция (a) = ∑ -∞ <i <∞ a i v t + i, где -∞ <t <∞
Вам нужно взять последнюю половину результата корреляции, и это должна быть автокорреляция, которую вы ищете. Простая функция python для этого:
Вам, конечно, потребуется проверка ошибок, чтобы убедиться, что
x
это действительно одномерный массив. Кроме того, это объяснение, вероятно, не самое математически строгое. Я бросал бесконечности, потому что определение свертки использует их, но это не обязательно применимо к автокорреляции. Таким образом, теоретическая часть этого объяснения может быть немного шаткой, но, надеюсь, практические результаты будут полезными. Эти страницы, посвященные автокорреляции, очень полезны и могут дать вам гораздо лучшую теоретическую базу, если вы не против пробираться через нотации и сложные концепции.источник
return numpy.correlate(x, x, mode='same')
np.correlate(x,x,mode='full')[len(x)//2:] != np.correlate(x,x,mode='same')
. Например,x = [1,2,3,1,2]; np.correlate(x,x,mode='full');
{>>> array([ 2, 5, 11, 13, 19, 13, 11, 5, 2])
}np.correlate(x,x,mode='same');
{>>> array([11, 13, 19, 13, 11])
}. Правильный:np.correlate(x,x,mode='full')[len(x)-1:];
{>>> array([19, 13, 11, 5, 2])
} см. Первый элемент - самый большой .[len(x)-1:]
начинается с 0-лага. Посколькуfull
режим дает размер результата2*len(x)-1
, A.Levy's[result.size/2:]
такой же, как[len(x)-1:]
. Хотя лучше сделать его int, например[result.size//2:]
.Автокорреляция бывает двух версий: статистической и свертки. Они оба делают то же самое, за исключением небольшой детали: статистическая версия нормализована для интервала [-1,1]. Вот пример того, как вы делаете статистический:
источник
numpy.corrcoef[x:-i], x[i:])[0,1]
во второй строке, поскольку возвращаемое значениеcorrcoef
представляет собой матрицу 2x2Используйте
numpy.corrcoef
функцию вместо,numpy.correlate
чтобы вычислить статистическую корреляцию для запаздывания t:источник
Думаю, есть 2 вещи, которые добавляют путаницу в эту тему:
Я создал 5 функций, которые вычисляют автокорреляцию 1d-массива с частичным отличием от неполного. Некоторые используют формулы из статистики, некоторые используют коррелят в смысле обработки сигналов, что также можно сделать с помощью БПФ. Но все результаты являются автокорреляциями в определении статистики , поэтому они иллюстрируют, как они связаны друг с другом. Код ниже:
Вот результат:
Мы не видим все 5 линий, потому что 3 из них перекрываются (фиолетовые). Перекрытия - это все неполные автокорреляции. Это связано с тем, что вычисления на основе методов обработки сигналов (
np.correlate
, FFT) не вычисляют другое среднее / стандартное значение для каждого перекрытия.Также обратите внимание, что результат
fft, no padding, non-partial
(красная линия) отличается, потому что он не заполняет временные ряды нулями перед выполнением БПФ, поэтому это круговое БПФ. Я не могу подробно объяснить почему, это то, что я узнал из других источников.источник
Поскольку я только что столкнулся с той же проблемой, я хотел бы поделиться с вами несколькими строками кода. Фактически, к настоящему времени существует несколько довольно похожих сообщений об автокорреляции в stackoverflow. Если вы определяете автокорреляцию как
a(x, L) = sum(k=0,N-L-1)((xk-xbar)*(x(k+L)-xbar))/sum(k=0,N-1)((xk-xbar)**2)
[это определение, данное в функции IDL a_correlate, и оно согласуется с тем, что я вижу в ответе 2 на вопрос № 12269834 ], то, похоже, следующее дает правильные результаты:Как видите, я тестировал это с кривой греха и равномерным случайным распределением, и оба результата выглядят так, как я ожидал их. Обратите внимание, что я использовал
mode="same"
вместо того,mode="full"
как другие.источник
Ваш вопрос 1 уже подробно обсуждался в нескольких отличных ответах здесь.
Я решил поделиться с вами несколькими строками кода, которые позволят вам вычислить автокорреляцию сигнала, основываясь только на математических свойствах автокорреляции. То есть автокорреляцию можно вычислить следующим образом:
вычесть среднее значение из сигнала и получить несмещенный сигнал
вычислить преобразование Фурье несмещенного сигнала
вычислить спектральную плотность мощности сигнала, взяв квадратную норму каждого значения преобразования Фурье несмещенного сигнала
вычислить обратное преобразование Фурье спектральной плотности мощности
нормализовать обратное преобразование Фурье спектральной плотности мощности на сумму квадратов несмещенного сигнала и взять только половину результирующего вектора
Код для этого следующий:
источник
p = np.abs(f)
?Я компьютерный биолог, и когда мне пришлось вычислить авто / кросс-корреляции между парами временных рядов стохастических процессов, я понял, что
np.correlate
не выполняет нужную мне работу.В самом деле, что , кажется, отсутствует
np.correlate
является усреднение по всем возможным парам точек времени на расстоянии т.Вот как я определил функцию, выполняющую то, что мне нужно:
Мне кажется, что ни один из предыдущих ответов не касается этого случая авто / взаимной корреляции: надеюсь, этот ответ может быть полезен кому-то, кто работает со стохастическими процессами, такими как я.
источник
Я использую talib.CORREL для такой автокорреляции, я подозреваю, что вы можете сделать то же самое с другими пакетами:
источник
Используя преобразование Фурье и теорему о свертке
Сложность времени составляет N * log (N)
Вот нормализованная и беспристрастная версия, это тоже N * log (N)
Метод, предложенный А. Леви, работает, но я тестировал его на своем ПК, его временная сложность составляет N * N
источник
Альтернатива numpy.correlate доступна в statsmodels.tsa.stattools.acf () . Это дает непрерывно убывающую функцию автокорреляции, подобную описанной OP. Реализовать это довольно просто:
Поведение по умолчанию - остановка на 40 nlags, но это можно настроить с помощью
nlag=
параметра для вашего конкретного приложения. Внизу страницы есть ссылка на статистику функции .источник
Я думаю, что настоящий ответ на вопрос OP кратко содержится в этом отрывке из документации Numpy.correlate:
Это означает, что при использовании без определения «режима» функция Numpy.correlate вернет скаляр, если ему задан один и тот же вектор для двух входных аргументов (то есть - когда используется для выполнения автокорреляции).
источник
Простое решение без панд:
источник
Постройте статистическую автокорреляцию с учетом серии результатов pandas datatime:
источник
autocorrelation_plot()
в этом случае? (см. stats.stackexchange.com/questions/357300/… )