pearsonr#
- scipy.stats.mstats.pearsonr(x, y)[源代码]#
用于测试非相关的皮尔逊相关系数和 p 值。
皮尔逊相关系数 [1] 衡量两个数据集之间的线性关系。p 值的计算依赖于每个数据集都呈正态分布的假设。(有关输入非正态性对相关系数分布的影响的讨论,请参见 Kowalski [3]。)与其他相关系数一样,该系数的取值范围在 -1 和 +1 之间,0 表示不相关。-1 或 +1 的相关性表示存在精确的线性关系。
- 参数:
- x(N,) 类似数组
输入数组。
- y(N,) 类似数组
输入数组。
- 返回:
- r浮点数
皮尔逊相关系数。
- p-值浮点数
双尾 p 值。
- 警告:
ConstantInputWarning
如果输入是常数数组,则会引发此警告。在这种情况下,相关系数未定义,因此返回
np.nan
。NearConstantInputWarning
如果输入“几乎”是常数,则会引发此警告。如果
norm(x - mean(x)) < 1e-13 * abs(mean(x))
,则认为数组x
几乎是常数。在这种情况下,计算x - mean(x)
中的数值误差可能会导致 r 的计算不准确。
另请参阅
spearmanr
斯皮尔曼等级顺序相关系数。
kendalltau
肯德尔 tau,一种用于有序数据的相关性度量。
注释
相关系数的计算方式如下
\[r = \frac{\sum (x - m_x) (y - m_y)} {\sqrt{\sum (x - m_x)^2 \sum (y - m_y)^2}}\]其中 \(m_x\) 是向量 x 的均值,而 \(m_y\) 是向量 y 的均值。
在假设 x 和 y 来自独立的正态分布(因此总体相关系数为 0)的情况下,样本相关系数 r 的概率密度函数为 ([1], [2])
\[f(r) = \frac{{(1-r^2)}^{n/2-2}}{\mathrm{B}(\frac{1}{2},\frac{n}{2}-1)}\]其中 n 是样本数,B 是 beta 函数。这有时被称为 r 的精确分布。这是在
pearsonr
中用于计算 p 值的分布。该分布是区间 [-1, 1] 上的 beta 分布,具有相等的形状参数 a = b = n/2 - 1。根据 SciPy 的 beta 分布实现,r 的分布为dist = scipy.stats.beta(n/2 - 1, n/2 - 1, loc=-1, scale=2)
pearsonr
返回的 p 值是双侧 p 值。p 值大致表示不相关系统产生的数据集的皮尔逊相关性至少与从这些数据集计算出的相关性一样极端的概率。更准确地说,对于给定的相关系数为 r 的样本,p 值是从总体中抽取的相关性为零的随机样本 x' 和 y' 的 abs(r') 大于或等于 abs(r) 的概率。对于上面显示的对象dist
,给定 r 和长度 n 的 p 值可以计算为p = 2*dist.cdf(-abs(r))
当 n 为 2 时,上述连续分布未明确定义。可以将 beta 分布的极限解释为形状参数 a 和 b 接近 a = b = 0 时,r = 1 和 r = -1 处具有相等概率质量的离散分布。更直接地说,可以观察到,给定数据 x = [x1, x2] 和 y = [y1, y2],并假设 x1 != x2 和 y1 != y2,r 的唯一可能值是 1 和 -1。因为长度为 2 的任何样本 x' 和 y' 的 abs(r') 将为 1,所以长度为 2 的样本的双尾 p 值始终为 1。
参考文献
[2]Student,“相关系数的可能误差”,Biometrika,第 6 卷,第 2-3 期,1908 年 9 月 1 日,第 302-310 页。
[3]C. J. Kowalski,“关于非正态性对样本积矩相关系数分布的影响” 皇家统计学会杂志。C 系列(应用统计),第 21 卷,第 1 期(1972 年),第 1-12 页。
示例
>>> import numpy as np >>> from scipy import stats >>> from scipy.stats import mstats >>> mstats.pearsonr([1, 2, 3, 4, 5], [10, 9, 2.5, 6, 4]) (-0.7426106572325057, 0.1505558088534455)
如果 y = a + b*x + e,其中 a,b 是常数,e 是一个随机误差项,假设独立于 x,则 x 和 y 之间存在线性关系。为简单起见,假设 x 是标准正态分布,a=0,b=1,并让 e 服从均值为零且标准差为 s>0 的正态分布。
>>> s = 0.5 >>> x = stats.norm.rvs(size=500) >>> e = stats.norm.rvs(scale=s, size=500) >>> y = x + e >>> mstats.pearsonr(x, y) (0.9029601878969703, 8.428978827629898e-185) # may vary
这应该接近给定的精确值
>>> 1/np.sqrt(1 + s**2) 0.8944271909999159
对于 s=0.5,我们观察到高度相关。通常,噪声的较大方差会降低相关性,而随着误差的方差趋于零,相关性会接近于 1。
重要的是要记住,除非 (x, y) 是联合正态分布,否则不相关并不意味着独立。即使存在非常简单的依赖结构,相关性也可能为零:如果 X 服从标准正态分布,则让 y = abs(x)。请注意,x 和 y 之间的相关性为零。实际上,由于 x 的期望为零,因此 cov(x, y) = E[x*y]。根据定义,这等于 E[x*abs(x)],由于对称性,它为零。以下代码行说明了此观察结果
>>> y = np.abs(x) >>> mstats.pearsonr(x, y) (-0.016172891856853524, 0.7182823678751942) # may vary
非零相关系数可能会产生误导。例如,如果 X 服从标准正态分布,则定义 y = x if x < 0,否则 y = 0。简单的计算表明,corr(x, y) = sqrt(2/Pi) = 0.797…,这意味着高度相关
>>> y = np.where(x < 0, x, 0) >>> mstats.pearsonr(x, y) (0.8537091583771509, 3.183461621422181e-143) # may vary
这是不直观的,因为如果 x 大于零,x 和 y 之间就没有依赖关系,如果我们对 x 和 y 进行采样,则大约一半的情况下会发生这种情况。