2014-02-19 33 views
1

在我写的模型中,我必须计算一个数量的误差函数。我正在试图做的是这样的:如何将自定义函数应用于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函数会更好,更清晰。

回答

1

我找到了解决方案。我没有意识到如果您使用装饰器创建了一个变量,传递给该函数的参数是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) 

和它的作品。

+0

啊哈!很高兴你明白了。前者可以用一些简单的功能,但不是全部。 –

0

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

我注意到你没有在列表理解中使你的sigma平方。这是问题吗?

+0

Chris,谢谢你的回复。为了清晰起见,我确实减少了问题中的示例,现在也增加了真实代码。请再看一下。 – elpres

+0

您可以创建代码的要点,并可以运行一些测试数据吗?可以是Python脚本或IPython笔记本。 –

+0

是的,我把代码[在这里](https://gist.github。COM/elpres/27763fa1b47a40536400)。 – elpres

相关问题