如何使用pymc为贝叶斯网络制作条件概率表(CPT)

时间:2014-04-02 10:09:44

标签: python bayesian-networks pymc dirichlet discrete-space

我想建立一个依赖于其他分类变量的离散(pymc.Categorical)变量的贝叶斯网络。 作为simplest示例,假设变量 a b 是分类的, b 取决于 a < / p>

尝试使用pymc对其进行编码(假设 a 采用三个值中的一个而 b 采用四个值中的一个)。我们的想法是使用pymc从数据中学习CPT分布。

import numpy as np
import pymc as pm
aRange = 3
bRange = 4

#make variable a
a = pm.Categorical('a',pm.Dirichlet('aCPT',np.ones(aRange)/aRange))

#make a CPT table as an array of 
CPTLines = np.empty(aRange, dtype=object)
for i in range(aRange):
    CPTLines[i] = pm.Dirichlet('CPTLine%i' %i,np.ones(bRange)/bRange)

#make a deterministic node that holds the relevant CPT line (dependent on state1)
@pm.deterministic
def selectedCPTLine(CPTLines=CPTLines,a=a):
    return CPTLines[a]

#make a node for variable b 
b=pm.Categorical('b', selectedCPTLine)

model = pm.MCMC([a, b, selectedCPTLine])

如果我们绘制此模型,它看起来像this

但是,运行此代码会出错:

Probabilities in categorical_like sum to [ 0.8603345]

显然,pymc可以将Dirichlet变量作为分类变量的参数。 当分类变量获得Dirichlet变量作为其参数时,它知道期望k-1概率向量,假设第k个概率将向量与1相加。然而,当Dirichlet变量是Dirichlet变量的输出时,这会分解。确定性变量,这是我制作CPT所需要的。

我是以正确的方式来做这件事的吗?如何解决表示不匹配问题?我应该提一下,我对pymc和Python来说相对较新。

此问题与之前关于making a discrete state Markov model with pymc

的问题有关

2 个答案:

答案 0 :(得分:2)

好的,谢谢。问题是,虽然通常情况下,PyMC会将Dirichlet识别为分类的父级并完成概率单纯形,但此处您的分类嵌入在Container中,而分类不需要进行自动调整。以下代码为您完成此操作:

import numpy as np
import pymc as pm
aRange = 3
bRange = 4

aCPT = pm.Dirichlet('aCPT', np.ones(aRange))

#make variable a
a = pm.Categorical('a', aCPT)

#make a CPT table as an array of
CPTLines = [pm.Dirichlet('CPTLine%i' %i, np.ones(bRange)) for i in range(aRange)]

#make a node for variable b
@pm.stochastic(dtype=int)
def b(value=0, CPT=CPTLines, a=a):
    return pm.categorical_like(value, p=pm.extend_dirichlet(CPT[a]))

model = pm.MCMC([a, b, CPTLines])

希望有所帮助。

答案 1 :(得分:0)

有几点困惑:

  • 您的模型似乎不包含任何数据(观察到的随机指标),因此没有适合模型的信息
  • 不确定Dirichlet变量是否是确定性输出的意思。只要概率为k-1长度并且总和小于1,就应该是好的。如果你有一个总和为1的值,你可以传递值的第一个k-1。