来自石榴的贝叶斯网络的样本

时间:2018-06-26 05:14:14

标签: python-3.5 bayesian-networks

我在石榴中使用 set the_text to read (POSIX path of ¬ (path to home folder) & ¬ "Dropbox/ToDo.txt" as POSIX file as alias) 构建了贝叶斯网络。我可以使用from_samples()从模型中获得最大可能的预测。我想知道是否有一种方法可以有条件(或无条件)地从该贝叶斯网络中采样?即是否从网络中获得随机样本,而不是最大可能的预测?

我看着model.predict(),但它正在抬起model.sample()

如果使用NotImplementedError无法做到这一点,那么还有哪些其他库适合使用Python的贝叶斯网络呢?

3 个答案:

答案 0 :(得分:1)

如果我正确看到提交历史记录,model.sample() should have been implemente到现在为止。

您可以查看PyMC,它也支持发行混合。 但是,我不知道其他任何具有类似工厂方法的工具箱,例如from_samples()在pomogranate中。

答案 1 :(得分:1)

只是为了用一个具体的例子来阐明上述答案,以便对某人有所帮助,让我们从以下简单的数据集(包含 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 

现在让我们使用 'exact' 算法和 pomegranate(使用 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结构和对应的CPTs如下图所示

enter image description here

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

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:

enter image description here

这次数据的对数似然是

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

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

答案 2 :(得分:0)

从“烘焙的”贝叶斯网络采样的一种方法是使用predict_proba方法。 Predict_proba返回与未提供其信息的每个节点相对应的分布的列表,条件是所提供的信息为条件。

例如:

bn = BayesianNetwork.from_samples(X)
proba = bn.predict_proba({"1":1,"2":0}) # proba will be an array of dists
samples = np.empty_like(proba)
for i in np.arange(proba.shape[0]):
    for j in np.arange(proba.shape[1]):
        if hasattr(proba[i][j],'sample'):
            samples[i,j] = proba[i][j].sample(10000).mean() #sample and aggregate however you want
        else:
            samples[i,j] = proba[i][j]
pd.Series(samples,index=X.columns) #convert samples to a pandas.Series with column labels as index