web-dev-qa-db-de.com

wie interpretiere ich die Werte von numpy.correlate und numpy.corrcoef?

Ich habe zwei 1D-Arrays und möchte deren Zusammenhänge sehen. Welches Verfahren sollte ich in numpy verwenden? Ich benutze numpy.corrcoef(arrayA, arrayB) und numpy.correlate(arrayA, arrayB) und beide geben Ergebnisse, die ich nicht verstehen oder verstehen kann. Kann jemand bitte wissen, wie man diese numerischen Ergebnisse verstehen und interpretieren kann (vorzugsweise anhand eines Beispiels)? Vielen Dank.

23
khan

numpy.correlate gibt einfach die Kreuzkorrelation zweier Vektoren zurück. 

wenn Sie die Kreuzkorrelation verstehen müssen, beginnen Sie mit http://en.wikipedia.org/wiki/Cross-correlation .

Ein gutes Beispiel ist die Autokorrelationsfunktion (ein Vektor, der mit sich selbst kreuzkorreliert ist):

import numpy as np

# create a vector
vector = np.random.normal(0,1,size=1000) 

# insert a signal into vector
vector[::50]+=10

# perform cross-correlation for all data points
output = np.correlate(vector,vector,mode='full')

Code graph

Dies gibt eine Kamm/Schah-Funktion mit einem Maximum zurück, wenn sich beide Datensätze überlappen. Da dies eine Autokorrelation ist, gibt es keine "Verzögerung" zwischen den beiden Eingangssignalen. Das Maximum der Korrelation ist daher vector.size-1. 

wenn Sie nur den Wert der Korrelation für überlappende Daten verwenden möchten, können Sie mode='valid' verwenden.

11
ebarr

Ich kann im Moment nur numpy.correlate kommentieren. Es ist ein mächtiges Werkzeug. Ich habe es zu zwei Zwecken benutzt. Die erste besteht darin, ein Muster in einem anderen Muster zu finden:

import numpy as np
import matplotlib.pyplot as plt

some_data = np.random.uniform(0,1,size=100)
subset = some_data[42:50]

mean = np.mean(some_data)
some_data_normalised = some_data - mean
subset_normalised = subset - mean

correlated = np.correlate(some_data_normalised, subset_normalised)
max_index = np.argmax(correlated)  # 42 !

Die zweite Verwendung, für die ich es verwendet habe (und wie das Ergebnis interpretiert werden soll), ist die Frequenzerkennung:

hz_a = np.cos(np.linspace(0,np.pi*6,100))
hz_b = np.cos(np.linspace(0,np.pi*4,100))

f, axarr = plt.subplots(2, sharex=True)

axarr[0].plot(hz_a)
axarr[0].plot(hz_b)
axarr[0].grid(True)

hz_a_autocorrelation = np.correlate(hz_a,hz_a,'same')[round(len(hz_a)/2):]
hz_b_autocorrelation = np.correlate(hz_b,hz_b,'same')[round(len(hz_b)/2):]

axarr[1].plot(hz_a_autocorrelation)
axarr[1].plot(hz_b_autocorrelation)
axarr[1].grid(True)

plt.show()

 three hz and two hz with autocorrelation show beneath

Finden Sie den Index der zweiten Peaks. Von diesem können Sie zurückgehen, um die Frequenz zu finden.

first_min_index = np.argmin(hz_a_autocorrelation)
second_max_index = np.argmax(hz_a_autocorrelation[first_min_index:])
frequency = 1/second_max_index
3
AJP

Wenn Sie hinsichtlich des Ergebnisses von np.correlate von int Vectors verblüfft sind, kann dies an overflow liegen:

>>> a = np.array([4,3,2,1,0,0,0,0,10000,0,0,0], dtype='int16')
>>> np.correlate(a,a[:4])
array([    30,     20,     11,      4,      0,  10000,  20000,  30000,
   -25536], dtype=int16)

Dieses Beispiel erläutert auch, wie Korrelate funktionieren:

30 = 4 * 4 + 3 * 3 + 2 * 2 + 1 * 1
20 = 4 * 3 + 3 * 2 + 2 * 1 + 1 * 0
11 = 4 * 2 + 3 * 1 + 2 * 0 + 1 * 0
...
40000 = 4 * 10000 + 3 * 0 + 2 * 0 + 1 * 0
erscheint als 40000 - 2 ** 16 = -25536

0
Rainald62