在 PyMC 中使用采样参数观察制服时出错

Error when observing on uniform with sampled parameters in PyMC

我是 PyMC 的新手,我正在尝试模拟您在墙上滚动弹珠并试图找到方块的情况。数据仅针对弹珠击中方块的值。

我首先对 x 位置和大小进行采样,然后根据具有制服的那些计算点,但出现错误。

import pymc3 as pm
import theano.tensor as tt

basic_model = pm.Model()

with basic_model:

    # We are assuming independence of these.
    x = pm.Uniform("x", lower=1, upper=30)
    l = pm.Uniform("l", lower=1, upper=30)

    lower = pm.Deterministic('lower', x-0.5*l)
    upper = pm.Deterministic('upper', x+0.5*l)

    point_x = pm.Uniform('point_x', lower=lower, upper=upper, observed=x_vals)

    pm.sample()

出现错误:

SamplingError: Initial evaluation of model at starting point failed!
 Starting values:
{'x_interval__': array(0.), 'l_interval__': array(0.)}

 Initial evaluation results:
 x_interval__   -1.39
 l_interval__   -1.39
 point_x         -inf
 Name: Log-probability of test_point, dtype: float64

显然问题出在 point_x。我猜这个错误与这样一个事实有关,即根据 xl 采样的值,观察到的数据可能会落在较低的上限范围之外。但我该如何解决这个问题?

采样器不知道如何处理从参数 space 的无效区域开始的问题。一个快速而肮脏的修复方法是提供 testval 个参数,以确保采样在逻辑上有效的解决方案中开始。例如,我们知道最小块必须有:

l_0 = np.max(x_vals) - np.min(x_vals)
x_0 = np.min(x_vals) + 0.5*l_0

并且可以使用那些:

x = pm.Uniform("x", lower=1, upper=30, testval=x_0)
l = pm.Uniform("l", lower=1, upper=30, testval=l_0)

此外,该模型的性质导致许多由于不可能而被拒绝,因此您可能希望使用 Metropolis 进行采样,这几乎总是需要更多的步骤和调整

pm.sample(tune=10000, draws=10000, step=pm.Metropolis())

替代模型

否则,请考虑重新参数化,以便参数 space 中只有有效的解决方案。一种方法是对 l 进行采样,然后使用它来约束 x。类似于:

other_model = pm.Model()

x_min = np.min(x_vals)
x_max = np.max(x_vals)
l_0 = x_max - x_min

with other_model:

    # these have logical constraints from the data
    l = pm.Uniform("l", lower=l_0, upper=30)
    x = pm.Uniform("x", lower=x_max - 0.5*l, upper=x_min + 0.5*l)
    
    lower = pm.Deterministic('lower', x - 0.5*l)
    upper = pm.Deterministic('upper', x + 0.5*l)

    point_x = pm.Uniform('point_x', lower=lower, upper=upper, observed=x_vals)

    res = pm.sample(step=pm.NUTS(), return_inferencedata=True)

另一种方法是直接对 lowerupper 进行采样,然后计算 xl 作为确定性变量。