pythonpython-3.xprobabilitybayesian-networkspgmpy

Find probability of a single occurrence in map_query in pgmpy


I am working on a bayesian network which looks like this

bn

I want to find the probability of P(+j|-e) which means that finding the probability that JohnCalls is true given earthquake is false. Here is the code that I wrote which includes the network

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()

I am getting the following output

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 |
+--------------+------------------+

I am getting the answer as output but what I think +j means to output only JohnCalls(1)

I am submitting it but it is still showing error of malformed feedback which means that there is some error in my code. The code is compiling and I am getting output but I think it is not in the form of the expected output thus the malformed feedback.

Is there any other way to extract only JohnCalls(1). Any help will be appreciated


Solution

  • I am not sure which pgmpy version you are on. But from 0.1.16, there is a get_value method in DiscreteFactor which returns a single value for the specified state. In your example, you can change the last line to something like this:

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