Reducing a Chain Event Graph#

A complete CEG shows all possible trajectories that an individual undergoing the process might experience. However, on observing any evidence, certain or uncertain, some edges and nodes become unvisited with probability 1. The CEG model can be reduced such that these edges and nodes are excluded, without any loss of information. Once reduced, the probabilities displayed can be also be revised.

For this example, we will use the falls.xlsx dataset.

from cegpy import StagedTree, ChainEventGraph, ChainEventGraphReducer
import pandas as pd

dataframe = pd.read_excel("falls.xlsx")

staged_tree = StagedTree(dataframe)
staged_tree.calculate_AHC_transitions()

falls_ceg = ChainEventGraph(staged_tree)
falls_ceg.create_figure()
../_images/e94e83032fc47ff652e7cbd097f84ae38d00e0fefdbf9d6890d6862cf0b962e9.png

When examining a dataset with a CEG, you may wish to see a subset of the graph, where some events are excluded with probability zero. Consider the CEG representation of the falls dataset; It may be interesting to split the graph into two graphs, one for individuals on the Communal paths, and another for people on the Community paths. This is achieved by using uncertain evidence. In our case, we know that anyone who is community assessed will have either passed along the Community Not Assessed edge or the Community Assessed edge, which can be done like so:

from cegpy import ChainEventGraphReducer

reducer = ChainEventGraphReducer(falls_ceg)
reducer.add_uncertain_edge_set(
    edge_set={
        ("w0", "w4", "Community Not Assessed"),
        ("w0", "w3", "Community Assessed"),
    }
)
print(reducer)
The evidence you have given is as follows:
 Evidence you are certain of:
   Edges = []
   Nodes = {}
 Evidence you are uncertain of:
   Edges = [
     {('w0', 'w3', 'Community Assessed'), ('w0', 'w4', 'Community Not Assessed')},
   ]
   Nodes = {
   }

The reduced graph is stored in the graph attribute, and is a ChainEventGraph object.

reducer.graph.create_figure()
../_images/f226b1f4458bfeed1b9400c76eb53e3168a76b5c859c3eb92ea61512f0c9a792.png

Likewise, we can do the same for the Communal graph. In this case, it could be simpler to just specify the sub-graph which contains all paths that pass through nodes w1 and w2.

reducer = ChainEventGraphReducer(falls_ceg)
reducer.add_uncertain_node_set({"w1", "w2"})
reducer.graph.create_figure()
../_images/456d759c70baf1c2df9261e80b1234fab6ee25ff368fad0ab4b56582065c6eb9.png

It may also be interesting to see the sub-graph of those Communal individuals who had a Fall.

reducer.add_uncertain_edge_set(
    {
        (u, v, l) 
        for (u, v, l) in reducer.graph.edges 
        if l == "Fall"
    }
)
print(reducer)
The evidence you have given is as follows:
 Evidence you are certain of:
   Edges = []
   Nodes = {}
 Evidence you are uncertain of:
   Edges = [
     {('w8', 'w_infinity', 'Fall'), ('w7', 'w_infinity', 'Fall'), ('w10', 'w_infinity', 'Fall'), ('w9', 'w_infinity', 'Fall')},
   ]
   Nodes = {
     {'w2', 'w1'},
   }

The probabilities are adjusted across all the edges, and back propagated through the graph automatically.

reducer.graph.create_figure()
../_images/4f1501ff353edc538021d5b174e67e36be9c83d17f20d0d7893dcd2df864dabf.png

When you would like to adjust the graph to only show paths which pass through a specific edge or node, certain evidence is used.

Take the following example. You’d like to see what might have happened to an individual who was Communal Assessed. This can be done by using the add_certain_edge method.

reducer.clear_all_evidence()

reducer.add_certain_edge("w0", "w1", "Communal Assessed")
# or reducer.add_certain_node("w1")
reducer.graph.create_figure()
../_images/d2ced0654095bdd28a701841ea908e71b8d0110c28227d5c9593c308eda0569c.png