为何numpy.correlate与numpy.corrcoef对归一化向量计算结果存在差异?
归一化互相关与皮尔逊相关系数的差异问题
我原本认为,对齐的归一化向量下,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, ...])
差异原因
两者的核心区别在于归一化的前提:
- 自定义的
normalizedCrossCorrelation函数是对原始向量做L2归一化(直接除以向量的L2范数),再计算点积,对应归一化互相关的结果。 numpy.corrcoef计算的是皮尔逊相关系数,它会先对向量减去各自的均值(去中心化),再对去均值后的向量做L2归一化,最后计算点积。
当测试向量的均值不为0时,两种归一化方式的结果自然会产生差异。比如测试用的v0均值约为0.6667,v1的均值也不为0,这就导致最终的相关值出现明显偏差。
内容的提问来源于stack exchange,提问作者user2183336
相关产品推荐
相关产品推荐

