我应该如何在PyMC中使用@pm.stochastic?
这是个比较简单的问题:我应该怎么使用 @pm.stochastic
? 我看过一些博客,里面说 @pm.stochastic
需要一个负的对数值:
@pm.stochastic(observed=True)
def loglike(value=data):
# some calculations that generate a numeric result
return -np.log(result)
我最近试过这个,但结果很糟糕。因为我还注意到,有些人用的是 np.log 而不是 -np.log,所以我也试了一下,结果好多了。@pm.stochastic
其实期待什么呢?我猜可能是因为一个很流行的例子用到了 np.log(1/(1+t_1-t_0))
,而写成了 -np.log(1+t_1-t_0)
,所以对符号有点混淆。
还有一个问题:这个装饰器在 value
参数上到底做了什么?我理解的是,我们从一些提议的先验值开始,这些值需要进入似然函数,而 @pm.stochastic
的基本想法是生成一个数字,用来和采样过程中前一次迭代生成的数字进行比较。似然函数应该接收 value
参数和一些先验值,但我不确定 value
是否仅仅是做这些,因为这是唯一的必需参数,但我可以这样写:
@pm.stochastic(observed=True)
def loglike(value=[1]):
data = [3,5,1] # some data
# some calculations that generate a numeric result
return np.log(result)
就我所知,这样的结果和之前是一样的。也许是因为我在装饰器中加了 observed=True
。如果我在一个默认是 observed=False
的随机变量中试这个,value
会在每次迭代中改变,以试图获得更好的似然值。
2 个回答
是的,容易让人困惑,因为@stochastic返回的是一种可能性,这实际上是错误的反面。所以你需要对自己定义的错误函数取负对数,然后把这个结果作为你的对数可能性返回。
@pm.stochastic
是一个装饰器,它需要一个函数作为输入。最简单的用法就是给它一个函数,这个函数的参数里有 value
,并且返回一个对数似然值。
你应该使用 @pm.stochastic
装饰器来为你模型中的参数定义一个自定义的先验。要为数据定义一个自定义的似然,你应该使用 @pm.observed
装饰器。这两个装饰器都会创建一个 pm.Stochastic
对象,这个对象的名字来自于它所装饰的函数,并且拥有所有熟悉的方法和属性(这里有一篇关于Python装饰器的不错的文章)。
例子:
一个参数 a
,它的先验分布是三角形分布:
@pm.stochastic
def a(value=.5):
if 0 <= value < 1:
return np.log(1.-value)
else:
return -np.inf
这里 value=.5
被用作参数的初始值,而将其改为 value=1
会引发异常,因为这个值超出了分布的支持范围。
一个似然 b
,它是以 a
为中心的正态分布,精度是固定的:
@pm.observed
def b(value=[.2,.3], mu=a):
return pm.normal_like(value, mu, 100.)
这里 value=[.2,.3]
用来表示观察到的数据。
我把这些内容整理在一个笔记本里,展示了所有的实际操作。