2009-03-13 2 views
69

Мне нужно сделать автокорреляцию набора чисел, что, как я понимаю, это просто корреляция множества с самим собой.Как я могу использовать numpy.correlate для автокорреляции?

Я пробовал это с помощью корреляционной функции numpy, но я не верю в результат, так как он почти всегда дает вектор, где первое число не самое большое, как и должно быть.

Таким образом, этот вопрос действительно два вопроса:

  1. Что именно numpy.correlate делать?
  2. Как я могу использовать его (или что-то еще) для автоматической корреляции?
+0

Смотрите также: http://stackoverflow.com/questions/12269834/is-there-any-numpy-autocorrellation-function-with-standardized-output для получения информации о нормализованной автокорреляции. – amcnabb

ответ

79

Чтобы ответить на ваш первый вопрос, numpy.correlate(a, v, mode) выполняет свертку a с обратной v и дают результаты обрежутся по указанному режиму. definition of convolution, С (т) = Σ -∞ < < я ∞ я v т + я где -∞ < < т ∞, позволяет сделать результаты от -∞ до ∞, но вы, очевидно, не может хранить бесконечно длинный массив. . Таким образом, он должен быть обрезан, и именно там режим приходит Есть 3 различных режима: полный, то же самое, & действует:

  • «полный» режим возвращается результаты для каждого t, где оба a и v имеют некоторые перекрываются.
  • «тот же» режим возвращает результат с той же длиной, что и самый короткий вектор (a или v).
  • «действительный» режим возвращает результаты только тогда, когда a и v полностью перекрывают друг друга. documentation для numpy.convolve дает более подробную информацию о режимах.

Для вашего второго вопроса, я думаю numpy.correlateэто дает вам автокорреляции, это просто дает вам немного больше, а также. Автокорреляция используется для определения того, насколько подобный сигнал или функция является для себя с определенной разницей во времени. При разнице во времени 0 автокорреляция должна быть самой высокой, потому что сигнал идентичен самому себе, поэтому вы ожидали, что первый элемент в массиве результатов автокорреляции будет самым большим. Однако корреляция не начинается с разницы во времени 0. Она начинается с отрицательной разницы во времени, закрывается до 0 и затем становится положительной.То есть, вы ожидали:

автокорреляции (а) = Σ -∞ < < я ∞ я v т + я где 0 = < < т ∞

Но что вы получили был:

автокорреляции (а) = Σ -∞ < < я ∞ я против т + я где -∞ < < т ∞

Что вам нужно сделать, это взять последнюю половину своего корреляционного результата, и это должно быть автокорреляцией вы ищете. Простая функция питона, чтобы сделать это было бы:

def autocorr(x): 
    result = numpy.correlate(x, x, mode='full') 
    return result[result.size/2:] 

Вы, конечно, потребуется ошибка проверки, чтобы убедиться, что x на самом деле 1-d массив. Кроме того, это объяснение, вероятно, не является наиболее математически строгим. Я обманывал бесконечности, потому что определение свертки использует их, но это не обязательно относится к автокорреляции. Таким образом, теоретическая часть этого объяснения может быть слегка отвратительной, но, надеюсь, практические результаты полезны. Thesepages на автокорреляции очень полезны и могут дать вам гораздо лучший теоретический фон, если вы не против пробираться через обозначения и тяжелые понятия.

+4

В текущих строках numpy режим «тот же» может быть указан для достижения именно того, что предложил А. Леви. Затем тело функции может читать «return numpy.correlate (x, x, mode =« same »)' –

+10

@DavidZwicker, но результаты разные! '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]) '} см. ** первый элемент ** является ** самым большим **. – Developer

+7

Обратите внимание, что этот ответ дает ненормализованную автокорреляцию. – amcnabb

12

Автокорреляция осуществляется в двух версиях: статистической и сверточной. Оба они делают то же самое, за исключением небольшой детали: первая нормализуется на интервале [-1,1]. Вот пример того, как вы статистическому:

def acf(x, length=20): 
    return numpy.array([1]+[numpy.corrcoef(x[:-i], x[i:]) \ 
     for i in range(1, length)]) 
+5

Вы хотите «numpy.corrcoef [x: -i], x [i:]) [0,1]' 'во второй строке, так как возвращаемое значение' 'corrcoef'' является матрицей 2x2 – luispedro

+0

В чем разница между статистическими и сверточными автокорреляциями? –

9

