python - scipy.stats.spearmanr 的不同结果取决于数据的生成方式

标签 python numpy scipy

我在使用 scipy.stats 中的 Spearmanr 时遇到一些奇怪的问题。我使用多项式的值来获取一些更有趣的相关性,但是如果我手动输入值(作为列表,转换为 numpy 数组),我会得到与我得到的不同的相关性如果我使用函数计算值。下面的代码应该可以说明我的意思:

import numpy as np
from scipy.stats import spearmanr    
data = np.array([  0.4,   1.2,   1. ,   0.4,   0. ,   0.4,   2.2,   6. ,  12.4,  22. ])
axis = np.arange(0, 10, dtype=np.float64)

print(spearmanr(axis, data))# gives a correlation of 0.693...

# Use this polynomial
poly = lambda x:  0.1*(x - 3.0)**3 + 0.1*(x - 1.0)**2 - x + 3.0

data2 = poly(axis)
print(data2) # It is the same as data

print(spearmanr(axis, data2))# gives a correlation of 0.729...

我确实注意到数组略有不同(即 data - data2 并非所有元素都完全为零),但差异很小 - 顺序为 1e-16。

如此微小的差异足以让 Spearmanr 甩掉这么多吗?

最佳答案

Is such a tiny difference enough to throw off spearmanr by this much?

是的,因为斯 PIL 曼的r是基于样本排名的。如此微小的差异可能会改变原本相等的值的排名:

sp.stats.rankdata(data)
# array([  3.,   6.,   5.,   3.,   1.,   3.,   7.,   8.,   9.,  10.])
# Note that all three values of 0.4 get the same rank 3.

sp.stats.rankdata(data2)
# array([  2.5,   6. ,   5. ,   2.5,   1. ,   4. ,   7. ,   8. ,   9. ,  10. ])
# Note that two values 0.4 get the rank 2.5 and one gets 4.

如果您添加一个小梯度(大于您观察到的数值差异)来打破这种联系,您将得到相同的结果:

print(spearmanr(axis, data + np.arange(10)*1e-12))
# SpearmanrResult(correlation=0.74545454545454537, pvalue=0.013330146315440047)

print(spearmanr(axis, data2 + np.arange(10)*1e-12))
# SpearmanrResult(correlation=0.74545454545454537, pvalue=0.013330146315440047)

然而,这将打破任何可能故意的联系,并可能导致高估或低估相关性。 numpy.round如果数据预计具有离散值,可能是更好的解决方案。

关于python - scipy.stats.spearmanr 的不同结果取决于数据的生成方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42371348/

相关文章:

python - scipy.optimize.minimize 无法收敛具有约束的矩阵输入

python - 什么时候需要在Python中定义单独的函数

python - 使用Python pptx获取图像文件名

Python:如何计算geotiff数组中值为1的相邻值?

python - 为什么我的蒙版生成的形状多边形无效?

numpy - 50Kx50K稀疏矩阵

python - 这些对在 dblquad 中返回固定值的函数的频繁调用是否可以避免?

python - 在 python 项目中不使用 __init__.py 文件是一种不好的做法吗?

python 导入不工作

python - pandas 向量的点积