Skip to main content

PICI -- Partially Identifiable Causal Inference

Table of Contents

  1. About
  2. Usage
  3. Theory
  4. Developer Tools
  5. Acknowledgements

About

PICI stands for Partially Identifiable Causal Inference. It is a causal inference package that can handle discrete Partially Identifiable Queries in Quasi-Markovian Structural Causal Models.

This project was based on the work of João Pedro Arroyo and João Gabriel Rodrigues on GitHub.

Usage

Install and import

  • Install the package.
pip install pici
  • Import the package.
import pici

Causal model creation

  • Create a causal model:
df = pd.read_csv(model_csv_path)
edges = "Z -> X, X -> Y, U1 -> X, U1 -> Y, U2 -> Z"
unobservable_variables = ["U1", "U2"]
custom_cardinalities = {"Z": 5, "X": 2, "Y": 16, "U1": 0, "U2": 0}
interventions=[('X',0)]
target=('Y',0)

model = pici.CausalModel(
  data=df,
  edges=edges,
  custom_cardinalities=custom_cardinalities,
  unobservables_labels=unobservable_variables,
  interventions=interventions,    # Optional in the model creation
  target=target,                  # Optional in the model creation
)
  • You can set the target and interventions:
model.set_interventions([('X', 1)])
model.set_target(('Y', 1))

Interventional query

  • You can make the query:
model.intervention_query()

Or you can pass the target and interventions as arguments:

model.intervention_query([('X', 1)], ('Y', 1))
  • When intervention_query is called, it automatically checks if your query is identifiable or partially identifiable.
  • If your query is identifiable, the return value is a string.
exact_value = model.intervention_query()
  • If your query is partially identifiable, the return value is a tuple of strings.
lower_bound, upper_bound = model.intervention_query()

Identifiability checker

  • You can check if your intervention is identifiable by Backdoor criterion, Frontdoor criterion, or ID algorithm:
edges = "U1 -> X, U1 -> Y, X -> W, W -> Y, U2 -> W"
unobservables_labels=["U1", "U2"]

model = CausalModel(
    data=df,
    edges=edges,
    unobservables_labels=unobservables_labels
)

is_identifiable, identifiable_method, additional_detail = model.is_identifiable_intervention(
    interventions=[("X", 0)], target=("Y", 1)
)

PN and PS approximations

  • You can make PN and PS approximations, which we call weak-pn and weak-ps. These approximations are based on the paper Probabilities of Causation and Root Cause Analysis with Quasi-Markovian Models by Laurentino et al., 2025 (public link soon).

The same way as the intervention_query, if it's identifiable it will return a string otherwise a tuple of strings.

pn_value = model.weak_pn_inference(intervention_label='X', target_label='Y')
ps_value = model.weak_ps_inference(intervention_label='X', target_label='Y')

Theory behind

If you want to understand the theory behind our approach, you can read the paper Arroyo et al., 2025.

Developer tools

All development tools are managed with Poetry.
To get started, install Poetry by following the official instructions, then activate the virtual environment.

Install

  • Install dependencies. Once you have installed Poetry, you can install the required packages:
poetry install

Virtual Environment

Activate the virtual environment:

  • Activate the Poetry virtual environment
eval $(poetry env activate)
  • To exit the Poetry virtual environment, run:
deactivate

Running Examples

Example:

python3 examples/example.py
  • You also can run unit tests:
python3 tests/run_all_tests.py

Linters

This project uses some linters to follow a code standardization that improves code consistency and cleanliness.

Ruff

This project uses Ruff to remove unused imports and sort them.

Usage example for a file:

ruff check your_file.py --fix -s

For all files in the current directory and sub-directories:

ruff check . --fix -s

Running this command will make changes automatically. We suggest using the flag -s to silence the numerous print logs.

Black

This project uses Black for automatic Python code formatting. Black is a code formatter that ensures consistency by enforcing a uniform style.

Usage example for a file:

black your_file.py

For all files in the current directory and sub-directories:

black .

Running this command will change automatically.

Acknowledgements

We thank the ICTi, Instituto de Ciência e Tecnologia Itaú, for providing key funding for this work through C2D - Centro de Ciência de Dados at Universidade de São Paulo.

Any opinions, findings, conclusions or recommendations expressed in this material are those of the authors and do not necessarily reflect the views of Itaú Unibanco and Instituto de Ciência e Tecnologia Itaú. All data used in this study comply with the Brazilian General Data Protection Law.

Release files for pici 0.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for pici 0.0.2
File Interpreter ABI Platform
pici-0.0.2-py3-none-any.whl Python 3 none any Details

Release files / pici-0.0.2-py3-none-any.whl

Download URL pici-0.0.2-py3-none-any.whl
Size 37.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
aa257051b4b91893a65e19ffa16a92f4aa5274fd212b225ddded5e8077858173
BLAKE2b-256 checksum
How to use checksums
7689eef0dc6a728753eef6beda0a9e56283e7c3b04e23cfae9cfd8a42f0d4c55
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.10.12

Release history Release notifications | RSS feed

This release

0.0.2 This release

1 release file

0.0.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page