在 pgmpy 中查找 map_query 中单次出现的概率

Find probability of a single occurrence in map_query in pgmpy

我正在研究如下所示的贝叶斯网络

bn

我想求 P(+j|-e) 的概率,这意味着在给定地震的情况下求 JohnCalls 为真的概率是假的。这是我写的代码,其中包括网络

from pgmpy.models import BayesianModel
from pgmpy.factors.discrete import TabularCPD
from pgmpy.inference import VariableElimination

def buildBN():

    #!!!!!!!!!!!!!!!  VERY IMPORTANT  !!!!!!!!!!!!!!!
    # MAKE SURE to use the terms "MaryCalls", "JohnCalls", "Alarm",
    # "Burglary" and "Earthquake" as the states/nodes of the Network.
    # And also use "burglary_model" as the name of your Bayesian model.
    ########-----YOUR CODE STARTS HERE-----########
    burglary_model = BayesianModel([('Burglary', 'Alarm'), 
                                ('Earthquake', 'Alarm'),
                                ('Alarm', 'JohnCalls'),
                                ('Alarm', 'MaryCalls')])
    
    # Parameter definition
    cpd_Burglary = TabularCPD(variable='Burglary', variable_card=2, 
                            values=[[0.999], [0.001]])
    cpd_Earthquake = TabularCPD(variable='Earthquake', variable_card=2, 
                            values=[[0.998], [0.002]])
    cpd_Alarm = TabularCPD(variable='Alarm', variable_card=2, 
                            values=[[0.999, 0.06, 0.71, 0.05], 
                                    [0.001, 0.94, 0.29, 0.95]], 
                            evidence=['Burglary', 'Earthquake'], 
                            evidence_card=[2, 2])
    cpd_JohnCalls = TabularCPD(variable='JohnCalls', variable_card=2, 
                            values=[[0.95, 0.1], [0.05, 0.9]], 
                            evidence=['Alarm'], evidence_card=[2])
    cpd_MaryCalls = TabularCPD(variable='MaryCalls', variable_card=2, 
                            values=[[0.99, 0.3], [0.01, 0.7]], 
                            evidence=['Alarm'], evidence_card=[2])

    burglary_model.add_cpds(cpd_Burglary, cpd_Earthquake, cpd_Alarm, cpd_JohnCalls, cpd_MaryCalls)

    ########-----YOUR CODE ENDS HERE-----########
    
    # Doing exact inference using Variable Elimination
    burglary_infer = VariableElimination(burglary_model)

    ########-----YOUR MAY TEST YOUR CODE BELOW -----########


    ########-----ADDITIONAL CODE STARTS HERE-----########

    print(burglary_infer.query(variables=['JohnCalls'], evidence={'Earthquake': 0}, elimination_order='MinFill', joint=False)['JohnCalls'])










    ########-----YOUR CODE ENDS HERE-----########
    
    return burglary_infer

buildBN()

我得到以下输出

Finding Elimination Order: : 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<?, ?it/s]
Eliminating: Burglary: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<?, ?it/s] 
Finding Elimination Order: : 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<?, ?it/s] 
Eliminating: Alarm: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<?, ?it/s] 
Finding Elimination Order: : 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<?, ?it/s]
Eliminating: Alarm: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<?, ?it/s] 
Finding Elimination Order: : 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3/3 [00:00<?, ?it/s] 
Eliminating: Alarm: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3/3 [00:00<?, ?it/s] 
Finding Elimination Order: : 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<?, ?it/s] 
Eliminating: Alarm: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 64.00it/s] 
Finding Elimination Order: : 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<?, ?it/s] 
Eliminating: Burglary: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<?, ?it/s] 
+--------------+------------------+
| JohnCalls    |   phi(JohnCalls) |
+==============+==================+
| JohnCalls(0) |           0.9489 |
+--------------+------------------+
| JohnCalls(1) |           0.0511 |
+--------------+------------------+

我得到的答案是输出,但我认为 +j 意味着只输出 JohnCalls(1)

我正在提交它,但它仍然显示格式错误的反馈错误,这意味着我的代码中存在一些错误。代码正在编译,我正在获取输出,但我认为它不是预期输出的形式,因此是错误的反馈。

有没有其他方法可以只提取 JohnCalls(1)。任何帮助将不胜感激

我不确定您使用的是哪个 pgmpy 版本。但是从 0.1.16 开始,DiscreteFactor 中有一个 get_value 方法,其中 returns 指定状态的单个值。在您的示例中,您可以将最后一行更改为如下内容:

>>> query_cpd = burglary_infer.query(variables=['JohnCalls'], evidence={'Earthquake': 0}, elimination_order='MinFill', joint=False)['JohnCalls']
>>> query_cpd.get_value(JohnCalls=1)
0.05109565