<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 This is the program for a student Bayesian network
Step1:  Add nodes and edges
Step2:  In a Bayesian network, each node has an associated CPD (conditional probability distribution).
Step3:  To check the consistency of the model and associated CPDs
Step4:  if an influence can flow in a trail in a network, it is known as an active trail
Step5:  You can query the network as follows
Step6:  Direct Causal Influence
Step7:  Indirect Causal Influence
<ASSISTANT_TASK:>
Python Code:
from pgmpy.models import BayesianModel
student_model = BayesianModel()
Explanation: This is the program for a student Bayesian network
End of explanation
student_model.add_nodes_from(['difficulty', 'intelligence', 'grade', 'sat', 'letter'])
student_model.nodes()
student_model.add_edges_from([('difficulty', 'grade'), ('intelligence', 'grade'), ('intelligence', 'sat'), ('grade', 'letter')])
student_model.edges()
Explanation: Add nodes and edges
End of explanation
from pgmpy.factors import TabularCPD
#TabularCPD?
cpd_difficulty = TabularCPD('difficulty', 2, [[0.6], [0.4]])
cpd_intelligence = TabularCPD('intelligence', 2, [[0.7], [0.3]])
cpd_sat = TabularCPD('sat', 2, [[0.95, 0.2], 
                                [0.05, 0.8]], evidence=['intelligence'], evidence_card=[2])
cpd_grade = TabularCPD('grade', 3, [[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=['intelligence', 'difficulty'], evidence_card=[2, 2])
cpd_letter = TabularCPD('letter', 2, [[0.1, 0.4, 0.99], [0.9, 0.6, 0.01]], evidence=['grade'], evidence_card=[3])
student_model.add_cpds(cpd_difficulty, cpd_intelligence, cpd_sat, cpd_grade, cpd_letter)
student_model.get_cpds()
print(cpd_difficulty) # 0:easy, 1:hard
print(cpd_intelligence) # 0:low, 1:high
print(cpd_grade) # 0:A, 1:B, 2:C
print(cpd_sat) # 0:low, 1:high
print(cpd_letter) # 0:week, 1:strong
Explanation: In a Bayesian network, each node has an associated CPD (conditional probability distribution).
End of explanation
student_model.check_model()
student_model.get_independencies()
Explanation: To check the consistency of the model and associated CPDs
End of explanation
student_model.is_active_trail('difficulty', 'intelligence')
student_model.is_active_trail('difficulty', 'intelligence',
observed='grade')
Explanation: if an influence can flow in a trail in a network, it is known as an active trail
End of explanation
from pgmpy.inference import VariableElimination
student_infer = VariableElimination(student_model)
# marginal prob of grade
probs = student_infer.query(['grade', 'letter'])
print(probs['grade'])
print(probs['letter'])
Explanation: You can query the network as follows: query(variables, evidence=None, elimination_order=None)
variables: list :
    list of variables for which you want to compute the probability
evidence: dict :
    a dict key, value pair as {var: state_of_var_observed} None if no evidence
elimination_order: list :
    order of variable eliminations (if nothing is provided) order is computed automatically
End of explanation
# probs of grades given knowing nothing about course difficulty and intelligence
print(probs['grade'])
# probs of grades knowing course is hard
prob_grade_hard = student_infer.query(['grade'], {'difficulty':1})
print(prob_grade_hard['grade'])
# probs of getting an A knowing course is easy, and intelligence is low
prob_grade_easy_smart = student_infer.query(['grade'], {'difficulty':0, 'intelligence':1})
print(prob_grade_easy_smart['grade'])
Explanation: Direct Causal Influence
End of explanation
# probs of letter knowing nothing
print(probs['letter'])
# probs of letter knowing course is difficult
prob_letter_hard = student_infer.query(['letter'], {'difficulty':1})
print(prob_letter_hard['letter'])
Explanation: Indirect Causal Influence
End of explanation
<END_TASK>