scipy.stats.mstats.

pearsonr#

scipy.stats.mstats.pearsonr(x, y)[source]#

皮尔逊相关系数和针对非相关性的 p 值测试。

皮尔逊相关系数 [1] 衡量两个数据集之间的线性关系。p 值的计算依赖于每个数据集都呈正态分布的假设。(请参见科瓦尔斯基 [3] 讨论输入非正态分布对相关系数分布的影响。)与其他相关系数相似,该系数在 -1 和 +1 之间变化,0 意味着没有相关性。-1 或 +1 的相关性意味着精确的线性关系。

参数:
x(N,) array_like

输入数组。

y(N,) array_like

输入数组。

返回值:
rfloat

皮尔逊相关系数。

p-valuefloat

双尾 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。对于 beta 分布的 SciPy 实现,r 的分布是

dist = scipy.stats.beta(n/2 - 1, n/2 - 1, loc=-1, scale=2)

p 值由 pearsonr 返回,是一个双边 p 值。p 值大致表示产生与从这些数据集计算得出的相关性至少与皮尔森相关性一样极端的无相关系统数据集的可能性。更确切地说,对于具有相关系数 r 的给定样本,p 值是不相关总体中抽取的随机样本 x’ 和 y’ 的 abs(r’) 大于或等于 abs(r) 的概率。对于上面显示的对象 dist,给定 r 和长度 n 的 p 值可以计算为

p = 2*dist.cdf(-abs(r))

当 n 等于 2 时,上述连续分布不能很好地定义。当形状参数 a 和 b 接近于 a = b = 0 时,人们可以将 beta 分布的极限解释为一个离散分布,其中 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。

参考文献

[1] (1,2)

“Pearson 相关系数”,维基百科,https://en.wikipedia.org/wiki/Pearson_correlation_coefficient

[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(如果 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 之间没有任何依赖性。