2つの1Dアレイがあり、それらの相互関係を確認したいです。 numpyでどの手順を使用する必要がありますか?私はnumpy.corrcoef(arrayA, arrayB)
とnumpy.correlate(arrayA, arrayB)
を使用していますが、両方とも理解も理解もできない結果を出しています。誰かがそれらの数値結果を理解して解釈する方法に光を当てることができますか?ありがとう。
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')
これは、両方のデータセットがオーバーラップしている場合、最大値のcomb/shah関数を返します。これは自己相関であるため、2つの入力信号間に「遅れ」はありません。したがって、相関の最大値はvector.size-1です。
重複するデータの相関値のみが必要な場合は、mode='valid'
。
コメントできるのは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()
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
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と表示されます