python - 当向其传递两组相同的数据时,自制的 pearson 相关实现返回 0.999...2

标签 python scipy pearson pearson-correlation

我厌倦了 scipy 和 numpy,并决定继续研究另一个实现,基于某处的 SO 答案。

from statistics import pstdev, mean

def pearson(x, y):
    sx = []
    sy = []

    mx = mean(x)
    my = mean(y)

    stdx = pstdev(x)
    stdy = pstdev(y)

    for i in x:
        sx.append((i - mx) / stdx)

    for j in y:
        sy.append((j - my) / stdy)

    return sum([i * j for i, j in zip(sx, sy)]) / len(x)

我向其中传递了一些数字,看看它是否给出了与 scipy.stats.pearsonr 相同的结果,看起来没问题。最后的一些数字有所不同,但没有什么突破性的......

直到我尝试将相同的数据集传递给它作为xy。当我这样做时,我得到了 0.9999999999999992,而 scipy 和 numpy 都说它是 1.0

这个实现有问题吗?我使用的是总体标准差而不是样本标准差,据我所知,numpy 和 scipy 都使用它。我想知道为什么这没有返回应有的 1.0 。难道是python本身的 float 问题?我已经在 Py 2 和 3 中尝试过,并且在两者中都得到了 0.999...

如果需要,我传递给它的数据集是:

[7, 1, 5, 1, 8, 5, 9, 8, 5, 10, 5, 8, 1, 8, 8, 8, 10, 4, 8, 9, 9, 6 , 8, 7, 8, 5, 10, 5, 6, 8, 8, 7, 9, 4, 6, 10, 7, 10, 4, 5, 4, 7, 4, 8, 9, 10, 9 , 8, 7, 8, 6, 8, 6, 6, 5, 7, 7, 7, 7, 3, 7, 8, 6, 8, 5, 7, 8, 7, 8, 6, 8, 6 , 9, 6, 6, 6, 8, 9, 5, 7, 9, 2, 9, 6, 7, 6, 7, 7, 5, 5, 7, 7, 8, 6, 9, 1, 3 , 6, 7, 9, 7, 7, 6, 9, 9, 4, 9, 9, 7, 9, 6, 2, 2, 8, 4, 7, 7, 6, 3, 7, 3, 5 , 10, 9, 8, 10, 8, 7, 4, 7, 8, 9, 8, 4, 7, 9, 7, 7, 6, 8, 8, 9, 9, 7, 4, 4, 7 , 3, 9, 3, 1, 8, 3, 9, 4, 8, 3, 9, 8, 8, 7, 9, 9, 8, 10, 8, 3, 10, 4, 7, 7, 10 , 8, 7, 8, 7, 1, 8, 9, 5, 7, 5, 5, 3, 5, 7, 7, 7, 2, 4, 1, 6, 9, 9, 7, 7, 10 , 9, 2, 9, 8, 2, 5, 1, 2, 5, 9, 1, 4, 8, 9, 6, 4, 4, 7, 3, 7, 9, 4, 3, 7, 8 , 7, 6, 8, 8, 7]

最佳答案

您对浮点行为的期望过于乐观。根据经验,您不会对结果不完全是 1.0 感到惊讶。例如,尝试使用更小的输入:

[7, 1, 5]

在我的盒子上,你的函数返回 1.0000000000000002。 “接近”1.0,但不完全是1.0。一般来说,这是您所能期望的最好结果。

要了解原因,请考虑“应该”计算什么:

math.sqrt(x)**2 == x

从数学上来说(以无限精度工作),应该始终返回 True。但在浮点中(无论使用多少精度,只要精度有界),它不可能总是正确的。事实上,反例很容易找到;就像刚才在我的盒子上一样:

>>> math.sqrt(2)**2
2.0000000000000004

问题是,在有限精度下,sqrt() 必然是一个多对一函数。它将域 1..N 压缩到范围 1..sqrt(N) 中,并且在有限精度下,域的基数大于该范围的基数。因此,域中必须存在不同的 xy 映射到范围内的相同值,因此不存在精确的函数逆。

您的函数比普通的 sqrt 更复杂,但工作原理相同。

关于python - 当向其传递两组相同的数据时,自制的 pearson 相关实现返回 0.999...2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44573450/

相关文章:

python - Django-在Elasticsearch搜索结果上显示模型数据

python - 如何在 scipy.interpolate 中设置三次样条插值的第一个和最后一个斜率?

python - 单个列表中可能的列表组合

python - 使用 nltk 通过 n-gram 模型创建新句子

python - 将圆投影到正方形上?

java - 需要一些关于在 java 中计算 Pearson 相关性的正确方向

r - 当您的数据是观察列表时,R 中的卡方检验

mysql - 群组功能使用无效;试图找到 PIL 逊相关系数

os.removexattr 的 Python 文档—— '*'(星号)参数是什么意思?

python - 如何理解外行的 numpy strides?