这就是我问这个问题的原因: 去年我编写了一些 C++ 代码来计算特定类型模型(由贝叶斯网络描述)的后验概率。该模型运行良好,其他一些人开始使用我的软件。现在我想改进我的模型。由于我已经为新模型编写了稍微不同的推理算法,因此我决定使用 python,因为运行时并不是至关重要的,python 可以让我编写更优雅和更易于管理的代码。
通常在这种情况下,我会在 python 中搜索现有的贝叶斯网络包,但我使用的推理算法是我自己的,我还认为这将是一个了解更多关于 python 良好设计的好机会。
我已经为网络图 (networkx) 找到了一个很棒的 python 模块,它允许您将字典附加到每个节点和每个边。本质上,这可以让我给出节点和边的属性。
对于特定网络及其观察数据,我需要编写一个函数来计算模型中未分配变量的可能性。
例如,在经典的“亚洲”网络(http://www.bayesserver.com/Resources/Images/AsiaNetwork.png)中,已知“X 射线结果”和“呼吸困难”的状态,我需要编写一个函数计算其他变量具有某些值的可能性(根据某些模型)。
这是我的编程问题: 我将尝试一些模型,将来我可能会想尝试另一种模型。例如,一种模型可能看起来与亚洲网络完全一样。在另一个模型中,可能会从“访问亚洲”到“患有肺癌”添加有向边。另一个模型可能使用原始的有向图,但给定“肺结核或癌症”和“患有支气管炎”节点的“呼吸困难”节点的概率模型可能不同。所有这些模型都将以不同的方式计算可能性。
所有模型将有大量重叠;例如,如果所有输入均为“0”,则进入“或”节点的多条边将始终为“0”,否则为“1”。但是有些模型的节点会在某个范围内采用整数值,而其他模型将是布尔值。
在过去,我一直在为如何编写这样的东西而苦苦挣扎。我不会说谎;有相当多的复制和粘贴代码,有时我需要将单个方法中的更改传播到多个文件。这次我真的很想花时间以正确的方式做到这一点。
一些选项:
- 我已经以正确的方式这样做了。先写代码,再问问题。复制和粘贴代码并为每个模型设置一个类会更快。世界是一个黑暗而杂乱无章的地方……
- 每个模型都是它自己的类,也是一般贝叶斯网络模型的子类。这个通用模型将使用一些将被覆盖的函数。Stroustrup 会感到自豪。
- 在同一个类中创建几个计算不同可能性的函数。
- 编写一个通用的 BayesianNetwork 库并将我的推理问题实现为该库读取的特定图表。节点和边应该被赋予像“Boolean”和“OrFunction”这样的属性,给定父节点的已知状态,可以用来计算不同结果的概率。这些属性字符串,例如“OrFunction”,甚至可以用来查找和调用正确的函数。也许几年后我会做出类似于 1988 年版 Mathematica 的东西!
非常感谢你的帮助。
更新: 面向对象的思想在这里有很大帮助(每个节点都有一组指定的特定节点子类型的前驱节点,并且每个节点都有一个似然函数,可以根据前驱节点的状态计算其不同结果状态的可能性等。 )。哎呀!