我试图在pymc3中实现一个相当简单的模型。要点是我有一些从随机选择序列生成的数据。这些选择可以被认为是一个多项式,并且该过程选择选择作为先前选择的函数。
使用Dirichlet先验模拟类别的总体概率。
必须为手头的数据定制似然函数。数据是从进程输出的0和1的列表。我已经在pymc2中成功制作了模型,你可以在this blog post找到它。这是一个python函数,它为这个问题生成测试数据:
ps = [0.2,0.35,0.25,0.15,0.0498,1/5000]
def make(ps):
out = []
while len(out) < 5:
n_spots = 5-len(out)
sp = sum(ps[:n_spots+1])
P = [x/sp for x in ps[:n_spots+1]]
l = np.argwhere(np.random.multinomial(1,P)==1).ravel()[0]
#if len(out) == 4:
# l = np.argwhere(np.random.multinomial(1,ps[:2])==1).ravel()[0]
out.extend([1]*l)
if (out and out[-1] == 1 and len(out) < 5) or l == 0:
out.append(0)
#print n_spots, l, len(out)
assert len(out) == 5
return out
当我正在学习/转向pymc3时,我正在尝试将观察到的数据输入到自定义似然函数中,并且我在此过程中遇到了几个问题。这可能是因为这是我第一次体验Theano,但我希望有人可以提供一些建议。
这是我的代码(使用上面的make函数):
import numpy as np
import pymc3 as pm
from scipy import optimize
import theano.tensor as T
from theano.compile.ops import as_op
from collections import Counter
# This function gets the attributes of the data that are relevant for calculating the likelihood
def scan(value):
groups = []
prev = False
s = 0
for i in xrange(5):
if value[i] == 0:
if prev:
groups.append((s,5-(i-s)))
prev = False
s = 0
else:
groups.append((0,5-i))
else:
prev = True
s += 1
if prev:
groups.append((s,4-(i-s)))
return groups
# The likelihood calculation for a single data point
def like1(v,p):
l = 1
groups = scan(v)
for n, s in groups:
l *= p[n]/p[:s+1].sum()
return T.log(l)
# my custom likelihood class
class CustomDist(pm.distributions.Discrete):
def __init__(self, ps, data, *args, **kwargs):
super(CustomDist, self).__init__(*args, **kwargs)
self.ps = ps
self.data = data
def logp(self,v):
all_l = 0
for v, k in self.data.items():
l = like1(v,self.ps)
all_l += l*k
return all_l
# model creation
model = pm.Model()
with model:
probs = pm.Dirichlet('probs',a=np.array([0.5]*6),shape=6,testval=np.array([1/6.0]*6))
output = CustomDist("rolls",ps=probs,data=data,observed=True)
我能在大约一分钟内找到MAP(我的机器是Windows 7,i7-4790 @ 3.6GHz)。 MAP与输入概率向量匹配良好,这至少意味着模型正确链接。
但是,当我尝试做痕迹时,我的内存使用量猛增(最多几次演出)而我实际上并没有足够耐心地让模型完成编译。我等了10分钟+ NUTS或HMC甚至在追踪之前编译。虽然大都市步进工作得很好(并且比pymc2快得多)。
我是否真的希望Theano能够很好地处理非theano数据的for循环?有没有更好的方法来编写这个代码,以便Theano可以很好地使用它,或者我是有限的,因为我的数据是一个自定义的python类型,不能用数组/矩阵操作进行分析?
提前感谢您的建议和反馈。请让我知道可能需要澄清的内容!