代码之家  ›  专栏  ›  技术社区  ›  Björn Pollex

有人能解释scipy中超几何分布的这种奇怪行为吗?

  •  11
  • Björn Pollex  · 技术社区  · 14 年前

    我正在MacOSX10.6.4上运行Python2.6.5(这不是本机版本,我自己安装的),带有Scipy0.8.0。如果我做了以下事情:

    >>> from scipy.stats import hypergeom
    >>> hypergeom.sf(5,10,2,5)
    

    IndexError . 然后我会:

    >>> hypergeom.sf(2,10,2,2)
    -4.44....
    

    我怀疑负值是由于浮点精度不好造成的。然后我再做第一次:

    >>> hypergeom.sf(5,10,2,5)
    0.0
    

    现在成功了!有人能解释一下吗?你也看到这种行为了吗?

    2 回复  |  直到 14 年前
        1
  •  3
  •   dr jimbob    14 年前

    def new_hypergeom_sf(k, *args, **kwds):
        from scipy.stats import hypergeom
        (M, n, N) = args[0:3]
        try:
            return hypergeom.sf(k, *args, **kwds)
        except Exception as inst:
            if k >= n and type(inst) == IndexError:
                return 0 ## or conversely 1 - hypergeom.cdf(k, *args, **kwds)
            else:
                raise inst
    

    现在,如果编辑/usr/share/pyshared/scipy/stats没有问题/分布.py(或等效文件),修复程序可能位于第3966行,其中现在显示:

        place(output,cond,self._sf(*goodargs))
        if output.ndim == 0:
            return output[()]
        return output
    

    但如果你把它改成:

        if output.ndim == 0:
            return output[()]
        place(output,cond,self._sf(*goodargs))
        if output.ndim == 0:
            return output[()]
        return output
    

    它现在可以在没有索引器的情况下工作。基本上,如果输出是零维的,因为它没有通过检查,它会尝试调用place,失败,并且不会生成分布。(如果已经创建了以前的发行版,则不会发生这种情况,这可能是早期测试中没有捕获到这种情况的原因)_基本.py)将改变数组的元素(虽然我不确定它是否会改变维数),所以最好还是在放置后保留0 dim检查。我还没有完全测试这一点,看看这个变化是否打破了任何其他(它适用于所有离散随机变量分布),所以它可能是最好的第一次修复。

    在同一部分中,此修复似乎效果更好:

    class rv_discrete(rv_generic):
    ...
        def sf(self, k, *args, **kwds):
        ...
            if any(cond):
                place(output,cond,self._sf(*goodargs))
            if output.ndim == 0:
                return output[()]
            return output
    
        2
  •  0
  •   Alexander Engelhardt    14 年前

    我不懂python,但函数的定义如下: 超几何sf(x,M,n,n,loc=0)

    M是有趣物体的数目,N是物体的总数,N是你“挑选一个”的频率(对不起,德国统计学家)。