CausalGraphs.jl: from measurement models to causal graphs

Hello Julia community,

A week ago, I mentioned some work around measurement models and uncertainty analysis in the "What projects have you been working on?" section of Julia Discourse.

Since then, that work has evolved into a more general abstraction for representing cause-effect relationships, which led me to start (a tiny package) named CausalGraphs.jl.

The initial motivation came from measurement models, uncertainty analysis, and Ishikawa (fishbone) diagrams. While working on this, I realized that the causal/dependency structure itself was worth representing as a reusable data model, rather than treating the Ishikawa diagram as the primary object.

So I extracted this part into a dedicated Julia package.

CausalGraphs.jl is intended for building, manipulating, analyzing, and visualizing cause-effect knowledge graphs.

The central idea is to separate:

  • Knowledge: causes, effects, measurements and their relationships
  • Views: Ishikawa/fishbone diagrams, dependency graphs and other visualizations
  • Models: mathematical and measurement models, uncertainty propagation, fault trees, etc.

This separation is important because an Ishikawa diagram is only one possible representation of the underlying structure.

Connecting causal structure and uncertainty

This also connects to another project I’ve been working on: SymbolicUncertainties.jl.

SymbolicUncertainties.jl is not public yet, but I’m making the documentation available while the design evolves.

The two projects are intended to address complementary aspects of the same problem:

              CausalGraphs.jl
                     |
                     | What depends on what?
                     | What are the contributing factors?
                     v
             Mathematical model
                     |
                     | How is the quantity computed?
                     v
          SymbolicUncertainties.jl
                     |
                     | How does uncertainty propagate?
                     | Which inputs dominate the result?
                     v
              Quantitative analysis

For example, an engineering measurement might have a causal structure involving temperature, calibration, sensor characteristics, environmental effects, acquisition noise, etc.

The graph describes how these quantities are related.

A mathematical model then describes how the measured quantity is calculated.

Finally, symbolic uncertainty analysis can describe how uncertainty propagates through that model.

This is one of the directions I’m exploring in relation to the GUM approach to measurement uncertainty.

Why make the graph a first-class object?

One of the things I’m interested in is whether this abstraction could be useful beyond measurement uncertainty.

The same causal/dependency graph could potentially be used for:

  • measurement and uncertainty analysis
  • root-cause analysis
  • reliability engineering
  • machine and system safety
  • fault-tree analysis
  • quality engineering
  • scientific and engineering models
  • sensitivity analysis

For example, an Ishikawa diagram could simply be one view of the graph, while other tools could operate directly on the graph structure.

This also potentially makes it possible to connect qualitative analysis with quantitative models without forcing either side to become the other.

Julia ecosystem

I’d particularly appreciate feedback on how this should fit into the existing Julia ecosystem.

In particular, I’m interested in the relationship with packages such as:

  • Graphs.jl
  • Makie
  • uncertainty quantification tools
  • symbolic modeling
  • reliability and safety analysis

Some questions I’m currently exploring:

  1. Is this separation between causal knowledge, views, and mathematical models a useful abstraction?

  2. Should CausalGraphs.jl build more explicitly on Graphs.jl?

  3. What is the best way to associate a causal/dependency graph with a symbolic mathematical model?

  4. Could this provide a useful bridge between qualitative causal analysis and quantitative uncertainty analysis?

  5. Are there existing Julia projects that already address parts of this problem that I should integrate with?

The project is still at an early stage (and is not registered in Julia General Registry), so I’m particularly interested in architecture and API feedback.

CausalGraphs.jl: GitHub - s-celles/CausalGraphs.jl: Julia package for building, manipulating, and analyzing cause-effect knowledge graphs · GitHub
Documentation: Home · CausalGraphs.jl
SymbolicUncertainties.jl: Home · SymbolicUncertainties.jl
Some rendering examples:

Graphs.bfs_tree(g, s[; dir=:out])

Provide a breadth-first traversal of the graph g starting with source vertex s, and return a directed acyclic graph of vertices in the order they were discovered. If dir is specified, use the corresponding edge direction (:in and :out are acceptable values).

and

DirectedAcyclicGraphs

address aspects of this. Causal inference depends on controlling for confounding and conflcting variable that muddy the waters between causes and effects (there seem always to be multiples of each), See Judiah Pearl’s The Book of Why if you haven’t already.

The separation of casual knowledge, views and mathematical models is core to creating an ontology, to use the current buzzword. It’s not enough to connect the dots (vertices), it’s also necessary to weight the edges, and descending levels of abstraction are needed to make that feasible to overcome the 7±2 register stack that wetware works with.