<jupyter_start><jupyter_text>Directed graphical modelsWe illustrate some basic properties of DGMs.<jupyter_code>!pip install  causalgraphicalmodels
!pip install pgmpy
from causalgraphicalmodels import CausalGraphicalModel
import pgmpy
import numpy as np
import pandas as pd<jupyter_output><empty_output><jupyter_text>Make the model<jupyter_code>sprinkler = CausalGraphicalModel(
    nodes=["cloudy", "rain", "sprinkler", "wet", "slippery"],
    edges=[
        ("cloudy", "rain"), 
        ("cloudy", "sprinkler"), 
        ("rain", "wet"),
        ("sprinkler", "wet"), 
        ("wet", "slippery")
    ]
)<jupyter_output><empty_output><jupyter_text>Draw the model<jupyter_code># draw return a graphviz `dot` object, which jupyter can render
out = sprinkler.draw()
type(out)

display(out)
out.render()<jupyter_output><empty_output><jupyter_text>Display the factorization<jupyter_code>print(sprinkler.get_distribution())<jupyter_output>P(season)P(sprinkler|season)P(rain|season)P(wet|rain,sprinkler)P(slippery|wet)<jupyter_text>D-separation<jupyter_code># check for d-seperation of two nodes
sprinkler.is_d_separated("slippery", "cloudy", {"wet"})<jupyter_output><empty_output><jupyter_text>Extract CI relationships<jupyter_code># get all the conditional independence relationships implied by a CGM
CI = sprinkler.get_all_independence_relationships()
print(CI)
records = []
for ci in CI:
  record = (ci[0], ci[1], ', '.join(x for x in ci[2]))
  records.append(record)

print(records)
df = pd.DataFrame(records, columns = ('X', 'Y', 'Z'))
display(df)
print(df.to_latex(index=False))<jupyter_output>\begin{tabular}{lll}
\toprule
         X &          Y &                          Z \\
\midrule
      rain &  sprinkler &                     cloudy \\
      rain &   slippery &                        wet \\
      rain &   slippery &             sprinkler, wet \\
      rain &   slippery &                cloudy, wet \\
      rain &   slippery &     sprinkler, cloudy, wet \\
 sprinkler &   slippery &                        wet \\
 sprinkler &   slippery &                  rain, wet \\
 sprinkler &   slippery &                cloudy, wet \\
 sprinkler &   slippery &          rain, cloudy, wet \\
    cloudy &   slippery &                        wet \\
    cloudy &   slippery &            rain, sprinkler \\
    cloudy &   slippery &                  rain, wet \\
    cloudy &   slippery &             sprinkler, wet \\
    cloudy &   slippery &       rain, sprinkler, wet \\
    cloudy &        wet &            rain, sprinkler \\
    cloudy &        wet &  slippery, rain, sprinkler \\
\bottomru[...]<jupyter_text>Inference<jupyter_code>from pgmpy.models import BayesianModel
from pgmpy.factors.discrete import TabularCPD

# Defining the model structure. We can define the network by just passing a list of edges.
model = BayesianModel([('C', 'S'), ('C', 'R'), ('S', 'W'), ('R', 'W'), ('W', 'L')])

# Defining individual CPDs.
cpd_c = TabularCPD(variable='C', variable_card=2, values=np.reshape([0.5, 0.5],(2,1)))

# In pgmpy the columns are the evidences and rows are the states of the variable.
 
cpd_s = TabularCPD(variable='S', variable_card=2, 
                   values=[[0.5, 0.9],
                           [0.5, 0.1]],
                  evidence=['C'],
                  evidence_card=[2])

cpd_r = TabularCPD(variable='R', variable_card=2, 
                   values=[[0.8, 0.2],
                           [0.2, 0.8]],
                  evidence=['C'],
                  evidence_card=[2])

cpd_w = TabularCPD(variable='W', variable_card=2, 
                   values=[[1.0, 0.1, 0.1, 0.01],
                           [0.0, 0.9, 0.9, 0.99]],
                  evidence=['S', 'R'],
                  evidence_card=[2, 2])

cpd_l = TabularCPD(variable='L', variable_card=2, 
                   values=[[0.9, 0.1],
                           [0.1, 0.9]],
                  evidence=['W'],
                  evidence_card=[2])

# Associating the CPDs with the network
model.add_cpds(cpd_c, cpd_s, cpd_r, cpd_w, cpd_l)

# check_model checks for the network structure and CPDs and verifies that the CPDs are correctly 
# defined and sum to 1.
model.check_model()



from pgmpy.inference import VariableElimination
infer = VariableElimination(model)

# p(R=1)= 0.5*0.2 + 0.5*0.8 = 0.5
probs = infer.query(['R']).values
print('\np(R=1) = ', probs[1])

# P(R=1|W=1) = 0.7079
probs = infer.query(['R'], evidence={'W': 1}).values
print('\np(R=1|W=1) = ', probs[1])


# P(R=1|W=1,S=1) = 0.3204
probs = infer.query(['R'], evidence={'W': 1, 'S': 1}).values
print('\np(R=1|W=1,S=1) = ', probs[1])<jupyter_output>Finding Elimination Order: : 100%|██████████| 4/4 [00:00<00:00, 557.40it/s]
Eliminating: W: 100%|██████████| 4/4 [00:00<00:00, 341.96it/s]
Finding Elimination Order: : 100%|██████████| 3/3 [00:00<00:00, 710.42it/s]
Eliminating: C: 100%|██████████| 3/3 [00:00<00:00, 435.59it/s]
Finding Elimination Order: : 100%|██████████| 2/2 [00:00<00:00, 754.71it/s]
Eliminating: C: 100%|██████████| 2/2 [00:00<00:00, 517.24it/s]
{'fraction_non_alphanumeric': 0.16388225934765313, 'fraction_numerical': 0.04136833731105807, 'mean_word_length': 2.654796511627907, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '2556', 'license': 'MIT', 'n_tokens_mistral': 2009, 'n_tokens_neox': 1843, 'n_words': 385, 'path': 'notebooks/sprinkler_pgm.ipynb', 'repo_name': 'animesh-007/pyprobml', 'size': '5028'}