改编自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 作为参数。我很感激任何提示/建议。谢谢!
最佳答案
实际的错误消息与您对 tt.ones()
的使用有关,它需要一个可迭代的参数:tt.ones([k])
。但是,这对您没有帮助,因为 pymc3 不支持在采样期间改变其形状的变量。您可以尝试边缘化参数数量并使用 pm.Potential
添加 logp。
关于python - 在 pymc3 混合模型采样步骤中包括簇数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45043025/