{"id":31108710,"url":"https://github.com/phlippe/ENCO","last_synced_at":"2025-09-17T06:45:34.399Z","repository":{"id":40512377,"uuid":"388067459","full_name":"phlippe/ENCO","owner":"phlippe","description":"Official repository of the paper \"Efficient Neural Causal Discovery without Acyclicity Constraints\"","archived":false,"fork":false,"pushed_at":"2022-11-12T08:45:12.000Z","size":125,"stargazers_count":54,"open_issues_count":0,"forks_count":10,"subscribers_count":2,"default_branch":"main","last_synced_at":"2023-03-05T04:35:35.049Z","etag":null,"topics":["causal-discovery","causality","pytorch","structure-learning"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phlippe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-07-21T09:40:14.000Z","updated_at":"2023-01-10T22:03:47.000Z","dependencies_parsed_at":"2023-01-23T16:15:57.773Z","dependency_job_id":null,"html_url":"https://github.com/phlippe/ENCO","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"purl":"pkg:github/phlippe/ENCO","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phlippe%2FENCO","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phlippe%2FENCO/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phlippe%2FENCO/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phlippe%2FENCO/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phlippe","download_url":"https://codeload.github.com/phlippe/ENCO/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phlippe%2FENCO/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275548988,"owners_count":25484678,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-17T02:00:09.119Z","response_time":84,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["causal-discovery","causality","pytorch","structure-learning"],"created_at":"2025-09-17T06:45:23.287Z","updated_at":"2025-09-17T06:45:34.380Z","avatar_url":"https://github.com/phlippe.png","language":"Python","funding_links":[],"categories":["🚀 GitHub Repositories"],"sub_categories":["🌟 **Real-World Magic**"],"readme":"# Efficient Neural Causal Discovery without Acyclicity Constraints\n\n[Short paper](https://phlippe.github.io/media/ENCO_CausalUAI_Camera_Ready.pdf) | [Long paper](https://arxiv.org/pdf/2107.10483.pdf) | [Poster](https://phlippe.github.io/media/ENCO_Poster.pdf) | [Tutorial ![Open filled In Collab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/phlippe/ENCO/blob/main/walkthrough.ipynb) \n\nThis is the official repository of the paper **Efficient Neural Causal Discovery without Acyclicity Constraints** by Phillip Lippe, Taco Cohen, and Efstratios Gavves. *Presented at the International Conference on Learning Representations (ICLR), 2022.*\n\n## Paper summary\n\n\u003ccenter\u003e\u003cimg src=\"ENCO_figure.svg\" width=\"800px\"\u003e\u003c/center\u003e\n\nLearning the structure of a causal graphical model using both observational and interventional data is a fundamental problem in many scientific fields.\nA promising direction is continuous optimization for score-based methods, which efficiently learn the causal graph in a data-driven manner.\nHowever, to date, those methods require slow constrained optimization to enforce acyclicity or lack convergence guarantees.\nIn this work, we present ENCO, an efficient structure learning method leveraging observational and interventional data.\nENCO formulates the graph search as an optimization of independent edge likelihoods with the edge orientation being modeled as a separate parameter.\nConsequently, we can provide convergence guarantees of ENCO under mild conditions without constraining the score function with respect to acyclicity.\nIn experiments, we show that ENCO handles various graph settings well, and even recovers graphs with up to 1,000 nodes in less than nine hours of compute using a single GPU (NVIDIA RTX3090) while having less than one mistake on average out of 1 million possible edges.\nFurther, ENCO can handle and detect latent confounders.\n\n## Requirements\n\nThe code is written in PyTorch (1.9) and Python 3.8. Higher versions of PyTorch and Python are expected to work as well.\n\nWe recommend to use conda for installing the requirements. If you haven't installed conda yet, you can find instructions [here](https://www.anaconda.com/products/individual). The steps for installing the requirements are:\n\n1. Create a new environment from the provided YAML file:\n   ```setup\n   conda env create -f environment.yml\n   ```\n   The environment installs PyTorch with CUDA 11.1. Adjust the CUDA version if you want to install it with CUDA 10.2, or remove it from the environment file if you want to install it on a CPU-only system.\n   \n2. Activate the environment\n   ```setup\n   conda activate enco\n   ```\n\n### Datasets\n\nTo reproduce the experiments in the paper, we provide datasets of causal graphs for the synthetic, confounder, and real-world experiments. The datasets can be download by executing `download_datasets.sh` (requires approx. 600MB disk space). Alternatively, the datasets can be accessed through [this link](https://drive.google.com/file/d/1mJXJpvkG8Ol4w6QlbzW4EETjpXmHPlMX/view?usp=sharing) (unzip the file in the `causal_graphs` folder).\n\n## Running experiments\n\nThe repository is structured in three main folders:\n* `causal_graphs` contains all utilities for creating, visualizing and handling causal graphs that we experiment on.\n* `causal_discovery` contains the code of ENCO for structure learning.\n* `experiments` contains all utilities to run experiments with ENCO on various causal graphs.\n\nDetails on running experiments as well as the commands for reproducing the experiments in the paper can be found in the [`experiments`](experiments/) folder.\n\n### Simple example\n\nWe created a quick walkthrough tutorial that goes through the most important functions/components in the repository in [`walkthrough.ipynb`](walkthrough.ipynb). In short, ENCO can be applied as follows:\n\n```python\nfrom causal_graphs.graph_generation import generate_categorical_graph, get_graph_func  # Functions for generating new graphs\nfrom causal_discovery.enco import ENCO\n\n# Create a graph on which ENCO should be applied\ngraph = generate_categorical_graph(num_vars=8, \n                                   min_categs=10,\n                                   max_categs=10,\n                                   graph_func=get_graph_func('random'),\n                                   edge_prob=0.4,\n                                   seed=42)\n\n# Create ENCO object\nenco_module = ENCO(graph=graph)\nif torch.cuda.is_available():\n    enco_module.to(torch.device('cuda:0'))\n\n# Run causal discovery\npredicted_adj_matrix = enco_module.discover_graph(num_epochs=10)\n```\n\n## FAQ\n\n\u003cdetails\u003e\n\u003csummary\u003eHow is the repository structured?\u003c/summary\u003e\n\u003cbr\u003e\n\nWe give a quick walkthrough of the most important functions/components in the repository in [`walkthrough.ipynb`](walkthrough.ipynb).  \n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eCan I also run the experiments on my CPU?\u003c/summary\u003e\n\u003cbr\u003e\n\nYes, a GPU is not a strict constraint to run ENCO. Especially for small graphs (about 10 variables), ENCO is similarly fast on a multi-core CPU than on a GPU. To speed up experiments for small graphs on a CPU, it is recommended to reduce the hidden size from `64` to `32`, and the graph samples in graph fitting from `100` to `20`.  \n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eHow can I apply ENCO to my own dataset?\u003c/summary\u003e\n\u003cbr\u003e\n\nIf your causal graph/dataset is specified in a `.bif` format as the real-world graphs, you can directly start an experiment on it using `experiments/run_exported_graphs.py`. The alternative format is a `.npz` file which contains a observational and interventional dataset. The file needs to contain the following keys:\n   \n* `data_obs`: A dataset of observational samples. This array must be of shape [M, num_vars] where M is the number of data points. For categorical data, it should be any integer data type (e.g. np.int32 or np.uint8).\n* `data_int`: A dataset of interventional samples. This array must be of shape [num_vars, K, num_vars] where K is the number of data points per intervention. The first axis indicates the variables on which has been intervened to gain this dataset.\n* `adj_matrix`: The ground truth adjacency matrix of the graph (shape [num_vars, num_vars], type bool or integer). The matrix is used to determine metrics like SHD during/after training. If the ground truth matrix is not known, you can submit a zero-matrix (keep in mind that the metrics cannot be used in this case).\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eCan I apply ENCO to continuous or categorical data?\u003c/summary\u003e\n\u003cbr\u003e\n\nBoth data types are supported in this repository. Simply make sure that the numpy array has the data type `np.float32` for continuous experiments, and `np.uint8` or `np.int32` for categorical data.  \n\n\u003c/details\u003e\n\n## Citation\nIf you use this code, please consider citing our work:\n```bibtex\n@inproceedings{lippe2022enco,\n author = {Lippe, Phillip and Cohen, Taco and Gavves, Efstratios},\n booktitle = {International Conference on Learning Representations},\n title = {Efficient Neural Causal Discovery without Acyclicity Constraints},\n url = {https://openreview.net/forum?id=eYciPrLuUhG},\n year = {2022}\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphlippe%2FENCO","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphlippe%2FENCO","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphlippe%2FENCO/lists"}