Python 中的贝叶斯网络:构建和采样

数据挖掘 机器学习 Python 数据集 采样 贝叶斯网络
2022-01-22 20:14:58

对于一个项目,我需要创建包含属性之间特定依赖关系的综合分类数据。这可以通过从预定义的贝叶斯网络中采样来完成。在互联网上进行了一些探索之后,我发现这Pomegranate是一个很好的贝叶斯网络包,但是 - 就我而言 - 从这样一个预定义的贝叶斯网络中采样似乎是不可能的。作为一个例子,model.sample()提出了一个NotImplementedError(尽管这个解决方案是这样说的)。

有谁知道是否存在为贝叶斯网络的构建和采样提供良好接口的库?

3个回答

只是为了用一个具体的例子来阐明上述答案,以便对某人有所帮助,让我们从以下简单的数据集开始(有 4 个变量和 5 个数据点):

import pandas as pd
df = pd.DataFrame({'A':[0,0,0,1,0], 'B':[0,0,1,0,0], 'C':[1,1,0,0,1], 'D':[0,1,0,1,1]})
df.head()

#   A   B   C   D
#0  0   0   1   0
#1  0   0   1   1
#2  0   1   0   0
#3  1   0   0   1
#4  0   0   1   1 

现在,让我们使用带有石榴的“精确”算法(使用 DP/A* 学习最佳 BN 结构)从上述数据中学习贝叶斯网络结构,使用以下代码片段:

import numpy as np
from pomegranate import *
model = BayesianNetwork.from_samples(df.to_numpy(), state_names=df.columns.values, algorithm='exact')
# model.plot()

下图显示了学习的 BN 结构以及相应的 CPT:

在此处输入图像描述

从上图可以看出,准确的解释了数据。我们可以使用模型计算数据的对数似然,如下所示:

np.sum(model.log_probability(df.to_numpy()))
# -7.253364813857112

一旦学习了 BN 结构,我们就可以从 BN 中采样如下:

model.sample()  
# array([[0, 1, 0, 0]], dtype=int64)

附带说明一下,如果我们algorithm='chow-liu'改为使用(它找到具有快速近似的树状结构),我们将获得以下 BN:

在此处输入图像描述

这次数据的对数似然是

np.sum(model.log_probability(df.to_numpy()))
# -8.386987635761297

这表明算法exact找到了更好的估计。

请使用该函数from_samples()从数据中构建贝叶斯 n/w。

在 github中有一个未解决的pomegranate问题在这个问题中,他们提到了一个持续的拉取请求,该请求实现了拒绝抽样和吉布斯抽样;PR讨论的最后一条评论来自7天前(2020年5月17日),所以没有放弃,而是积极开发。您可以使用来自该 PR 的版本从您的贝叶斯网络中采样。pomegranate