在PyMC 2.3中创建随机装饰器

时间:2014-06-12 16:51:50

标签: python numpy pymc

我正在尝试复制documentations中为PyMC 2.3提供的示例:

@pm2.stochastic(dtype=int)
    def switchpoint(value=1900, t_l=1851, t_h=1962):
    """The switchpoint for the rate of disaster occurrence."""
    if value > t_h or value < t_l:
        # Invalid values
        return -np.inf
    else:
        # Uniform log-likelihood
        return -np.log(t_h - t_l + 1)

尝试分配时:

test = switchpoint()

我收到错误消息(本帖末尾的完整错误消息):

  

TypeError:'numpy.ndarray'对象不可调用

我猜它是兼容性问题;我正在使用Enthought Canopy Python 2.7.6(64位)发行版。 Numpy版本1.8.0和Scipy 0.13.3。

任何人都可以帮我找到问题所在吗?

注意:我在google网上发现一个相对较小的old thread,显然问题相同。但是,该线程没有更新问题的状态。

以下是完整的错误消息:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/arash/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pymc/CommonDeterministics.py", line 975, in __call__
    plot=False)
  File "/Users/arash/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pymc/PyMCObjects.py", line 435, in __init__
    verbose=verbose)
  File "/Users/arash/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pymc/Node.py", line 216, in __init__
    Node.__init__(self, doc, name, parents, cache_depth, verbose=verbose)
  File "/Users/arash/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pymc/Node.py", line 127, in __init__
    self.parents = parents
  File "/Users/arash/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pymc/Node.py", line 150, in _set_parents
    self.gen_lazy_function()
  File "/Users/arash/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pymc/PyMCObjects.py", line 446, in gen_lazy_function
    self._value.force_compute()
  File "LazyFunction.pyx", line 257, in pymc.LazyFunction.LazyFunction.force_compute (pymc/LazyFunction.c:2409)
  File "/Users/arash/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pymc/CommonDeterministics.py", line 967, in eval_fun
    return self(*args, **kwargs)
TypeError: 'numpy.ndarray' object is not callable

1 个答案:

答案 0 :(得分:2)

PyMC实际上将switchpoint转换为常规变量。所以你只需要做

test = switchpoint

它看起来很奇怪,因为你将它定义为一个装饰功能,但实际上并不是你应该如何使用它。如果你看看你可以定义随机变量的其他方法更有意义,就像这样:

switchpoint = DiscreteUniform('switchpoint', lower=0, upper=110, doc='Switchpoint[year]')

而且:

def switchpoint_logp(value, t_l, t_h):
    if value > t_h or value < t_l:
        return -np.inf
    else:
        return -np.log(t_h - t_l + 1)

def switchpoint_rand(t_l, t_h):
    from numpy.random import random
    return np.round( (t_l - t_h) * random() ) + t_l

switchpoint = Stochastic( logp = switchpoint_logp,
                doc = 'The switchpoint for the rate of disaster occurrence.',
                name = 'switchpoint',
                parents = {'t_l': 1851, 't_h': 1962},
                random = switchpoint_rand,
                trace = True,
                value = 1900,
                dtype=int,
                rseed = 1.,
                observed = False,
                cache_depth = 2,
                plot=True,
                verbose = 0)