web-dev-qa-db-ja.com

numpy.correlateとnumpy.corrcoefの値をどのように解釈するのですか?

2つの1Dアレイがあり、それらの相互関係を確認したいです。 numpyでどの手順を使用する必要がありますか?私はnumpy.corrcoef(arrayA, arrayB)numpy.correlate(arrayA, arrayB)を使用していますが、両方とも理解も理解もできない結果を出しています。誰かがそれらの数値結果を理解して解釈する方法に光を当てることができますか?ありがとう。

25
khan

numpy.correlateは、単に2つのベクトルの相互相関を返します。

相互相関を理解する必要がある場合は、 http://en.wikipedia.org/wiki/Cross-correlation から始めてください。

良い例は、自己相関関数(それ自体と相互相関するベクトル)を見るとわかります。

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

これは、両方のデータセットがオーバーラップしている場合、最大値のcomb/shah関数を返します。これは自己相関であるため、2つの入力信号間に「遅れ」はありません。したがって、相関の最大値はvector.size-1です。

重複するデータの相関値のみが必要な場合は、mode='valid'

12
ebarr

コメントできるのはnumpy.correlate 現時点では。これは強力なツールです。私は2つの目的に使用しました。最初の方法は、別のパターン内のパターンを見つけることです。

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 !

私が使用した2番目の使用法(および結果の解釈方法)は、周波数検出用です。

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

2番目のピークのインデックスを見つけます。これから、周波数を見つけるために戻ることができます。

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

intベクトルのnp.correlateの結果について困惑している場合は、overflowが原因である可能性があります。

>>> 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)

この例では、相関の仕組みについても説明します。

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
は40000-2 ** 16 = -25536と表示されます

1
Rainald62