两个向量的相关性计算:numpy.corrcoef与卷积方法对比问题
为什么用卷积计算的相关性和numpy.corrcoef结果不同?
你用卷积计算相关性和np.corrcoef结果不一致的核心原因是忽略了皮尔逊相关系数要求数据先去均值,同时两者计算的统计量本质不同:
np.corrcoef计算的是皮尔逊相关系数,它的定义基于去均值后的协方差与标准差的比值,公式为:ρ = Cov(X,Y) / (σₓσᵧ)
其中Cov(X,Y)是X和Y的协方差(即E[(X-μₓ)(Y-μᵧ)]),σₓ、σᵧ分别是X和Y的标准差。而且np.corrcoef默认使用样本相关系数,计算时会用n-1作为分母(n是样本量)来做无偏估计。你的卷积代码计算的是未去均值的原始交叉相关,具体来说:
rxx是array1所有元素的平方和(Σxᵢ²),而不是去均值后的平方和(Σ(xᵢ-μₓ)²)rxy是array1和array2对应元素的乘积和(Σxᵢyᵢ),而不是去均值后的交叉乘积和(Σ(xᵢ-μₓ)(yᵢ-μᵧ))
这和皮尔逊系数的定义完全不符,所以结果自然不同。
修正后的卷积实现方法
要让卷积方法得到和np.corrcoef一致的结果,需要先对数据去均值,再计算,同时匹配样本相关系数的分母(用n-1):
import numpy as np array1 = np.array([1,3,10,4,2]) array2 = np.array([3,7,1,5,6]) # 先对数组去均值 array1_centered = array1 - np.mean(array1) array2_centered = array2 - np.mean(array2) # 计算去均值后的自相关和交叉相关(取中心值,即对应无偏移的乘积和) rxx_centered = np.convolve(array1_centered, np.flip(array1_centered))[array1_centered.size - 1] ryy_centered = np.convolve(array2_centered, np.flip(array2_centered))[array2_centered.size - 1] rxy_centered = np.convolve(array1_centered, np.flip(array2_centered))[array1_centered.size - 1] # 计算样本皮尔逊相关系数(分母用n-1) n = len(array1) rho = (rxy_centered / (n-1)) / np.sqrt( (rxx_centered/(n-1)) * (ryy_centered/(n-1)) ) # 简化后等价于 rxy_centered / np.sqrt(rxx_centered * ryy_centered) print("修正后的卷积计算结果:", rho) # 对比np.corrcoef结果 correlation = np.corrcoef(array1, array2)[0, 1] print("np.corrcoef结果:", correlation)
运行后两者结果会一致(约为-0.485)。
补充说明
- 如果你计算的是总体相关系数(分母用n),只需要把上述代码中的
n-1换成n即可,但np.corrcoef默认是样本相关系数,所以用n-1才能匹配。 - 卷积计算的中心值本质上就是两个数组的点积,所以其实可以直接用
np.dot(array1_centered, array2_centered)替代卷积计算,效率更高,结果完全一致。
内容的提问来源于stack exchange,提问作者Niutoniano
相关产品推荐
相关产品推荐

