2017-02-21 186 views
1

我使用scipy.stats中的spearmanr出现了一些奇怪的问题。我使用多项式的值来获得一些更有趣的相关性,但如果我手动输入值(作为列表,转换为numpy数组),我会得到与我得到的不同的相关性如果我使用函数计算值。下面的代码应该证明我的意思:scipy.stats.spearmanr的不同结果取决于数据的生成方式

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的顺序。

这么小的差距足以让斯巴克尔甩这么多吗?

回答

1

这么小的差距足以甩开spearmanr这么多吗?

是的,因为斯皮尔曼的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可能是优选的解决方案。

相关问题