在pymc3混合模型采样步骤中包括簇数

时间:2017-07-11 19:28:36

标签: python pymc3

改编自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作为参数。我感谢任何提示/建议。谢谢!

1 个答案:

答案 0 :(得分:3)

实际的错误消息是关于tt.ones()的使用情况,它需要一个可迭代的参数:tt.ones([k])。但是,这不会对你有所帮助,因为pymc3不支持在采样过程中改变形状的变量。您可以尝试边缘化参数的数量,并使用pm.Potential添加logp。