我此时的理解是概率编程类似于贝叶斯网络,只是被翻译成编程语言来创建自动推理模型?
没错。概率程序可以被视为等同于贝叶斯网络,但用更丰富的语言表示。 概率编程作为一个领域提出了这样的表示,以及利用这些表示的算法,因为有时更丰富的表示会使问题更容易。
例如,考虑一个概率程序,它模拟一种更可能折磨男性的疾病:
N = 1000000;
for i = 1:N {
male[i] ~ Bernoulli(0.5);
disease[i] ~ if male[i] then Bernoulli(0.8) else Bernoulli(0.3)
}
这个概率程序等价于下面的贝叶斯网络,并附有适当的条件概率表:
对于这种高度重复的网络,作者经常使用车牌符号来使他们的描述更加简洁:
但是,车牌符号是一种用于人类可读出版物的设备,而不是与编程语言相同的形式语言。此外,对于更复杂的模型,车牌符号可能会变得更难理解和维护。最后,编程语言带来了其他好处,例如更容易表达条件概率的原始操作。
那么,这只是一个方便的表示的问题吗?不,因为更抽象的表示包含更多可用于改进推理的高级信息。
假设我们想要计算N 患有该疾病的个体中数量 的概率分布。一个简单且通用的贝叶斯网络算法必须考虑到disease 变量的大量分配2^N 组合,以便计算该答案。
然而,概率程序表示明确指出disease[i] 和male[i] 的条件概率对于所有i 都是相同的。推理算法可以利用它来计算disease[i] 的边际概率,这对于所有i 都是相同的,使用患病人数因此将是二项分布B(N, P(disease[i])) 的事实,并将其作为所需的答案, 在N 中的时间常数。它还能够提供对这一结论的解释,这对用户来说更容易理解和更有洞察力。
有人可能会争辩说这种比较是不公平的,因为知识渊博的用户不会提出为显式 O(N) 大小的贝叶斯网络定义的查询,而是通过利用其简单结构提前简化问题。但是,用户可能没有足够的知识来进行这种简化,尤其是对于更复杂的情况,或者可能没有时间去做,或者可能会犯错误,或者可能事先不知道模型将是什么,因此她无法像这样手动简化它。概率编程提供了自动进行这种简化的可能性。
公平地说,大多数当前的概率编程工具(例如 JAGS 和 Stan)不执行这种更复杂的数学推理(通常称为 提升概率推理),而是只需在贝叶斯网络上执行马尔可夫链蒙特卡罗 (MCMC) 采样,相当于概率程序(但通常无需提前构建整个网络,这也是另一个可能的收获)。无论如何,这种便利已经足以证明它们的使用是合理的。