【问题标题】:Why I get nan in spearman correlation in python为什么我在 python 的 spearman 相关中得到 nan
【发布时间】:2021-04-06 19:31:45
【问题描述】:

我正在使用scipy 来计算相关性。我计算斯皮尔曼相关性的代码如下。

from scipy import stats
sequence_1 = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
sequence_2 = [0, 0.009783728115345005, 0, 0, 0.0019759230121848587, 0.0007535430349118562, 0.0002661781514710257, 0, 0, 0.0007835762419683435]
myspearman = stats.spearmanr(sequence_1,sequence_2)
print(myspearman)

我从代码中得到以下结果。

SpearmanrResult(correlation=nan, pvalue=nan)

尽管本主题中有一些 SO 问题,但它们并没有专门回答我的问题。

我的问题如下。

  • 我想以某种方式获得相关性的值。从这个意义上说,什么 是nan的等效值吗?
  • 我的另一个问题是;有没有办法避免这种情况并变得实际 python 中的值?

如果需要,我很乐意提供更多详细信息。

【问题讨论】:

  • 您确定要 spearman 相关性而不是 pearson 相关性?通常,spearman 相关是对排名数据执行的,因此不太可能出现如此多的联系。
  • @LucasRoberts 我很乐意尝试pearson 相关性,如果它没有给出任何 nans :)
  • @EmJ, pearsonr() 也将返回 Nan。但是,如果您使用的是 SciPy 版本 1.3.X,它将返回一条信息性消息。我相信 Warren 提供了一个补丁来解决这个问题并提供信息丰富的错误消息。这也与您在这种情况下所希望的一样多,尽管您没有收到关于 spearmanr 的信息性消息。
  • @EmJ,我建议你在 scipy github repo 上提交一个错误报告:github.com/scipy/scipy/issues 或者如果你愿意,我可以代表你打开一个并链接这个帖子。

标签: python scipy


【解决方案1】:

为什么spearmanr 会输出NaN

sequence_1没有变化,因此其标准差等于 0,这将导致在 spearmanr() 函数中进行零除,从而返回 NaN

在这种情况下NaN 的等效值是多少?

从数学上讲,当两个列表之一中的标准差为零(其中随机变量的所有实例都采用完全相同的值)时,Spearman 相关系数未定义。我建议你研究公式here 更好地理解为什么这不简单!

有没有办法避免这种情况并在 Python 中获取实际值?

由于实际值未定义,因此您确实会获得带有NaN正确 值。但是,您可能希望依赖其他公式来解决此类问题,例如两个变量之间的协方差 - 在这种情况下,协方差将等于零。

【讨论】:

【解决方案2】:

这里有两个问题,第一个问题已经在混血王子的回答中评论过了。

对于该问题,您在scipy.stats 中选择哪种类型的关联并不重要,因为您要关联的两个序列之一的可变性为 0。

我在对帖子的评论中指出,通常spearmanr() 用于排名,而且您似乎没有关联排名数据。我正在根据 2 个序列的非整数值进行评估——通常排名是非负整数值。

鉴于第二个问题(看起来),我建议使用pearsonr()。如果您的 scipy 版本是 1.3.X 或更高版本,则错误消息会提供信息并准确地告诉您这个问题:

>>> myspearman = stats.pearsonr(sequence_1,sequence_2)
/Users/rlucas/scipy-dev/scipy/scipy/stats/stats.py:3508: PearsonRConstantInputWarning: An input array is constant; the correlation coefficent is not defined.
  warnings.warn(PearsonRConstantInputWarning())

此外,为了保持一致性,scipy.stats.spearmanr() 应该对spearmanr() 发出类似的警告。我在 github repo 中打开了一个问题,提到了这个问题并与这个 SO 线程交叉链接。还放置从这里到问题的交叉链接,

https://github.com/scipy/scipy/issues/11111

【讨论】:

    【解决方案3】:

    这个问题可以通过更高级的 Scipy 功能轻松解决,用于 spearman 测试。

    只需执行以下操作:

    1. 导入 Scipy 的高级功能进行 spearman 测试:
    • from scipy.stats.mstats import spearmanr
    1. 使用此函数进行 spearman 测试:
    • spearmanr(sequence_1,sequence_2)
    1. 因此你得到:SpearmanrResult(correlation=0.0, pvalue=1.0)

    就是这样,希望对你有帮助:)

    【讨论】:

      【解决方案4】:

      误差主要是由于第一个系列的标准偏差为零。

      只需更改第一个系列中的一个值,如下所示,您将获得结果,因为现在标准差不为零。

      from scipy import stats
      sequence_1 = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0]
      sequence_2 = [0, 0.009783728115345005, 0, 0, 0.0019759230121848587, 0.0007535430349118562, 0.0002661781514710257, 0, 0, 0.0007835762419683435]
      myspearman = stats.spearmanr(sequence_1,sequence_2)
      print(myspearman)
      

      输出

      SpearmanrResult(correlation=0.30949223029508643, pvalue=0.3841919479937841)
      

      【讨论】:

      • 我不认为问题来自零的存在,而是来自两个列表之一中没有差异!
      猜你喜欢
      • 1970-01-01
      • 2018-05-09
      • 2022-04-02
      • 1970-01-01
      • 1970-01-01
      • 2020-11-18
      • 2018-02-01
      • 2021-03-21
      • 2019-11-10
      相关资源
      最近更新 更多