{"id":25215616,"url":"https://github.com/deezer/gravity_graph_autoencoders","last_synced_at":"2025-10-25T14:31:25.109Z","repository":{"id":69995914,"uuid":"205351876","full_name":"deezer/gravity_graph_autoencoders","owner":"deezer","description":"Source code from the CIKM 2019 article \"Gravity-Inspired Graph Autoencoders for Directed Link Prediction\" by G. Salha, S. Limnios, R. Hennequin, V.A. Tran and M. Vazirgiannis","archived":false,"fork":false,"pushed_at":"2023-12-14T10:13:19.000Z","size":5253,"stargazers_count":42,"open_issues_count":0,"forks_count":10,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-04-16T11:27:17.454Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/deezer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-08-30T09:38:01.000Z","updated_at":"2024-02-09T02:00:07.000Z","dependencies_parsed_at":"2023-03-11T07:41:37.618Z","dependency_job_id":null,"html_url":"https://github.com/deezer/gravity_graph_autoencoders","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deezer%2Fgravity_graph_autoencoders","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deezer%2Fgravity_graph_autoencoders/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deezer%2Fgravity_graph_autoencoders/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deezer%2Fgravity_graph_autoencoders/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/deezer","download_url":"https://codeload.github.com/deezer/gravity_graph_autoencoders/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238161490,"owners_count":19426669,"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","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":[],"created_at":"2025-02-10T18:15:09.283Z","updated_at":"2025-10-25T14:31:19.299Z","avatar_url":"https://github.com/deezer.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Gravity-Inspired Graph Autoencoders for Directed Link Prediction\n\nThis repository provides Python code to reproduce experiments from the article [Gravity-Inspired Graph Autoencoders for Directed Link Prediction](https://arxiv.org/pdf/1905.09570.pdf) published in the proceedings of the 28th ACM International Conference on Information and Knowledge Management (CIKM 2019).\n\nWe release Tensorflow implementations of the following **four directed graph embedding models** from the paper:\n - *Gravity-Inspired Graph Autoencoders*\n - *Gravity-Inspired Graph Variational Autoencoders*\n - *Source-Target Graph Autoencoders*\n - *Source-Target Graph Variational Autoencoders*\n\ntogether with standard *Graph Autoencoders (AE)* and *Graph Variational Autoencoders (VAE)* models from [Kipf and Welling (2016)](https://arxiv.org/pdf/1611.07308.pdf). \n\nWe evaluate all six models on the **three directed link prediction tasks** introduced in section 4.1 of our paper:\n- *General Directed Link Prediction*\n- *Biased Negative Samples Directed Link Prediction*\n- *Bidirectionality Prediction*\n\nOur code builds upon Thomas Kipf's [original Tensorflow implementation](https://github.com/tkipf/gae) of standard Graph AE/VAE.\n\n**Note (December 2023):** Kudos to [Claudio Moroni](https://github.com/ClaudMor) for developing a PyTorch implementation of these models, [publicly available here](https://github.com/ClaudMor/gravity_gae_torch_geometric).\n\n\u003cbr\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg height=\"550\" src=\"graph_visu_cora.png\"\u003e\n\u003c/p\u003e\n\n## Installation\n\n```bash\npython setup.py install\n```\n\nRequirements: tensorflow (1.x), networkx, numpy, scikit-learn, scipy\n\n\n## Run Experiments\n\n```bash\ncd gravity_gae\npython train.py --model=gcn_vae --dataset=cora --task=task_1\npython train.py --model=gravity_gcn_vae --dataset=cora --task=task_1\n```\n\nThe above commands will train a *Graph VAE (line 2)* and a *Gravity-Inspired Graph VAE (line 3)* on *Cora dataset* and will evaluate node embdeddings on *Task 1: General Directed Link Prediction*, with all parameters set to default values.\n\n#### Complete list of parameters\n\n\n| Parameter        | Type           | Description  | Default Value |\n| :-------------: |:-------------:| :-------------------------------|:-------------: |\n| `model`     | string | Name of the model, among:\u003cbr\u003e - `gcn_ae`: Graph AE from Kipf and Welling (2016), with 2-layer\u003cbr\u003e GCN encoder and inner product decoder\u003cbr\u003e - `gcn_vae`: Graph VAE from Kipf and Welling (2016), with Gaussian \u003cbr\u003e distributions, 2-layer GCN encoders and inner product decoder\u003cbr\u003e - `source_target_gcn_ae`: Source-Target Graph AE, as introduced \u003cbr\u003e in section 2.6 of paper, with 2-layer GCN encoder and asymmetric inner product decoder \u003cbr\u003e - `source_target_gcn_vae`: Source-Target Graph VAE, as introduced \u003cbr\u003e in section 2.6, with Gaussian distributions, 2-layer GCN encoders and asymmetric inner product\u003cbr\u003e - `gravity_gcn_ae`: Gravity-Inspired Graph AE, as introduced in \u003cbr\u003e section 3.3 of paper, with 2-layer GCN encoder and  gravity-inspired asymmetric decoder \u003cbr\u003e - `gravity_gcn_vae`: Gravity-Inspired Graph VAE, as introduced in \u003cbr\u003e section 3.4 of paper, with Gaussian distributions, 2-layer GCN encoders and gravity-inspired decoder| `gcn_ae` |\n| `dataset`    | string      | Name of the dataset, among:\u003cbr\u003e - `cora`: scientific publications citation network, from [LINQS](https://linqs.soe.ucsc.edu/data) \u003cbr\u003e - `citeseer`: scientific publications citation network, from [LINQS](https://linqs.soe.ucsc.edu/data) \u003cbr\u003e - `google`: hyperlink network from web pages, from [KONECT](http://konect.uni-koblenz.de/networks/) \u003cbr\u003e \u003cbr\u003e Note: you can specify any additional graph dataset, in *edgelist* format,\u003cbr\u003e by editing `input_data.py`| `cora`|\n| `task` | string |Name of the link prediction evaluation task, among: \u003cbr\u003e - `task_1`: General Directed Link Prediction \u003cbr\u003e - `task_2`: Biased Negative Samples Directed Link Prediction \u003cbr\u003e - `task_3`: Bidirectionality Prediction| `task_1`|\n| `dropout`| float | Dropout rate | `0.` |\n| `epoch`| int | Number of epochs in model training | `200` |\n| `features`| boolean | Include node features or not in GCN encoder | `False` |\n| `lamb`| float | \"Lambda\" parameter from Gravity AE/VAE models as introduced in \u003cbr\u003e section 3.5 of paper, to balance mass and proximity terms' | `1.` |\n| `learning_rate`| float | Initial learning rate (with Adam optimizer) | `0.1` |\n| `hidden`| int | Number of units in GCN encoder hidden layer | `64` |\n| `dimension`| int | Dimension of GCN output. It is: \u003cbr\u003e - equal to embedding dimension for standard AE/VAE \u003cbr\u003e and Source-Target AE/VAE models \u003cbr\u003e - equal to (embedding dimension - 1) for gravity-inspired AE/VAE \u003cbr\u003e models, as the last dimension captures the \"mass\" parameter \u003cbr\u003e \u003cbr\u003e Dimension must be *even* for Source-Target AE/VAE model | `32` |\n| `normalize`| boolean | For Gravity models: whether to normalize embedding vectors | `False`|\n| `epsilon`| float | For Gravity models: add epsilon to L2 distances computations, for numerical stability | `0.01`|\n| `nb_run`| integer | Number of model runs + tests | `1` |\n| `prop_val`| float | Proportion of edges in validation set (for Task 1) | `5.` |\n| `prop_test`| float | Proportion of edges in test set (for Tasks 1, 2) | `10.` |\n| `validation`| boolean | Whether to report validation results  at each epoch (for Task 1) | `False` |\n| `verbose`| boolean | Whether to print full comments details | `True` |\n\n#### Models from the paper\n\n**Cora** - Task 1\n\n```Bash\npython train.py --dataset=cora --model=gcn_vae --task=task_1 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=cora --model=gcn_ae --task=task_1 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=cora --model=source_target_gcn_vae --task=task_1 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=cora --model=source_target_gcn_ae --task=task_1 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=cora --model=gravity_gcn_vae --task=task_1 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=33 --lamb=1.0 --nb_run=5\npython train.py --dataset=cora --model=gravity_gcn_ae --task=task_1 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=33 --lamb=1.0 --nb_run=5\n```\n\n**Cora** - Task 2\n\n```Bash\npython train.py --dataset=cora --model=gcn_vae --task=task_2 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=cora --model=gcn_ae --task=task_2 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=cora --model=source_target_gcn_vae --task=task_2 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=cora --model=source_target_gcn_ae --task=task_2 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=64 --nb_run=5\npython train.py --dataset=cora --model=gravity_gcn_vae --task=task_2 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=33 --lamb=0.05 --nb_run=5\npython train.py --dataset=cora --model=gravity_gcn_ae --task=task_2 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=33 --lamb=0.05 --normalize=True --nb_run=5\n```\n**Cora** - Task 3\n\n```Bash\npython train.py --dataset=cora --model=gcn_vae --task=task_3 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=cora --model=gcn_ae --task=task_3 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=cora --model=source_target_gcn_vae --task=task_3 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=cora --model=source_target_gcn_ae --task=task_3 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=cora --model=gravity_gcn_vae --task=task_3 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=33 --lamb=1.0 --nb_run=5\npython train.py --dataset=cora --model=gravity_gcn_ae --task=task_3 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=33 --lamb=1.0 --nb_run=5\n```\n\n**Citeseer** - Task 1\n\n```Bash\npython train.py --dataset=citeseer --model=gcn_vae --task=task_1 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=citeseer --model=gcn_ae --task=task_1 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=citeseer --model=source_target_gcn_vae --task=task_1 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=citeseer --model=source_target_gcn_ae --task=task_1 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=citeseer --model=gravity_gcn_vae --task=task_1 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=33 --lamb=1.0 --nb_run=5\npython train.py --dataset=citeseer --model=gravity_gcn_ae --task=task_1 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=33 --lamb=1.0 --nb_run=5\n```\n\n**Citeseer** - Task 2\n\n```Bash\npython train.py --dataset=citeseer --model=gcn_vae --task=task_2 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=citeseer --model=gcn_ae --task=task_2 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=citeseer --model=source_target_gcn_vae --task=task_2 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=citeseer --model=source_target_gcn_ae --task=task_2 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=citeseer --model=gravity_gcn_vae --task=task_2 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=33 --lamb=0.05 --nb_run=5\npython train.py --dataset=citeseer --model=gravity_gcn_ae --task=task_2 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=33 --lamb=0.05 --normalize=True --nb_run=5\n```\n**Citeseer** - Task 3\n\n```Bash\npython train.py --dataset=citeseer --model=gcn_vae --task=task_3 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=citeseer --model=gcn_ae --task=task_3 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=citeseer --model=source_target_gcn_vae --task=task_3 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=citeseer --model=source_target_gcn_ae --task=task_3 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=citeseer --model=gravity_gcn_vae --task=task_3 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=33 --lamb=1.0 --nb_run=5\npython train.py --dataset=citeseer --model=gravity_gcn_ae --task=task_3 --epochs=200 --learning_rate=0.1 --hidden=64 --dimension=33 --lamb=1.0 --nb_run=5\n```\n\n**Google** - Task 1\n\n```Bash\npython train.py --dataset=google --model=gcn_vae --task=task_1 --epochs=200 --learning_rate=0.2 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=google --model=gcn_ae --task=task_1 --epochs=200 --learning_rate=0.2 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=google --model=source_target_gcn_vae --task=task_1 --epochs=200 --learning_rate=0.2 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=google --model=source_target_gcn_ae --task=task_1 --epochs=200 --learning_rate=0.2 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=google --model=gravity_gcn_vae --task=task_1 --epochs=200 --learning_rate=0.2 --hidden=64 --dimension=33 --lamb=10.0 --nb_run=5\npython train.py --dataset=google --model=gravity_gcn_ae --task=task_1 --epochs=200 --learning_rate=0.2 --hidden=64 --dimension=33 --lamb=10.0 --nb_run=5\n```\n\n**Google** - Task 2\n\n```Bash\npython train.py --dataset=google --model=gcn_vae --task=task_2 --epochs=200 --learning_rate=0.2 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=google --model=gcn_ae --task=task_2 --epochs=200 --learning_rate=0.2 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=google --model=source_target_gcn_vae --task=task_2 --epochs=200 --learning_rate=0.2 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=google --model=source_target_gcn_ae --task=task_2 --epochs=200 --learning_rate=0.2 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=google --model=gravity_gcn_vae --task=task_2 --epochs=200 --learning_rate=0.2 --hidden=64 --dimension=33 --lamb=0.05 --nb_run=5\npython train.py --dataset=google --model=gravity_gcn_ae --task=task_2 --epochs=200 --learning_rate=0.2 --hidden=64 --dimension=33 --lamb=0.05 --normalize=True --epsilon=1.0 --nb_run=5\n```\n\n**Google** - Task 3\n\n```Bash\npython train.py --dataset=google --model=gcn_vae --task=task_3 --epochs=200 --learning_rate=0.2 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=google --model=gcn_ae --task=task_3 --epochs=200 --learning_rate=0.2 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=google --model=source_target_gcn_vae --task=task_3 --epochs=200 --learning_rate=0.2 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=google --model=source_target_gcn_ae --task=task_3 --epochs=200 --learning_rate=0.2 --hidden=64 --dimension=32 --nb_run=5\npython train.py --dataset=google --model=gravity_gcn_vae --task=task_3 --epochs=200 --learning_rate=0.2 --hidden=64 --dimension=33 --lamb=10.0 --nb_run=5\npython train.py --dataset=google --model=gravity_gcn_ae --task=task_3 --epochs=200 --learning_rate=0.2 --hidden=64 --dimension=33 --lamb=10.0 --nb_run=5\n```\n\nNotes:\n - Set `--nb_run=100` to report mean AUC and AP, along with standard errors, over 100 runs, as in the paper\n - We recommend GPU usage for faster learning\n\n## Cite\n\nPlease cite our paper if you use this code in your own work:\n\n```BibTeX\n@inproceedings{salha2019gravity,\n  title={Gravity-Inspired Graph Autoencoders for Directed Link Prediction},\n  author={Salha, Guillaume and Limnios, Stratis and Hennequin, Romain and Tran, Viet Anh and Vazirgiannis, Michalis},\n  booktitle={ACM International Conference on Information and Knowledge Management (CIKM)},\n  year={2019}\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeezer%2Fgravity_graph_autoencoders","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeezer%2Fgravity_graph_autoencoders","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeezer%2Fgravity_graph_autoencoders/lists"}