Adjustment Identification Distance: A ๐๐๐๐๐๐ for Causal Structure Learning
This is an early release of ๐๐๐๐๐๐ ๐ฅ and feedback is very welcome! Just open an issue on github.
If you publish research using ๐๐๐๐๐๐, please cite our article
@article{henckel2024adjustment,
title = {{Adjustment Identification Distance: A gadjid for Causal Structure Learning}},
author = {Leonard Henckel and Theo Wรผrtzen and Sebastian Weichwald},
journal = {{arXiv preprint arXiv:2402.08616}},
year = {2024},
doi = {10.48550/arXiv.2402.08616},
}
Get Started Real Quick ๐ โ Introductory Example
Just pip install gadjid to install the latest release of ๐๐๐๐๐๐
and run python -c "import gadjid; help(gadjid)" to get started
(or see install alternatives).
import gadjid
from gadjid import example, ancestor_aid, oset_aid, parent_aid, shd
import numpy as np
help(gadjid)
example.run_parent_aid()
Gtrue = np.array([
[0, 1, 1, 1, 1],
[0, 0, 1, 1, 1],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]
], dtype=np.int8)
Gguess = np.array([
[0, 0, 1, 1, 1],
[1, 0, 1, 1, 1],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]
], dtype=np.int8)
print(ancestor_aid(Gtrue, Gguess, edge_direction="from row to column"))
print(shd(Gtrue, Gguess))
๐๐๐๐๐๐ is implemented in Rust and can conveniently be called from Python via our Python wrapper (implemented using maturin and PyO3).
Evaluating graphs learned by causal discovery algorithms is difficult: The number of edges that differ between two graphs does not reflect how the graphs differ with respect to the identifying formulas they suggest for causal effects. We introduce a framework for developing causal distances between graphs which includes the structural intervention distance for directed acyclic graphs as a special case. We use this framework to develop improved adjustment-based distances as well as extensions to completed partially directed acyclic graphs and causal orders. We develop new reachability algorithms to compute the distances efficiently and to prove their low polynomial time complexity. In our package gadjid, we provide implementations of our distances; they are orders of magnitude faster with proven lower time complexity than the structural intervention distance and thereby provide a success metric for causal discovery that scales to graph sizes that were previously prohibitive.
Parallelism โ setting the number of threads
๐๐๐๐๐๐ uses rayon for parallelism
using, per default, as many threads as there are physical CPU cores.
The number of threads to use can be set via the environment variable RAYON_NUM_THREADS.
We recommend to do so and to set the number of threads manually,
not least to be explicit and to avoid the small runtime overhead for determining the number of physical CPU cores.
Implemented Distances
ancestor_aid(Gtrue, Gguess, edge_direction)oset_aid(Gtrue, Gguess, edge_direction)parent_aid(Gtrue, Gguess, edge_direction)- for convenience, the following distances are implemented, too
shd(Gtrue, Gguess)sid(Gtrue, Gguess, edge_direction)โ only for DAGs!
where Gtrue and Gguess are adjacency matrices of a DAG or CPDAG
and edge_direction determines whether a 1 at r-th row and c-th column of an adjacency matrix
codes the edge r โ c (edge_direction="from row to column") or c โ r (edge_direction="from column to row").
The functions are not symmetric in their inputs:
To calculate a distance,
identifying formulas for causal effects are inferred in the graph Gguess
and verified against the graph Gtrue.
Distances return a tuple (normalised_distance, mistake_count)
of the fraction of causal effects inferred in Gguess that are wrong relative to Gtrue, normalised_distance,
and the number of wrongly inferred causal effects, mistake_count.
There are $p(p-1)$ pairwise causal effects to infer in graphs with $p$ nodes
and we define normalisation as normalised_distance = mistake_count / p(p-1).
You may also calculate the SID between DAGs via parent_aid(DAGtrue, DAGguess, edge_direction),
but we recommend ancestor_aid and oset_aid and for CPDAG inputs the parent_aid does not coincide with the SID
(see also our accompanying article).
If edge_direction="from row to column", then
a 1 in row r and column c codes a directed edge r โ c;
if edge_direction="from column to row", then
a 1 in row r and column c codes a directed edge c โ r;
for either setting of edge_direction,
a 2 in row r and column c codes an undirected edge r โ c
(an additional 2 in row c and column r is ignored;
one of the two entries is sufficient to code an undirected edge).
An adjacency matrix for a DAG may only contain 0s and 1s. An adjacency matrix for a CPDAG may only contain 0s, 1s and 2s. DAG and CPDAG inputs are validated for acyclicity. However, for CPDAG inputs, the user needs to ensure the adjacency matrix indeed codes a valid CPDAG (instead of just a PDAG).
Empirical Runtime Analysis
Experiments run on a laptop with 8 GB RAM and 4-core i5-8365U processor. Here, for a graph with $p$ nodes, sparse graphs have $10p$ edges in expectation, dense graphs have $0.3p(p-1)/2$ edges in expectation, and x-sparse graphs have $0.75p$ edges in expectation.
Maximum graph size feasible within 1 minute
| Method | sparse | dense |
|---|---|---|
| Parent-AID | 13601 | 962 |
| Ancestor-AID | 8211 | 932 |
| Oset-AID | 1105 | 508 |
| SID in R | 256 | 239 |
Results obtained with ๐๐๐๐๐๐ v0.1.0 using the Python interface and the SID R package v1.1 from CRAN.
Average runtime
| Method | x-sparse ($p=1000$) | sparse ($p=256$) | dense ($p=239$) |
|---|---|---|---|
| Parent-AID | 7.3 ms | 30.5 ms | 173 ms |
| Ancestor-AID | 3.4 ms | 40.9 ms | 207 ms |
| Oset-AID | 5.0 ms | 567 ms | 1.68 s |
| SID in R | ~1โ2 h | ~60 s | ~60 s |
Results obtained with ๐๐๐๐๐๐ v0.1.0 using the Python interface and the SID R package v1.1 from CRAN.
LICENSE
๐๐๐๐๐๐ is available in source code form at https://github.com/CausalDisco/gadjid.
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
See also the MPL-2.0 FAQ.
Release files for gadjid 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| gadjid-0.1.0.tar.gz | 45.5 kB | Details |
Built distributions (wheels)
Total release size: 6.2 MB
Release files / gadjid-0.1.0.tar.gz
| Download URL | gadjid-0.1.0.tar.gz |
|---|---|
| Size | 45.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3a74c07960ee92b42ffc342dfd25a3c48cbbc2a375881401f83b223a8af93959
|
|
BLAKE2b-256 checksum How to use checksums |
fedbf85da1d0aeaf34d3c5ff00485c35f359cc96c4ca9263e42b1a4fc10a55f9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|
Release files / gadjid-0.1.0-pp310-pypy310_pp73-win_amd64.whl
| Download URL | gadjid-0.1.0-pp310-pypy310_pp73-win_amd64.whl |
|---|---|
| Size | 230.8 kB |
| Tags | PyPy 3.10 PyPy 3.10 7.3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
98e9491e54238ed0199b012223cbbbf7ec9d052ab92be1f4b718c6047b4c6639
|
|
BLAKE2b-256 checksum How to use checksums |
d34c10529ef353f4e10201fe275603f65c91e90dba1bdf691637ac4f79ceffc5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|
Release files / gadjid-0.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | gadjid-0.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 368.9 kB |
| Tags | Linux glibc 2.17+ x86-64 PyPy 3.10 PyPy 3.10 7.3 |
|
SHA-256 checksum How to use checksums |
0957e4f563ad915ec92b86b0ef7a3e9a4729275900de0e2d49a1a5106cc86553
|
|
BLAKE2b-256 checksum How to use checksums |
a6b703786cbf7b835a30dc1e1d84735969f517a3d47efe7ad3e5f8957581e66a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|
Release files / gadjid-0.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | gadjid-0.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 370.8 kB |
| Tags | Linux glibc 2.17+ ARM64 PyPy 3.10 PyPy 3.10 7.3 |
|
SHA-256 checksum How to use checksums |
233f0938afeb3221a304984e8d42724f98bd8663ef149d9b6b2c88ac62e077b5
|
|
BLAKE2b-256 checksum How to use checksums |
24ebacf7474953b28ca5e4bb9b145daee2385914100d98c8c67b28c683bf9a2f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|
Release files / gadjid-0.1.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl
| Download URL | gadjid-0.1.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl |
|---|---|
| Size | 310.2 kB |
| Tags | PyPy 3.10 PyPy 3.10 7.3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
b26dee51744893bc9b62549f40fbdf62d7458652d8eb3c030ffc5dd74929a0b6
|
|
BLAKE2b-256 checksum How to use checksums |
856c460fd1ebe9996d56d00781c774cbf8cd84a8bc8a0e7c8ccf63edb6044337
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|
Release files / gadjid-0.1.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl
| Download URL | gadjid-0.1.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl |
|---|---|
| Size | 324.4 kB |
| Tags | PyPy 3.10 PyPy 3.10 7.3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
49ec4c724b05d8ad1eb55d405734a87e025147289f2d92499de0312a0a5831a3
|
|
BLAKE2b-256 checksum How to use checksums |
0d644871e4215c8f3a1656c5a88b295a59330589b12d672577c4c6cf15251d6e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|
Release files / gadjid-0.1.0-pp39-pypy39_pp73-win_amd64.whl
| Download URL | gadjid-0.1.0-pp39-pypy39_pp73-win_amd64.whl |
|---|---|
| Size | 230.8 kB |
| Tags | PyPy 3.9 PyPy 3.9 7.3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
f70c8d9f372f779d89c1677ebc32ff09cfde71451a0fb448b319b2beaef61df3
|
|
BLAKE2b-256 checksum How to use checksums |
c1ddced718adf6558d5230c3eb10287d1c30d022b8465303948e3b5f9b290492
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|
Release files / gadjid-0.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | gadjid-0.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 368.9 kB |
| Tags | Linux glibc 2.17+ x86-64 PyPy 3.9 PyPy 3.9 7.3 |
|
SHA-256 checksum How to use checksums |
aebb0c97e2062619b7967a54913f75d44facf678de2e5b69ce5803198932f0eb
|
|
BLAKE2b-256 checksum How to use checksums |
bb6ae40aa34237ee47ca114aaed3ec1b9eb8dcf5038273a0d549f0d24dcde57e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|
Release files / gadjid-0.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | gadjid-0.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 370.8 kB |
| Tags | Linux glibc 2.17+ ARM64 PyPy 3.9 PyPy 3.9 7.3 |
|
SHA-256 checksum How to use checksums |
ba289c6db73e0347978609475dbf6d655afb1153793a69e745e55f2f142402ae
|
|
BLAKE2b-256 checksum How to use checksums |
9b6c7e23a5bf5851966aad69a8bd69d05bc2d9f656011627eb67957fc1ca2390
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|
Release files / gadjid-0.1.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl
| Download URL | gadjid-0.1.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl |
|---|---|
| Size | 310.2 kB |
| Tags | PyPy 3.9 PyPy 3.9 7.3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
3bce721d9de32fec20821e3d3cd5d342324ba72e395caf3dcb6eab0b6780458c
|
|
BLAKE2b-256 checksum How to use checksums |
d896bd24333ac74e013048c1b0dd07599b3cee16c8e03e9c3b578a4d220b40f6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|
Release files / gadjid-0.1.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl
| Download URL | gadjid-0.1.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl |
|---|---|
| Size | 324.4 kB |
| Tags | PyPy 3.9 PyPy 3.9 7.3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
10ca98e04f129c6410eb7620edf7cbdd46637e53844084bf5e428284ae854416
|
|
BLAKE2b-256 checksum How to use checksums |
fbd136cc0822e63e75a2050e0d220124212d02493348ce3d19f24f1bc9e0ffbd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|
Release files / gadjid-0.1.0-cp38-abi3-win_arm64.whl
| Download URL | gadjid-0.1.0-cp38-abi3-win_arm64.whl |
|---|---|
| Size | 220.1 kB |
| Tags | CPython 3.8 Windows ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
1f45ff3032f7e80b04cd83bace38c4dad935ae7ae0dc52271a4e91d1b397a162
|
|
BLAKE2b-256 checksum How to use checksums |
a500864fef364c43cfa2690f7eb093a254bb17ceb3eb213a8642b8404e0e4dea
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|
Release files / gadjid-0.1.0-cp38-abi3-win_amd64.whl
| Download URL | gadjid-0.1.0-cp38-abi3-win_amd64.whl |
|---|---|
| Size | 232.2 kB |
| Tags | CPython 3.8 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
551e132268ffac3215c920032112ace7ed39436f369e170e43fa126d694486c8
|
|
BLAKE2b-256 checksum How to use checksums |
07e1f27eb262ebc05837202d40d6dc93853649d03ffcc57272d64207c7d93608
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|
Release files / gadjid-0.1.0-cp38-abi3-musllinux_1_1_x86_64.whl
| Download URL | gadjid-0.1.0-cp38-abi3-musllinux_1_1_x86_64.whl |
|---|---|
| Size | 539.3 kB |
| Tags | CPython 3.8 Linux musl 1.1+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
d9310080a90fc4aaded93d081023b5bb9080590c0df24c66439cda178d003288
|
|
BLAKE2b-256 checksum How to use checksums |
aed2a851c5f685d6f61a445a44f5019076a3f77c0070dbd3a2c9b76e6eba2e15
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|
Release files / gadjid-0.1.0-cp38-abi3-musllinux_1_1_aarch64.whl
| Download URL | gadjid-0.1.0-cp38-abi3-musllinux_1_1_aarch64.whl |
|---|---|
| Size | 549.3 kB |
| Tags | CPython 3.8 Linux musl 1.1+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
936513302decb33831d9403d7d21f0dc1f995d739ddc1e1984960c35e1737d2e
|
|
BLAKE2b-256 checksum How to use checksums |
a389bf47e9ac904b96fd9a2920084928de77fc134ee5fbcada281b6a6cf573e4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|
Release files / gadjid-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | gadjid-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 369.4 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
3d734b47d544a466b16f0a64370d28df771e8d86e9ab074f3aae40fb19a13689
|
|
BLAKE2b-256 checksum How to use checksums |
ccea0bfd2c3211fad72934dc70e6d899f9aa74d728d19d3f1eb2d7256e9ec74b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|
Release files / gadjid-0.1.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | gadjid-0.1.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 371.4 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
ffa49fe6fd891f1200d4d07ed6a6475ba485c1f28a3e78a8e59201687471dc75
|
|
BLAKE2b-256 checksum How to use checksums |
81dc87938a5abe33c557d57cbd5804b35c76e42ebefcaaf3f77dee09da3fa4f7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|
Release files / gadjid-0.1.0-cp38-abi3-macosx_11_0_arm64.whl
| Download URL | gadjid-0.1.0-cp38-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 311.1 kB |
| Tags | CPython 3.8 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
18c70e77af471c7d885c9e721b1755065733c82602fc897fcdb981e0e92f0752
|
|
BLAKE2b-256 checksum How to use checksums |
32daf863cefd025484f242b292d9d70d85bbdd3af027ad3681aa50c80009597b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|
Release files / gadjid-0.1.0-cp38-abi3-macosx_10_12_x86_64.whl
| Download URL | gadjid-0.1.0-cp38-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 324.7 kB |
| Tags | CPython 3.8 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
fc237ad67c4bef18752700b861c3e47346b64579f132b33e4ea9504d60378ca7
|
|
BLAKE2b-256 checksum How to use checksums |
1618e0f14798a1fb70b1c001f7c76e38a529af2c75d5ee693a05596d281848a8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.7.0
|