Как я только что столкнулся с той же проблемой, я хотел бы разделить несколько строк кода с вами. На самом деле в настоящее время имеется несколько довольно похожих сообщений об автокорреляции в stackoverflow. Если вы определяете автокорреляции как a(x, L) = sum(k=0,N-L-1)((xk-xbar)*(x(k+L)-xbar))/sum(k=0,N-1)((xk-xbar)**2) [это определение дано в функции a_correlate IDL и он согласен с тем, что я вижу в ответ 2 вопроса #12269834], то следующий, кажется, дает правильные результаты:

import numpy as np 
import matplotlib.pyplot as plt 

# generate some data 
x = np.arange(0.,6.12,0.01) 
y = np.sin(x) 
# y = np.random.uniform(size=300) 
yunbiased = y-np.mean(y) 
ynorm = np.sum(yunbiased**2) 
acor = np.correlate(yunbiased, yunbiased, "same")/ynorm 
# use only second half 
acor = acor[len(acor)/2:] 

plt.plot(acor) 
plt.show() 

Как вы видите, что я проверил это с кривой греха и равномерным случайным распределением, и оба результата выглядят так, как я ожидал бы их. Обратите внимание, что я использовал mode="same" вместо mode="full", как и другие.

13

Используя numpy.corrcoef функции вместо numpy.correlate для расчета статистической корреляции для лага т:

def autocorr(x, t=1): 
    numpy.corrcoef(numpy.array([x[0:len(x)-t], x[t:len(x)]])) 
+0

Не «коэффициенты корреляции» относятся к автокорреляции, используемой при обработке сигналов, а не к автокорреляции, используемой для статистики? https://en.wikipedia.org/wiki/Autocorrelation#Signal_processing –

+0

@ DanielPendergast Я не так хорошо знаком с обработкой сигналов. Из numpy docs: «Коэффициенты корреляции момента продукта Return Pearson». Это версия обработки сигнала? –

0

Я думаю, что реальный ответ на вопрос ФПА является сжато, содержащимся в данном отрывке из документации Numpy.correlate :

mode : {'valid', 'same', 'full'}, optional 
    Refer to the `convolve` docstring. Note that the default 
    is `valid`, unlike `convolve`, which uses `full`. 

Это означает, что при использовании без «режима» определения, функция Numpy.correlate возвращает скаляр, когда дается один и тот же вектор для двух входных аргументов (то есть - когда используемый для выполнения автокорреляции).

1

Я использую талиб.CORREL для автокорреляции, как это, я подозреваю, что вы могли бы сделать то же самое с другими пакетами:

def autocorrelate(x, period): 

    # x is a deep indicator array 
    # period of sample and slices of comparison 

    # oldest data (period of input array) may be nan; remove it 
    x = x[-np.count_nonzero(~np.isnan(x)):] 
    # subtract mean to normalize indicator 
    x -= np.mean(x) 
    # isolate the recent sample to be autocorrelated 
    sample = x[-period:] 
    # create slices of indicator data 
    correls = [] 
    for n in range((len(x)-1), period, -1): 
     alpha = period + n 
     slices = (x[-alpha:])[:period] 
     # compare each slice to the recent sample 
     correls.append(ta.CORREL(slices, sample, period)[-1]) 
    # fill in zeros for sample overlap period of recent correlations  
    for n in range(period,0,-1): 
     correls.append(0) 
    # oldest data (autocorrelation period) will be nan; remove it 
    correls = np.array(correls[-np.count_nonzero(~np.isnan(correls)):])  

    return correls 

# CORRELATION OF BEST FIT 
# the highest value correlation  
max_value = np.max(correls) 
# index of the best correlation 
max_index = np.argmax(correls) 
5

Ваш вопрос 1 уже широко обсуждается в несколько отличных ответов здесь.

Я думал поделиться с вами несколькими строками кода, которые позволят вам вычислить автокорреляцию сигнала, основанного только на математических свойствах автокорреляции. То есть, автокорреляция может быть вычислена следующим образом:

  1. вычесть среднее из сигнала и получить несмещенный сигнал

  2. вычислить преобразование Фурье несмещенного сигнала

  3. вычислительном спектральная плотность мощности сигнала, взяв квадратную норму каждого значения преобразования Фурье несмещенного сигнала

  4. вычислить обратное преобразование Фурье от спектральная плотность мощности

  5. нормализуют обратное преобразование Фурье спектральной плотности мощности по сумме квадратов несмещенного сигнала, и принимать только половину результирующего вектора

Код, чтобы сделать это заключается в следующем:

def autocorrelation (x) : 
    """ 
    Compute the autocorrelation of the signal, based on the properties of the 
    power spectral density of the signal. 
    """ 
    xp = x-np.mean(x) 
    f = np.fft.fft(xp) 
    p = np.array([np.real(v)**2+np.imag(v)**2 for v in f]) 
    pi = np.fft.ifft(p) 
    return np.real(pi)[:x.size/2]/np.sum(xp**2) 
+0

Возможно ли, что с этим что-то не так? Я не могу сопоставить результаты с другими функциями автокорреляции. Функция выглядит схожей, но кажется несколько хлипкой. – pindakaas

+0

@pindakaas вы могли бы быть более конкретным? пожалуйста, предоставьте информацию о том, какие расхождения вы найдете, с какими функциями. – Ruggero

+0

Почему бы не использовать 'p = np.abs (f)'? – dylnan

Смежные вопросы