来自石榴贝叶斯网络的样本
Sample from a Bayesian network in pomegranate
我在 pomegranate 中使用 from_samples()
构建了一个贝叶斯网络。我能够使用 model.predict()
从模型中获得最大可能的预测。我想知道是否有办法有条件地(或无条件地)从这个贝叶斯网络中抽样?即是否有从网络中获取随机样本而不是最大可能的预测?
我看了model.sample()
,但是它在加注NotImplementedError
。
此外,如果使用 pomegranate
无法做到这一点,还有哪些其他库对 Python 中的贝叶斯网络非常有用?
model.sample()
should have been implemente 如果我正确地看到提交历史记录,那么现在
您可以查看 PyMC,它也支持分布混合。
但是,我不知道任何其他具有类似工厂方法的工具箱,如 pomogranate 中的 from_samples()
。
从 'baked' 贝叶斯网络中采样的一种方法是使用 predict_proba 方法。 predict_proba returns 对应于未提供信息的每个节点的分布列表,以提供的信息为条件。
例如:
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
为了用一个具体的例子来阐明上述答案,以便对某人有所帮助,让我们从以下简单数据集(具有 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如下图所示
从上图可以看出,对数据的解释很准确。我们可以使用以下模型计算数据的对数似然:
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
找到更好的估计值。
我在 pomegranate 中使用 from_samples()
构建了一个贝叶斯网络。我能够使用 model.predict()
从模型中获得最大可能的预测。我想知道是否有办法有条件地(或无条件地)从这个贝叶斯网络中抽样?即是否有从网络中获取随机样本而不是最大可能的预测?
我看了model.sample()
,但是它在加注NotImplementedError
。
此外,如果使用 pomegranate
无法做到这一点,还有哪些其他库对 Python 中的贝叶斯网络非常有用?
model.sample()
should have been implemente 如果我正确地看到提交历史记录,那么现在
您可以查看 PyMC,它也支持分布混合。
但是,我不知道任何其他具有类似工厂方法的工具箱,如 pomogranate 中的 from_samples()
。
从 'baked' 贝叶斯网络中采样的一种方法是使用 predict_proba 方法。 predict_proba returns 对应于未提供信息的每个节点的分布列表,以提供的信息为条件。
例如:
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
为了用一个具体的例子来阐明上述答案,以便对某人有所帮助,让我们从以下简单数据集(具有 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如下图所示
从上图可以看出,对数据的解释很准确。我们可以使用以下模型计算数据的对数似然:
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
找到更好的估计值。