scipy.stats.

pearsonr#

scipy.stats.pearsonr(x, y, *, alternative='two-sided', method=None, axis=0)[source]#

用于检验非相关性的皮尔逊相关系数和 p 值。

皮尔逊相关系数[1]用于衡量两个数据集之间的线性关系。和其他相关系数一样,该系数介于 -1 和 +1 之间,0 表示没有相关性。相关系数 -1 或 +1 表示精确的线性关系。正相关性表示 x 增大时,y 也增大。负相关性表示 x 增大时,y 减小。

此函数还执行零假设的检验,即样本基础上的分布没有相关性且呈正态分布。(请参阅 Kowalski [3],了解输入的非正态性对相关系数分布的影响)。p 值大致表示无相关系统生成数据集的概率,这些数据集的皮尔逊相关性至少与从这些数据集中计算所得的值一样极端。

参数:
x类似数组

输入数组。

y类似数组

输入数组。

axis整数或无(默认值)

执行计算的轴。默认值为 0。如果没有则在执行计算前转换两个数组。

添加于 1.13.0 版本。

alternative{‘two-sided’, ‘greater’, ‘less’}, 可选

定义备选假设。默认值为“双边”。下列选项可用

  • “双边”:相关性为非零

  • “小于”:相关性为负(小于零)

  • “大于”:相关性为正(大于零)

添加于 1.9.0 版本。

method重新抽样方法,可选

定义用于计算 p 值的方法。如果 methodPermutationMethod/MonteCarloMethod 的实例,则使用 scipy.stats.permutation_test/scipy.stats.monte_carlo_test 根据设定的配置选项及其他适当设置计算 p 值。否则,将按注释中记录的方式计算 p 值。

添加于 1.11.0 版本。

返回:
resultPearsonRResult

具有下列属性的对象

statisticfloat

皮尔逊积差相关系数。

pvaluefloat

所选择的备选假设的 p 值。

该对象具有下列方法

confidence_interval(confidence_level, method)

本例计算了置信水平为给定值时的相关系数statistic的置信区间。将置信区间返回给命名元组, 字段为lowhigh。如果未提供method, 将使用 Fisher 变换计算置信区间 [1]。如果methodBootstrapMethod的一个实例, 则使用配置选项和其他适当设置来计算置信区间scipy.stats.bootstrap。在某些情况下, 置信限度可能是 NaN, 这对于非常小的样本 (~6 个观测值)来说是典型的。

警告:
ConstantInputWarning

如果输入是一个常量数组则引发异常。在这种情况下相关系数无定义, 因此返回np.nan

NearConstantInputWarning

如果输入“几乎”是常量, 则引发异常。如果norm(x - mean(x)) < 1e-13 * abs(mean(x)), 则阵列x被认为几乎是常量。在这种情况下, 计算 x - mean(x) 时出现的数字错误可能会导致 r 计算不准确。

另请参见

spearmanr

Spearman 等级相关系数。

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 值的分布,当 method 参数保留其默认值(None)时。该分布是位于 [-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 值。对于具有相关系数 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。

为了向后兼容,返回的对象还像包含统计量和 p 值的长度为 2 的元组。

参考文献

[1] (1,2,3)

“皮尔逊相关系数”,维基百科,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
>>> x, y = [1, 2, 3, 4, 5, 6, 7], [10, 9, 2.5, 6, 4, 3, 2]
>>> res = stats.pearsonr(x, y)
>>> res
PearsonRResult(statistic=-0.828503883588428, pvalue=0.021280260007523286)

执行该测试的确切置乱版本

>>> rng = np.random.default_rng()
>>> method = stats.PermutationMethod(n_resamples=np.inf, random_state=rng)
>>> stats.pearsonr(x, y, method=method)
PearsonRResult(statistic=-0.828503883588428, pvalue=0.028174603174603175)

在数据从uniform 分布中抽取的零假设下执行该测试

>>> method = stats.MonteCarloMethod(rvs=(rng.uniform, rng.uniform))
>>> stats.pearsonr(x, y, method=method)
PearsonRResult(statistic=-0.828503883588428, pvalue=0.0188)

生成一个渐近 90% 置信区间

>>> res.confidence_interval(confidence_level=0.9)
ConfidenceInterval(low=-0.9644331982722841, high=-0.3460237473272273)

对于引导置信区间

>>> method = stats.BootstrapMethod(method='BCa', random_state=rng)
>>> res.confidence_interval(confidence_level=0.9, method=method)
ConfidenceInterval(low=-0.9983163756488651, high=-0.22771001702132443)  # may vary

如果提供了 N 维数组,则会根据大多数 scipy.stats 函数所采用的惯例,在单个调用中执行多个检验

>>> rng = np.random.default_rng()
>>> x = rng.standard_normal((8, 15))
>>> y = rng.standard_normal((8, 15))
>>> stats.pearsonr(x, y, axis=0).statistic.shape  # between corresponding columns
(15,)
>>> stats.pearsonr(x, y, axis=1).statistic.shape  # between corresponding rows
(8,)

要执行数组切片之间所有成对的比较,请使用标准的 NumPy 广播技术。例如,要计算所有行对之间的相关性,执行以下操作

>>> stats.pearsonr(x[:, np.newaxis, :], y, axis=-1).statistic.shape
(8, 8)

如果 y = a + b*x + e,其中的 a、b 是常量,并且 e 是假设与 x 无关的随机误差项,则 x 和 y 之间存在线性关系。为了简单,假设 x 是标准正态分布,a=0、b=1,并且让 e 服从均值为零、标准差为 s>0 的正态分布。

>>> rng = np.random.default_rng()
>>> s = 0.5
>>> x = stats.norm.rvs(size=500, random_state=rng)
>>> e = stats.norm.rvs(scale=s, size=500, random_state=rng)
>>> y = x + e
>>> stats.pearsonr(x, y).statistic
0.9001942438244763

这应该接近给定的确切值

>>> 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)
>>> stats.pearsonr(x, y)
PearsonRResult(statistic=-0.05444919272687482, pvalue=0.22422294836207743)

非零相关系数可能会具有误导性。例如,如果 X 具有标准正态分布,则定义 y = x(如果 x < 0 ),否则定义 y = 0。一个简单的计算显示 corr(x, y) = sqrt(2/Pi) = 0.797…,表示高度相关

>>> y = np.where(x < 0, x, 0)
>>> stats.pearsonr(x, y)
PearsonRResult(statistic=0.861985781588, pvalue=4.813432002751103e-149)

这不直观,因为如果 x 大于零,则 x 和 y 无相关性,而如果我们对 x 和 y 进行抽样,则这种情况大约发生在一半情况下。