在 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
。我猜这个错误与这样一个事实有关,即根据 x
和 l
采样的值,观察到的数据可能会落在较低的上限范围之外。但我该如何解决这个问题?
采样器不知道如何处理从参数 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)
另一种方法是直接对 lower
和 upper
进行采样,然后计算 x
和 l
作为确定性变量。
我是 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
。我猜这个错误与这样一个事实有关,即根据 x
和 l
采样的值,观察到的数据可能会落在较低的上限范围之外。但我该如何解决这个问题?
采样器不知道如何处理从参数 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)
另一种方法是直接对 lower
和 upper
进行采样,然后计算 x
和 l
作为确定性变量。