这就是为什么我问这个问题:
去年,我编写了一些C++代码来计算特定类型模型(由贝叶斯网络描述)的后验概率。该模型运行良好,其他人开始使用我的软件。现在,我想改进我的模型。由于我已经为新模型编写了略有不同的推理算法,因此我决定使用python,因为运行时并不是至关重要的,并且python可以让我编写更加优雅和易于管理的代码。
通常在这种情况下,我会在python中搜索现有的贝叶斯网络包,但是我使用的推理算法是我自己的,并且我还认为这将是一个很好的机会,以了解更多关于python良好设计的知识。
我已经找到了一个很棒的用于网络图的python模块(networkx),它允许您将字典附加到每个节点和每个边缘。本质上,这将使我可以指定节点和边的属性。
对于特定的网络及其观察到的数据,我需要编写一个函数来计算模型中未分配变量的可能性。
例如,在经典的“亚洲”网络(http://www.bayesserver.com/Resources/Images/AsiaNetwork.png)中,已知“XRay结果”和“呼吸困难”的状态,我需要编写一个函数来计算其他变量具有特定值的可能性(根据某些模型) )。
这是我的编程问题:
我将尝试一些模型,将来有可能在此之后再尝试其他模型。例如,一种模型可能看起来完全像亚洲网络。在另一种模型中,可以将“从亚洲访问”添加到“有肺癌”。另一个模型可能使用原始的有向图,但是给定“肺结核或癌症”和“有支气管炎”节点的“呼吸困难”节点的概率模型可能有所不同。所有这些模型将以不同的方式计算可能性。
所有模型将有大量重叠;例如,如果所有输入均为“0”,则进入“或”节点的多个边将始终为“0”,否则为“1”。但是某些模型的节点将采用某个范围内的整数值,而其他模型将为 bool 值。
过去,我一直在努力编写此类程序。我不会撒谎;有大量的复制和粘贴代码,有时我需要将单个方法中的更改传播到多个文件。这次我真的很想花时间做正确的事情。
一些选项:
非常感谢你的帮助。
更新:
面向对象的思想在这里有很大帮助(每个节点都有一组指定的特定子类型的前任节点,每个节点都有一个似然函数,可以根据给定前任节点的状态计算其不同结果状态的可能性,等等)。 OOP FTW!
最佳答案
业余时间我一直在从事这类工作。我想我现在正在处理同一问题的第三版或第四版。我实际上正准备发布另一个版本的Fathom(https://github.com/davidrichards/fathom/wiki),其中包含动态贝叶斯模型和不同的持久层。
当我试图弄清楚我的答案时,它已经相当长了。我对此表示歉意。这是我一直在解决问题的方式,它似乎回答了您的某些问题(某种程度上是间接的):
我从Judea Pearl在贝叶斯网络中对信念传播的分解开始。也就是说,它是一个图表,其中 parent 有先验几率(因果支持),而 child 有几率(诊断支持)。这样,基本类就是BeliefNode,就像您在BeliefNodes之间的一个额外节点LinkMatrix所描述的那样。通过这种方式,我通过我使用的LinkMatrix类型显式选择了我正在使用的可能性类型。它使解释信念网络之后的工作变得更容易,并使计算更简单。
我对基本BeliefNode所做的任何子类化或更改都将用于对连续变量进行装箱,而不是更改传播规则或节点关联。
我决定将所有数据保留在BeliefNode中,而仅将固定数据保留在LinkedMatrix中。这与确保我以最少的网络 Activity 维护干净的信念更新有关。这意味着我的BeliefNode存储:
根据节点之间关系的性质,可以使用多种不同的算法来构造LinkMatrix。您要描述的所有模型都只是您要使用的不同类。可能最简单的方法是默认为or-gate,然后如果节点之间有特殊关系,则选择其他方法来处理LinkMatrix。
我使用MongoDB进行持久性和缓存。我在事件模型中访问此数据,以实现速度和异步访问。这使网络性能相当好,同时如果需要的话还可以有很大的机会。另外,由于我以这种方式使用Mongo,因此我可以轻松地为相同的知识库创建新的上下文。因此,例如,如果我有诊断树,则对诊断的某些诊断支持将来自患者的症状和检查。我要做的是为该患者创建上下文,然后根据该特定患者的证据来传播我的信念。同样,如果医生说患者可能患有两种或更多种疾病,那么我可以更改一些链接矩阵,以不同方式传播信念更新。
如果您不想在系统上使用像Mongo这样的东西,但是您计划在知识库上使用多个消费者,则需要采用某种缓存系统以确保您正在使用新的缓存。 -随时更新节点。
我的作品是开源的,因此您可以根据需要进行后续操作。都是Ruby,因此它与Python类似,但不一定是直接替代。我喜欢设计的一件事是,人类解释结果所需的所有信息都可以在节点本身中找到,而不是在代码中找到。这可以在定性描述中或在网络结构中完成。
因此,这是我与您的设计之间的一些重要差异:
一个重要的警告:我正在谈论的一些内容尚未发布。我一直在讨论直到今天凌晨2:00左右的内容,所以它绝对是最新的,而且也得到了我的定期关注,但尚未公开。由于这是我的一种热情,如果您愿意,我很乐意回答任何问题或在项目上共同努力。
关于python - 贝叶斯网络针对特定应用的pythonic实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3783708/