我想建立一个离散的贝叶斯网络(pymc.类别)变量依赖于其他分类变量。举一个最简单的例子,假设变量 a 和 b 是分类的,b 依赖于
这是尝试使用 pymc 对其进行编码(假设 a 取三个值之一,b 取四个值之一)。这个想法是,CPT分布将使用pymc从数据中学习。
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])
如果我们绘制这个模型,它看起来像这样
但是,运行此代码时,我们会收到一个错误:
Probabilities in categorical_like sum to [ 0.8603345]
显然,pymc 可以将狄利克雷变量作为分类变量的参数。当分类变量获得狄利克雷变量作为其参数时,它知道期望概率的 k-1 向量,假设第 k 个概率将向量总和为 1。但是,当狄利克雷变量是确定性变量的输出时,这就会崩溃,这是我制作CPT所需要的。
我这样做的方式是否正确?如何解决表示不匹配问题?我应该提到,我对pymc和Python相对较新。
这个问题与之前关于用pymc制作离散状态马尔可夫模型的问题有关
好的,谢谢。问题是,虽然通常,PyMC 会将狄利克雷识别为分类的父级并完成概率单纯形,但在这里您的分类嵌入在容器中,并且分类不会进行所需的自动调整。以下代码将为您执行此操作:
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])
希望有帮助。
几个困惑点:
- 您的模型似乎不包含任何数据(观察到的随机指标),因此没有信息来拟合模型
- 不确定狄利克雷变量是确定性的输出是什么意思。只要概率的长度为 k-1 并且它们的总和小于 1,您应该很好。如果你有一个总和为统一的值,你可以只传递值的第一个 k-1。