from pgmpy.models import BayesianModel
from pgmpy.factors.discrete import TabularCPD
from pgmpy.inference import VariableElimination
# 通过边来定义贝叶斯模型
model = BayesianModel([('D', 'G'), ('I', 'G'), ('G', 'L'), ('I', 'S')])
# 定义条件概率分布
cpd_d = TabularCPD(variable='D', variable_card=2, values=[[0.6, 0.4]])
cpd_i = TabularCPD(variable='I', variable_card=2, values=[[0.7, 0.3]])
# variable:变量
# variable_card:基数
# values:变量值
# evidence:
cpd_g = TabularCPD(variable='G', variable_card=3,
values=[[0.3, 0.05, 0.9, 0.5],
[0.4, 0.25, 0.08, 0.3],
[0.3, 0.7, 0.02, 0.2]],
evidence=['I', 'D'],
evidence_card=[2, 2])
cpd_l = TabularCPD(variable='L', variable_card=2,
values=[[0.1, 0.4, 0.99],
[0.9, 0.6, 0.01]],
evidence=['G'],
evidence_card=[3])
cpd_s = TabularCPD(variable='S', variable_card=2,
values=[[0.95, 0.2],
[0.05, 0.8]],
evidence=['I'],
evidence_card=[2])
# 将有向无环图与条件概率分布表关联
model.add_cpds(cpd_d, cpd_i, cpd_g, cpd_l, cpd_s)
# 验证模型:检查网络结构和CPD,并验证CPD是否正确定义和总和为1
model.check_model()
# 获得G点的概率表
print(model.get_cpds('G'))
# 获得G点的基数
print(model.get_cardinality('G'))
# 获取贝叶斯网络的局部依赖关系
print(model.local_independencies(['D','I','S','G','L']))
# 贝叶斯推理:变量消除
infer = VariableElimination(model)
print(infer.query(['G']), ['G'])
print(infer.query(['G'], evidence={'D':0, 'I':1})['G'])
print(infer.map_query('G'))
在你的代码中,最后一行 print(infer.map_query('G')) 的 map_query() 方法返回的是最可能的后验分布,即最大后验概率(MAP)分布,而 'G' 变量没有给定任何的证据条件,所以它的概率分布是空的,返回空列表。
你可以尝试添加证据条件到 map_query() 方法中,比如 print(infer.map_query(variables=['G'], evidence={'D': 0, 'I': 1})),这将会给定 D=0 和 I=1 的证据条件,输出最可能的后验分布。
此外,在 infer.query(['G']) 中,你需要提供待查询变量的列表,而你的代码中 ['G'] 作为字符串和 print 函数是分离的,需要将它移动到函数调用的参数里,即 print(infer.query(['G']))。