numpy.correlate 和 numpy.corrcoef 之间的值差异?

问题描述 投票:0回答:1

据我了解,

numpy.correlate
numpy.corrcoef
对于对齐的归一化向量应该产生相同的结果。两个直接相反的情况:

from math import isclose as near
import numpy as np


def normalizedCrossCorrelation(a, b):
    assert len(a) == len(b)
    normalized_a = [aa / np.linalg.norm(a) for aa in a]
    normalized_b = [bb / np.linalg.norm(b) for bb in b]
    return np.correlate(normalized_a, normalized_b)[0]


def test_normalizedCrossCorrelationOfSimilarVectorsRegression0():
    v0 = [1, 2, 3, 2, 1, 0, -2, -1, 0]
    v1 = [1, 1.9, 2.8, 2, 1.1, 0, -2.2, -0.9, 0.2]
    assert near(normalizedCrossCorrelation(v0, v1), 0.9969260391224474)
    print(f"{np.corrcoef(v0, v1)=}")
    assert near(normalizedCrossCorrelation(v0, v1), np.corrcoef(v0, v1)[0, 1])


def test_normalizedCrossCorrelationOfSimilarVectorsRegression1():
    v0 = [1, 2, 3, 2, 1, 0, -2, -1, 0]
    v1 = [0.8, 1.9, 2.5, 2.1, 1.2, -0.3, -2.4, -1.4, 0.4]
    assert near(normalizedCrossCorrelation(v0, v1), 0.9809817769512982)
    print(f"{np.corrcoef(v0, v1)=}")
    assert near(normalizedCrossCorrelation(v0, v1), np.corrcoef(v0, v1)[0, 1])

Pytest 输出:

E       assert False
E        +  where False = near(0.9969260391224474, 0.9963146417122921)
E        +    where 0.9969260391224474 = normalizedCrossCorrelation([1, 2, 3, 2, 1, 0, ...], [1, 1.9, 2.8, 2, 1.1, 0, ...])


E       assert False
E        +  where False = near(0.9809817769512982, 0.9826738919606931)
E        +    where 0.9809817769512982 = normalizedCrossCorrelation([1, 2, 3, 2, 1, 0, ...], [0.8, 1.9, 2.5, 2.1, 1.2, -0.3, ...])
python numpy signal-processing correlation cross-correlation
1个回答
0
投票

我认为你的

np.correlate
公式是错误的,它不会产生相关系数。

考虑第一个例子

v0 = [1, 2, 3, 2, 1, 0, -2, -1, 0]
v1 = [1, 1.9, 2.8, 2, 1.1, 0, -2.2, -0.9, 0.2]


np.correlate(v0 / np.linalg.norm(v0), v1 / np.linalg.norm(v1))[0] # 0.9969260391224474
# you can also use
#    np.correlate(v0 , v1 , mode='valid') / np.linalg.norm(v0) / np.linalg.norm(v1)
# but you get same number
np.corrcoef(v0, v1)[0][1]                                         # 0.9963146417122921

不使用浮点计算的正确答案应该是 59 Sqrt[5/17534],近似于

0.99631464171229218403
,与
np.corrcoef
惊人地相同。

考虑到

np.correlate(a, b)

a
b
是相同大小的一维数组时,返回标量积(例如
np.dot(a, b)
)。协方差可以计算(即使不推荐)为
E[v0 v1] - E[v0]E[v1]
。这可以这样做

(np.correlate(v0 , v1 , mode='valid') / len(v0) - np.mean(v0) * np.mean(v1))[0]

这等于

np.cov(v0, v1, ddof=0)[0][1]
。所以你可以将相关性计算为

((np.correlate(v0 , v1 , mode='valid') / len(v0) - np.mean(v0) * np.mean(v1)) / np.std(v0) / np.std(v1))[0]

顺便说一句,只需使用

np.corrcoef
np.cov

© www.soinside.com 2019 - 2024. All rights reserved.