2014-02-19 70 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

相關問題