改编自this SO question高斯分离混合物,我希望在采样步骤中包括簇(混合物)的数量 - 假设它是未知的。
当已知群集k
的数量时,此脚本有效:
import numpy as np
import pymc3 as pm
import theano.tensor as tt
n = [500, 200, 300]
means = [21.8, 42.0, 62.7]
precision = 0.1
sigma = np.sqrt(1 / precision)
data = np.concatenate([np.random.normal(loc=mean1, scale=sigma, size=n1)
for n1, mean1 in zip(n, means)])
k = len(n)
with pm.Model() as model1:
p = pm.Dirichlet('p', a=np.ones(k))
means = pm.Uniform('mean', 15, 80, shape=k)
sigma = pm.Uniform('sigma', 0, 20)
process = pm.NormalMixture('obs', p, means, sd=sigma, observed=data)
with model1:
trace = pm.sample(10000)
我尝试了几种不同的方式来对k
进行采样,但都没有效果:
with pm.Model() as model1:
k = pm.DiscreteUniform('k', lower=2, upper=5)
ones_k = tt.ones(k) #or ones_k = np.ones(k)
p = pm.Dirichlet('p', a=ones_k)
means = pm.Uniform('mean', 15, 80, shape=k)
sigma = pm.Uniform('sigma', 0, 20)
process = pm.NormalMixture('obs', p, means, sd=sigma, observed=data)
我在第TypeError: Alloc object argument after * must be an iterable, not FreeRV
行收到错误ones_k = tt.ones(k)
,显然tt.ones
期望迭代而不是pymc3.FreeRV作为参数。我感谢任何提示/建议。谢谢!
答案 0 :(得分:3)
实际的错误消息是关于tt.ones()
的使用情况,它需要一个可迭代的参数:tt.ones([k])
。但是,这不会对你有所帮助,因为pymc3不支持在采样过程中改变形状的变量。您可以尝试边缘化参数的数量,并使用pm.Potential
添加logp。