如何将自定义函数应用于PyMC中的变量?

时间:2014-02-19 09:53:32

标签: python bayesian pymc

在我写的模型的一个步骤中,我必须计算数量的误差函数。我想做的事情看起来像这样:

from math import erf
import numpy as np
import pymc as pm

sig = pm.Exponential('sig', beta=0.1, size=10)
x = erf(sig ** 2)

此操作失败,因为erf对阵列无效。我试过了:

@pm.deterministic
def x(sig=sig):
    return [erf(s) for s in sig]

但没有成功,我知道可以通过以下方式获得结果:

np_erf = np.vectorize(erf)
x = np_erf((sig ** 2).value)

但这似乎不是正确的方法,因为它不会产生pm.Deterministic而只会产生np.array。我怎么能这样做呢? (PyMC是版本2.3)


编辑:为简洁起见,上面的示例进行了简化,以下是相关段落在实际代码中的含义。理想情况下,我希望这可以工作:

mu = pm.LinearCombination('mu', [...], [...])
sig2 = pm.exp(mu) ** 2
f = 1 / (pm.sqrt(np.pi * sig2 / 2.0) * erf(W / sig2))

但如果失败并显示消息TypeError: only length-1 arrays can be converted to Python scalars。走np.vectorize路线

np_erf = np.vectorize(erf)
f = 1 / (pm.sqrt(np.pi * sig2 / 2.0) * np_erf(W / sig2))

崩溃时出现相同的错误消息。列表理解

@pm.deterministic
def f(sig2=sig2):
    return [1 / (pm.sqrt(np.pi * s / 2.0) * erf(W / s)) for s in sig2]

可以这样工作,但稍后会在此处的代码中导致错误:

@pm.observed(plot=True)
def y(value=df['dist'], sig2=sig2, f=f):
    return (np.log(np.exp(-(value ** 2) / 2.0 / sig2) * f)).sum()

,错误为AttributeError: log

我已经使用数值近似计算了误差函数,这意味着一般设置是正确的。直接使用erf函数会更好更清晰。

2 个答案:

答案 0 :(得分:1)

我找到了解决方案。我没有意识到如果使用pymc.deterministic装饰器创建变量,传递给函数的参数是numpy.array,而不是pymc.Distribution。这允许numpy.vectorize函数并将其应用于变量。而不是

sig = pm.Exponential('sig', beta=0.1, size=10)
x = erf(sig ** 2)

你需要使用

sig = pm.Exponential('sig', beta=0.1, size=10)
np_erf = np_vectorize(erf)

@pm.deterministic
def x(sig=sig):
    return np_erf(sig ** 2)

它有效。

答案 1 :(得分:0)

“没有成功”,你的意思是什么?错误是什么?

我注意到你没有在列表理解中将你的sigma放在一边。这是问题吗?