我想使用 SymPy 正态分布,因为我用它进行一些符号计算。
from sympy.stats import Normal, cdf
from scipy.stats import norm
norm.cdf(10, 10, 0.1)
def survival(x):
y = Normal("x", 10, 0.1)
return cdf(y)(x)
survival(10)
此代码产生以下错误:
UnboundLocalError: local variable 'reprec' referenced before assignment
值得注意的是,通过以下调整,它似乎有效:
return cdf(y, meijerg=False)(x)
有人可以解释一下这种行为吗?
最佳答案
一般要点:
- SymPy 统计模块还有一些改进的空间。特别是,文档承认为正态随机变量返回的 CDF“需要来自
simplify
的一些帮助”才能变得可用。 - float ,尤其是那些不能在二进制系统中精确表示的 float ,对 SymPy 来说是毒药。您认为您传递的是 0.1,但它实际上是
3602879701896397/36028797018963968
并且符号集成例程正在发生变化。
关于第一点;以下示例表明 cdf(x)(t)
是一个有风险的命题。
>>> x = Normal('x', 1, 1)
>>> cdf(x)(1)
nan
问题是未简化的 cdf 被 _z-1
除。更好的方法:
>>> simplify(cdf(x))(1)
1/2
关于第二个:由于 CDF 是通过符号积分计算的,因此将 float 作为参数传递可能会使积分器的生命周期变得非常困难,以至于使用 Meijer G 函数进行积分时会遇到一些隐藏得很深的错误。使用 Rational(1, 10)
或 S(1)/10
创建有理数 1/10,而不是十进制 0.1。
>>> from sympy import S
>>> x = Normal("x", 10, S(1)/10)
>>> simplify(cdf(x))(10)
1/2
关于python - 使用 SymPy 评估正态分布的 CDF 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47218740/