spearmanr#
- scipy.stats.spearmanr(a, b=None, axis=0, nan_policy='propagate', alternative='two-sided')[source]#
计算相关 p 值的 Spearman 秩相关系数。
Spearman 等级相关系数是非参数度量,用于度量两个数据集之间关系的单调性。与其他相关系数一样,该系数在 -1 和 +1 之间变化,其中 0 表示没有相关性。-1 或 +1 的相关性表示精确的单调关系。正相关意味着当 x 增加时,y 也增加。负相关意味着当 x 增加时,y 减少。
p 值大致表示无相关系统产生数据集的概率,这些数据集的 Spearman 相关性至少与其从这些数据集计算得出的相关性一样极端。虽然 p 值的计算没有对样本的底层分布做出严格的假设,但仅对非常大的样本 (>500 个观测值) 才准确。对于较小的样本量,请考虑置换检验(参见下面的示例部分)。
- 参数:
- a、b1D 或 2D array_like,b 是可选的
一或两个一维或二维数组,其中包含多个变量和观察值。当它们是一维时,每个数组代表单一变量的观测值向量。有关二维情况下行为的信息,请参见以下内容中的
axis
。这两个数组需要在axis
维度中具有相同的长度。- axisint 或无选项,非必需
如果 axis=0(默认),那么每个列表示一个变量,其中观察值分布在各行中。如果 axis=1,则关系发生转换:每行代表一个变量,而列包含观测值。如果 axis=None,那么这两个数组将被展开。
- nan_policy{'propagate', 'raise', 'omit'},非必需
定义处理输入包含 NaN 值时的方式。提供以下选项(默认选项为“propagate”)
“propagate”:返回 NaN
“raise”:抛出错误
“omit”:忽略 NaN 值执行计算
- alternative{'two-sided', 'less', 'greater'},非必需
定义对立假设。默认值为 'two-sided'。提供以下选项
“two-sided”:相关性不等于零
“less”:相关性为负 (小于零)
“greater”:相关性为正 (大于零)
1.7.0 版中添加了这一选项。
- Returns:
- resSignificanceResult
包含属性的对象
- statisticfloat 或 ndarray (二维正方形)
Spearman 相关性矩阵或相关性系数(如果仅将两个变量指定为参数)。相关性矩阵为正方形,其长度等于
a
和b
中变量 (列或行) 的总数。- pvaluefloat
假设检验 p 值,其零假设是两个样本没有序数相关性。有关对立假设的信息,请参见上面的 alternative。pvalue 的形状与 statistic 相同。
- Warns:
ConstantInputWarning
如果输入是常量数组,则会引发此警告。在这种情况下,没有定义相关性系数,因此将返回
np.nan
。
References
[1]兹威林格,D. 和科科斯卡,S.(2000 年)。CRC 标准概率与统计表格和公式。查普曼和霍尔:纽约。2000。第 14.7 节
[2]肯德尔,M. G. 和斯图尔特,A. (1973)。统计学高级理论,第 2 卷:推断和关系。格里芬。1973。第 31.18 节
[3]Kershenobich,D.,菲耶罗,F. J. 和罗金德,M.(1970 年)。人肝硬化症中游离脯氨酸水平和胶原蛋白含量之间的关系。《临床研究杂志》,49(12),2246-2249。
[4]霍兰德,M.,沃尔夫,D. A. 和奇肯,E.(2013 年)。非参数统计方法。约翰·威利父子公司。
[5]B.菲普森和G.K.斯密斯。“置换p值应永不为零:在置换随机抽取时计算精确的p值。”遗传学和分子生物学统计应用 9.1(2010 年)。
[6]拉德布鲁克,J,& Dudley,H。(1998 年)。为何置换检验优于生物医学研究中的 t 检验和 F 检验。美国统计学家,52(2),127-132。
示例
考虑来自[3]的以下数据,该研究调查了不健康的肝脏中游离脯氨酸(一种氨基酸)与总胶原蛋白(一种经常出现在结缔组织中的蛋白质)之间的关系。
下面的
x
和y
数组记录了两种化合物的测量值。观察值是配对的:每个游离脯氨酸测量值都取自与同一指标处的总胶原蛋白测量值的同个肝脏。>>> import numpy as np >>> # total collagen (mg/g dry weight of liver) >>> x = np.array([7.1, 7.1, 7.2, 8.3, 9.4, 10.5, 11.4]) >>> # free proline (μ mole/g dry weight of liver) >>> y = np.array([2.8, 2.9, 2.8, 2.6, 3.5, 4.6, 5.0])
这些数据在[4]中使用斯皮尔曼秩相关系数进行分析,这种统计数据对样本之间的单调相关性很敏感。
>>> from scipy import stats >>> res = stats.spearmanr(x, y) >>> res.statistic 0.7000000000000001
对于具有强烈正序数相关性的样本,该统计量值往往较高(接近 1),对于具有强烈负序数相关性的样本,该值往往较低(接近 -1),对于序数相关性较弱的样本,该值幅度较小(接近 0)。
通过将统计量的观测值与零分布进行比较来执行检验:在总胶原蛋白和游离脯氨酸测量值相互独立的零假设下导出的统计量值分布。
对于此检验,可以转换统计量,使得大样本的零分布成为自由度为
len(x) - 2
的学生的 t 分布。>>> import matplotlib.pyplot as plt >>> dof = len(x)-2 # len(x) == len(y) >>> dist = stats.t(df=dof) >>> t_vals = np.linspace(-5, 5, 100) >>> pdf = dist.pdf(t_vals) >>> fig, ax = plt.subplots(figsize=(8, 5)) >>> def plot(ax): # we'll reuse this ... ax.plot(t_vals, pdf) ... ax.set_title("Spearman's Rho Test Null Distribution") ... ax.set_xlabel("statistic") ... ax.set_ylabel("probability density") >>> plot(ax) >>> plt.show()
比较通过p值量化:在零分布中极端或更极端的值的比例,比统计量的观测值极端。在统计量为正的双边检验中,大于转换统计量并且小于观测统计量负值的零分布元素均被视为“更极端”。
>>> fig, ax = plt.subplots(figsize=(8, 5)) >>> plot(ax) >>> rs = res.statistic # original statistic >>> transformed = rs * np.sqrt(dof / ((rs+1.0)*(1.0-rs))) >>> pvalue = dist.cdf(-transformed) + dist.sf(transformed) >>> annotation = (f'p-value={pvalue:.4f}\n(shaded area)') >>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8) >>> _ = ax.annotate(annotation, (2.7, 0.025), (3, 0.03), arrowprops=props) >>> i = t_vals >= transformed >>> ax.fill_between(t_vals[i], y1=0, y2=pdf[i], color='C0') >>> i = t_vals <= -transformed >>> ax.fill_between(t_vals[i], y1=0, y2=pdf[i], color='C0') >>> ax.set_xlim(-5, 5) >>> ax.set_ylim(0, 0.1) >>> plt.show()
>>> res.pvalue 0.07991669030889909 # two-sided p-value
如果p值“小”,即从独立分布中抽样数据产生如此极端的统计量值具有很低的概率,则可以将此视为反对零假设、支持备择假设的证据:总胶原蛋白和游离脯氨酸的分布不独立。请注意
反之则不成立;也就是说,检验不用于提供支持零假设的证据。
在分析数据之前,选择一个用于区分“过小”值的阈值[5]考虑假阳性(错误地拒绝空假设)和假阴性(未能拒绝一个错误的空假设)的风险。
较小的 p 值并不代表一个较大的效果,相反,它们只能为一个“显著”的效果提供证据,意为它们不太可能在空假设下发生。
假设在进行实验之前,作者有理由预测总体胶原和游离脯氨酸测量值之间存在正相关,并且他们决定评估针对单侧备择方案的空假设的合理性,即游离脯氨酸具有一个和总体胶原正序相关的相关关系。在这种情况下,空分布中仅那些大于或等于观察到的统计量的值被视为更加极端。
>>> res = stats.spearmanr(x, y, alternative='greater') >>> res.statistic 0.7000000000000001 # same statistic >>> fig, ax = plt.subplots(figsize=(8, 5)) >>> plot(ax) >>> pvalue = dist.sf(transformed) >>> annotation = (f'p-value={pvalue:.6f}\n(shaded area)') >>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8) >>> _ = ax.annotate(annotation, (3, 0.018), (3.5, 0.03), arrowprops=props) >>> i = t_vals >= transformed >>> ax.fill_between(t_vals[i], y1=0, y2=pdf[i], color='C0') >>> ax.set_xlim(1, 5) >>> ax.set_ylim(0, 0.1) >>> plt.show()
>>> res.pvalue 0.03995834515444954 # one-sided p-value; half of the two-sided p-value
请注意,t 分布提供空分布的一个渐近逼近;它仅适用于具有许多观察值的样本。对于小样本,执行置换检验可能更为合适:在空假设(总体胶原和游离脯氨酸是独立的)下,每次游离脯氨酸测量值都有相同可能性与任何总体胶原测量值一起观察到。因此,我们可以在
x
和y
之间的每个可能元素配对下通过计算统计数据以形成一个精确的空分布。>>> def statistic(x): # explore all possible pairings by permuting `x` ... rs = stats.spearmanr(x, y).statistic # ignore pvalue ... transformed = rs * np.sqrt(dof / ((rs+1.0)*(1.0-rs))) ... return transformed >>> ref = stats.permutation_test((x,), statistic, alternative='greater', ... permutation_type='pairings') >>> fig, ax = plt.subplots(figsize=(8, 5)) >>> plot(ax) >>> ax.hist(ref.null_distribution, np.linspace(-5, 5, 26), ... density=True) >>> ax.legend(['aymptotic approximation\n(many observations)', ... f'exact \n({len(ref.null_distribution)} permutations)']) >>> plt.show()
>>> ref.pvalue 0.04563492063492063 # exact one-sided p-value