Andrej Janchevski commited on
Commit ·
5e0b3dd
0
Parent(s):
Initial commit - add source files from research repos
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .gitattributes +13 -0
- .gitignore +3 -0
- src/research/COINs-KGGeneration/README.md +60 -0
- src/research/COINs-KGGeneration/data/FB15k-237/MSR-LA_Data_Full Rights_FB15K-237 Knowledge Base Completion Dataset (2650).docx +0 -0
- src/research/COINs-KGGeneration/data/FB15k-237/README.txt +41 -0
- src/research/COINs-KGGeneration/data/FB15k-237/test.txt +0 -0
- src/research/COINs-KGGeneration/data/FB15k-237/train.txt +3 -0
- src/research/COINs-KGGeneration/data/FB15k-237/valid.txt +0 -0
- src/research/COINs-KGGeneration/data/NELL-995/README.md +15 -0
- src/research/COINs-KGGeneration/data/NELL-995/entity2id.txt +0 -0
- src/research/COINs-KGGeneration/data/NELL-995/entity2vec.bern +3 -0
- src/research/COINs-KGGeneration/data/NELL-995/kb_env_rl.txt +3 -0
- src/research/COINs-KGGeneration/data/NELL-995/ranked_relations.csv +426 -0
- src/research/COINs-KGGeneration/data/NELL-995/raw.kb +3 -0
- src/research/COINs-KGGeneration/data/NELL-995/relation2id.txt +400 -0
- src/research/COINs-KGGeneration/data/NELL-995/relation2vec.bern +0 -0
- src/research/COINs-KGGeneration/data/NELL-995/test.txt +0 -0
- src/research/COINs-KGGeneration/data/NELL-995/train.txt +3 -0
- src/research/COINs-KGGeneration/data/NELL-995/valid.txt +543 -0
- src/research/COINs-KGGeneration/data/WN18RR/test.txt +0 -0
- src/research/COINs-KGGeneration/data/WN18RR/train.txt +0 -0
- src/research/COINs-KGGeneration/data/WN18RR/valid.txt +0 -0
- src/research/COINs-KGGeneration/graph_analysis/KGist/__init__.py +0 -0
- src/research/COINs-KGGeneration/graph_analysis/KGist/anomaly_detector.py +83 -0
- src/research/COINs-KGGeneration/graph_analysis/KGist/correct_assertion.py +72 -0
- src/research/COINs-KGGeneration/graph_analysis/KGist/evaluator.py +271 -0
- src/research/COINs-KGGeneration/graph_analysis/KGist/graph.py +188 -0
- src/research/COINs-KGGeneration/graph_analysis/KGist/main.py +86 -0
- src/research/COINs-KGGeneration/graph_analysis/KGist/model.py +388 -0
- src/research/COINs-KGGeneration/graph_analysis/KGist/rule.py +263 -0
- src/research/COINs-KGGeneration/graph_analysis/KGist/searcher.py +257 -0
- src/research/COINs-KGGeneration/graph_analysis/METIS/libmetis.so +3 -0
- src/research/COINs-KGGeneration/graph_analysis/METIS/metis.dll +3 -0
- src/research/COINs-KGGeneration/graph_analysis/__init__.py +0 -0
- src/research/COINs-KGGeneration/graph_analysis/main.py +566 -0
- src/research/COINs-KGGeneration/graph_analysis/metrics.py +950 -0
- src/research/COINs-KGGeneration/graph_analysis/stats.py +158 -0
- src/research/COINs-KGGeneration/graph_completion/README.md +89 -0
- src/research/COINs-KGGeneration/graph_completion/__init__.py +0 -0
- src/research/COINs-KGGeneration/graph_completion/configs/freebase.yml +29 -0
- src/research/COINs-KGGeneration/graph_completion/configs/freebase_betae.yml +44 -0
- src/research/COINs-KGGeneration/graph_completion/configs/freebase_complex.yml +31 -0
- src/research/COINs-KGGeneration/graph_completion/configs/freebase_distmult.yml +31 -0
- src/research/COINs-KGGeneration/graph_completion/configs/freebase_gnn.yml +34 -0
- src/research/COINs-KGGeneration/graph_completion/configs/freebase_gqe.yml +39 -0
- src/research/COINs-KGGeneration/graph_completion/configs/freebase_q2b.yml +40 -0
- src/research/COINs-KGGeneration/graph_completion/configs/freebase_rotate.yml +29 -0
- src/research/COINs-KGGeneration/graph_completion/configs/hep.yml +28 -0
- src/research/COINs-KGGeneration/graph_completion/configs/nell.yml +30 -0
- src/research/COINs-KGGeneration/graph_completion/configs/nell_betae.yml +44 -0
.gitattributes
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/src/research/COINs-KGGeneration/data/FB15k-237/text_emnlp.txt filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
/src/research/COINs-KGGeneration/data/FB15k-237/train.txt filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
/src/research/COINs-KGGeneration/data/NELL-995/entity2vec.bern filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
/src/research/COINs-KGGeneration/data/NELL-995/kb_env_rl.txt filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
/src/research/COINs-KGGeneration/data/NELL-995/raw.kb filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
/src/research/COINs-KGGeneration/data/NELL-995/train.txt filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
/src/research/MultiProxAn/checkpoints/qm9.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
/src/research/MultiProxAn/checkpoints/qm9_c.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.pdf filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.jpg filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.so filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.dll filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
.gitignore
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.idea/
|
| 2 |
+
__pycache__
|
| 3 |
+
.ipynb_checkpoints
|
src/research/COINs-KGGeneration/README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# COINs: Knowledge Graph Inference with Model-based Acceleration
|
| 2 |
+
|
| 3 |
+
LoG 2024 conference submission
|
| 4 |
+
|
| 5 |
+
---------
|
| 6 |
+
|
| 7 |
+
## Abstract
|
| 8 |
+
|
| 9 |
+
We present a new method, called COINs for **CO**mmunity **IN**formed graph embedding**s**, to enhance the efficiency of
|
| 10 |
+
knowledge graph models for link prediction and conjunctive query answering. COINs uses a community-detection-based graph
|
| 11 |
+
data augmentation and a two-step prediction pipeline: we first achieve node localization through community prediction,
|
| 12 |
+
and subsequently, we further localize within the predicted community. We establish theoretical criteria to evaluate our
|
| 13 |
+
method in our specific context and establish a direct expression of the reduction in time complexity. We empirically
|
| 14 |
+
demonstrate an important scalability-performance trade-off where for the median evaluation sample we preserve 97.18% of
|
| 15 |
+
the baseline accuracy in single-hop query answering, for only 7.52% of the original computational cost on a
|
| 16 |
+
single-CPU-GPU machine.
|
| 17 |
+
|
| 18 |
+
## Instructions
|
| 19 |
+
|
| 20 |
+
### Obtaining the code
|
| 21 |
+
|
| 22 |
+
Clone this repository by running:
|
| 23 |
+
|
| 24 |
+
`git clone https://github.com/ResearchWeasel/coins-log-2024.git`
|
| 25 |
+
|
| 26 |
+
### Dependencies
|
| 27 |
+
|
| 28 |
+
The implementation requires version `3.6.13` of the Python programming language.
|
| 29 |
+
To install it and the dependent Python packages, we recommend having [Anaconda](https://www.anaconda.com/download), then
|
| 30 |
+
running the following commands from the main directory of the repository files:
|
| 31 |
+
|
| 32 |
+
1. `conda create --name coins python=3.6.13`
|
| 33 |
+
2. `conda activate coins`
|
| 34 |
+
3. `pip install -r requirements.txt`
|
| 35 |
+
4. `export PYTHONPATH='.'`
|
| 36 |
+
|
| 37 |
+
### Reproducing results
|
| 38 |
+
|
| 39 |
+
To regenerate the tables and figures provided in the paper, run the Jupyter notebook `graph_completion/Plotting.ipynb`.
|
| 40 |
+
|
| 41 |
+
Figure PDFs will be saved to the `graph_completion/results` directory.
|
| 42 |
+
|
| 43 |
+
To run end-to-end a COINs training and evaluation experiment from the paper, run the following command from the main
|
| 44 |
+
directory of the repository files:
|
| 45 |
+
|
| 46 |
+
- GPU:
|
| 47 |
+
|
| 48 |
+
`CUDA_VISIBLE_DEVICES=<GPU ID> python graph_completion/main.py -cf='graph_completion/configs/<CONFIG FILENAME>.yml'`
|
| 49 |
+
|
| 50 |
+
- CPU (after setting the `device` config parameter to `cpu` in the YAML file):
|
| 51 |
+
|
| 52 |
+
`python graph_completion/main.py -cf='graph_completion/configs/<CONFIG FILENAME>.yml'`
|
| 53 |
+
|
| 54 |
+
The experiment results will be saved to a directory in `graph_completion/results/<DATASET>/runs`.
|
| 55 |
+
|
| 56 |
+
----------
|
| 57 |
+
|
| 58 |
+
## Authors
|
| 59 |
+
|
| 60 |
+
- Anonymous
|
src/research/COINs-KGGeneration/data/FB15k-237/MSR-LA_Data_Full Rights_FB15K-237 Knowledge Base Completion Dataset (2650).docx
ADDED
|
Binary file (38.5 kB). View file
|
|
|
src/research/COINs-KGGeneration/data/FB15k-237/README.txt
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FB15K-237 Knowledge Base Completion Dataset
|
| 2 |
+
|
| 3 |
+
This dataset contains knowledge base relation triples and textual mentions of Freebase entity pairs, as used in the work published in [1] and [2].
|
| 4 |
+
The knowledge base triples are a subset of the FB15K set [3], originally derived from Freebase. The textual mentions are derived from 200 million sentences from the ClueWeb12 [5] corpus coupled with Freebase entity mention annotations [4].
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
FILE FORMAT DETAILS
|
| 8 |
+
|
| 9 |
+
The files train.txt, valid.txt, and test.text contain the training, development, and test set knowledge base triples used in both [1] and [2].
|
| 10 |
+
The file text_cvsc.txt contains the textual triples used in [2] and the file text_emnlp.txt contains the textual triples used in [1].
|
| 11 |
+
|
| 12 |
+
The knowledge base triples contain lines like this:
|
| 13 |
+
|
| 14 |
+
/m/0grwj /people/person/profession /m/05sxg2
|
| 15 |
+
|
| 16 |
+
The format is:
|
| 17 |
+
|
| 18 |
+
mid1 relation mid2
|
| 19 |
+
|
| 20 |
+
The separator is a tab character; the mids are Freebase ids of entities, and the relation is a single or a two-hop relation from Freebase, where an intermediate complex value type entity has been collapsed out.
|
| 21 |
+
|
| 22 |
+
The textual mentions files have lines like this:
|
| 23 |
+
|
| 24 |
+
/m/02qkt [XXX]:<-nn>:fact:<-pobj>:in:<-prep>:game:<-nsubj>:'s:<ccomp>:pivot:<nsubj>:[YYY] /m/05sb1 3
|
| 25 |
+
|
| 26 |
+
This indicates the mids of two Freebase entities, together with a fully lexicalized dependency path between the entities. The last element in the tuple is the number of occurrences of the specified entity pair with the given dependency path in sentences from ClueWeb12.
|
| 27 |
+
The dependency paths are specified as sequences of words (like the word "fact" above) and labeled dependency links (like <nsubj> above). The direction of traversal of a dependency arc is indicated by whether there is a - sign in front of the arc label "e.g." <-nsubj> vs <nsubj>.
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
REFERENCES
|
| 31 |
+
|
| 32 |
+
[1] Kristina Toutanova, Danqi Chen, Patrick Pantel, Hoifung Poon, Pallavi Choudhury, and Michael Gamon. Representing text for joint embedding of text and knowledge bases. In Proceedings of EMNLP 2015.
|
| 33 |
+
[2] Kristina Toutanova and Danqi Chen. Observed versus latent features for knowledge base and text inference. In Proceedings of the 3rd Workshop on Continuous Vector Space Models and Their Compositionality 2015.
|
| 34 |
+
[3] Antoine Bordes, Nicolas Usunier, Alberto Garcia Duran, Jason Weston, and Oksana Yakhnenko. Translating embeddings for modeling multirelational data. In Advances in Neural Information Processing Systems (NIPS) 2013.
|
| 35 |
+
[4] Evgeniy Gabrilovich, Michael Ringgaard, and Amarnag Subramanya. FACC1: Freebase annotation of ClueWeb corpora, Version 1 (release date 2013-06-26, format version 1, correction level 0). http://lemurproject.org/clueweb12/FACC1/
|
| 36 |
+
[5] http://lemurproject.org/clueweb12/
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
CONTACT
|
| 40 |
+
|
| 41 |
+
Please contact Kristina Toutanova kristout@microsoft.com if you have questions about the dataset.
|
src/research/COINs-KGGeneration/data/FB15k-237/test.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
src/research/COINs-KGGeneration/data/FB15k-237/train.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:61099230e4439f90885ca9767739e31e8e32f54736fa1c35952b27997bc7c08a
|
| 3 |
+
size 21005177
|
src/research/COINs-KGGeneration/data/FB15k-237/valid.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
src/research/COINs-KGGeneration/data/NELL-995/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# NELL-995 Dataset for Knowledge Graph Reasoning
|
| 2 |
+
We build this dataset from the 995th iteration of CMU's NELL System
|
| 3 |
+
|
| 4 |
+
## Explanation about some files in the directory
|
| 5 |
+
* kb_env_rl.txt: knowledge graph used to build the RL environment
|
| 6 |
+
* raw.kb: the raw KB data
|
| 7 |
+
* entity2vec.bern/relation2vec.bern: embedding used to represent RL states
|
| 8 |
+
* tasks/: this directory contains data for each reasoning task
|
| 9 |
+
* tasks/${relation}/*.vec: trained TransD(H) Embeddings
|
| 10 |
+
* tasks/${relation}/*.bern: trained TransR Embedding trained
|
| 11 |
+
* tasks/${relation}/*.unif: trained TransE Embeddings
|
| 12 |
+
* tasks/${relation}/transX: triples used to train the KB embeddings
|
| 13 |
+
* tasks/${relation}/train.pairs: train triples in the PRA format
|
| 14 |
+
* tasks/${relation}/test.pairs: test triples in the PRA format
|
| 15 |
+
* tasks/${relation}/path_to_use.txt: reasoning paths found the RL agent
|
src/research/COINs-KGGeneration/data/NELL-995/entity2id.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
src/research/COINs-KGGeneration/data/NELL-995/entity2vec.bern
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e157b44e75d04d339d4a7a5b4732e85096be090b225f84ca3297374cbfe49617
|
| 3 |
+
size 71753696
|
src/research/COINs-KGGeneration/data/NELL-995/kb_env_rl.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:48b080737899828cc98f269feb4d63418f73cfe2dac3b60fe0e5015b34bd7ecf
|
| 3 |
+
size 26540694
|
src/research/COINs-KGGeneration/data/NELL-995/ranked_relations.csv
ADDED
|
@@ -0,0 +1,426 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
generalizations 2202099
|
| 2 |
+
concept:haswikipediaurl 303608
|
| 3 |
+
concept:atdate 15175
|
| 4 |
+
concept:latitudelongitude 6332
|
| 5 |
+
concept:proxyfor 5362
|
| 6 |
+
concept:agentcreated 4668
|
| 7 |
+
concept:atlocation 4272
|
| 8 |
+
concept:subpartof 4073
|
| 9 |
+
concept:teamplaysagainstteam 3411
|
| 10 |
+
concept:mutualproxyfor 3320
|
| 11 |
+
concept:itemfoundinroom 2472
|
| 12 |
+
concept:professionistypeofprofession 2361
|
| 13 |
+
concept:locationlocatedwithinlocation 2273
|
| 14 |
+
concept:clothingtogowithclothing 2242
|
| 15 |
+
concept:subpartoforganization 2087
|
| 16 |
+
concept:bookwriter 2083
|
| 17 |
+
concept:furniturefoundinroom 2037
|
| 18 |
+
concept:athleteplayssport 2008
|
| 19 |
+
concept:agentcollaborateswithagent 1928
|
| 20 |
+
concept:chemicalistypeofchemical 1812
|
| 21 |
+
concept:agentcontrols 1745
|
| 22 |
+
concept:worksfor 1707
|
| 23 |
+
concept:organizationhiredperson 1617
|
| 24 |
+
concept:animalistypeofanimal 1582
|
| 25 |
+
concept:agentactsinlocation 1493
|
| 26 |
+
concept:hasofficeincity 1486
|
| 27 |
+
concept:animalpreyson 1429
|
| 28 |
+
concept:bodypartcontainsbodypart 1393
|
| 29 |
+
concept:teamplaysinleague 1386
|
| 30 |
+
concept:cityliesonriver 1369
|
| 31 |
+
concept:agentparticipatedinevent 1356
|
| 32 |
+
concept:agriculturalproductcookedwithagriculturalproduct 1302
|
| 33 |
+
concept:academicprogramatuniversity 1294
|
| 34 |
+
concept:athleteplaysforteam 1288
|
| 35 |
+
concept:athleteplaysinleague 1269
|
| 36 |
+
concept:companyeconomicsector 1226
|
| 37 |
+
concept:agentinvolvedwithitem 1197
|
| 38 |
+
concept:competeswith 1194
|
| 39 |
+
concept:journalistwritesforpublication 1185
|
| 40 |
+
concept:agentcompeteswithagent 1148
|
| 41 |
+
concept:agentcontributedtocreativework 1030
|
| 42 |
+
concept:televisionstationaffiliatedwith 1001
|
| 43 |
+
concept:weaponssuchasweapons 993
|
| 44 |
+
concept:personbelongstoorganization 969
|
| 45 |
+
concept:plantincludeplant 941
|
| 46 |
+
concept:politicianusendorsedbypoliticianus 913
|
| 47 |
+
concept:persondiedincountry 907
|
| 48 |
+
concept:drughassideeffect 886
|
| 49 |
+
concept:organizationheadquarteredincity 829
|
| 50 |
+
concept:touristattractionsuchastouristattraction 826
|
| 51 |
+
concept:athleteflyouttosportsteamposition 802
|
| 52 |
+
concept:countrylocatedingeopoliticallocation 794
|
| 53 |
+
concept:musicartistgenre 774
|
| 54 |
+
concept:personleadsorganization 771
|
| 55 |
+
concept:sportsgameteam 730
|
| 56 |
+
concept:agentbelongstoorganization 727
|
| 57 |
+
concept:musicianplaysinstrument 703
|
| 58 |
+
concept:organizationterminatedperson 694
|
| 59 |
+
concept:citylocatedinstate 690
|
| 60 |
+
concept:animaldevelopdisease 669
|
| 61 |
+
concept:athletehomestadium 667
|
| 62 |
+
concept:synonymfor 655
|
| 63 |
+
concept:animaleatfood 650
|
| 64 |
+
concept:personborninlocation 642
|
| 65 |
+
concept:hasspouse 638
|
| 66 |
+
concept:persongraduatedfromuniversity 621
|
| 67 |
+
concept:beveragemadefrombeverage 614
|
| 68 |
+
concept:statelocatedingeopoliticallocation 612
|
| 69 |
+
concept:bakedgoodservedwithbeverage 601
|
| 70 |
+
concept:personhasjobposition 595
|
| 71 |
+
concept:sportusesequipment 564
|
| 72 |
+
concept:visualartistartform 562
|
| 73 |
+
concept:drugworkedonbyagent 560
|
| 74 |
+
concept:personbornincity 554
|
| 75 |
+
concept:buildinglocatedincity 550
|
| 76 |
+
concept:citylocatedincountry 531
|
| 77 |
+
concept:politicianholdsoffice 529
|
| 78 |
+
concept:hotelincity 528
|
| 79 |
+
concept:musicianinmusicartist 527
|
| 80 |
+
concept:countryalsoknownas 501
|
| 81 |
+
concept:academicfieldsuchasacademicfield 497
|
| 82 |
+
concept:politicianrepresentslocation 482
|
| 83 |
+
concept:actorstarredinmovie 470
|
| 84 |
+
concept:persongraduatedschool 442
|
| 85 |
+
concept:animalsuchasinsect 433
|
| 86 |
+
concept:agriculturalproductincludingagriculturalproduct 429
|
| 87 |
+
concept:bankbankincountry 428
|
| 88 |
+
concept:bacteriaisthecausativeagentofphysiologicalcondition 427
|
| 89 |
+
concept:persondiedatage 416
|
| 90 |
+
concept:coachwontrophy 414
|
| 91 |
+
concept:conceptprerequisiteof 404
|
| 92 |
+
concept:organizationheadquarteredincountry 402
|
| 93 |
+
concept:producesproduct 400
|
| 94 |
+
concept:athleteledsportsteam 400
|
| 95 |
+
concept:topmemberoforganization 389
|
| 96 |
+
concept:stadiumlocatedincity 384
|
| 97 |
+
concept:attractionofcity 384
|
| 98 |
+
concept:headquarteredin 383
|
| 99 |
+
concept:animalthatfeedoninsect 383
|
| 100 |
+
concept:arthropodcalledarthropod 378
|
| 101 |
+
concept:hasofficeincountry 378
|
| 102 |
+
concept:teamplayssport 371
|
| 103 |
+
concept:languageofuniversity 369
|
| 104 |
+
concept:languageofcountry 367
|
| 105 |
+
concept:teamplaysincity 363
|
| 106 |
+
concept:airportincity 362
|
| 107 |
+
concept:weaponmadeincountry 361
|
| 108 |
+
concept:automakerproducesmodel 358
|
| 109 |
+
concept:personhascitizenship 358
|
| 110 |
+
concept:emotionassociatedwithdisease 352
|
| 111 |
+
concept:teamwontrophy 352
|
| 112 |
+
concept:fooddecreasestheriskofdisease 351
|
| 113 |
+
concept:acquired 348
|
| 114 |
+
concept:parentofperson 347
|
| 115 |
+
concept:arthropodandotherarthropod 343
|
| 116 |
+
concept:drugpossiblytreatsphysiologicalcondition 341
|
| 117 |
+
concept:organizationacronymhasname 341
|
| 118 |
+
concept:animalsuchasfish 339
|
| 119 |
+
concept:politicianusholdsoffice 330
|
| 120 |
+
concept:politicianusmemberofpoliticalgroup 321
|
| 121 |
+
concept:mammalsuchasmammal 320
|
| 122 |
+
concept:agriculturalproductcomingfromvertebrate 315
|
| 123 |
+
concept:riveremptiesintoriver 312
|
| 124 |
+
concept:leaguestadiums 311
|
| 125 |
+
concept:specializationof 301
|
| 126 |
+
concept:fishservedwithfood 289
|
| 127 |
+
concept:personhasresidenceingeopoliticallocation 288
|
| 128 |
+
concept:animalsuchasinvertebrate 287
|
| 129 |
+
concept:televisionstationincity 276
|
| 130 |
+
concept:directordirectedmovie 272
|
| 131 |
+
concept:ceoof 271
|
| 132 |
+
concept:istallerthan 260
|
| 133 |
+
concept:parkincity 259
|
| 134 |
+
concept:personchargedwithcrime 255
|
| 135 |
+
concept:sportfansincountry 250
|
| 136 |
+
concept:personalsoknownas 245
|
| 137 |
+
concept:arterycalledartery 242
|
| 138 |
+
concept:athleteinjuredhisbodypart 242
|
| 139 |
+
concept:sportschoolincountry 239
|
| 140 |
+
concept:agriculturalproductcutintogeometricshape 234
|
| 141 |
+
concept:animaleatvegetable 230
|
| 142 |
+
concept:personmovedtostateorprovince 230
|
| 143 |
+
concept:thinghascolor 230
|
| 144 |
+
concept:citylocatedingeopoliticallocation 229
|
| 145 |
+
concept:automobilemakerdealersincity 225
|
| 146 |
+
concept:radiostationincity 214
|
| 147 |
+
concept:sportsgamewinner 213
|
| 148 |
+
concept:invertebratefeedonfood 213
|
| 149 |
+
concept:thinghasshape 209
|
| 150 |
+
concept:professionusestool 208
|
| 151 |
+
concept:agriculturalproductcontainchemical 206
|
| 152 |
+
concept:organizationdissolvedatdate 205
|
| 153 |
+
concept:haswife 203
|
| 154 |
+
concept:hobbiessuchashobbies 202
|
| 155 |
+
concept:buildingfeaturemadefrombuildingmaterial 200
|
| 156 |
+
concept:athleteplayssportsteamposition 194
|
| 157 |
+
concept:foodcancausedisease 192
|
| 158 |
+
concept:organizationalsoknownas 184
|
| 159 |
+
concept:sportusesstadium 183
|
| 160 |
+
concept:agriculturalproducttoattractinsect 171
|
| 161 |
+
concept:citycapitalofcountry 170
|
| 162 |
+
concept:sporthassportsteamposition 167
|
| 163 |
+
concept:teamalsoknownas 166
|
| 164 |
+
concept:statelocatedincountry 160
|
| 165 |
+
concept:stateorprovinceisborderedbystateorprovince 159
|
| 166 |
+
concept:musicgenressuchasmusicgenres 158
|
| 167 |
+
concept:objectpartofobject 155
|
| 168 |
+
concept:organizationheadquarteredinstateorprovince 148
|
| 169 |
+
concept:fatherofperson 147
|
| 170 |
+
concept:agriculturalproductcamefromcountry 147
|
| 171 |
+
concept:newspaperincity 144
|
| 172 |
+
concept:lakeinstate 144
|
| 173 |
+
concept:objectfoundinscene 143
|
| 174 |
+
concept:teamhomestadium 143
|
| 175 |
+
concept:agriculturalproductgrowninlandscapefeatures 140
|
| 176 |
+
concept:companyalsoknownas 137
|
| 177 |
+
concept:countrycurrency 134
|
| 178 |
+
concept:coachesteam 133
|
| 179 |
+
concept:academicfieldconcernssubject 132
|
| 180 |
+
concept:cityalsoknownas 129
|
| 181 |
+
concept:ismultipleof 128
|
| 182 |
+
concept:athletebeatathlete 127
|
| 183 |
+
concept:athletewinsawardtrophytournament 125
|
| 184 |
+
concept:hashusband 124
|
| 185 |
+
concept:personleadsgeopoliticalorganization 123
|
| 186 |
+
concept:statehascapital 118
|
| 187 |
+
concept:mountaininstate 116
|
| 188 |
+
concept:bankboughtbank 113
|
| 189 |
+
concept:automobilemakerdealersincountry 111
|
| 190 |
+
concept:plantrepresentemotion 111
|
| 191 |
+
concept:transportationincity 109
|
| 192 |
+
concept:awardtrophytournamentisthechampionshipgameofthenationalsport 105
|
| 193 |
+
concept:coachesinleague 103
|
| 194 |
+
concept:sportsgamesport 94
|
| 195 |
+
concept:hassibling 92
|
| 196 |
+
concept:motherofperson 92
|
| 197 |
+
concept:clothingmadefromplant 92
|
| 198 |
+
concept:museumincity 91
|
| 199 |
+
concept:plantgrowinginplant 90
|
| 200 |
+
concept:beveragecontainsprotein 86
|
| 201 |
+
concept:automobilemakercardealersinstateorprovince 85
|
| 202 |
+
concept:agriculturalproductgrowinginstateorprovince 84
|
| 203 |
+
concept:jobpositionusesacademicfield 83
|
| 204 |
+
concept:hasfamilymember 82
|
| 205 |
+
concept:languageschoolincity 81
|
| 206 |
+
concept:animalssuchasmammals 81
|
| 207 |
+
concept:wineryproduceswine 81
|
| 208 |
+
concept:hospitalincity 78
|
| 209 |
+
concept:personhasresidenceincity 72
|
| 210 |
+
concept:personattendsschool 70
|
| 211 |
+
concept:collidedwith 66
|
| 212 |
+
concept:vegetableproductioninstateorprovince 65
|
| 213 |
+
concept:hasbrother 63
|
| 214 |
+
concept:musclelocatedinbodypart 63
|
| 215 |
+
concept:aquariumincity 62
|
| 216 |
+
concept:teammate 59
|
| 217 |
+
concept:objectlookslikeobject 57
|
| 218 |
+
concept:colorassociatedwithvisualizableattribute 53
|
| 219 |
+
concept:writerwasbornincity 52
|
| 220 |
+
concept:itemexistsatlocation 52
|
| 221 |
+
concept:locationofbombing 50
|
| 222 |
+
concept:productinstanceof 49
|
| 223 |
+
concept:countriessuchascountries 49
|
| 224 |
+
concept:personhasage 49
|
| 225 |
+
concept:diseasecausesphysiologicalcondition 47
|
| 226 |
+
concept:athletessuchasathletes 46
|
| 227 |
+
concept:streetincity 45
|
| 228 |
+
concept:attractionmadeofbuildingmaterial 45
|
| 229 |
+
concept:personleadscity 41
|
| 230 |
+
concept:victiminbombing 41
|
| 231 |
+
concept:personhasresidenceinstateorprovince 40
|
| 232 |
+
concept:restaurantincity 39
|
| 233 |
+
concept:commentatorofbombing 39
|
| 234 |
+
concept:locationofprotest 39
|
| 235 |
+
concept:vegetablecanbeservedwithgrain 39
|
| 236 |
+
concept:productbeinglauched 37
|
| 237 |
+
concept:personwrittenaboutinpublication 36
|
| 238 |
+
concept:attractionbefallincity 35
|
| 239 |
+
concept:arthropodthatfeedoninsect 35
|
| 240 |
+
concept:invertebratehascolor 32
|
| 241 |
+
concept:professionssuchasprofessions 32
|
| 242 |
+
concept:companyproducesvideogamesystem 31
|
| 243 |
+
concept:agentcreatedorganization 31
|
| 244 |
+
concept:musicfestivalssuchasmusicfestivals 30
|
| 245 |
+
concept:organizationhasofficialwebsite 30
|
| 246 |
+
concept:attackerinbombing 30
|
| 247 |
+
concept:televisionshowssuchastelevisionshows 30
|
| 248 |
+
concept:mountainatgeopoliticallocation 30
|
| 249 |
+
concept:personhasresidenceincountry 30
|
| 250 |
+
concept:animalsuchasmollusk 29
|
| 251 |
+
concept:conferencessuchasconferences 29
|
| 252 |
+
concept:toolssuchastools 29
|
| 253 |
+
concept:locationofearthquake 29
|
| 254 |
+
concept:locationofroadaccident 28
|
| 255 |
+
concept:malemovedtostateorprovince 28
|
| 256 |
+
concept:organizationcreatedatdate 28
|
| 257 |
+
concept:personhasethnicity 27
|
| 258 |
+
concept:coachworksincountry 27
|
| 259 |
+
concept:amphibiansuchasamphibian 27
|
| 260 |
+
concept:productproducedincountry 27
|
| 261 |
+
concept:criminalssuchascriminals 27
|
| 262 |
+
concept:personbirthdate 26
|
| 263 |
+
concept:bakegoodistypicalincountry 26
|
| 264 |
+
concept:personhasreligion 26
|
| 265 |
+
concept:arteryarisesfromartery 26
|
| 266 |
+
concept:athletecoach 26
|
| 267 |
+
concept:persondiedinstateorprovince 25
|
| 268 |
+
concept:diseasemaybecausedbydrug 25
|
| 269 |
+
concept:actorofprotest 25
|
| 270 |
+
concept:marriedinyear 25
|
| 271 |
+
concept:comediancanbethesameasfemale 24
|
| 272 |
+
concept:arthropodlookslikeinsect 24
|
| 273 |
+
concept:personinacademicfield 24
|
| 274 |
+
concept:invertebrateturnintoinsect 24
|
| 275 |
+
concept:mammalinducesemotion 23
|
| 276 |
+
concept:launchingproductcompany 23
|
| 277 |
+
concept:victiminroadaccident 23
|
| 278 |
+
concept:epicenterofearthquake 22
|
| 279 |
+
concept:personborninstateorprovince 22
|
| 280 |
+
concept:personbornincountry 21
|
| 281 |
+
concept:arthropodbesometimesconfusewithinsect 21
|
| 282 |
+
concept:countryisthehomeofsportsteam 21
|
| 283 |
+
concept:meatcomesfromanimal 21
|
| 284 |
+
concept:musicsongisatrackofmusicalbum 20
|
| 285 |
+
concept:stadiumoreventvenuedisclosescompany 20
|
| 286 |
+
concept:bankchiefexecutiveceo 20
|
| 287 |
+
concept:zooincity 20
|
| 288 |
+
concept:vegetableisproducedatcountry 19
|
| 289 |
+
concept:launchingproducttype 19
|
| 290 |
+
concept:visualartistartmovement 19
|
| 291 |
+
concept:damagedinbombing 18
|
| 292 |
+
concept:professionactsatthesameareaofpoliticissue 18
|
| 293 |
+
concept:vehicleistypeofvehicle 18
|
| 294 |
+
concept:athletealsoknownas 18
|
| 295 |
+
concept:languageofcity 18
|
| 296 |
+
concept:agentstudiesphysiologicalcondition 18
|
| 297 |
+
concept:actorworkedwithdirector 17
|
| 298 |
+
concept:eventdate 17
|
| 299 |
+
concept:arachnidiseatenbybird 17
|
| 300 |
+
concept:shoppingmallincity 17
|
| 301 |
+
concept:clothmadeofplant 17
|
| 302 |
+
concept:agentholdssharesincompany 17
|
| 303 |
+
concept:persondiedincity 17
|
| 304 |
+
concept:magnitudeofearthquaque 17
|
| 305 |
+
concept:celebritysuchascelebrity 16
|
| 306 |
+
concept:injuredinbombing 16
|
| 307 |
+
concept:actorsuchasactor 16
|
| 308 |
+
concept:coachcanspeaklanguage 16
|
| 309 |
+
concept:mammaleatsinsect 16
|
| 310 |
+
concept:numberofinjuredinbombing 16
|
| 311 |
+
concept:mlareaexpert 15
|
| 312 |
+
concept:stateorprovinceattainstrainstation 15
|
| 313 |
+
concept:automobilemakerchiefexecutiveceo 15
|
| 314 |
+
concept:wineryatfarm 15
|
| 315 |
+
concept:hassister 15
|
| 316 |
+
concept:architectssuchasarchitects 15
|
| 317 |
+
concept:buildingispartofuniversity 15
|
| 318 |
+
concept:musicalartisthadapetanimal 15
|
| 319 |
+
concept:astronautwasonamissionwithastronaut 15
|
| 320 |
+
concept:arthropodsuchascrustacean 15
|
| 321 |
+
concept:athletepublishesinblog 15
|
| 322 |
+
concept:numberofkilledinbombing 14
|
| 323 |
+
concept:languagespokenatisland 14
|
| 324 |
+
concept:coachstudiedatuniversity 14
|
| 325 |
+
concept:officebuildingroominbuilding 14
|
| 326 |
+
concept:buildingfeaturebuiltabovelake 14
|
| 327 |
+
concept:productlauchpredecessor 14
|
| 328 |
+
concept:productlauchvenue 14
|
| 329 |
+
concept:politicianuswenttoschool 14
|
| 330 |
+
concept:beveragecansoftendisease 14
|
| 331 |
+
concept:arteriessuchasarteries 14
|
| 332 |
+
concept:politicsbillconcernsissue 14
|
| 333 |
+
concept:agenthaswebsite 13
|
| 334 |
+
concept:sourceofearthquake 13
|
| 335 |
+
concept:newpaperhaswebsite 13
|
| 336 |
+
concept:grainusedtomakecandy 13
|
| 337 |
+
concept:weaponusedinprotest 13
|
| 338 |
+
concept:placeofworshippracticesreligion 13
|
| 339 |
+
concept:productlauchcompetingcompany 13
|
| 340 |
+
concept:magazineisleadbyceo 13
|
| 341 |
+
concept:meetingeventtitlehasspeakingperson 12
|
| 342 |
+
concept:politicsbillsponsoredbypoliticianus 12
|
| 343 |
+
concept:targetinbombing 12
|
| 344 |
+
concept:meetingeventtitleatdate 12
|
| 345 |
+
concept:meetingeventtitlehasmeetingeventtype 12
|
| 346 |
+
concept:prodctlaunchingproductcompetitor 12
|
| 347 |
+
concept:farmlocatedinstate 12
|
| 348 |
+
concept:meetingeventtitleinbuilding 12
|
| 349 |
+
concept:guiltyofroadaccident 12
|
| 350 |
+
concept:meetingeventtitleinofficebuildingroom 12
|
| 351 |
+
concept:mlauthorofsoftware 12
|
| 352 |
+
concept:farmproducesagriculturalproduct 12
|
| 353 |
+
concept:academicfieldhassubfield 12
|
| 354 |
+
concept:zipcodeinlocation 11
|
| 355 |
+
concept:academicfieldusedbyeconomicsector 11
|
| 356 |
+
concept:politicsgroupconcernsissue 11
|
| 357 |
+
concept:awardtrophytournamentwasawardedonstadium 11
|
| 358 |
+
concept:softwareisprogrammedinprogramminglanguage 11
|
| 359 |
+
concept:astronautssuchasaustronauts 11
|
| 360 |
+
concept:sportsgamescore 11
|
| 361 |
+
concept:drugexpectedreleasedate 11
|
| 362 |
+
concept:airportsuchasairport 11
|
| 363 |
+
concept:arthropodcanbeveryirritatingtomammal 11
|
| 364 |
+
concept:commentatorofearthquake 11
|
| 365 |
+
concept:hotelwasbuiltatfarm 11
|
| 366 |
+
concept:bombinghaswitness 11
|
| 367 |
+
concept:hotelbuiltatpark 11
|
| 368 |
+
concept:explosivesinbombing 10
|
| 369 |
+
concept:aquariumssuchasaquariums 10
|
| 370 |
+
concept:sportsgamedate 10
|
| 371 |
+
concept:videogamessuchasvideogames 10
|
| 372 |
+
concept:restaurantlocatedinskyscraper 10
|
| 373 |
+
concept:persondeathdate 10
|
| 374 |
+
concept:buildingbelongstoorganization 10
|
| 375 |
+
concept:moviessuchasmovies 10
|
| 376 |
+
concept:booksuchasbook 10
|
| 377 |
+
concept:religionssuchasreligions 10
|
| 378 |
+
concept:victiminearthquake 10
|
| 379 |
+
concept:archaeasuchasarchaea 10
|
| 380 |
+
concept:reasonofcollision 10
|
| 381 |
+
concept:timeofearthquake 9
|
| 382 |
+
concept:arachnidssuchasarachnids 9
|
| 383 |
+
concept:commentatorofprotest 9
|
| 384 |
+
concept:birdmayconsumeprotein 9
|
| 385 |
+
concept:victiminprotest 9
|
| 386 |
+
concept:athleteplayedforschool 9
|
| 387 |
+
concept:bacteriacancauseillnessfromfood 9
|
| 388 |
+
concept:athletefracturedbone 9
|
| 389 |
+
concept:numberofinjuredinroadaccident 9
|
| 390 |
+
concept:personineconomicsector 9
|
| 391 |
+
concept:timeofbombing 9
|
| 392 |
+
concept:damagedinearthquake 8
|
| 393 |
+
concept:insecteatsgrain 8
|
| 394 |
+
concept:athletecanbethesameasactor 8
|
| 395 |
+
concept:injuredinprotest 8
|
| 396 |
+
concept:televisionshowisbasedonmovie 8
|
| 397 |
+
concept:criminalarrestedincountry 8
|
| 398 |
+
concept:numberofcasualtiesinroadaccident 7
|
| 399 |
+
concept:timeofroadaccident 7
|
| 400 |
+
concept:sportsgameloserscore 7
|
| 401 |
+
concept:sportsgamewinnerscore 7
|
| 402 |
+
concept:injuredinearthquake 7
|
| 403 |
+
concept:automobileenginesuchasautomobileengine 7
|
| 404 |
+
concept:injuredinroadaccident 7
|
| 405 |
+
concept:sportsgameloser 6
|
| 406 |
+
concept:islandhasskiarea 6
|
| 407 |
+
concept:universityledmusicfestival 6
|
| 408 |
+
concept:commentatorofroadaccident 6
|
| 409 |
+
concept:agentowns 5
|
| 410 |
+
concept:numberofinjuredinprotest 5
|
| 411 |
+
concept:sportnamehasoriginlanguage 5
|
| 412 |
+
concept:publicationpublishedinmagazine 5
|
| 413 |
+
concept:coachalsoknownas 5
|
| 414 |
+
concept:securityinbombing 5
|
| 415 |
+
concept:numberofcasualtiesinearthquake 5
|
| 416 |
+
concept:numberofinjuredinearthquake 5
|
| 417 |
+
concept:stadiumalsoknownas 5
|
| 418 |
+
concept:numberofarrestedinbombing 5
|
| 419 |
+
concept:prodctlaunchingproductprice 3
|
| 420 |
+
concept:damagedinprotest 3
|
| 421 |
+
concept:celebritycanbethesameasceo 3
|
| 422 |
+
concept:timeofprotest 2
|
| 423 |
+
concept:persondiedinlocation 2
|
| 424 |
+
concept:scientistcanbethesameaswriter 1
|
| 425 |
+
concept:farmlocatedincountry 1
|
| 426 |
+
concept:eventatlocation 1
|
src/research/COINs-KGGeneration/data/NELL-995/raw.kb
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:6ca558a996843f8fff7185e56e32fe6ede5c266244c8ff6e77070064e300272b
|
| 3 |
+
size 12961921
|
src/research/COINs-KGGeneration/data/NELL-995/relation2id.txt
ADDED
|
@@ -0,0 +1,400 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
concept:agriculturalproductcookedwithagriculturalproduct 0
|
| 2 |
+
concept:agriculturalproductgrowninlandscapefeatures 1
|
| 3 |
+
concept:sportfansincountry 2
|
| 4 |
+
concept:beveragemadefrombeverage_inv 3
|
| 5 |
+
concept:emotionassociatedwithdisease_inv 4
|
| 6 |
+
concept:personbelongstoorganization_inv 5
|
| 7 |
+
concept:agentcontrols_inv 6
|
| 8 |
+
concept:clothingtogowithclothing_inv 7
|
| 9 |
+
concept:cityliesonriver 8
|
| 10 |
+
concept:agriculturalproductincludingagriculturalproduct 9
|
| 11 |
+
concept:musicianinmusicartist 10
|
| 12 |
+
concept:radiostationincity 11
|
| 13 |
+
concept:specializationof 12
|
| 14 |
+
concept:specializationof_inv 13
|
| 15 |
+
concept:hasspouse 14
|
| 16 |
+
concept:agentcollaborateswithagent_inv 15
|
| 17 |
+
concept:bankboughtbank_inv 16
|
| 18 |
+
concept:conceptprerequisiteof 17
|
| 19 |
+
concept:automobilemakerdealersincountry 18
|
| 20 |
+
concept:actorstarredinmovie_inv 19
|
| 21 |
+
concept:stateorprovinceisborderedbystateorprovince 20
|
| 22 |
+
concept:televisionstationincity 21
|
| 23 |
+
concept:personleadsgeopoliticalorganization 22
|
| 24 |
+
concept:languageofuniversity 23
|
| 25 |
+
concept:sportschoolincountry_inv 24
|
| 26 |
+
concept:cityliesonriver_inv 25
|
| 27 |
+
concept:headquarteredin_inv 26
|
| 28 |
+
concept:hasspouse_inv 27
|
| 29 |
+
concept:subpartof_inv 28
|
| 30 |
+
concept:objectpartofobject 29
|
| 31 |
+
concept:musicgenressuchasmusicgenres_inv 30
|
| 32 |
+
concept:atdate_inv 31
|
| 33 |
+
concept:atlocation 32
|
| 34 |
+
concept:weaponssuchasweapons_inv 33
|
| 35 |
+
concept:organizationheadquarteredincity 34
|
| 36 |
+
concept:organizationterminatedperson_inv 35
|
| 37 |
+
concept:stadiumlocatedincity_inv 36
|
| 38 |
+
concept:personborninlocation 37
|
| 39 |
+
concept:sportsgameteam_inv 38
|
| 40 |
+
concept:agriculturalproductcontainchemical_inv 39
|
| 41 |
+
concept:musicartistgenre 40
|
| 42 |
+
concept:stadiumlocatedincity 41
|
| 43 |
+
concept:parentofperson_inv 42
|
| 44 |
+
concept:emotionassociatedwithdisease 43
|
| 45 |
+
concept:academicfieldconcernssubject_inv 44
|
| 46 |
+
concept:languageofcountry_inv 45
|
| 47 |
+
concept:haswife 46
|
| 48 |
+
concept:transportationincity 47
|
| 49 |
+
concept:hobbiessuchashobbies 48
|
| 50 |
+
concept:awardtrophytournamentisthechampionshipgameofthenationalsport_inv 49
|
| 51 |
+
concept:parkincity_inv 50
|
| 52 |
+
concept:attractionofcity 51
|
| 53 |
+
concept:countrylocatedingeopoliticallocation_inv 52
|
| 54 |
+
concept:museumincity 53
|
| 55 |
+
concept:companyalsoknownas 54
|
| 56 |
+
concept:athletehomestadium 55
|
| 57 |
+
concept:hashusband 56
|
| 58 |
+
concept:organizationdissolvedatdate 57
|
| 59 |
+
concept:animalthatfeedoninsect_inv 58
|
| 60 |
+
concept:conceptprerequisiteof_inv 59
|
| 61 |
+
concept:personleadsgeopoliticalorganization_inv 60
|
| 62 |
+
concept:professionusestool 61
|
| 63 |
+
concept:professionusestool_inv 62
|
| 64 |
+
concept:teamplaysincity 63
|
| 65 |
+
concept:personmovedtostateorprovince_inv 64
|
| 66 |
+
concept:politicianusholdsoffice_inv 65
|
| 67 |
+
concept:fatherofperson 66
|
| 68 |
+
concept:motherofperson_inv 67
|
| 69 |
+
concept:automobilemakerdealersincity 68
|
| 70 |
+
concept:plantgrowinginplant_inv 69
|
| 71 |
+
concept:hotelincity_inv 70
|
| 72 |
+
concept:objectfoundinscene_inv 71
|
| 73 |
+
concept:citylocatedinstate 72
|
| 74 |
+
concept:hassibling 73
|
| 75 |
+
concept:arthropodandotherarthropod 74
|
| 76 |
+
concept:atlocation_inv 75
|
| 77 |
+
concept:furniturefoundinroom 76
|
| 78 |
+
concept:hobbiessuchashobbies_inv 77
|
| 79 |
+
concept:athleteledsportsteam_inv 78
|
| 80 |
+
concept:plantincludeplant_inv 79
|
| 81 |
+
concept:personbornincity 80
|
| 82 |
+
concept:fishservedwithfood 81
|
| 83 |
+
concept:teamplayssport 82
|
| 84 |
+
concept:persondiedincountry 83
|
| 85 |
+
concept:attractionofcity_inv 84
|
| 86 |
+
concept:persongraduatedfromuniversity 85
|
| 87 |
+
concept:musicianinmusicartist_inv 86
|
| 88 |
+
concept:radiostationincity_inv 87
|
| 89 |
+
concept:personchargedwithcrime_inv 88
|
| 90 |
+
concept:weaponssuchasweapons 89
|
| 91 |
+
concept:countrycurrency 90
|
| 92 |
+
concept:personborninlocation_inv 91
|
| 93 |
+
concept:automakerproducesmodel 92
|
| 94 |
+
concept:countrylocatedingeopoliticallocation 93
|
| 95 |
+
concept:buildinglocatedincity 94
|
| 96 |
+
concept:bankbankincountry_inv 95
|
| 97 |
+
concept:teamplaysagainstteam_inv 96
|
| 98 |
+
concept:ceoof_inv 97
|
| 99 |
+
concept:animalsuchasfish 98
|
| 100 |
+
concept:persondiedatage_inv 99
|
| 101 |
+
concept:hasofficeincity 100
|
| 102 |
+
concept:organizationalsoknownas 101
|
| 103 |
+
concept:agentcreated 102
|
| 104 |
+
concept:organizationacronymhasname 103
|
| 105 |
+
concept:politicianrepresentslocation 104
|
| 106 |
+
concept:agentcompeteswithagent 105
|
| 107 |
+
concept:sportusesstadium 106
|
| 108 |
+
concept:citylocatedingeopoliticallocation_inv 107
|
| 109 |
+
concept:itemfoundinroom_inv 108
|
| 110 |
+
concept:animalistypeofanimal_inv 109
|
| 111 |
+
concept:sportsgameteam 110
|
| 112 |
+
concept:teamalsoknownas_inv 111
|
| 113 |
+
concept:persongraduatedfromuniversity_inv 112
|
| 114 |
+
concept:agentinvolvedwithitem_inv 113
|
| 115 |
+
concept:agentactsinlocation_inv 114
|
| 116 |
+
concept:countryalsoknownas 115
|
| 117 |
+
concept:languageofuniversity_inv 116
|
| 118 |
+
concept:personhasjobposition 117
|
| 119 |
+
concept:latitudelongitude 118
|
| 120 |
+
concept:teamplaysinleague 119
|
| 121 |
+
concept:athletebeatathlete 120
|
| 122 |
+
concept:companyeconomicsector_inv 121
|
| 123 |
+
concept:teamplayssport_inv 122
|
| 124 |
+
concept:personhascitizenship_inv 123
|
| 125 |
+
concept:persondiedincountry_inv 124
|
| 126 |
+
concept:televisionstationincity_inv 125
|
| 127 |
+
concept:organizationheadquarteredincity_inv 126
|
| 128 |
+
concept:motherofperson 127
|
| 129 |
+
concept:clothingmadefromplant 128
|
| 130 |
+
concept:televisionstationaffiliatedwith 129
|
| 131 |
+
concept:personleadsorganization 130
|
| 132 |
+
concept:leaguestadiums_inv 131
|
| 133 |
+
concept:sportusesequipment_inv 132
|
| 134 |
+
concept:museumincity_inv 133
|
| 135 |
+
concept:foodcancausedisease 134
|
| 136 |
+
concept:plantincludeplant 135
|
| 137 |
+
concept:beveragecontainsprotein_inv 136
|
| 138 |
+
concept:directordirectedmovie_inv 137
|
| 139 |
+
concept:animalsuchasinvertebrate 138
|
| 140 |
+
concept:riveremptiesintoriver_inv 139
|
| 141 |
+
concept:bookwriter_inv 140
|
| 142 |
+
concept:worksfor 141
|
| 143 |
+
concept:politicianrepresentslocation_inv 142
|
| 144 |
+
concept:agentinvolvedwithitem 143
|
| 145 |
+
concept:academicfieldsuchasacademicfield_inv 144
|
| 146 |
+
concept:clothingtogowithclothing 145
|
| 147 |
+
concept:airportincity_inv 146
|
| 148 |
+
concept:agentbelongstoorganization 147
|
| 149 |
+
concept:visualartistartform 148
|
| 150 |
+
concept:professionistypeofprofession_inv 149
|
| 151 |
+
concept:athleteinjuredhisbodypart_inv 150
|
| 152 |
+
concept:mutualproxyfor 151
|
| 153 |
+
concept:fooddecreasestheriskofdisease 152
|
| 154 |
+
concept:agriculturalproductgrowinginstateorprovince_inv 153
|
| 155 |
+
concept:musicgenressuchasmusicgenres 154
|
| 156 |
+
concept:agentactsinlocation 155
|
| 157 |
+
concept:mountaininstate 156
|
| 158 |
+
concept:countrycurrency_inv 157
|
| 159 |
+
concept:academicprogramatuniversity 158
|
| 160 |
+
concept:automobilemakercardealersinstateorprovince 159
|
| 161 |
+
concept:drugworkedonbyagent 160
|
| 162 |
+
concept:stateorprovinceisborderedbystateorprovince_inv 161
|
| 163 |
+
concept:bookwriter 162
|
| 164 |
+
concept:teamalsoknownas 163
|
| 165 |
+
concept:agentbelongstoorganization_inv 164
|
| 166 |
+
concept:coachesteam 165
|
| 167 |
+
concept:weaponmadeincountry 166
|
| 168 |
+
concept:sportusesstadium_inv 167
|
| 169 |
+
concept:mammalsuchasmammal 168
|
| 170 |
+
concept:actorstarredinmovie 169
|
| 171 |
+
concept:buildingfeaturemadefrombuildingmaterial_inv 170
|
| 172 |
+
concept:bodypartcontainsbodypart_inv 171
|
| 173 |
+
concept:agentcompeteswithagent_inv 172
|
| 174 |
+
concept:foodcancausedisease_inv 173
|
| 175 |
+
concept:arthropodandotherarthropod_inv 174
|
| 176 |
+
concept:drugworkedonbyagent_inv 175
|
| 177 |
+
concept:producesproduct_inv 176
|
| 178 |
+
concept:animalsuchasinvertebrate_inv 177
|
| 179 |
+
concept:mountaininstate_inv 178
|
| 180 |
+
concept:politicianusmemberofpoliticalgroup 179
|
| 181 |
+
concept:objectfoundinscene 180
|
| 182 |
+
concept:fishservedwithfood_inv 181
|
| 183 |
+
concept:athleteflyouttosportsteamposition_inv 182
|
| 184 |
+
concept:invertebratefeedonfood 183
|
| 185 |
+
concept:animaleatvegetable 184
|
| 186 |
+
concept:plantrepresentemotion_inv 185
|
| 187 |
+
concept:statehascapital 186
|
| 188 |
+
concept:animaleatfood_inv 187
|
| 189 |
+
concept:newspaperincity_inv 188
|
| 190 |
+
concept:animaleatvegetable_inv 189
|
| 191 |
+
concept:teamwontrophy_inv 190
|
| 192 |
+
concept:persongraduatedschool_inv 191
|
| 193 |
+
concept:televisionstationaffiliatedwith_inv 192
|
| 194 |
+
concept:journalistwritesforpublication 193
|
| 195 |
+
concept:agentcontributedtocreativework 194
|
| 196 |
+
concept:agriculturalproductincludingagriculturalproduct_inv 195
|
| 197 |
+
concept:istallerthan_inv 196
|
| 198 |
+
concept:bacteriaisthecausativeagentofphysiologicalcondition 197
|
| 199 |
+
concept:athleteplaysinleague 198
|
| 200 |
+
concept:agriculturalproductcutintogeometricshape 199
|
| 201 |
+
concept:drughassideeffect 200
|
| 202 |
+
concept:sporthassportsteamposition_inv 201
|
| 203 |
+
concept:personhasresidenceingeopoliticallocation 202
|
| 204 |
+
concept:topmemberoforganization 203
|
| 205 |
+
concept:animalsuchasfish_inv 204
|
| 206 |
+
concept:organizationdissolvedatdate_inv 205
|
| 207 |
+
concept:coachesinleague 206
|
| 208 |
+
concept:athleteplayssport 207
|
| 209 |
+
concept:transportationincity_inv 208
|
| 210 |
+
concept:fatherofperson_inv 209
|
| 211 |
+
concept:academicfieldsuchasacademicfield 210
|
| 212 |
+
concept:agentparticipatedinevent_inv 211
|
| 213 |
+
concept:lakeinstate_inv 212
|
| 214 |
+
concept:companyeconomicsector 213
|
| 215 |
+
concept:academicprogramatuniversity_inv 214
|
| 216 |
+
concept:chemicalistypeofchemical_inv 215
|
| 217 |
+
concept:animalsuchasinsect_inv 216
|
| 218 |
+
concept:personbelongstoorganization 217
|
| 219 |
+
concept:athleteplayssportsteamposition_inv 218
|
| 220 |
+
concept:itemfoundinroom 219
|
| 221 |
+
concept:athleteplayssportsteamposition 220
|
| 222 |
+
concept:plantrepresentemotion 221
|
| 223 |
+
concept:personhasresidenceingeopoliticallocation_inv 222
|
| 224 |
+
concept:personalsoknownas_inv 223
|
| 225 |
+
concept:teamwontrophy 224
|
| 226 |
+
concept:thinghascolor_inv 225
|
| 227 |
+
concept:athleteplaysforteam 226
|
| 228 |
+
concept:headquarteredin 227
|
| 229 |
+
concept:arterycalledartery 228
|
| 230 |
+
concept:agriculturalproductcamefromcountry_inv 229
|
| 231 |
+
concept:journalistwritesforpublication_inv 230
|
| 232 |
+
concept:statelocatedingeopoliticallocation 231
|
| 233 |
+
concept:bakedgoodservedwithbeverage 232
|
| 234 |
+
concept:athleteledsportsteam 233
|
| 235 |
+
concept:sportschoolincountry 234
|
| 236 |
+
concept:furniturefoundinroom_inv 235
|
| 237 |
+
concept:statelocatedincountry 236
|
| 238 |
+
concept:countryalsoknownas_inv 237
|
| 239 |
+
concept:touristattractionsuchastouristattraction_inv 238
|
| 240 |
+
concept:agentcontributedtocreativework_inv 239
|
| 241 |
+
concept:citylocatedincountry_inv 240
|
| 242 |
+
concept:animalpreyson_inv 241
|
| 243 |
+
concept:automobilemakercardealersinstateorprovince_inv 242
|
| 244 |
+
concept:personalsoknownas 243
|
| 245 |
+
concept:cityalsoknownas_inv 244
|
| 246 |
+
concept:agriculturalproductgrowinginstateorprovince 245
|
| 247 |
+
concept:parkincity 246
|
| 248 |
+
concept:musicartistgenre_inv 247
|
| 249 |
+
concept:riveremptiesintoriver 248
|
| 250 |
+
concept:organizationalsoknownas_inv 249
|
| 251 |
+
concept:drughassideeffect_inv 250
|
| 252 |
+
concept:coachwontrophy 251
|
| 253 |
+
concept:mutualproxyfor_inv 252
|
| 254 |
+
concept:agriculturalproductcutintogeometricshape_inv 253
|
| 255 |
+
concept:organizationhiredperson_inv 254
|
| 256 |
+
concept:competeswith 255
|
| 257 |
+
concept:organizationhiredperson 256
|
| 258 |
+
concept:politicianusendorsedbypoliticianus 257
|
| 259 |
+
concept:ceoof 258
|
| 260 |
+
concept:automobilemakerdealersincity_inv 259
|
| 261 |
+
concept:chemicalistypeofchemical 260
|
| 262 |
+
concept:bankbankincountry 261
|
| 263 |
+
concept:ismultipleof_inv 262
|
| 264 |
+
concept:teamhomestadium_inv 263
|
| 265 |
+
concept:athletebeatathlete_inv 264
|
| 266 |
+
concept:personmovedtostateorprovince 265
|
| 267 |
+
concept:producesproduct 266
|
| 268 |
+
concept:coachesteam_inv 267
|
| 269 |
+
concept:organizationacronymhasname_inv 268
|
| 270 |
+
concept:musicianplaysinstrument 269
|
| 271 |
+
concept:politicianusendorsedbypoliticianus_inv 270
|
| 272 |
+
concept:personleadsorganization_inv 271
|
| 273 |
+
concept:citylocatedinstate_inv 272
|
| 274 |
+
concept:agriculturalproducttoattractinsect 273
|
| 275 |
+
concept:drugpossiblytreatsphysiologicalcondition 274
|
| 276 |
+
concept:teamplaysagainstteam 275
|
| 277 |
+
concept:arthropodcalledarthropod 276
|
| 278 |
+
concept:proxyfor_inv 277
|
| 279 |
+
concept:teamplaysincity_inv 278
|
| 280 |
+
concept:thinghasshape 279
|
| 281 |
+
concept:clothingmadefromplant_inv 280
|
| 282 |
+
concept:haswife_inv 281
|
| 283 |
+
concept:hasofficeincountry_inv 282
|
| 284 |
+
concept:buildingfeaturemadefrombuildingmaterial 283
|
| 285 |
+
concept:thinghasshape_inv 284
|
| 286 |
+
concept:sportfansincountry_inv 285
|
| 287 |
+
concept:bacteriaisthecausativeagentofphysiologicalcondition_inv 286
|
| 288 |
+
concept:athleteplayssport_inv 287
|
| 289 |
+
concept:weaponmadeincountry_inv 288
|
| 290 |
+
concept:visualartistartform_inv 289
|
| 291 |
+
concept:hasofficeincity_inv 290
|
| 292 |
+
concept:cityalsoknownas 291
|
| 293 |
+
concept:politicianholdsoffice 292
|
| 294 |
+
concept:drugpossiblytreatsphysiologicalcondition_inv 293
|
| 295 |
+
concept:locationlocatedwithinlocation 294
|
| 296 |
+
concept:teamplaysinleague_inv 295
|
| 297 |
+
concept:persondiedatage 296
|
| 298 |
+
concept:statelocatedingeopoliticallocation_inv 297
|
| 299 |
+
concept:buildinglocatedincity_inv 298
|
| 300 |
+
concept:hotelincity 299
|
| 301 |
+
concept:agentparticipatedinevent 300
|
| 302 |
+
concept:airportincity 301
|
| 303 |
+
concept:bakedgoodservedwithbeverage_inv 302
|
| 304 |
+
concept:synonymfor 303
|
| 305 |
+
concept:statehascapital_inv 304
|
| 306 |
+
concept:newspaperincity 305
|
| 307 |
+
concept:objectpartofobject_inv 306
|
| 308 |
+
concept:bankboughtbank 307
|
| 309 |
+
concept:agriculturalproductcookedwithagriculturalproduct_inv 308
|
| 310 |
+
concept:athleteflyouttosportsteamposition 309
|
| 311 |
+
concept:citylocatedingeopoliticallocation 310
|
| 312 |
+
concept:agriculturalproductcomingfromvertebrate_inv 311
|
| 313 |
+
concept:agriculturalproducttoattractinsect_inv 312
|
| 314 |
+
concept:animaldevelopdisease 313
|
| 315 |
+
concept:beveragemadefrombeverage 314
|
| 316 |
+
concept:personbornincity_inv 315
|
| 317 |
+
concept:athletehomestadium_inv 316
|
| 318 |
+
concept:languageofcountry 317
|
| 319 |
+
concept:plantgrowinginplant 318
|
| 320 |
+
concept:beveragecontainsprotein 319
|
| 321 |
+
concept:mammalsuchasmammal_inv 320
|
| 322 |
+
concept:istallerthan 321
|
| 323 |
+
concept:automobilemakerdealersincountry_inv 322
|
| 324 |
+
concept:animaldevelopdisease_inv 323
|
| 325 |
+
concept:directordirectedmovie 324
|
| 326 |
+
concept:coachesinleague_inv 325
|
| 327 |
+
concept:fooddecreasestheriskofdisease_inv 326
|
| 328 |
+
concept:animalthatfeedoninsect 327
|
| 329 |
+
concept:animaleatfood 328
|
| 330 |
+
concept:latitudelongitude_inv 329
|
| 331 |
+
concept:parentofperson 330
|
| 332 |
+
concept:automakerproducesmodel_inv 331
|
| 333 |
+
concept:atdate 332
|
| 334 |
+
concept:athleteplaysinleague_inv 333
|
| 335 |
+
concept:personhasjobposition_inv 334
|
| 336 |
+
concept:awardtrophytournamentisthechampionshipgameofthenationalsport 335
|
| 337 |
+
concept:competeswith_inv 336
|
| 338 |
+
concept:companyalsoknownas_inv 337
|
| 339 |
+
concept:politicianholdsoffice_inv 338
|
| 340 |
+
concept:statelocatedincountry_inv 339
|
| 341 |
+
concept:sportsgamewinner_inv 340
|
| 342 |
+
concept:animalpreyson 341
|
| 343 |
+
concept:synonymfor_inv 342
|
| 344 |
+
concept:agriculturalproductgrowninlandscapefeatures_inv 343
|
| 345 |
+
concept:thinghascolor 344
|
| 346 |
+
concept:athleteinjuredhisbodypart 345
|
| 347 |
+
concept:sportusesequipment 346
|
| 348 |
+
concept:invertebratefeedonfood_inv 347
|
| 349 |
+
concept:organizationheadquarteredincountry 348
|
| 350 |
+
concept:athletewinsawardtrophytournament 349
|
| 351 |
+
concept:animalistypeofanimal 350
|
| 352 |
+
concept:sporthassportsteamposition 351
|
| 353 |
+
concept:politicianusholdsoffice 352
|
| 354 |
+
concept:animalsuchasinsect 353
|
| 355 |
+
concept:citylocatedincountry 354
|
| 356 |
+
concept:academicfieldconcernssubject 355
|
| 357 |
+
concept:subpartoforganization 356
|
| 358 |
+
concept:acquired 357
|
| 359 |
+
concept:subpartof 358
|
| 360 |
+
concept:agentcreated_inv 359
|
| 361 |
+
concept:sportsgamewinner 360
|
| 362 |
+
concept:politicianusmemberofpoliticalgroup_inv 361
|
| 363 |
+
concept:ismultipleof 362
|
| 364 |
+
concept:teamhomestadium 363
|
| 365 |
+
concept:organizationheadquarteredincountry_inv 364
|
| 366 |
+
concept:citycapitalofcountry_inv 365
|
| 367 |
+
concept:professionistypeofprofession 366
|
| 368 |
+
concept:acquired_inv 367
|
| 369 |
+
concept:sportsgamesport_inv 368
|
| 370 |
+
concept:proxyfor 369
|
| 371 |
+
concept:agriculturalproductcamefromcountry 370
|
| 372 |
+
concept:arthropodcalledarthropod_inv 371
|
| 373 |
+
concept:topmemberoforganization_inv 372
|
| 374 |
+
concept:subpartoforganization_inv 373
|
| 375 |
+
concept:persongraduatedschool 374
|
| 376 |
+
concept:coachwontrophy_inv 375
|
| 377 |
+
concept:athletewinsawardtrophytournament_inv 376
|
| 378 |
+
concept:touristattractionsuchastouristattraction 377
|
| 379 |
+
concept:agriculturalproductcontainchemical 378
|
| 380 |
+
concept:personchargedwithcrime 379
|
| 381 |
+
concept:agriculturalproductcomingfromvertebrate 380
|
| 382 |
+
concept:athleteplaysforteam_inv 381
|
| 383 |
+
concept:agentcontrols 382
|
| 384 |
+
concept:locationlocatedwithinlocation_inv 383
|
| 385 |
+
concept:personhascitizenship 384
|
| 386 |
+
concept:worksfor_inv 385
|
| 387 |
+
concept:hassibling_inv 386
|
| 388 |
+
concept:leaguestadiums 387
|
| 389 |
+
concept:bodypartcontainsbodypart 388
|
| 390 |
+
concept:arterycalledartery_inv 389
|
| 391 |
+
concept:hashusband_inv 390
|
| 392 |
+
concept:citycapitalofcountry 391
|
| 393 |
+
concept:organizationheadquarteredinstateorprovince_inv 392
|
| 394 |
+
concept:organizationheadquarteredinstateorprovince 393
|
| 395 |
+
concept:lakeinstate 394
|
| 396 |
+
concept:sportsgamesport 395
|
| 397 |
+
concept:organizationterminatedperson 396
|
| 398 |
+
concept:hasofficeincountry 397
|
| 399 |
+
concept:agentcollaborateswithagent 398
|
| 400 |
+
concept:musicianplaysinstrument_inv 399
|
src/research/COINs-KGGeneration/data/NELL-995/relation2vec.bern
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
src/research/COINs-KGGeneration/data/NELL-995/test.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
src/research/COINs-KGGeneration/data/NELL-995/train.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:826606112803d19cef310b45a908e6793d89c0ce99fed60d71a9c2095b71d8f6
|
| 3 |
+
size 12571114
|
src/research/COINs-KGGeneration/data/NELL-995/valid.txt
ADDED
|
@@ -0,0 +1,543 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
concept_athlete_roberto_alomar concept:athleteplaysinleague concept_sportsleague_mlb
|
| 2 |
+
concept_sportsteam_eastern_michigan_eagles concept:teamplaysinleague concept_sportsleague_ncaa
|
| 3 |
+
concept_athlete_kris_draper concept:athleteplaysforteam concept_sportsteam_red_wings
|
| 4 |
+
concept_athlete_gabe_kapler concept:athleteplaysforteam concept_sportsteam_tampa_bay_devil_rays
|
| 5 |
+
concept_athlete_zach_miner concept:athleteplayssport concept_sport_baseball
|
| 6 |
+
concept_actor_howard_witt concept:worksfor concept_website_chicago_tribune
|
| 7 |
+
concept_city_london_city concept:organizationhiredperson concept_politicianus_ken_livingstone
|
| 8 |
+
concept_athlete_derrick_harvey concept:athleteplayssport concept_sport_football
|
| 9 |
+
concept_sportsteam_dowling_college_golden_lions concept:teamplaysinleague concept_sportsleague_ncaa
|
| 10 |
+
concept_coach_bill_stewart concept:worksfor concept_city_abc
|
| 11 |
+
concept_athlete_jerry_rice concept:athleteplaysinleague concept_sportsleague_nfl
|
| 12 |
+
concept_athlete_johnny_estrada concept:athleteplaysinleague concept_sportsleague_mlb
|
| 13 |
+
concept_coach_mike_martz concept:worksfor concept_sportsteam_rams
|
| 14 |
+
concept_company_cnn concept:organizationhiredperson concept_personmexico_ryan_whitney
|
| 15 |
+
concept_coach_brady_quinn concept:athleteplaysforteam concept_sportsteam_cleveland_browns
|
| 16 |
+
concept_athlete_lebron concept:personborninlocation concept_city_york
|
| 17 |
+
concept_coach_tom_renney concept:worksfor concept_sportsteam_rangers
|
| 18 |
+
concept_athlete_print concept:agentbelongstoorganization concept_company_adobe
|
| 19 |
+
concept_athlete_dustin_pedroia concept:athleteplayssport concept_sport_baseball
|
| 20 |
+
concept_sportsteam_utah_valley_wolverines concept:teamplaysinleague concept_sportsleague_ncaa
|
| 21 |
+
concept_athlete_cody_scarpetta concept:athleteplayssport concept_sport_baseball
|
| 22 |
+
concept_coach_a_j__burnett concept:athleteplayssport concept_sport_baseball
|
| 23 |
+
concept_sportsteam_ivy_league concept:teamplaysinleague concept_sportsleague_ncaa
|
| 24 |
+
concept_athlete_lorenzen_wright concept:athleteplaysforteam concept_sportsteam_reds
|
| 25 |
+
concept_person_abbas concept:personleadsorganization concept_musicartist_faction
|
| 26 |
+
concept_university_cu concept:organizationhiredperson concept_coach_gary_barnett
|
| 27 |
+
concept_sportsteam_mac_gear concept:teamplaysinleague concept_sportsleague_ncaa
|
| 28 |
+
concept_sportsteam_md_baltimore_county_retrievers concept:teamplaysinleague concept_sportsleague_ncaa
|
| 29 |
+
concept_person_christopher002 concept:personborninlocation concept_city_york
|
| 30 |
+
concept_politicianus_william_powers concept:worksfor concept_magazine_national_journal
|
| 31 |
+
concept_sportsteam_southeastern_louisiana_lions concept:teamplaysinleague concept_sportsleague_ncaa
|
| 32 |
+
concept_sportsteam_columbia_university_lions concept:teamplaysinleague concept_sportsleague_ncaa
|
| 33 |
+
concept_university_msu concept:organizationhiredperson concept_coach_dantonio
|
| 34 |
+
concept_athlete_phil_coke concept:athletehomestadium concept_stadiumoreventvenue_pete_times_forum
|
| 35 |
+
concept_person_arnold001 concept:personborninlocation concept_city_york
|
| 36 |
+
concept_athlete_jeff_garcia concept:athleteplaysforteam concept_sportsteam_bucs
|
| 37 |
+
concept_blog_audubon concept:organizationheadquarteredincity concept_city_new_orleans
|
| 38 |
+
concept_personus_scott_pelley concept:personleadsorganization concept_televisionnetwork_cbs
|
| 39 |
+
concept_coach_bobby_gonzalez concept:worksfor concept_university_seton_hall
|
| 40 |
+
concept_person_rob_parker concept:worksfor concept_televisionstation_detroit_news
|
| 41 |
+
concept_personus_george_lucas concept:worksfor concept_magazine_lucasarts
|
| 42 |
+
concept_company_west_virginia concept:organizationhiredperson concept_coach_beilein
|
| 43 |
+
concept_musician_agencies concept:agentbelongstoorganization concept_landscapefeatures_states
|
| 44 |
+
concept_city_pittsburgh concept:organizationhiredperson concept_male_dave_wannstedt
|
| 45 |
+
concept_personmexico_brendan_harris concept:athletehomestadium concept_stadiumoreventvenue_yankee_stadium
|
| 46 |
+
concept_coach_boeheim concept:worksfor concept_sportsleague_syracuse
|
| 47 |
+
concept_personmexico_craig_counsell concept:athleteplaysforteam concept_sportsteam_yankees
|
| 48 |
+
concept_journalist_kathleen_parker concept:worksfor concept_newspaper_washington_post_writers_group
|
| 49 |
+
concept_company_west_virginia concept:organizationhiredperson concept_athlete_rich_rodriguez
|
| 50 |
+
concept_person_arthur concept:personborninlocation concept_county_york_city
|
| 51 |
+
concept_company_clinton concept:organizationheadquarteredincity concept_city_brooklyn
|
| 52 |
+
concept_sportsteam_jacksonville_jaguars concept:teamplaysinleague concept_sportsleague_nfl
|
| 53 |
+
concept_sportsteam_man_united concept:teamplaysinleague concept_sportsleague_fa
|
| 54 |
+
concept_radiostation_kogo concept:organizationheadquarteredincity concept_city_san_diego
|
| 55 |
+
concept_sportsteam_shenandoah_hornets concept:teamplaysinleague concept_sportsleague_ncaa
|
| 56 |
+
concept_sportsteam_edmonton_oilers concept:teamplayssport concept_sport_hockey
|
| 57 |
+
concept_athlete_hideo_nomo concept:athleteplaysforteam concept_sportsteam_dodgers
|
| 58 |
+
concept_sportsteam_tufts_jumbos concept:teamplaysinleague concept_sportsleague_ncaa
|
| 59 |
+
concept_sportsteam_cavs concept:organizationhiredperson concept_writer_brown
|
| 60 |
+
concept_radiostation_wfp concept:organizationheadquarteredincity concept_city_rome
|
| 61 |
+
concept_athlete_graham_cooke concept:athleteplayssport concept_sport_golf
|
| 62 |
+
concept_coach_torry_holt concept:athleteplayssport concept_sport_football
|
| 63 |
+
concept_sportsteam_crew concept:teamplayssport concept_sport_basketball
|
| 64 |
+
concept_sportsteam_miami_marlins concept:teamplaysinleague concept_sportsleague_mlb
|
| 65 |
+
concept_coach_gene_chizik concept:worksfor concept_university_auburn
|
| 66 |
+
concept_athlete_kevin_hart concept:athleteplayssport concept_sport_baseball
|
| 67 |
+
concept_athlete_ethier concept:athleteplaysforteam concept_sportsteam_dodgers
|
| 68 |
+
concept_sportsteam_unlv_runnin_rebels concept:teamplaysinleague concept_sportsleague_ncaa
|
| 69 |
+
concept_athlete_red_grange concept:athleteplaysinleague concept_sportsleague_nfl
|
| 70 |
+
concept_ceo_sheldon_adelson concept:personleadsorganization concept_biotechcompany_las_vegas_sands_corp_
|
| 71 |
+
concept_athlete_dimitar_berbatov concept:athleteplaysforteam concept_sportsteam_man_utd
|
| 72 |
+
concept_athlete_ronaldo concept:athleteplaysforteam concept_sportsteam_man_utd
|
| 73 |
+
concept_geopoliticallocation_manchester_city concept:teamplaysinleague concept_sportsleague_fa
|
| 74 |
+
concept_journalist_jacques_steinberg concept:worksfor concept_website_new_york_times
|
| 75 |
+
concept_coach_lenny_moore concept:athleteplaysforteam concept_sportsteam_steelers
|
| 76 |
+
concept_university_cu concept:organizationhiredperson concept_coach_dan_hawkins
|
| 77 |
+
concept_athlete_marwin_vega concept:athleteplayssport concept_sport_baseball
|
| 78 |
+
concept_athlete_johan_petro concept:athleteplaysinleague concept_sportsleague_nba
|
| 79 |
+
concept_person_peter_munk concept:worksfor concept_biotechcompany_barrick_gold_corporation
|
| 80 |
+
concept_radiostation_kxcv concept:organizationheadquarteredincity concept_city_maryville
|
| 81 |
+
concept_athlete_ken_venturi concept:athleteplayssport concept_sport_golf
|
| 82 |
+
concept_stateorprovince_illinois concept:organizationhiredperson concept_coach_bruce_weber
|
| 83 |
+
concept_journalist_george_will concept:worksfor concept_city_abc
|
| 84 |
+
concept_ceo_tod_nielsen concept:personleadsorganization concept_company_borland
|
| 85 |
+
concept_personus_john_browne concept:worksfor concept_company_bp001
|
| 86 |
+
concept_athlete_tony_esposito concept:athletehomestadium concept_stadiumoreventvenue_wrigley_field
|
| 87 |
+
concept_athlete_tony_pena concept:athleteplaysinleague concept_sportsleague_mlb
|
| 88 |
+
concept_person_carly_fiorina001 concept:personleadsorganization concept_university_hewlett_packard
|
| 89 |
+
concept_sportsteam_rhode_island_rams concept:teamplaysinleague concept_sportsleague_ncaa
|
| 90 |
+
concept_athlete_edgar_renteria concept:athleteplayssport concept_sport_baseball
|
| 91 |
+
concept_person_bill concept:personborninlocation concept_city_york
|
| 92 |
+
concept_athlete_gary_sheffield concept:athleteplaysforteam concept_sportsteam_yankees
|
| 93 |
+
concept_company_stax concept:organizationhiredperson concept_ceo_jim_stewart
|
| 94 |
+
concept_person_edward001 concept:personborninlocation concept_county_york_city
|
| 95 |
+
concept_athlete_miroslav_klose concept:athleteplaysforteam concept_sportsteam_germany
|
| 96 |
+
concept_company_murray concept:organizationheadquarteredincity concept_island_manhattan
|
| 97 |
+
concept_personmexico_ryan_whitney concept:worksfor concept_governmentorganization_capitol
|
| 98 |
+
concept_athlete_jordan_schafer concept:athleteplayssport concept_sport_baseball
|
| 99 |
+
concept_sportsteam_new_paltz_hawks concept:teamplaysinleague concept_sportsleague_ncaa
|
| 100 |
+
concept_athlete_renaldo_balkman concept:athleteplaysforteam concept_sportsteam_nuggets
|
| 101 |
+
concept_coach_tyler_kennedy concept:athleteplaysforteam concept_sportsteam_pittsburgh_penguins
|
| 102 |
+
concept_stateorprovince_colorado concept:organizationhiredperson concept_coach_gary_barnett
|
| 103 |
+
concept_sportsteam_northeast_wisconsin_technical_college concept:teamplaysinleague concept_sportsleague_ncaa
|
| 104 |
+
concept_athlete_jimmy_gobble concept:athleteplayssport concept_sport_baseball
|
| 105 |
+
concept_sportsteam_se_louisiana_lions concept:teamplaysinleague concept_sportsleague_ncaa
|
| 106 |
+
concept_athlete_logan_kensing concept:athleteplayssport concept_sport_baseball
|
| 107 |
+
concept_terroristorganization_state concept:agentbelongstoorganization concept_politicalparty_house
|
| 108 |
+
concept_athlete_guillermo_mota concept:athleteplayssport concept_sport_baseball
|
| 109 |
+
concept_sportsteam_new_york_bobcats concept:teamplaysinleague concept_sportsleague_ncaa
|
| 110 |
+
concept_coach_dave_winfield concept:athleteplayssport concept_sport_baseball
|
| 111 |
+
concept_personnorthamerica_kenneth_d__lewis concept:personleadsorganization concept_country___america
|
| 112 |
+
concept_personeurope_william_paley concept:personleadsorganization concept_company_cnn__pbs
|
| 113 |
+
concept_coach_j_j__hardy concept:athleteplayssport concept_sport_baseball
|
| 114 |
+
concept_athlete_rich_gannon concept:athleteplaysforteam concept_sportsteam_oakland_raiders
|
| 115 |
+
concept_website_experience concept:organizationhiredperson concept_personmexico_ryan_whitney
|
| 116 |
+
concept_televisionstation_wgby_tv concept:agentbelongstoorganization concept_company_pbs
|
| 117 |
+
concept_person_andrea concept:personborninlocation concept_county_york_city
|
| 118 |
+
concept_athlete_ramon_ramirez concept:athleteplaysinleague concept_sportsleague_mlb
|
| 119 |
+
concept_televisionstation_wxia concept:organizationheadquarteredincity concept_city_atlanta
|
| 120 |
+
concept_politicsblog_rolling_stone concept:organizationhiredperson concept_personus_jann_wenner
|
| 121 |
+
concept_athlete_jermaine_clark concept:athleteplayssport concept_sport_baseball
|
| 122 |
+
concept_athlete_kevin_cash concept:athleteplayssport concept_sport_baseball
|
| 123 |
+
concept_company_borders concept:organizationhiredperson concept_comedian_george_jones
|
| 124 |
+
concept_writer_byron_york concept:personleadsorganization concept_newspaper_national_review
|
| 125 |
+
concept_city_dallas concept:organizationhiredperson concept_personaustralia_avery_johnson
|
| 126 |
+
concept_nongovorganization_u_s_ concept:organizationhiredperson concept_coach_bob_bradley
|
| 127 |
+
concept_person_cole concept:personborninlocation concept_county_york_city
|
| 128 |
+
concept_writer_anne_applebaum concept:worksfor concept_website_washington_post
|
| 129 |
+
concept_politicianus_bill_kristol concept:worksfor concept_website_new_york_times
|
| 130 |
+
concept_athlete_eduardo_perez concept:athleteplayssport concept_sport_baseball
|
| 131 |
+
concept_building_united_states_capitol concept:organizationheadquarteredincity concept_city_washington_d_c
|
| 132 |
+
concept_athlete_rick_vandenhurk concept:athleteplayssport concept_sport_baseball
|
| 133 |
+
concept_athlete_tyler_flowers concept:athleteplaysinleague concept_sportsleague_mlb
|
| 134 |
+
concept_athlete_brad_james concept:athleteplayssport concept_sport_baseball
|
| 135 |
+
concept_radiostation_king concept:organizationheadquarteredincity concept_city_seattle
|
| 136 |
+
concept_athlete_luis_valbuena concept:athleteplaysinleague concept_sportsleague_mlb
|
| 137 |
+
concept_athlete_jesse_litsch concept:athleteplayssport concept_sport_baseball
|
| 138 |
+
concept_athlete_bernard_berrian concept:athletehomestadium concept_stadiumoreventvenue_metrodome
|
| 139 |
+
concept_sportsteam_northern_illinois_huskies concept:teamplaysinleague concept_sportsleague_ncaa
|
| 140 |
+
concept_city_discussion concept:organizationhiredperson concept_personmexico_ryan_whitney
|
| 141 |
+
concept_biotechcompany_tesco concept:organizationhiredperson concept_ceo_sir_terry_leahy
|
| 142 |
+
concept_personcanada_ian_davis concept:worksfor concept_company_mckinsey
|
| 143 |
+
concept_person_sabrina concept:personborninlocation concept_city_york
|
| 144 |
+
concept_actor_megyn_kelly concept:worksfor concept_governmentorganization_fox_news
|
| 145 |
+
concept_athlete_matt_murton concept:athletehomestadium concept_stadiumoreventvenue_wrigley_field
|
| 146 |
+
concept_athlete_rafael_soriano concept:athleteplayssport concept_sport_baseball
|
| 147 |
+
concept_person_ahmadinejad concept:personborninlocation concept_city_york
|
| 148 |
+
concept_athlete_deron_williams concept:athleteplaysforteam concept_sportsteam_utah_jazz
|
| 149 |
+
concept_athlete_jaime_garcia concept:athleteplayssport concept_sport_baseball
|
| 150 |
+
concept_athlete_jay_morrish concept:athleteplayssport concept_sport_golf
|
| 151 |
+
concept_sportsteam_texas_arlington_mavericks concept:teamplaysinleague concept_sportsleague_ncaa
|
| 152 |
+
concept_person_jessica001 concept:personborninlocation concept_city_york
|
| 153 |
+
concept_athlete_henrik_lundqvist concept:athleteplaysforteam concept_sportsteam_rangers
|
| 154 |
+
concept_athlete_edwin_encarnacion concept:athleteplayssport concept_sport_baseball
|
| 155 |
+
concept_ceo_larry_probst concept:personleadsorganization concept_company_electronic_arts
|
| 156 |
+
concept_athlete_felix_pie concept:athleteplayssport concept_sport_baseball
|
| 157 |
+
concept_sportsteam_minnesota_vikings concept:organizationhiredperson concept_coach_dennis_green
|
| 158 |
+
concept_coach_richard_hamilton concept:athleteplaysforteam concept_sportsteam_pistons
|
| 159 |
+
concept_person_turner concept:personborninlocation concept_city_york
|
| 160 |
+
concept_personmexico_ryan_church concept:athleteplaysinleague concept_sportsleague_mlb
|
| 161 |
+
concept_athlete_paul_hornung concept:athleteplaysinleague concept_sportsleague_nfl
|
| 162 |
+
concept_athlete_bob_wickman concept:athleteplayssport concept_sport_baseball
|
| 163 |
+
concept_personcanada_peter_mansbridge concept:worksfor concept_company_cbc
|
| 164 |
+
concept_city_washington_d_c concept:organizationhiredperson concept_celebrity_don_james
|
| 165 |
+
concept_sportsteam_rochester_yellow_jackets concept:teamplaysinleague concept_sportsleague_ncaa
|
| 166 |
+
concept_person_courtney concept:personborninlocation concept_city_york
|
| 167 |
+
concept_athlete_magic_johnson concept:athleteplaysforteam concept_sportsteam_los_angeles_lakers
|
| 168 |
+
concept_scientist_ingvar_kamprad concept:personleadsorganization concept_company_ikea
|
| 169 |
+
concept_athlete_brad_voyles concept:athleteplayssport concept_sport_baseball
|
| 170 |
+
concept_person_douglas concept:personborninlocation concept_county_york_city
|
| 171 |
+
concept_person_matthews concept:personborninlocation concept_city_york
|
| 172 |
+
concept_athlete_jose_garcia concept:athleteplayssport concept_sport_baseball
|
| 173 |
+
concept_televisionstation_ktar concept:organizationheadquarteredincity concept_city_phoenix
|
| 174 |
+
concept_radiostation_kvoa_tv concept:organizationheadquarteredincity concept_city_tucson
|
| 175 |
+
concept_sportsteam_milwaukee_braves concept:teamplayssport concept_sport_baseball
|
| 176 |
+
concept_athlete_jerome_bettis concept:athleteplaysforteam concept_sportsteam_steelers
|
| 177 |
+
concept_sportsteam_detroit_lions concept:teamplaysinleague concept_sportsleague_nfl
|
| 178 |
+
concept_sportsteam_red_sox concept:teamplayssport concept_sport_baseball
|
| 179 |
+
concept_athlete_charles_barkley concept:athleteplaysinleague concept_sportsleague_nba
|
| 180 |
+
concept_radiostation_kunm concept:organizationheadquarteredincity concept_city_albuquerque
|
| 181 |
+
concept_athlete_charles_barkley concept:athleteplaysforteam concept_sportsteam_rockets
|
| 182 |
+
concept_sportsteam_north_park_vikings concept:teamplaysinleague concept_sportsleague_ncaa
|
| 183 |
+
concept_athlete_craig_breslow concept:athleteplayssport concept_sport_baseball
|
| 184 |
+
concept_coach_matthew_lombardi concept:athleteplaysforteam concept_sportsteam_lee_flames
|
| 185 |
+
concept_athlete_philippoussis concept:athleteplayssport concept_sport_tennis
|
| 186 |
+
concept_coach_guus_hiddink concept:worksfor concept_country_russia
|
| 187 |
+
concept_athlete_travis_blackley concept:athleteplayssport concept_sport_baseball
|
| 188 |
+
concept_personaustralia_smith concept:worksfor concept_sportsteam_falcons
|
| 189 |
+
concept_athlete_kei_igawa concept:athleteplaysinleague concept_sportsleague_mlb
|
| 190 |
+
concept_radiostation_kisw_fm concept:organizationheadquarteredincity concept_city_seattle
|
| 191 |
+
concept_sportsteam_santa_clara_university concept:teamplaysinleague concept_sportsleague_international
|
| 192 |
+
concept_coach_lendale_white concept:athletehomestadium concept_stadiumoreventvenue_lp_field
|
| 193 |
+
concept_personmexico_carlos_guevara concept:athleteplayssport concept_sport_baseball
|
| 194 |
+
concept_journalist_richard_anderson concept:personleadsorganization concept_biotechcompany_delta_air_lines_inc_
|
| 195 |
+
concept_athlete_brian_gionta concept:athleteplaysforteam concept_sportsteam_devils
|
| 196 |
+
concept_athlete_dmitri_young concept:athleteplaysforteam concept_sportsteam_detroit_tigers
|
| 197 |
+
concept_coach_van_note concept:athleteplaysforteam concept_sportsteam_pirates
|
| 198 |
+
concept_scientist_mitch_kapor concept:worksfor concept_city_lotus
|
| 199 |
+
concept_blog_today concept:organizationhiredperson concept_personmexico_ryan_whitney
|
| 200 |
+
concept_coach_mike_d_antoni concept:worksfor concept_sportsteam_knicks
|
| 201 |
+
concept_sportsleague_new concept:organizationhiredperson concept_coach_spagnuolo
|
| 202 |
+
concept_televisionstation_kutv concept:organizationheadquarteredincity concept_county_salt_lake
|
| 203 |
+
concept_coach_stoops concept:worksfor concept_company_arizona
|
| 204 |
+
concept_athlete_jermaine_o_neal concept:athleteplaysforteam concept_sportsteam_pacers
|
| 205 |
+
concept_male_kirsten_powers concept:worksfor concept_mountain_fox
|
| 206 |
+
concept_athlete_mark_prior concept:athleteplayssport concept_sport_baseball
|
| 207 |
+
concept_sportsteam_oakland_athletics concept:teamplaysinleague concept_sportsleague_mlb
|
| 208 |
+
concept_country_party concept:organizationhiredperson concept_personus_party
|
| 209 |
+
concept_coach_nate_mclouth concept:athleteplayssport concept_sport_baseball
|
| 210 |
+
concept_athlete_warren_sapp concept:athleteplaysinleague concept_sportsleague_nfl
|
| 211 |
+
concept_person_lee001 concept:personborninlocation concept_city_york
|
| 212 |
+
concept_personaustralia_david_nagel concept:personleadsorganization concept_company_palmsource
|
| 213 |
+
concept_sportsteam_buffalo_bills concept:organizationhiredperson concept_coach_jauron
|
| 214 |
+
concept_athlete_sidney_crosby concept:athleteplaysforteam concept_sportsteam_pittsburgh_penguins
|
| 215 |
+
concept_personmexico_shaun_marcum concept:athleteplaysinleague concept_sportsleague_mlb
|
| 216 |
+
concept_sportsteam_oregon_state_beavers concept:teamplaysinleague concept_sportsleague_ncaa
|
| 217 |
+
concept_athlete_lidstrom concept:athleteplaysforteam concept_sportsteam_red_wings
|
| 218 |
+
concept_sportsteam_australian_national_university concept:teamplaysinleague concept_sportsleague_international
|
| 219 |
+
concept_athlete_farmar concept:athletehomestadium concept_stadiumoreventvenue_staples_center
|
| 220 |
+
concept_athlete_victor_diaz concept:athleteplayssport concept_sport_baseball
|
| 221 |
+
concept_personmexico_ryan_whitney concept:worksfor concept_city_washington_d_c
|
| 222 |
+
concept_athlete_jeff_lacy concept:athleteplayssport concept_sport_boxing
|
| 223 |
+
concept_coach_kip_wells concept:athleteplaysforteam concept_sportsteam_bruins
|
| 224 |
+
concept_ceo_david_gergen concept:worksfor concept_retailstore_united_technologies
|
| 225 |
+
concept_country___america concept:organizationhiredperson concept_personmexico_ryan_whitney
|
| 226 |
+
concept_athlete_dwight_howard concept:athleteplaysinleague concept_sportsleague_nba
|
| 227 |
+
concept_sportsteam_brewers concept:teamplaysinleague concept_sportsleague_mlb
|
| 228 |
+
concept_athlete_bryzgalov concept:athletehomestadium concept_stadiumoreventvenue_honda_center
|
| 229 |
+
concept_stateorprovince_minnesota concept:organizationhiredperson concept_coach_tim_brewster
|
| 230 |
+
concept_sportsteam_cavaliers concept:teamplaysinleague concept_sportsleague_nba
|
| 231 |
+
concept_coach_kevin_youkilis concept:athleteplaysinleague concept_sportsleague_mlb
|
| 232 |
+
concept_athlete_aaron_fultz concept:athleteplayssport concept_sport_baseball
|
| 233 |
+
concept_coach_ed_orgeron concept:worksfor concept_stateorprovince_ole_miss
|
| 234 |
+
concept_sportsteam_va_commonwealth_rams concept:teamplaysinleague concept_sportsleague_ncaa
|
| 235 |
+
concept_website_fortune concept:organizationheadquarteredincity concept_city_new_york
|
| 236 |
+
concept_athlete_randall_simon concept:athleteplaysforteam concept_sportsteam_pirates
|
| 237 |
+
concept_female_sarah_caldwell concept:personleadsorganization concept_organization_opera_company_of_boston
|
| 238 |
+
concept_radiostation_kola concept:organizationheadquarteredincity concept_city_redlands
|
| 239 |
+
concept_person_daniel concept:personborninlocation concept_airport_jersey
|
| 240 |
+
concept_person_angela concept:personborninlocation concept_city_york
|
| 241 |
+
concept_university_novartis concept:organizationhiredperson concept_ceo_daniel_vasella
|
| 242 |
+
concept_athlete_brian_moehler concept:athleteplaysinleague concept_sportsleague_mlb
|
| 243 |
+
concept_personaustralia_smith concept:worksfor concept_university_oklahoma_state
|
| 244 |
+
concept_radiostation_kprl concept:organizationheadquarteredincity concept_city_paso_robles
|
| 245 |
+
concept_athlete_mike_lowell concept:athleteplaysforteam concept_sportsteam_red_sox
|
| 246 |
+
concept_televisionstation_kfmb concept:organizationheadquarteredincity concept_city_san_diego
|
| 247 |
+
concept_university_raiders concept:organizationhiredperson concept_actor_bill_callahan
|
| 248 |
+
concept_athlete_joe_sakic concept:athleteplayssport concept_sport_hockey
|
| 249 |
+
concept_journalist_joe_henderson concept:worksfor concept_televisionstation_tampa_tribune
|
| 250 |
+
concept_actor_scott_mcnealy concept:worksfor concept_company_sun
|
| 251 |
+
concept_sportsteam_sam_houston_state_bearkats concept:teamplaysinleague concept_sportsleague_ncaa
|
| 252 |
+
concept_athlete_steve_trachsel concept:athleteplayssport concept_sport_baseball
|
| 253 |
+
concept_personmexico_ryan_whitney concept:worksfor concept_nongovorganization_council
|
| 254 |
+
concept_sportsteam_marshall_university concept:teamplayssport concept_sport_basketball
|
| 255 |
+
concept_city_georgetown concept:organizationhiredperson concept_person_thompson
|
| 256 |
+
concept_person_mitchell concept:personborninlocation concept_county_york_city
|
| 257 |
+
concept_athlete_juan_acevedo concept:athleteplayssport concept_sport_baseball
|
| 258 |
+
concept_sportsteam_atlantic_coast_conference concept:teamplaysinleague concept_sportsleague_ncaa
|
| 259 |
+
concept_sportsteam_rockies concept:teamplaysinleague concept_sportsleague_mlb
|
| 260 |
+
concept_university_kansas_city concept:organizationhiredperson concept_athlete_paul_brown
|
| 261 |
+
concept_sportsteam_maryland_baltimore_county_retrievers concept:teamplaysinleague concept_sportsleague_ncaa
|
| 262 |
+
concept_athlete_evan_longoria concept:athleteplayssport concept_sport_baseball
|
| 263 |
+
concept_person_pat_riley concept:worksfor concept_sportsteam_heat
|
| 264 |
+
concept_person_ron_perelman concept:worksfor concept_company_revlon
|
| 265 |
+
concept_athlete_chris_davis concept:athleteplayssport concept_sport_hockey
|
| 266 |
+
concept_university_kansas_state concept:organizationhiredperson concept_actor_ron_prince
|
| 267 |
+
concept_athlete_cedric_simmons concept:athleteplaysinleague concept_sportsleague_nba
|
| 268 |
+
concept_university_byu concept:organizationhiredperson concept_coach_gary_crowton
|
| 269 |
+
concept_sportsteam_emory_eagles concept:teamplaysinleague concept_sportsleague_ncaa
|
| 270 |
+
concept_person_otis concept:personborninlocation concept_county_york_city
|
| 271 |
+
concept_sportsteam_morehead_state_eagles concept:teamplaysinleague concept_sportsleague_ncaa
|
| 272 |
+
concept_sportsteam_montana_state concept:teamplaysinleague concept_sportsleague_ncaa
|
| 273 |
+
concept_athlete_chris_davis concept:athleteplaysinleague concept_sportsleague_nhl
|
| 274 |
+
concept_city_toronto concept:organizationhiredperson concept_coach_mitch_williams
|
| 275 |
+
concept_university_unc concept:organizationhiredperson concept_coach_dean_smith
|
| 276 |
+
concept_athlete_carlos_beltran concept:athleteplaysinleague concept_sportsleague_mlb
|
| 277 |
+
concept_coach_steve_spurrier concept:worksfor concept_sportsteam_redskins
|
| 278 |
+
concept_athlete_mewelde_moore concept:athletehomestadium concept_stadiumoreventvenue_heinz_field
|
| 279 |
+
concept_sportsteam_hampton_university concept:teamplayssport concept_sport_basketball
|
| 280 |
+
concept_company_missouri concept:organizationhiredperson concept_person_anderson
|
| 281 |
+
concept_company_time_warner concept:organizationhiredperson concept_person_gerald_levin
|
| 282 |
+
concept_athlete_grant_hill concept:athleteplaysinleague concept_sportsleague_nba
|
| 283 |
+
concept_coach_marion_barber_iii concept:athleteplaysforteam concept_sportsteam_dallas_cowboys
|
| 284 |
+
concept_athlete_james_farrior concept:athletehomestadium concept_stadiumoreventvenue_heinz_field
|
| 285 |
+
concept_person_caroline002 concept:personborninlocation concept_city_york
|
| 286 |
+
concept_athlete_rip_hamilton concept:athleteplaysinleague concept_sportsleague_nba
|
| 287 |
+
concept_athlete_stephen_drew concept:athleteplaysinleague concept_sportsleague_mlb
|
| 288 |
+
concept_sportsteam_drake_bulldogs concept:teamplaysinleague concept_sportsleague_ncaa
|
| 289 |
+
concept_coach_kevin_youkilis concept:athleteplaysforteam concept_sportsteam_red_sox
|
| 290 |
+
concept_sportsteam_seahawks concept:organizationhiredperson concept_coach_jim_zorn
|
| 291 |
+
concept_athlete_scott_cassidy concept:athleteplayssport concept_sport_baseball
|
| 292 |
+
concept_stateorprovince_indiana concept:organizationhiredperson concept_coach_bobby_knight
|
| 293 |
+
concept_athlete_chris_smith concept:athleteplaysinleague concept_sportsleague_mlb
|
| 294 |
+
concept_televisionstation_kpho concept:organizationheadquarteredincity concept_city_phoenix
|
| 295 |
+
concept_sportsteam_gonzaga_bulldogs concept:teamplaysinleague concept_sportsleague_ncaa
|
| 296 |
+
concept_athlete_zach_thomas concept:athleteplayssport concept_sport_football
|
| 297 |
+
concept_company_flyglobespan concept:organizationheadquarteredincity concept_city_edinburgh
|
| 298 |
+
concept_person_pearson concept:personborninlocation concept_city_york
|
| 299 |
+
concept_athlete_rajai_davis concept:athleteplaysinleague concept_sportsleague_mlb
|
| 300 |
+
concept_nongovorganization_opposition concept:organizationhiredperson concept_personmexico_ryan_whitney
|
| 301 |
+
concept_sportsleague_new concept:organizationhiredperson concept_coach_sparano
|
| 302 |
+
concept_televisionstation_kera_tv concept:agentbelongstoorganization concept_company_pbs
|
| 303 |
+
concept_athlete_david_murphy concept:athleteplaysinleague concept_sportsleague_nhl
|
| 304 |
+
concept_athlete_otto_graham concept:athleteplayssport concept_sport_football
|
| 305 |
+
concept_athlete_alex_herrera concept:athleteplayssport concept_sport_baseball
|
| 306 |
+
concept_sportsteam_mid_eastern_athletic_conference concept:teamplaysinleague concept_sportsleague_ncaa
|
| 307 |
+
concept_athlete_darrick_martin concept:athleteplaysinleague concept_sportsleague_nba
|
| 308 |
+
concept_terroristorganization_state concept:organizationhiredperson concept_coach_kay_yow
|
| 309 |
+
concept_person_max001 concept:personborninlocation concept_city_york
|
| 310 |
+
concept_politicianus_newt_gingrich concept:personleadsorganization concept_politicalparty_house
|
| 311 |
+
concept_sportsteam_la_clippers concept:teamplaysinleague concept_sportsleague_nba
|
| 312 |
+
concept_sportsteam_minnesota_wilds concept:teamplayssport concept_sport_hockey
|
| 313 |
+
concept_sportsteam_buccaneers concept:organizationhiredperson concept_coach_john_gruden
|
| 314 |
+
concept_country_syria concept:organizationhiredperson concept_personmexico_ryan_whitney
|
| 315 |
+
concept_company_focus concept:organizationhiredperson concept_personmexico_ryan_whitney
|
| 316 |
+
concept_televisionstation_kshb concept:organizationheadquarteredincity concept_county_kansas_city
|
| 317 |
+
concept_person_ter_petrosyan concept:personleadsorganization concept_country_republic_of_armenia
|
| 318 |
+
concept_athlete_nomar_garciaparra concept:athleteplaysinleague concept_sportsleague_mlb
|
| 319 |
+
concept_athlete_roddy_white concept:athleteplaysforteam concept_sportsteam_falcons
|
| 320 |
+
concept_personeurope_azim_premji concept:personleadsorganization concept_sportsteam_wipro_technologies
|
| 321 |
+
concept_sportsteam_vanguard_lions concept:teamplaysinleague concept_sportsleague_ncaa
|
| 322 |
+
concept_coach_vincent_lecavalier concept:athleteplaysforteam concept_sportsteam_tampa_bay_lightning
|
| 323 |
+
concept_athlete_jonathan_stewart concept:athleteplayssport concept_sport_football
|
| 324 |
+
concept_athlete_jo_jo_reyes concept:athleteplayssport concept_sport_baseball
|
| 325 |
+
concept_stateorprovince_oregon concept:organizationhiredperson concept_coach_ernie_kent
|
| 326 |
+
concept_coach_brian_kelly concept:worksfor concept_geopoliticallocation_central_michigan
|
| 327 |
+
concept_athlete_robert_trent_jones_ii concept:athleteplayssport concept_sport_golf
|
| 328 |
+
concept_politician_jobs concept:worksfor concept_county_god
|
| 329 |
+
concept_person_jeff_zucker concept:worksfor concept_company_nbc_universal001
|
| 330 |
+
concept_televisionstation_kfts concept:agentbelongstoorganization concept_company_pbs
|
| 331 |
+
concept_athlete_brandon_marshall concept:athleteplayssport concept_sport_golf
|
| 332 |
+
concept_politician_john_peyton concept:worksfor concept_city_jacksonville
|
| 333 |
+
concept_person_tony_snow concept:worksfor concept_musicartist_news
|
| 334 |
+
concept_creditunion_kansas concept:organizationhiredperson concept_athlete_roy_williams
|
| 335 |
+
concept_person_albert002 concept:personborninlocation concept_city_york
|
| 336 |
+
concept_athlete_john_bale concept:athleteplayssport concept_sport_baseball
|
| 337 |
+
concept_company_new_york concept:organizationhiredperson concept_politician_michael_r__bloomberg
|
| 338 |
+
concept_televisionstation_kxne_tv concept:agentbelongstoorganization concept_company_pbs
|
| 339 |
+
concept_personnorthamerica_bret_baier concept:worksfor concept_governmentorganization_fox_news
|
| 340 |
+
concept_radiostation_kcsm concept:organizationheadquarteredincity concept_city_san_mateo
|
| 341 |
+
concept_athlete_gaby_hernandez concept:athleteplayssport concept_sport_baseball
|
| 342 |
+
concept_athlete_dustin_moseley concept:athleteplayssport concept_sport_baseball
|
| 343 |
+
concept_radiostation_kska concept:organizationheadquarteredincity concept_city_anchorage
|
| 344 |
+
concept_coach_vincent_lecavalier concept:athleteplayssport concept_sport_baseball
|
| 345 |
+
concept_personeurope_allan_moss concept:worksfor concept_bank_macquarie_bank
|
| 346 |
+
concept_athlete_jerry_rice concept:athleteplayssport concept_sport_football
|
| 347 |
+
concept_person_john003 concept:worksfor concept_politicsblog_ny_times
|
| 348 |
+
concept_person_abbas concept:personleadsorganization concept_nongovorganization_fatah_leadership
|
| 349 |
+
concept_person_mitchell001 concept:personborninlocation concept_city_york
|
| 350 |
+
concept_writer_david_broder concept:worksfor concept_city_washington_d_c
|
| 351 |
+
concept_blog_komu_tv concept:agentbelongstoorganization concept_company_nbc
|
| 352 |
+
concept_athlete_jason_bere concept:athleteplayssport concept_sport_baseball
|
| 353 |
+
concept_creditunion_kansas concept:organizationhiredperson concept_personcanada_self
|
| 354 |
+
concept_company_boehringer_ingelheim concept:organizationheadquarteredincity concept_city_ridgefield
|
| 355 |
+
concept_sportsteam_texas_el_paso_miners concept:teamplaysinleague concept_sportsleague_ncaa
|
| 356 |
+
concept_stateorprovince_tennessee concept:organizationhiredperson concept_personmexico_bruce_pearl
|
| 357 |
+
concept_journalist_natalie_angier concept:worksfor concept_musicartist_times
|
| 358 |
+
concept_sportsteam_temple_university concept:teamplaysinleague concept_sportsleague_international
|
| 359 |
+
concept_athlete_kei_igawa concept:athletehomestadium concept_stadiumoreventvenue_yankee_stadium
|
| 360 |
+
concept_sportsteam_knicks concept:teamplaysinleague concept_sportsleague_nba
|
| 361 |
+
concept_athlete_felix_hernandez concept:athleteplaysforteam concept_sportsteam_mariners
|
| 362 |
+
concept_person_ty_willingham concept:worksfor concept_city_washington_d_c
|
| 363 |
+
concept_televisionstation_wmeb_tv concept:agentbelongstoorganization concept_company_pbs
|
| 364 |
+
concept_person_perenchio concept:personleadsorganization concept_city_univision
|
| 365 |
+
concept_journalist_jane_mayer concept:worksfor concept_website_new_york_american
|
| 366 |
+
concept_athlete_yoslan_herrera concept:athleteplayssport concept_sport_baseball
|
| 367 |
+
concept_athlete_casey_kotchman concept:athleteplayssport concept_sport_baseball
|
| 368 |
+
concept_journalist_rocky_anderson concept:worksfor concept_biotechcompany_salt_lake_city
|
| 369 |
+
concept_athlete_bill_mazeroski concept:athleteplayssport concept_sport_baseball
|
| 370 |
+
concept_person_gundy concept:worksfor concept_university_osu
|
| 371 |
+
concept_athlete_ryan_braun concept:athleteplaysinleague concept_sportsleague_mlb
|
| 372 |
+
concept_athlete_rafer_alston concept:athleteplaysinleague concept_sportsleague_nba
|
| 373 |
+
concept_website_new_yorker_magazine concept:organizationheadquarteredincity concept_city_new_york
|
| 374 |
+
concept_athlete_john_axford concept:athleteplaysinleague concept_sportsleague_mlb
|
| 375 |
+
concept_professor_david_levy concept:worksfor concept_politicsblog_turner_sports
|
| 376 |
+
concept_sportsteam_miami_dolphins concept:teamplaysinleague concept_sportsleague_nfl
|
| 377 |
+
concept_athlete_braden_looper concept:athleteplaysinleague concept_sportsleague_nfl
|
| 378 |
+
concept_ceo_sergey_brin concept:personleadsorganization concept_university_google
|
| 379 |
+
concept_company_pakistan concept:organizationhiredperson concept_personmexico_ryan_whitney
|
| 380 |
+
concept_athlete_pedro_feliz concept:athleteplaysinleague concept_sportsleague_mlb
|
| 381 |
+
concept_sportsteam_washington_state concept:teamplaysinleague concept_sportsleague_ncaa
|
| 382 |
+
concept_company_chevron001 concept:organizationheadquarteredincity concept_city_san_ramon
|
| 383 |
+
concept_personafrica_mike_davis concept:worksfor concept_university_uab
|
| 384 |
+
concept_geopoliticalorganization_address concept:organizationhiredperson concept_personmexico_ryan_whitney
|
| 385 |
+
concept_professor_greg_palast concept:worksfor concept_governmentorganization_bbc
|
| 386 |
+
concept_sportsteam_texas_a_m_international_university concept:teamplaysinleague concept_sportsleague_international
|
| 387 |
+
concept_sportsteam_twins concept:teamplaysinleague concept_sportsleague_mlb
|
| 388 |
+
concept_sportsteam_quebec_nordiques concept:teamplaysinleague concept_sportsleague_nhl
|
| 389 |
+
concept_sportsteam_n2009_all_star concept:teamplaysinleague concept_sportsleague_mlb
|
| 390 |
+
concept_company_amazon_com_inc concept:organizationhiredperson concept_personus_jeff_bezos
|
| 391 |
+
concept_athlete_sidney_crosby concept:athletehomestadium concept_stadiumoreventvenue_mellon_arena
|
| 392 |
+
concept_politicalparty_conservatives concept:organizationhiredperson concept_personmexico_ryan_whitney
|
| 393 |
+
concept_sportsteam_cal_state_san_bernardino_coyotes concept:teamplaysinleague concept_sportsleague_ncaa
|
| 394 |
+
concept_athlete_placido_polanco concept:athleteplayssport concept_sport_baseball
|
| 395 |
+
concept_athlete_brad_ausmus_gg concept:athleteplaysforteam concept_sportsteam_astros
|
| 396 |
+
concept_coach_reggie_herring concept:worksfor concept_stateorprovince_arkansas
|
| 397 |
+
concept_sportsteam_curtin_university concept:teamplaysinleague concept_sportsleague_international
|
| 398 |
+
concept_personmexico_jack_morris concept:athleteplaysinleague concept_sportsleague_mlb
|
| 399 |
+
concept_sportsteam_knicks concept:organizationhiredperson concept_personmexico_isaiah_thomas
|
| 400 |
+
concept_person_norman001 concept:personborninlocation concept_city_york
|
| 401 |
+
concept_televisionstation_wha__tv concept:agentbelongstoorganization concept_company_pbs
|
| 402 |
+
concept_coach_shanahan concept:worksfor concept_city_denver
|
| 403 |
+
concept_athlete_garret_anderson concept:athletehomestadium concept_stadiumoreventvenue_old_trafford
|
| 404 |
+
concept_personnorthamerica_maria_shriver concept:worksfor concept_company_nbc
|
| 405 |
+
concept_athlete_vicente_padilla concept:athletehomestadium concept_stadiumoreventvenue_giants_stadium
|
| 406 |
+
concept_athlete_isaiah_thomas concept:athleteplaysinleague concept_sportsleague_nba
|
| 407 |
+
concept_televisionstation_kosu concept:organizationheadquarteredincity concept_city_stillwater
|
| 408 |
+
concept_sportsteam_lewis_flyers concept:teamplaysinleague concept_sportsleague_ncaa
|
| 409 |
+
concept_athlete_kyle_farnsworth concept:athleteplayssport concept_sport_baseball
|
| 410 |
+
concept_athlete_ben_eager concept:athletehomestadium concept_stadiumoreventvenue_wrigley_field
|
| 411 |
+
concept_personeurope_james_wright concept:worksfor concept_university_villanova
|
| 412 |
+
concept_athlete_yuniesky_betancourt concept:athleteplayssport concept_sport_baseball
|
| 413 |
+
concept_sportsteam_harvard_divinity_school concept:teamplaysinleague concept_sportsleague_international
|
| 414 |
+
concept_athlete_darren_mcfadden concept:athletehomestadium concept_stadiumoreventvenue_mcafee_coliseum
|
| 415 |
+
concept_athlete_carlos_boozer concept:athleteplaysforteam concept_sportsteam_utah_jazz
|
| 416 |
+
concept_athlete_alexei_ramirez concept:athleteplaysforteam concept_sportsteam_white_sox
|
| 417 |
+
concept_athlete_mark_mcgwire_and_sammy_sosa concept:athleteplaysinleague concept_sportsleague_nfl
|
| 418 |
+
concept_athlete_esteban_yan concept:athleteplayssport concept_sport_baseball
|
| 419 |
+
concept_coach_mike_holmgren concept:worksfor concept_sportsteam_packers
|
| 420 |
+
concept_university_oklahoma_state concept:organizationhiredperson concept_coach_travis_ford
|
| 421 |
+
concept_athlete_tom_glavine concept:athleteplayssport concept_sport_baseball
|
| 422 |
+
concept_athlete_pau_gasol concept:athleteplayssport concept_sport_basketball
|
| 423 |
+
concept_athlete_mike_cameron concept:athleteplayssport concept_sport_baseball
|
| 424 |
+
concept_coach_mike_stoops concept:worksfor concept_company_arizona
|
| 425 |
+
concept_athlete_jeremy_bonderman concept:athleteplaysinleague concept_sportsleague_mlb
|
| 426 |
+
concept_personus_steve_ballmer concept:worksfor concept_university_microsoft
|
| 427 |
+
concept_journalist_timothy_egan concept:worksfor concept_musicartist_times
|
| 428 |
+
concept_athlete_scott_linebrink concept:athleteplaysinleague concept_sportsleague_mlb
|
| 429 |
+
concept_coach_steve_spagnuolo concept:worksfor concept_city_st_louis
|
| 430 |
+
concept_personnorthamerica_neil_bogart concept:personleadsorganization concept_city_casablanca
|
| 431 |
+
concept_professor_david_yu concept:personleadsorganization concept_company_betfair
|
| 432 |
+
concept_athlete_nick_young concept:athleteplaysforteam concept_sportsteam_washington_wizards
|
| 433 |
+
concept_televisionstation_wfxu concept:agentbelongstoorganization concept_televisionnetwork_pbs
|
| 434 |
+
concept_person_oscar_wyatt concept:worksfor concept_newspaper_texas
|
| 435 |
+
concept_televisionstation_wmfe_tv concept:agentbelongstoorganization concept_company_pbs
|
| 436 |
+
concept_radiostation_kut concept:organizationheadquarteredincity concept_city_austin
|
| 437 |
+
concept_writer_joshua_nkomo concept:worksfor concept_politicalparty_zimbabwe_african_peoples_union
|
| 438 |
+
concept_sportsteam_grace_lancers concept:teamplaysinleague concept_sportsleague_ncaa
|
| 439 |
+
concept_politicianus_john_lafferty concept:worksfor concept_sportsteam_carnegie_mellon_university
|
| 440 |
+
concept_athlete_corey_maggette concept:athleteplayssport concept_sport_basketball
|
| 441 |
+
concept_website_wsb_tv concept:organizationheadquarteredincity concept_city_atlanta
|
| 442 |
+
concept_building_houses concept:organizationhiredperson concept_personus_democratic
|
| 443 |
+
concept_sportsteam_florida_st__seminoles concept:teamplaysinleague concept_sportsleague_ncaa
|
| 444 |
+
concept_athlete_tommy_maddox concept:athletehomestadium concept_stadiumoreventvenue_heinz_field
|
| 445 |
+
concept_personmexico_jose_bautista concept:athleteplayssport concept_sport_baseball
|
| 446 |
+
concept_sportsteam_jaguars concept:teamplaysinleague concept_sportsleague_nfl
|
| 447 |
+
concept_politicalparty_senate concept:organizationhiredperson concept_person_lower
|
| 448 |
+
concept_coach_alexander_frolov concept:athleteplaysforteam concept_sportsteam_kings_college
|
| 449 |
+
concept_sportsleague_notice concept:organizationhiredperson concept_personmexico_ryan_whitney
|
| 450 |
+
concept_professionalorganization_cal concept:organizationhiredperson concept_person_jeff_tedford
|
| 451 |
+
concept_sportsteam_san_jose_state_spartans concept:teamplaysinleague concept_sportsleague_ncaa
|
| 452 |
+
concept_company_martha_stewart concept:organizationheadquarteredincity concept_city_new_york
|
| 453 |
+
concept_person_britney concept:personborninlocation concept_city_york
|
| 454 |
+
concept_personmexico_ryan_whitney concept:personleadsorganization concept_governmentorganization_agency
|
| 455 |
+
concept_athlete_ryan_rowland_smith concept:athletehomestadium concept_stadiumoreventvenue_safeco_field
|
| 456 |
+
concept_person_wendy001 concept:personborninlocation concept_city_york
|
| 457 |
+
concept_athlete_ed_belfour concept:athleteplaysforteam concept_sportsteam_blackhawks
|
| 458 |
+
concept_personmexico_ryan_whitney concept:personleadsorganization concept_website_change
|
| 459 |
+
concept_athlete_eric_byrnes concept:athleteplaysinleague concept_sportsleague_mlb
|
| 460 |
+
concept_televisionstation_wcfe_tv concept:agentbelongstoorganization concept_company_pbs
|
| 461 |
+
concept_biotechcompany_section concept:agentbelongstoorganization concept_stateorprovince_contact
|
| 462 |
+
concept_male_gerald_green concept:athleteplaysinleague concept_sportsleague_nba
|
| 463 |
+
concept_televisionstation_kyve_tv concept:agentbelongstoorganization concept_company_pbs
|
| 464 |
+
concept_athlete_udonis_haslem concept:athleteplaysforteam concept_sportsteam_heat
|
| 465 |
+
concept_personaustralia_jobs concept:worksfor concept_publication_macworld
|
| 466 |
+
concept_person_abbas concept:personleadsorganization concept_city_name
|
| 467 |
+
concept_athlete_j_d__martin concept:athleteplayssport concept_sport_baseball
|
| 468 |
+
concept_ceo_thomas_m__ryan concept:worksfor concept_biotechcompany_cvs_caremark
|
| 469 |
+
concept_athlete_rashard_lewis concept:athleteplayssport concept_sport_basketball
|
| 470 |
+
concept_politicianus_jon_scott concept:worksfor concept_mountain_fox
|
| 471 |
+
concept_politician_jobs concept:worksfor concept_blog_today
|
| 472 |
+
concept_athlete_jorge_julio concept:athleteplayssport concept_sport_baseball
|
| 473 |
+
concept_sportsteam_njit_highlanders concept:teamplaysinleague concept_sportsleague_ncaa
|
| 474 |
+
concept_sportsteam_hershey_bears concept:teamplayssport concept_sport_hockey
|
| 475 |
+
concept_sportsteam_northwestern concept:organizationhiredperson concept_coach_pat_fitzgerald
|
| 476 |
+
concept_coach_carroll concept:worksfor concept_university_southern_cal
|
| 477 |
+
concept_personmexico_jason_taylor concept:athleteplayssport concept_sport_football
|
| 478 |
+
concept_coach_andrew_ladd concept:athletehomestadium concept_stadiumoreventvenue_wrigley_field
|
| 479 |
+
concept_athlete_bobby_orr concept:athleteplaysforteam concept_sportsteam_blackhawks
|
| 480 |
+
concept_writer_luca concept:personleadsorganization concept_winery_ferrari
|
| 481 |
+
concept_person_levine concept:personborninlocation concept_city_york
|
| 482 |
+
concept_sportsteam_purdue_university concept:teamplayssport concept_sport_basketball
|
| 483 |
+
concept_politicianus_mikhail_gorbachev concept:personleadsorganization concept_organization_soviet
|
| 484 |
+
concept_coach_brett_lee concept:worksfor concept_university_uw
|
| 485 |
+
concept_televisionstation_kwhy concept:organizationheadquarteredincity concept_county_los_angeles_county
|
| 486 |
+
concept_televisionstation_kcpq_tv concept:organizationheadquarteredincity concept_city_tacoma
|
| 487 |
+
concept_sportsteam_capitals concept:organizationhiredperson concept_athlete_ovechkin
|
| 488 |
+
concept_radiostation_word_fm concept:organizationheadquarteredincity concept_city_pittsburgh
|
| 489 |
+
concept_sportsteam_dalhousie_university concept:teamplaysinleague concept_sportsleague_international
|
| 490 |
+
concept_sportsleague_new concept:organizationhiredperson concept_coach_sean_payton
|
| 491 |
+
concept_televisionstation_kmne_tv concept:agentbelongstoorganization concept_company_pbs
|
| 492 |
+
concept_governmentorganization_federal concept:organizationheadquarteredincity concept_city_boston
|
| 493 |
+
concept_sportsteam_st__louis_cardinals concept:teamplayssport concept_sport_baseball
|
| 494 |
+
concept_sportsteam_minnesota_timberwolves concept:teamplayssport concept_sport_basketball
|
| 495 |
+
concept_athlete_eric_milton concept:athleteplayssport concept_sport_baseball
|
| 496 |
+
concept_athlete_jayson_werth concept:athleteplayssport concept_sport_baseball
|
| 497 |
+
concept_sportsteam_dayton_flyers concept:teamplaysinleague concept_sportsleague_ncaa
|
| 498 |
+
concept_athlete_laurence_maroney concept:athletehomestadium concept_stadiumoreventvenue_gillette_stadium
|
| 499 |
+
concept_coach_richard_zednik concept:athleteplaysforteam concept_sportsteam_florida_international
|
| 500 |
+
concept_athlete_derrick_harvey concept:athleteplaysinleague concept_sportsleague_nfl
|
| 501 |
+
concept_county_duke_university concept:organizationhiredperson concept_coach_mike_krzyzewski
|
| 502 |
+
concept_person_katsuaki_watanabe concept:worksfor concept_automobilemaker_toyota_motor
|
| 503 |
+
concept_athlete_rafael_perez concept:athleteplaysinleague concept_sportsleague_mlb
|
| 504 |
+
concept_sportsteam_old_dominion_university concept:teamplaysinleague concept_sportsleague_international
|
| 505 |
+
concept_personmexico_melky_cabrera concept:athleteplaysforteam concept_sportsteam_yankees
|
| 506 |
+
concept_sportsteam_west_virginia_state_yellow_jackets concept:teamplaysinleague concept_sportsleague_ncaa
|
| 507 |
+
concept_country_russia concept:organizationhiredperson concept_coach_hiddink
|
| 508 |
+
concept_county_chicago concept:organizationhiredperson concept_politicianus_richard_m__daley
|
| 509 |
+
concept_company_remark concept:organizationhiredperson concept_personmexico_ryan_whitney
|
| 510 |
+
concept_person_richard002 concept:worksfor concept_city_uk
|
| 511 |
+
concept_person_richard002 concept:personborninlocation concept_city_york
|
| 512 |
+
concept_coach_aaron_harang concept:athleteplaysforteam concept_sportsteam_blackhawks
|
| 513 |
+
concept_televisionstation_knxv concept:organizationheadquarteredincity concept_city_phoenix
|
| 514 |
+
concept_athlete_david_carr concept:athleteplaysforteam concept_sportsteam_texans
|
| 515 |
+
concept_sportsteam_florida_international concept:organizationhiredperson concept_coach_john_fox
|
| 516 |
+
concept_athlete_rod_smith concept:athletehomestadium concept_stadiumoreventvenue_invesco_field
|
| 517 |
+
concept_athlete_jaromir_jagr concept:athletehomestadium concept_stadiumoreventvenue_giants_stadium
|
| 518 |
+
concept_recordlabel_death_row concept:organizationhiredperson concept_person_suge_knight
|
| 519 |
+
concept_sportsteam_bond_university concept:teamplaysinleague concept_sportsleague_international
|
| 520 |
+
concept_athlete_ivan_rodriguez concept:athletehomestadium concept_stadiumoreventvenue_yankee_stadium
|
| 521 |
+
concept_athlete_denny_bautista concept:athleteplaysinleague concept_sportsleague_mlb
|
| 522 |
+
concept_athlete_phil_hughes_and_ian_kennedy concept:athletehomestadium concept_stadiumoreventvenue_yankee_stadium
|
| 523 |
+
concept_sportsteam_new_york_liberty concept:teamplaysinleague concept_sportsleague_wnba
|
| 524 |
+
concept_personmexico_shaun_marcum concept:athleteplaysforteam concept_sportsteam_blue_jays
|
| 525 |
+
concept_sportsteam_steelers concept:teamplaysinleague concept_sportsleague_nfl
|
| 526 |
+
concept_sportsteam_lsu concept:organizationhiredperson concept_person_skip_bertman
|
| 527 |
+
concept_person_lynch concept:personborninlocation concept_city_york
|
| 528 |
+
concept_athlete_mike_myers concept:athleteplayssport concept_sport_baseball
|
| 529 |
+
concept_athlete_joe_bradley concept:athleteplaysforteam concept_sportsteam_pats
|
| 530 |
+
concept_athlete_sean_taylor concept:athleteplaysforteam concept_sportsteam_saints
|
| 531 |
+
concept_radiostation_ketr concept:organizationheadquarteredincity concept_city_commerce
|
| 532 |
+
concept_coach_lubomir_visnovsky concept:athleteplaysforteam concept_sportsteam_oilers
|
| 533 |
+
concept_sportsteam_york_university concept:teamplaysinleague concept_sportsleague_international
|
| 534 |
+
concept_personus_rex_tillerson concept:agentbelongstoorganization concept_petroleumrefiningcompany_exxonmobil
|
| 535 |
+
concept_sportsteam_cal_poly_slo_mustangs concept:teamplaysinleague concept_sportsleague_ncaa
|
| 536 |
+
concept_athlete_jordan_staal concept:athleteplaysforteam concept_sportsteam_pittsburgh_penguins
|
| 537 |
+
concept_athlete_mike_wallace concept:worksfor concept_company_n60_minutes
|
| 538 |
+
concept_politician_kaine concept:personleadsorganization concept_publication_richmond
|
| 539 |
+
concept_athlete_darrent_williams concept:athletehomestadium concept_stadiumoreventvenue_invesco_field
|
| 540 |
+
concept_person_brent_staples concept:worksfor concept_website_new_york_times
|
| 541 |
+
concept_personasia_rick_ankiel concept:athleteplayssport concept_sport_football
|
| 542 |
+
concept_person_levon_ter__petrosyan concept:worksfor concept_country_armenia
|
| 543 |
+
concept_person_charles_prince concept:personleadsorganization concept_company_citigroup
|
src/research/COINs-KGGeneration/data/WN18RR/test.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
src/research/COINs-KGGeneration/data/WN18RR/train.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
src/research/COINs-KGGeneration/data/WN18RR/valid.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
src/research/COINs-KGGeneration/graph_analysis/KGist/__init__.py
ADDED
|
File without changes
|
src/research/COINs-KGGeneration/graph_analysis/KGist/anomaly_detector.py
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from math import log2 as log
|
| 2 |
+
from scipy.special import gammaln
|
| 3 |
+
from collections import defaultdict
|
| 4 |
+
import numpy as np
|
| 5 |
+
from itertools import chain, combinations
|
| 6 |
+
from graph_analysis.KGist.evaluator import Evaluator
|
| 7 |
+
|
| 8 |
+
class AnomalyDetector:
|
| 9 |
+
def __init__(self, model):
|
| 10 |
+
self.idify = model.graph.idify
|
| 11 |
+
self.model = model
|
| 12 |
+
self.evaluator = Evaluator(self.model.graph)
|
| 13 |
+
self.subject_to_rules = dict()
|
| 14 |
+
for rule in self.model.rules:
|
| 15 |
+
sub = rule[0] if type(rule) is tuple else rule.root
|
| 16 |
+
if sub not in self.subject_to_rules:
|
| 17 |
+
self.subject_to_rules[sub] = set()
|
| 18 |
+
self.subject_to_rules[sub].add(rule)
|
| 19 |
+
|
| 20 |
+
self.binomial_map = dict()
|
| 21 |
+
self.edge_to_id = dict()
|
| 22 |
+
for m, edge in model.graph.id_to_edge.items():
|
| 23 |
+
sub, pred, obj = edge
|
| 24 |
+
self.edge_to_id[(sub, pred, obj)] = m
|
| 25 |
+
|
| 26 |
+
def length_binomial(self, n, k):
|
| 27 |
+
'''
|
| 28 |
+
:n: n in (n choose k)
|
| 29 |
+
:k: k in (n choose k)
|
| 30 |
+
|
| 31 |
+
:return: log_2(n choose k)
|
| 32 |
+
'''
|
| 33 |
+
if (n, k) in self.binomial_map:
|
| 34 |
+
return self.binomial_map[(n, k)]
|
| 35 |
+
|
| 36 |
+
length = (gammaln(n + 1) - gammaln(k + 1) - gammaln((n + 1) - k)) / np.log(2)
|
| 37 |
+
self.binomial_map[(n, k)] = length
|
| 38 |
+
return length
|
| 39 |
+
|
| 40 |
+
def score_blame_edge(self, node, pred):
|
| 41 |
+
'''
|
| 42 |
+
The number of bits describing the node as an exception to rules.
|
| 43 |
+
'''
|
| 44 |
+
def powerset(iterable):
|
| 45 |
+
s = list(iterable)
|
| 46 |
+
return chain.from_iterable(combinations(s, r) for r in range(1, len(s)+1))
|
| 47 |
+
|
| 48 |
+
score = 0
|
| 49 |
+
rules = set()
|
| 50 |
+
for labels in powerset(self.model.graph.labels(node)):
|
| 51 |
+
if labels in self.subject_to_rules:
|
| 52 |
+
rules.update(self.subject_to_rules[labels])
|
| 53 |
+
|
| 54 |
+
def has_pred(rule, pred):
|
| 55 |
+
if type(rule) is tuple:
|
| 56 |
+
return rule[1][0][0] == pred
|
| 57 |
+
else:
|
| 58 |
+
return pred in rule.get_preds()
|
| 59 |
+
|
| 60 |
+
rules = set(filter(lambda rule: has_pred(rule, pred), rules))
|
| 61 |
+
|
| 62 |
+
for rule in rules:
|
| 63 |
+
cas = set(self.model.graph.candidates[rule]['ca_to_size'].keys()) if type(rule) is tuple else set(real.root for real in rule.correct_assertions)
|
| 64 |
+
if node not in cas:
|
| 65 |
+
num_assertions = self.model.graph.nodes_with_type(rule[0] if type(rule) is tuple else rule.root)
|
| 66 |
+
num_correct = len(self.model.graph.candidates[rule]['ca_to_size'] if type(rule) is tuple else rule.correct_assertions)
|
| 67 |
+
num_exceptions = num_assertions - num_correct
|
| 68 |
+
assert(num_assertions > 0)
|
| 69 |
+
assert(num_exceptions > 0)
|
| 70 |
+
score += (1 / num_exceptions) * self.length_binomial(num_assertions, num_exceptions)
|
| 71 |
+
return score
|
| 72 |
+
|
| 73 |
+
def score_edge(self, edge, blame_edge=True):
|
| 74 |
+
if self.idify:
|
| 75 |
+
edge = (self.model.graph.node_to_id[edge[0]], self.model.graph.pred_to_id[edge[1]], self.model.graph.node_to_id[edge[2]])
|
| 76 |
+
eid = self.edge_to_id[edge] if type(edge) is tuple else edge
|
| 77 |
+
sub, pred, obj = edge if type(edge) is tuple else self.model.graph.id_to_edge[eid]
|
| 78 |
+
score = 0
|
| 79 |
+
if eid not in self.model.tensor: # edges not in the model are not explained
|
| 80 |
+
# number of bits describing the unexplained edge
|
| 81 |
+
score = (1 / (self.model.graph.m - len(self.model.tensor))) * self.evaluator.length_negative_edge_error(self.model)
|
| 82 |
+
score += self.score_blame_edge(sub, pred) + self.score_blame_edge(obj, pred)
|
| 83 |
+
return score
|
src/research/COINs-KGGeneration/graph_analysis/KGist/correct_assertion.py
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from collections import defaultdict
|
| 2 |
+
|
| 3 |
+
class Node:
|
| 4 |
+
def __init__(self, name, typ):
|
| 5 |
+
self.name = name
|
| 6 |
+
self.type = typ
|
| 7 |
+
# maps (pred, dir, node_type) to node names
|
| 8 |
+
self.neighbors_of_type = dict()
|
| 9 |
+
# node names
|
| 10 |
+
self.neighbors = set()
|
| 11 |
+
|
| 12 |
+
def add_neighbor(self, pred, dir, node_type, node):
|
| 13 |
+
if (pred, dir, node_type) not in self.neighbors_of_type:
|
| 14 |
+
self.neighbors_of_type[(pred, dir, node_type)] = set()
|
| 15 |
+
self.neighbors_of_type[(pred, dir, node_type)].add(node)
|
| 16 |
+
self.neighbors.add(node)
|
| 17 |
+
|
| 18 |
+
class CorrectAssertion:
|
| 19 |
+
'''
|
| 20 |
+
A class which represents realized rules as rooted subgraphs.
|
| 21 |
+
'''
|
| 22 |
+
def __init__(self, root, label):
|
| 23 |
+
self.root = root
|
| 24 |
+
# maps node names to node objects
|
| 25 |
+
self.nodes = dict()
|
| 26 |
+
self.edges = set()
|
| 27 |
+
self.edge_ids = set()
|
| 28 |
+
self.labels = set()
|
| 29 |
+
|
| 30 |
+
def add_edge(self, edge, eid=None, labels=False):
|
| 31 |
+
'''
|
| 32 |
+
:edge: (u, u_typ, pred, dir, v, v_typ)
|
| 33 |
+
:eid: the id of the edge in the full graph
|
| 34 |
+
:labels: boolean specifying whether or not to add node labels
|
| 35 |
+
'''
|
| 36 |
+
u, u_typ, pred, dir, v, v_typ = edge
|
| 37 |
+
sub = u if dir == 'out' else v
|
| 38 |
+
sub_typ = u_typ if dir == 'out' else v_typ
|
| 39 |
+
obj = u if dir == 'in' else v
|
| 40 |
+
obj_typ = u_typ if dir == 'in' else v_typ
|
| 41 |
+
if u not in self.nodes:
|
| 42 |
+
self.nodes[u] = Node(u, u_typ)
|
| 43 |
+
if v not in self.nodes:
|
| 44 |
+
self.nodes[v] = Node(v, v_typ)
|
| 45 |
+
self.nodes[sub].add_neighbor(pred, 'out', obj_typ, obj)
|
| 46 |
+
self.nodes[obj].add_neighbor(pred, 'in', sub_typ, sub)
|
| 47 |
+
self.edges.add(edge)
|
| 48 |
+
# edge coverage
|
| 49 |
+
if eid != None:
|
| 50 |
+
self.edge_ids.add(eid)
|
| 51 |
+
# label coverage
|
| 52 |
+
if labels:
|
| 53 |
+
if u != self.root:
|
| 54 |
+
for label in u_typ:
|
| 55 |
+
self.labels.add((label, u))
|
| 56 |
+
if v != self.root:
|
| 57 |
+
for label in v_typ:
|
| 58 |
+
self.labels.add((label, v))
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
def merge(self, correct_assertion):
|
| 62 |
+
assert(self.root == correct_assertion.root)
|
| 63 |
+
for edge in correct_assertion.edges:
|
| 64 |
+
self.add_edge(edge)
|
| 65 |
+
self.edge_ids.update(correct_assertion.edge_ids)
|
| 66 |
+
self.labels.update(correct_assertion.labels)
|
| 67 |
+
|
| 68 |
+
def compose(self, correct_assertion):
|
| 69 |
+
for edge in correct_assertion.edges:
|
| 70 |
+
self.add_edge(edge)
|
| 71 |
+
self.edge_ids.update(correct_assertion.edge_ids)
|
| 72 |
+
self.labels.update(correct_assertion.labels)
|
src/research/COINs-KGGeneration/graph_analysis/KGist/evaluator.py
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from math import log2 as log
|
| 2 |
+
from scipy.special import comb
|
| 3 |
+
from scipy.sparse import csr_matrix
|
| 4 |
+
import numpy as np
|
| 5 |
+
from collections import defaultdict
|
| 6 |
+
from scipy.special import gammaln
|
| 7 |
+
from graph_analysis.KGist.rule import Rule
|
| 8 |
+
|
| 9 |
+
class Evaluator:
|
| 10 |
+
'''
|
| 11 |
+
Evaluates a model or a rule.
|
| 12 |
+
'''
|
| 13 |
+
def __init__(self, graph):
|
| 14 |
+
self.graph = graph
|
| 15 |
+
self.log_V = log(self.graph.n)
|
| 16 |
+
self.log_E = log(self.graph.m)
|
| 17 |
+
self.log_E_plus_1 = log(self.graph.m + 1)
|
| 18 |
+
self.log_labels_plus_1 = log(self.graph.total_num_labels + 1)
|
| 19 |
+
self.log_LV = log(self.graph.num_node_labels)
|
| 20 |
+
# a cache for L_N since this can be slow to do many times
|
| 21 |
+
self.length_natural_number_map = dict()
|
| 22 |
+
# a cache for log of binomials
|
| 23 |
+
self.binomial_map = dict()
|
| 24 |
+
self.rule_to_length = dict()
|
| 25 |
+
|
| 26 |
+
def evaluate(self, model, with_lengths=False):
|
| 27 |
+
'''
|
| 28 |
+
L(M) + L(G|M) - (Section 3.2)
|
| 29 |
+
'''
|
| 30 |
+
length_model = self.length_model(model)
|
| 31 |
+
length_error, neg_edge, neg_node = self.length_graph_with_model(model)
|
| 32 |
+
val = length_model + length_error
|
| 33 |
+
if with_lengths:
|
| 34 |
+
return val, length_model, neg_edge, neg_node
|
| 35 |
+
return val
|
| 36 |
+
|
| 37 |
+
def evaluate_change(self, model, rule, prev_model_len):
|
| 38 |
+
'''
|
| 39 |
+
L(M union {r}) + L(G|M union {r})
|
| 40 |
+
|
| 41 |
+
:return: the MDL objective after inserting a new rule to M
|
| 42 |
+
'''
|
| 43 |
+
# update score
|
| 44 |
+
neg_edge = self.length_negative_edge_error(model)
|
| 45 |
+
neg_node = self.length_negative_label_error(model)
|
| 46 |
+
length_error_with_rule = neg_edge + neg_node
|
| 47 |
+
length_model_with_rule = self.length_model_new_rule(model, rule, prev_model_len)
|
| 48 |
+
val = length_model_with_rule + length_error_with_rule
|
| 49 |
+
|
| 50 |
+
return val, length_model_with_rule, neg_edge, neg_node
|
| 51 |
+
|
| 52 |
+
def length_model_new_rule(self, model, rule, length_model):
|
| 53 |
+
'''
|
| 54 |
+
L(M union {r})
|
| 55 |
+
|
| 56 |
+
:return: the length of the model with a new rule added
|
| 57 |
+
'''
|
| 58 |
+
# old length
|
| 59 |
+
length = length_model
|
| 60 |
+
length += self.length_rule(rule) + self.length_rule_assertions(rule, model)
|
| 61 |
+
|
| 62 |
+
return length
|
| 63 |
+
|
| 64 |
+
def length_natural_number(self, n):
|
| 65 |
+
'''
|
| 66 |
+
:n: a number
|
| 67 |
+
|
| 68 |
+
:return: the number of bits required to transmit the number
|
| 69 |
+
'''
|
| 70 |
+
if n <= 0:
|
| 71 |
+
return 0
|
| 72 |
+
if n in self.length_natural_number_map:
|
| 73 |
+
return self.length_natural_number_map[n]
|
| 74 |
+
c = log(2.865064)
|
| 75 |
+
i = log(n)
|
| 76 |
+
while i > 0:
|
| 77 |
+
c = c + i
|
| 78 |
+
i = log(i)
|
| 79 |
+
self.length_natural_number_map[n] = c # cache the value
|
| 80 |
+
return c
|
| 81 |
+
|
| 82 |
+
def length_binomial(self, n, k):
|
| 83 |
+
'''
|
| 84 |
+
:n: n in (n choose k)
|
| 85 |
+
:k: k in (n choose k)
|
| 86 |
+
|
| 87 |
+
:return: log_2(n choose k)
|
| 88 |
+
'''
|
| 89 |
+
# we cache computations that we've already made for speedups
|
| 90 |
+
if (n, k) in self.binomial_map:
|
| 91 |
+
return self.binomial_map[(n, k)]
|
| 92 |
+
|
| 93 |
+
# gammln computation of log_e(n choose k) with change of base to log_2
|
| 94 |
+
length = (gammaln(n + 1) - gammaln(k + 1) - gammaln((n + 1) - k)) / np.log(2)
|
| 95 |
+
# cache the result for future use
|
| 96 |
+
self.binomial_map[(n, k)] = length
|
| 97 |
+
return length
|
| 98 |
+
|
| 99 |
+
def length_model(self, model):
|
| 100 |
+
'''
|
| 101 |
+
L(M) - (Section 3.2.1)
|
| 102 |
+
|
| 103 |
+
:model: a list of rules and their (partial-)matches
|
| 104 |
+
|
| 105 |
+
:return: the number of bits required to transmit the model
|
| 106 |
+
'''
|
| 107 |
+
rules = model.rules.keys()
|
| 108 |
+
# num rules
|
| 109 |
+
length = log(2 * self.graph.num_node_labels * self.graph.num_edge_labels * self.graph.num_node_labels + 1)
|
| 110 |
+
# rules
|
| 111 |
+
length += sum(self.length_rule(rule) + self.length_rule_assertions(rule, model) for rule in rules)
|
| 112 |
+
|
| 113 |
+
return length
|
| 114 |
+
|
| 115 |
+
def length_rule(self, rule):
|
| 116 |
+
'''
|
| 117 |
+
L(g) - (Section 3.2.1)
|
| 118 |
+
|
| 119 |
+
:rule: (parent, children)
|
| 120 |
+
- recusrive case
|
| 121 |
+
- parent: a set of node labels
|
| 122 |
+
- children: a set of elements like (edge_type, dir, rule)
|
| 123 |
+
- base case (parent is a leaf)
|
| 124 |
+
- parent: a set of node labels
|
| 125 |
+
- children: an empty set
|
| 126 |
+
|
| 127 |
+
:return: the number of bits required to transmit a rule
|
| 128 |
+
'''
|
| 129 |
+
if type(rule) is not tuple:
|
| 130 |
+
'''
|
| 131 |
+
Level 1+ rules.
|
| 132 |
+
'''
|
| 133 |
+
# node labels
|
| 134 |
+
length = self.log_LV
|
| 135 |
+
length += sum(-log(self.graph.node_label_counts[label] / self.graph.n) for label in rule.root)
|
| 136 |
+
# num branches
|
| 137 |
+
length += self.length_natural_number(len(rule.children) + 1)
|
| 138 |
+
for child in rule.children:
|
| 139 |
+
edge_type, _, child = child
|
| 140 |
+
# edge dir
|
| 141 |
+
length += 1
|
| 142 |
+
# edge label
|
| 143 |
+
length += -log(self.graph.edge_label_counts[edge_type] / self.graph.m)
|
| 144 |
+
# children
|
| 145 |
+
length += self.length_rule(child)
|
| 146 |
+
return length
|
| 147 |
+
|
| 148 |
+
parent, children = rule
|
| 149 |
+
|
| 150 |
+
# parent labels
|
| 151 |
+
length = self.log_LV
|
| 152 |
+
length += sum(-log(self.graph.node_label_counts[label] / self.graph.n) for label in parent)
|
| 153 |
+
# num branches
|
| 154 |
+
length += self.length_natural_number(len(children) + 1)
|
| 155 |
+
for child in children:
|
| 156 |
+
edge_type, _, rule_prime = child
|
| 157 |
+
# edge type
|
| 158 |
+
length += -log(self.graph.edge_label_counts[edge_type] / self.graph.m)
|
| 159 |
+
# edge dir
|
| 160 |
+
length += 1
|
| 161 |
+
# visit child
|
| 162 |
+
length += self.length_rule(rule_prime)
|
| 163 |
+
return length
|
| 164 |
+
|
| 165 |
+
def length_rule_assertions(self, rule, model, correct_assertions=None, info=False):
|
| 166 |
+
'''
|
| 167 |
+
L(alpha(g)) - (Section 3.2.1)
|
| 168 |
+
'''
|
| 169 |
+
if type(rule) is not tuple:
|
| 170 |
+
'''
|
| 171 |
+
Level 1+ rules.
|
| 172 |
+
'''
|
| 173 |
+
if rule.tuplify() in self.rule_to_length:
|
| 174 |
+
return self.rule_to_length[rule.tuplify()]
|
| 175 |
+
# num assertions
|
| 176 |
+
num_assertions = self.graph.nodes_with_type(rule.root)
|
| 177 |
+
# num exceptions
|
| 178 |
+
num_correct = len(rule.correct_assertions)
|
| 179 |
+
num_exceptions = num_assertions - num_correct
|
| 180 |
+
length = log(num_assertions)
|
| 181 |
+
# exception ids
|
| 182 |
+
length += self.length_binomial(num_assertions, num_exceptions)
|
| 183 |
+
cost_of_exceptions = length
|
| 184 |
+
# correct assertions
|
| 185 |
+
def length_correct_assertion(real, real_node, _rule, depth=1):
|
| 186 |
+
'''
|
| 187 |
+
:real: a CorrectAssertion, which we descend recusrively to encode
|
| 188 |
+
:_rule: a Rule, of which real is a relization
|
| 189 |
+
'''
|
| 190 |
+
_length = 0
|
| 191 |
+
# for r' in chi(r)
|
| 192 |
+
for pred, dir, child in _rule.children:
|
| 193 |
+
# num spokes
|
| 194 |
+
_length += self.log_V
|
| 195 |
+
# spoke ids
|
| 196 |
+
num_assertions = len(real.nodes[real_node].neighbors_of_type[(pred, dir, child.root)])
|
| 197 |
+
_length += self.length_binomial(self.graph.n - 1, num_assertions)
|
| 198 |
+
# visit children
|
| 199 |
+
for real_child in real.nodes[real_node].neighbors_of_type[(pred, dir, child.root)]:
|
| 200 |
+
_length += length_correct_assertion(real, real_child, child, depth + 1)
|
| 201 |
+
return _length
|
| 202 |
+
|
| 203 |
+
for real in rule.correct_assertions: # each correct_assertion is a tree
|
| 204 |
+
length += length_correct_assertion(real, real.root, rule)
|
| 205 |
+
|
| 206 |
+
self.rule_to_length[rule.tuplify()] = length
|
| 207 |
+
if info:
|
| 208 |
+
# length, length of excpetions, length of cas
|
| 209 |
+
return length, cost_of_exceptions, length - cost_of_exceptions
|
| 210 |
+
return length
|
| 211 |
+
|
| 212 |
+
if rule in self.rule_to_length:
|
| 213 |
+
return self.rule_to_length[rule]
|
| 214 |
+
# correct assertions
|
| 215 |
+
correct_assertions = model.rules[rule] if model else correct_assertions
|
| 216 |
+
# num assertions
|
| 217 |
+
num_assertions = self.graph.nodes_with_type(rule[0])
|
| 218 |
+
# num exceptions
|
| 219 |
+
num_correct = len(correct_assertions)
|
| 220 |
+
num_exceptions = num_assertions - num_correct
|
| 221 |
+
length = log(num_assertions)
|
| 222 |
+
# exception ids
|
| 223 |
+
length += self.length_binomial(num_assertions, num_exceptions)
|
| 224 |
+
cost_of_exceptions = length
|
| 225 |
+
|
| 226 |
+
def length_rule_tree(rule, rho):
|
| 227 |
+
# num_to_choose_from = self.graph.nodes_with_type(rule[1][0][2][0])
|
| 228 |
+
# assert(num_to_choose_from >= rho)
|
| 229 |
+
return self.log_V + self.length_binomial(self.graph.n - 1, rho)
|
| 230 |
+
|
| 231 |
+
# correct assertions
|
| 232 |
+
for ca in correct_assertions:
|
| 233 |
+
# size correct assertion
|
| 234 |
+
length += length_rule_tree(rule, ca)
|
| 235 |
+
self.rule_to_length[rule] = length
|
| 236 |
+
if info:
|
| 237 |
+
return length, cost_of_exceptions, length - cost_of_exceptions
|
| 238 |
+
return length
|
| 239 |
+
|
| 240 |
+
def length_graph_with_model(self, model):
|
| 241 |
+
'''
|
| 242 |
+
L(G|M) - (Section 3.2.2)
|
| 243 |
+
'''
|
| 244 |
+
negative_edge_error = self.length_negative_edge_error(model)
|
| 245 |
+
negative_node_error = self.length_negative_label_error(model)
|
| 246 |
+
length = negative_edge_error + negative_node_error
|
| 247 |
+
return length, negative_edge_error, negative_node_error
|
| 248 |
+
|
| 249 |
+
def length_negative_edge_error(self, model):
|
| 250 |
+
'''
|
| 251 |
+
L(A-) - (Section 3.2.2)
|
| 252 |
+
'''
|
| 253 |
+
# number of ones modeled
|
| 254 |
+
num_modeled = len(model.tensor)
|
| 255 |
+
# num ones
|
| 256 |
+
num_unexplained = self.graph.m - num_modeled
|
| 257 |
+
# ones
|
| 258 |
+
length = self.length_binomial((self.graph.n ** 2) * self.graph.num_edge_labels - num_modeled, num_unexplained)
|
| 259 |
+
return length
|
| 260 |
+
|
| 261 |
+
def length_negative_label_error(self, model):
|
| 262 |
+
'''
|
| 263 |
+
L(L-) - (Section 3.2.2)
|
| 264 |
+
'''
|
| 265 |
+
# number of ones modeled
|
| 266 |
+
num_modeled = len(model.label_matrix)
|
| 267 |
+
# num ones
|
| 268 |
+
num_unexplained = self.graph.total_num_labels - num_modeled
|
| 269 |
+
# ones
|
| 270 |
+
length = self.length_binomial(self.graph.num_node_labels * self.graph.n - num_modeled, num_unexplained)
|
| 271 |
+
return length
|
src/research/COINs-KGGeneration/graph_analysis/KGist/graph.py
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import numpy as np
|
| 2 |
+
from collections import defaultdict
|
| 3 |
+
import os
|
| 4 |
+
from itertools import chain, combinations
|
| 5 |
+
from scipy.sparse import lil_matrix
|
| 6 |
+
import itertools
|
| 7 |
+
import sys
|
| 8 |
+
import _pickle as pickle
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
class Graph:
|
| 12 |
+
'''
|
| 13 |
+
A Knowledge Graph representation which seeks to make the operations needed
|
| 14 |
+
for this method as efficient as possible.
|
| 15 |
+
'''
|
| 16 |
+
def __init__(self, name, ext='txt', delimiter=' ', idify=False, verbose=True, load_candidates_from_disk=False):
|
| 17 |
+
'''
|
| 18 |
+
:name: the name of the graph to load.
|
| 19 |
+
:ext: the file extension for the graph files.
|
| 20 |
+
:delimiter: the delimiter for the graph files.
|
| 21 |
+
:idify: if true, converts strings to ids
|
| 22 |
+
:verbose: whether or not to print simple stats (e.g., num nodes)
|
| 23 |
+
|
| 24 |
+
Assumes:
|
| 25 |
+
1) ../data/{name}.{ext} edgelist.
|
| 26 |
+
2) ../data/{name}_labels.{ext} node label mapping.
|
| 27 |
+
|
| 28 |
+
e.g., ../data/dbpedia.txt and ../data/dbpedia_labels.txt
|
| 29 |
+
'''
|
| 30 |
+
edgelist = f"graph_analysis/KGist/data/{name}.txt"
|
| 31 |
+
label_map = f"graph_analysis/KGist/data/{name}_labels.txt"
|
| 32 |
+
self.name = name
|
| 33 |
+
self.node_list = set()
|
| 34 |
+
self.node_to_labels = dict()
|
| 35 |
+
self.node_label_counts = defaultdict(int)
|
| 36 |
+
self.edge_label_counts = defaultdict(int)
|
| 37 |
+
self.idify = idify
|
| 38 |
+
# load the graph
|
| 39 |
+
self.load(edgelist, label_map, delimiter, verbose, load_candidates_from_disk)
|
| 40 |
+
self.num_node_labels = len(self.label_matrix)
|
| 41 |
+
if verbose:
|
| 42 |
+
print('|V| = {}'.format(self.n))
|
| 43 |
+
print('|E| = {}'.format(self.m))
|
| 44 |
+
print('|L_V| = {}'.format(self.num_node_labels))
|
| 45 |
+
print('|L_E| = {}'.format(self.num_edge_labels))
|
| 46 |
+
|
| 47 |
+
def load(self, edgelist, label_map, delimiter, verbose, load_candidates_from_disk):
|
| 48 |
+
'''
|
| 49 |
+
Loads a knowledge graph.
|
| 50 |
+
|
| 51 |
+
:edgelist: a path to the graph edgelist.
|
| 52 |
+
:label_map: a path to the node label mapping.
|
| 53 |
+
:delimiter: the delimiter used in the above files.
|
| 54 |
+
'''
|
| 55 |
+
self.label_matrix = dict()
|
| 56 |
+
if self.idify:
|
| 57 |
+
nid = 0
|
| 58 |
+
eid = 0
|
| 59 |
+
lid = 0
|
| 60 |
+
self.id_to_pred = dict()
|
| 61 |
+
self.pred_to_id = dict()
|
| 62 |
+
self.id_to_node = dict()
|
| 63 |
+
self.node_to_id = dict()
|
| 64 |
+
self.label_to_id = dict()
|
| 65 |
+
self.id_to_label = dict()
|
| 66 |
+
# read node label mapping
|
| 67 |
+
with open(label_map, mode="r", encoding="utf-8") as f:
|
| 68 |
+
for line in f.read().split("\n"):
|
| 69 |
+
line = line.strip().split(delimiter)
|
| 70 |
+
node = line[0]
|
| 71 |
+
if self.idify:
|
| 72 |
+
self.id_to_node[nid] = node
|
| 73 |
+
self.node_to_id[node] = nid
|
| 74 |
+
node = nid
|
| 75 |
+
nid += 1
|
| 76 |
+
self.node_list.add(node)
|
| 77 |
+
labels = tuple(line[1:])
|
| 78 |
+
self.node_to_labels[node] = labels
|
| 79 |
+
for label in labels:
|
| 80 |
+
if self.idify:
|
| 81 |
+
if label not in self.label_to_id:
|
| 82 |
+
self.label_to_id[label] = lid
|
| 83 |
+
self.id_to_label[lid] = label
|
| 84 |
+
lid += 1
|
| 85 |
+
label = self.label_to_id[label]
|
| 86 |
+
self.node_label_counts[label] += 1
|
| 87 |
+
if label not in self.label_matrix:
|
| 88 |
+
self.label_matrix[label] = set()
|
| 89 |
+
self.label_matrix[label].add(node)
|
| 90 |
+
if self.idify:
|
| 91 |
+
self.node_to_labels[node] = tuple(self.label_to_id[label] for label in line[1:])
|
| 92 |
+
if verbose:
|
| 93 |
+
print('Node labels loaded.')
|
| 94 |
+
|
| 95 |
+
# candidates map to matches
|
| 96 |
+
self.candidates = dict()
|
| 97 |
+
self.m = 0
|
| 98 |
+
self.id_to_edge = dict()
|
| 99 |
+
# read edgelist
|
| 100 |
+
edge_labels = set()
|
| 101 |
+
with open(edgelist, mode="r", encoding="utf-8") as f:
|
| 102 |
+
self.tensor = set()
|
| 103 |
+
for line in f.read().split("\n"):
|
| 104 |
+
if len(line.strip().split(delimiter)) != 3:
|
| 105 |
+
continue
|
| 106 |
+
sub, pred, obj = line.strip().split(delimiter)
|
| 107 |
+
edge_labels.add(pred)
|
| 108 |
+
if self.idify:
|
| 109 |
+
if sub not in self.node_to_id:
|
| 110 |
+
self.node_to_id[sub] = nid
|
| 111 |
+
self.id_to_node[nid] = sub
|
| 112 |
+
nid += 1
|
| 113 |
+
sub = self.node_to_id[sub]
|
| 114 |
+
if obj not in self.node_to_id:
|
| 115 |
+
self.node_to_id[obj] = nid
|
| 116 |
+
self.id_to_node[nid] = obj
|
| 117 |
+
nid += 1
|
| 118 |
+
obj = self.node_to_id[obj]
|
| 119 |
+
if pred not in self.pred_to_id:
|
| 120 |
+
self.pred_to_id[pred] = eid
|
| 121 |
+
self.id_to_pred[eid] = pred
|
| 122 |
+
eid += 1
|
| 123 |
+
pred = self.pred_to_id[pred]
|
| 124 |
+
self.edge_label_counts[pred] += 1
|
| 125 |
+
self.node_list.add(sub)
|
| 126 |
+
self.node_list.add(obj)
|
| 127 |
+
self.tensor.add(self.m)
|
| 128 |
+
if not load_candidates_from_disk:
|
| 129 |
+
# candidates
|
| 130 |
+
sub_labels = self.labels(sub)
|
| 131 |
+
# obj labels
|
| 132 |
+
obj_labels = self.labels(obj)
|
| 133 |
+
sls_ols = list(itertools.product(sub_labels, obj_labels))
|
| 134 |
+
for sl, ol in sls_ols:
|
| 135 |
+
if ((sl,), ((pred, 'out', ((ol,), ())),)) not in self.candidates:
|
| 136 |
+
self.candidates[((sl,), ((pred, 'out', ((ol,), ())),))] = {'label_coverage': set(),
|
| 137 |
+
'edges': set(),
|
| 138 |
+
'ca_to_size': defaultdict(int)}
|
| 139 |
+
self.candidates[((sl,), ((pred, 'out', ((ol,), ())),))]['label_coverage'].add((ol, obj))
|
| 140 |
+
self.candidates[((sl,), ((pred, 'out', ((ol,), ())),))]['edges'].add(self.m)
|
| 141 |
+
self.candidates[((sl,), ((pred, 'out', ((ol,), ())),))]['ca_to_size'][sub] += 1
|
| 142 |
+
|
| 143 |
+
if ((ol,), ((pred, 'in', ((sl,), ())),)) not in self.candidates:
|
| 144 |
+
self.candidates[((ol,), ((pred, 'in', ((sl,), ())),))] = {'label_coverage': set(),
|
| 145 |
+
'edges': set(),
|
| 146 |
+
'ca_to_size': defaultdict(int)}
|
| 147 |
+
self.candidates[((ol,), ((pred, 'in', ((sl,), ())),))]['label_coverage'].add((sl, sub))
|
| 148 |
+
self.candidates[((ol,), ((pred, 'in', ((sl,), ())),))]['edges'].add(self.m)
|
| 149 |
+
self.candidates[((ol,), ((pred, 'in', ((sl,), ())),))]['ca_to_size'][obj] += 1
|
| 150 |
+
self.id_to_edge[self.m] = (sub, pred, obj)
|
| 151 |
+
self.m += 1
|
| 152 |
+
if verbose and self.m % 10000 == 0:
|
| 153 |
+
sys.stdout.write('\r{}'.format(self.m))
|
| 154 |
+
sys.stdout.flush()
|
| 155 |
+
typ_to_nodes = dict()
|
| 156 |
+
for candidate, info in self.candidates.items():
|
| 157 |
+
if candidate[0] not in typ_to_nodes:
|
| 158 |
+
typ_to_nodes[candidate[0]] = set((candidate[0][0], node) for node in self.nodes_with_type(candidate[0], num_only=False))
|
| 159 |
+
# info['label_coverage'].update(typ_to_nodes[candidate[0]])
|
| 160 |
+
self.node_list = list(self.node_list)
|
| 161 |
+
self.num_edge_labels = len(edge_labels)
|
| 162 |
+
self.total_num_labels = 0
|
| 163 |
+
for label, nodes in self.label_matrix.items():
|
| 164 |
+
self.total_num_labels += len(nodes)
|
| 165 |
+
self.n = len(self.node_list)
|
| 166 |
+
|
| 167 |
+
if load_candidates_from_disk:
|
| 168 |
+
with open('../data/{}_candidates.pickle'.format(self.name), 'rb') as f:
|
| 169 |
+
self.candidates = pickle.load(f)
|
| 170 |
+
|
| 171 |
+
if verbose:
|
| 172 |
+
print()
|
| 173 |
+
|
| 174 |
+
def nodes(self):
|
| 175 |
+
return self.node_list
|
| 176 |
+
|
| 177 |
+
def labels(self, node):
|
| 178 |
+
return self.node_to_labels[node]
|
| 179 |
+
|
| 180 |
+
def nodes_with_type(self, typ, num_only=True):
|
| 181 |
+
if len(typ) == 1:
|
| 182 |
+
return len(self.label_matrix[typ[0]]) if num_only else self.label_matrix[typ[0]]
|
| 183 |
+
return len(set.intersection(*list(self.label_matrix[label] for label in typ))) if num_only else set.intersection(*list(self.label_matrix[label] for label in typ))
|
| 184 |
+
|
| 185 |
+
def tuplify(self, rule):
|
| 186 |
+
if self.idify:
|
| 187 |
+
return (tuple(self.id_to_label[label] for label in rule[0]), tuple((self.id_to_pred[child[0]], child[1], self.tuplify(child[2])) for child in rule[1]))
|
| 188 |
+
return (rule[0], tuple((child[0], child[1], self.tuplify(child[2])) for child in rule[1]))
|
src/research/COINs-KGGeneration/graph_analysis/KGist/main.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
from graph_analysis.KGist.graph import Graph
|
| 3 |
+
from graph_analysis.KGist.model import Model
|
| 4 |
+
from graph_analysis.KGist.searcher import Searcher
|
| 5 |
+
from graph_analysis.KGist.evaluator import Evaluator
|
| 6 |
+
|
| 7 |
+
def parse_args():
|
| 8 |
+
def str2bool(v):
|
| 9 |
+
if v.lower() in ('yes', 'true', 't', 'y', '1'):
|
| 10 |
+
return True
|
| 11 |
+
elif v.lower() in ('no', 'false', 'f', 'n', '0'):
|
| 12 |
+
return False
|
| 13 |
+
else:
|
| 14 |
+
raise argparse.ArgumentTypeError('Boolean value expected.')
|
| 15 |
+
|
| 16 |
+
parser = argparse.ArgumentParser()
|
| 17 |
+
parser.add_argument('--graph',
|
| 18 |
+
'-g',
|
| 19 |
+
type=str,
|
| 20 |
+
required=True,
|
| 21 |
+
help='The name of graph: nell or dbpedia if using our parsed data.')
|
| 22 |
+
parser.add_argument('--rule_merging',
|
| 23 |
+
'-Rm',
|
| 24 |
+
type=str2bool,
|
| 25 |
+
default=False,
|
| 26 |
+
required=False,
|
| 27 |
+
help='If True, then run merging refinement (Section 4.2.2).')
|
| 28 |
+
parser.add_argument('--rule_nesting',
|
| 29 |
+
'-Rn',
|
| 30 |
+
type=str2bool,
|
| 31 |
+
default=False,
|
| 32 |
+
required=False,
|
| 33 |
+
help='If True, then run nesting refinement (Section 4.2.2).')
|
| 34 |
+
parser.add_argument('--idify',
|
| 35 |
+
'-i',
|
| 36 |
+
type=str2bool,
|
| 37 |
+
default=True,
|
| 38 |
+
required=False,
|
| 39 |
+
help='If True, then convert entities to integer ids for faster processing.')
|
| 40 |
+
parser.add_argument('--verbosity',
|
| 41 |
+
'-v',
|
| 42 |
+
type=int,
|
| 43 |
+
default=1000000,
|
| 44 |
+
required=False,
|
| 45 |
+
help='How often to print output. If 0, then silence output.')
|
| 46 |
+
parser.add_argument('--output_path',
|
| 47 |
+
'-o',
|
| 48 |
+
type=str,
|
| 49 |
+
default='../output/',
|
| 50 |
+
help='path for output and log files')
|
| 51 |
+
return parser.parse_args()
|
| 52 |
+
|
| 53 |
+
def main(args):
|
| 54 |
+
graph = Graph(args.graph, idify=args.idify, verbose=args.verbosity > 0)
|
| 55 |
+
if args.verbosity > 0:
|
| 56 |
+
print('Graph loaded.')
|
| 57 |
+
searcher = Searcher(graph)
|
| 58 |
+
if args.verbosity > 0:
|
| 59 |
+
print('Creating model.')
|
| 60 |
+
|
| 61 |
+
model = searcher.build_model(verbosity=args.verbosity,
|
| 62 |
+
passes=2,
|
| 63 |
+
label_qualify=True,
|
| 64 |
+
order=['mdl_err', 'coverage', 'lex'])
|
| 65 |
+
if args.verbosity > 0:
|
| 66 |
+
print('***** Initial model *****')
|
| 67 |
+
model.print_stats()
|
| 68 |
+
model.save('{}{}_model'.format(args.output_path, args.graph))
|
| 69 |
+
|
| 70 |
+
if args.rule_merging:
|
| 71 |
+
model = model.merge_rules(verbosity=args.verbosity)
|
| 72 |
+
if args.verbosity > 0:
|
| 73 |
+
print('***** Model refined with Rm *****')
|
| 74 |
+
model.print_stats()
|
| 75 |
+
model.save('{}{}_model_Rm'.format(args.output_path, args.graph))
|
| 76 |
+
|
| 77 |
+
if args.rule_nesting:
|
| 78 |
+
model = model.nest_rules(verbosity=args.verbosity)
|
| 79 |
+
if args.verbosity:
|
| 80 |
+
print('***** Model refined with Rn *****')
|
| 81 |
+
model.print_stats()
|
| 82 |
+
model.save('{}{}_model_Rm_Rn'.format(args.output_path, args.graph))
|
| 83 |
+
|
| 84 |
+
if __name__ == "__main__":
|
| 85 |
+
args = parse_args()
|
| 86 |
+
main(args)
|
src/research/COINs-KGGeneration/graph_analysis/KGist/model.py
ADDED
|
@@ -0,0 +1,388 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from collections import defaultdict
|
| 2 |
+
from graph_analysis.KGist.evaluator import Evaluator
|
| 3 |
+
from itertools import chain, combinations
|
| 4 |
+
import os
|
| 5 |
+
import sys
|
| 6 |
+
import json
|
| 7 |
+
import networkx as nx
|
| 8 |
+
from graph_analysis.KGist.rule import Rule
|
| 9 |
+
from graph_analysis.KGist.correct_assertion import CorrectAssertion
|
| 10 |
+
from copy import copy, deepcopy
|
| 11 |
+
import _pickle as pickle
|
| 12 |
+
import random
|
| 13 |
+
|
| 14 |
+
class Model:
|
| 15 |
+
'''
|
| 16 |
+
A model consisting of rules which explain a knowledge graph.
|
| 17 |
+
'''
|
| 18 |
+
def __init__(self, graph):
|
| 19 |
+
'''
|
| 20 |
+
:graph: the knowledge graph being modeled
|
| 21 |
+
'''
|
| 22 |
+
self.graph = graph
|
| 23 |
+
# rules stored mapping to matches
|
| 24 |
+
self.rules = dict()
|
| 25 |
+
self.node_label_counts = defaultdict(int)
|
| 26 |
+
self.tensor = set()
|
| 27 |
+
self.label_matrix = set()
|
| 28 |
+
self.cache = {'last_updated_rule': None}
|
| 29 |
+
self.rule_graph = None
|
| 30 |
+
self.shared_root_rule_dependency_graph = None
|
| 31 |
+
self.subject_to_rules = dict()
|
| 32 |
+
|
| 33 |
+
def add_rule(self, rule, ghost=False):
|
| 34 |
+
'''
|
| 35 |
+
:rule: the rule to be added
|
| 36 |
+
:ghost: (**ONLY MEANT FOR TESTING**) parameter that can be set to true during testing to not add the assertions of a rule.
|
| 37 |
+
'''
|
| 38 |
+
# store rule
|
| 39 |
+
if rule in self.rules:
|
| 40 |
+
print('Already added')
|
| 41 |
+
return
|
| 42 |
+
|
| 43 |
+
if ghost:
|
| 44 |
+
self.rules[rule] = 'ghost'
|
| 45 |
+
return
|
| 46 |
+
|
| 47 |
+
if type(rule) is not tuple:
|
| 48 |
+
self.rules[rule] = 'level1'
|
| 49 |
+
if rule.root not in self.subject_to_rules:
|
| 50 |
+
self.subject_to_rules[rule.root] = set()
|
| 51 |
+
self.subject_to_rules[rule.root].add(rule)
|
| 52 |
+
else:
|
| 53 |
+
self.rules[rule] = list(self.graph.candidates[rule]['ca_to_size'].values())
|
| 54 |
+
if rule[0] not in self.subject_to_rules:
|
| 55 |
+
self.subject_to_rules[rule[0]] = set()
|
| 56 |
+
self.subject_to_rules[rule[0]].add(rule)
|
| 57 |
+
self.make_assertions(rule)
|
| 58 |
+
|
| 59 |
+
def remove_rule(self, rule):
|
| 60 |
+
'''
|
| 61 |
+
:rule: the rule to be removed
|
| 62 |
+
'''
|
| 63 |
+
if rule != self.cache['last_updated_rule']:
|
| 64 |
+
print('We can only remove the last added rule.')
|
| 65 |
+
return
|
| 66 |
+
if rule not in self.rules: # make sure the rule is actually there
|
| 67 |
+
return
|
| 68 |
+
# remove rule
|
| 69 |
+
del self.rules[rule]
|
| 70 |
+
if type(rule) is not tuple:
|
| 71 |
+
self.subject_to_rules[rule.root].remove(rule)
|
| 72 |
+
if len(self.subject_to_rules[rule.root]) == 0:
|
| 73 |
+
del self.subject_to_rules[rule.root]
|
| 74 |
+
else:
|
| 75 |
+
self.subject_to_rules[rule[0]].remove(rule)
|
| 76 |
+
if len(self.subject_to_rules[rule[0]]) == 0:
|
| 77 |
+
del self.subject_to_rules[rule[0]]
|
| 78 |
+
|
| 79 |
+
self.undo_assertions(rule)
|
| 80 |
+
|
| 81 |
+
def make_assertions(self, rule):
|
| 82 |
+
'''
|
| 83 |
+
Fills in model's tensor and node label map with assertions of a rule
|
| 84 |
+
|
| 85 |
+
:rule: a rule
|
| 86 |
+
'''
|
| 87 |
+
# reset cache
|
| 88 |
+
self.cache = {'last_updated_rule': rule}
|
| 89 |
+
|
| 90 |
+
# update cache
|
| 91 |
+
if type(rule) is not tuple:
|
| 92 |
+
self.cache['new_edges'] = rule.get_edges_covered().difference(self.tensor)
|
| 93 |
+
self.cache['new_labels'] = rule.get_labels_covered().difference(self.label_matrix)
|
| 94 |
+
else:
|
| 95 |
+
self.cache['new_edges'] = self.graph.candidates[rule]['edges'].difference(self.tensor)
|
| 96 |
+
self.cache['new_labels'] = self.graph.candidates[rule]['label_coverage'].difference(self.label_matrix)
|
| 97 |
+
|
| 98 |
+
self.tensor.update(self.cache['new_edges'])
|
| 99 |
+
self.label_matrix.update(self.cache['new_labels'])
|
| 100 |
+
|
| 101 |
+
def undo_assertions(self, rule):
|
| 102 |
+
'''
|
| 103 |
+
Removes things from model's tensor and node label map
|
| 104 |
+
|
| 105 |
+
:rule: a rule
|
| 106 |
+
'''
|
| 107 |
+
self.tensor.difference_update(self.cache['new_edges'])
|
| 108 |
+
self.label_matrix.difference_update(self.cache['new_labels'])
|
| 109 |
+
|
| 110 |
+
def build_rule_graph(self, build_prime=False, force=False):
|
| 111 |
+
'''
|
| 112 |
+
Builds a dependency graph.
|
| 113 |
+
- Nodes are rules
|
| 114 |
+
- (r1, r2) means that r1's tail is r2's head and denotes a possible composition
|
| 115 |
+
|
| 116 |
+
:return: a dependency graph of rules connected by their possible compositions
|
| 117 |
+
'''
|
| 118 |
+
if not force and self.rule_graph:
|
| 119 |
+
return
|
| 120 |
+
|
| 121 |
+
root_to_rule = defaultdict(list)
|
| 122 |
+
# find dependencies and store as edges for a dependency graph
|
| 123 |
+
edges = list()
|
| 124 |
+
tree_rules = list()
|
| 125 |
+
for rule in self.rules:
|
| 126 |
+
if type(rule) is tuple:
|
| 127 |
+
parent, children = rule
|
| 128 |
+
rule = Rule(parent, children)
|
| 129 |
+
self.plant_forest(rule)
|
| 130 |
+
root_to_rule[rule.root].append(rule)
|
| 131 |
+
tree_rules.append(rule)
|
| 132 |
+
|
| 133 |
+
if not build_prime:
|
| 134 |
+
# build graph
|
| 135 |
+
for rule in tree_rules:
|
| 136 |
+
# if leaf matches other rules' roots
|
| 137 |
+
if len(set(rule.get_leaves()).intersection(set(root_to_rule.keys()))) > 0:
|
| 138 |
+
# get the matching rules
|
| 139 |
+
matching_rules = set()
|
| 140 |
+
for leaf in rule.get_leaves():
|
| 141 |
+
if leaf in root_to_rule:
|
| 142 |
+
matching_rules.update(root_to_rule[leaf])
|
| 143 |
+
for other_rule in matching_rules:
|
| 144 |
+
if rule.root in other_rule.get_leaves(): # don't allow loops
|
| 145 |
+
continue
|
| 146 |
+
edges.append((rule, other_rule))
|
| 147 |
+
|
| 148 |
+
self.rule_graph = nx.DiGraph(edges)
|
| 149 |
+
|
| 150 |
+
if build_prime:
|
| 151 |
+
def jaccard_sim(r1, r2):
|
| 152 |
+
a = set(real.root for real in r1.correct_assertions)
|
| 153 |
+
b = set(real.root for real in r2.correct_assertions)
|
| 154 |
+
return len(a.intersection(b)) / len(a.union(b)) if len(a.union(b)) > 0 else 0
|
| 155 |
+
# build rule graph prime, which encodes dependencies of shared root types
|
| 156 |
+
edges = list()
|
| 157 |
+
for rule in tree_rules:
|
| 158 |
+
for other_rule in root_to_rule[rule.root]:
|
| 159 |
+
if rule != other_rule: #(other_rule, rule) not in edges:
|
| 160 |
+
self.plant_forest(rule)
|
| 161 |
+
self.plant_forest(other_rule)
|
| 162 |
+
if jaccard_sim(rule, other_rule) == 1.0:
|
| 163 |
+
edges.append((rule, other_rule))
|
| 164 |
+
self.shared_root_rule_dependency_graph = nx.Graph(edges)
|
| 165 |
+
|
| 166 |
+
def pickle_copy(self, obj):
|
| 167 |
+
name = '{}'.format(random.randint(0, 10000000))
|
| 168 |
+
with open('{}.pickle'.format(name), 'wb') as handle:
|
| 169 |
+
pickle.dump(obj, handle)
|
| 170 |
+
|
| 171 |
+
with open('{}.pickle'.format(name), 'rb') as handle:
|
| 172 |
+
new_obj = pickle.load(handle)
|
| 173 |
+
|
| 174 |
+
os.remove('{}.pickle'.format(name))
|
| 175 |
+
|
| 176 |
+
return new_obj
|
| 177 |
+
|
| 178 |
+
def merge_rules(self, verbosity=1000000):
|
| 179 |
+
'''
|
| 180 |
+
Perfrom merging refinement (Rm).
|
| 181 |
+
|
| 182 |
+
:return: A new Model object with Rm applied to self.
|
| 183 |
+
'''
|
| 184 |
+
self.build_rule_graph(build_prime=True)
|
| 185 |
+
merged = set()
|
| 186 |
+
merged_model = Model(self.graph)
|
| 187 |
+
# find sets of rules that all have the same root (i.e., cliques in the dependency graph)
|
| 188 |
+
cliques = list(nx.find_cliques(self.shared_root_rule_dependency_graph))
|
| 189 |
+
n = len(cliques)
|
| 190 |
+
i = 0
|
| 191 |
+
for i, clique in enumerate(cliques):
|
| 192 |
+
# create a new rule composed that will consist of those in the clique merged
|
| 193 |
+
new_rule = self.pickle_copy(clique[0])
|
| 194 |
+
for r2 in clique[1:]:
|
| 195 |
+
new_rule.merge(r2)
|
| 196 |
+
merged_model.add_rule(new_rule)
|
| 197 |
+
if verbosity > 0 and i > 0 and i % 100 == 0:
|
| 198 |
+
print('{}% of candidate merges tested.'.format(round(i / n * 100, 2)))
|
| 199 |
+
if verbosity > 0:
|
| 200 |
+
print('{}% of candidate merges tested.'.format(round(i / n * 100, 2) if n > 0 else 100))
|
| 201 |
+
|
| 202 |
+
covered = set(node.tuplify() for node in self.shared_root_rule_dependency_graph.nodes())
|
| 203 |
+
for rule in self.rules.keys():
|
| 204 |
+
if rule not in covered:
|
| 205 |
+
merged_model.add_rule(rule)
|
| 206 |
+
|
| 207 |
+
return merged_model
|
| 208 |
+
|
| 209 |
+
def plant_forest(self, rule):
|
| 210 |
+
'''
|
| 211 |
+
Grow a forest of correct_assertions for a level-0 rule
|
| 212 |
+
'''
|
| 213 |
+
if rule.instantiated():
|
| 214 |
+
return
|
| 215 |
+
leaves = list()
|
| 216 |
+
roots = set(self.graph.candidates[rule.tuplify()]['ca_to_size'].keys())
|
| 217 |
+
# maps roots to the correct_assertions where they are the root
|
| 218 |
+
roots_to_correct_assertions = dict()
|
| 219 |
+
# iterate over edges explained by rule and construct stars
|
| 220 |
+
for eid in self.graph.candidates[rule.tuplify()]['edges']:
|
| 221 |
+
sub, pred, obj = self.graph.id_to_edge[eid]
|
| 222 |
+
dir = rule.children[0][1]
|
| 223 |
+
# decide which is root and spoke
|
| 224 |
+
root = sub if dir == 'out' else obj
|
| 225 |
+
spoke = obj if dir == 'out' else sub
|
| 226 |
+
u, v = root, spoke
|
| 227 |
+
# create a rule correct_assertion for the root
|
| 228 |
+
if root not in roots_to_correct_assertions:
|
| 229 |
+
roots_to_correct_assertions[root] = CorrectAssertion(root, label=rule.root)
|
| 230 |
+
root = roots_to_correct_assertions[root]
|
| 231 |
+
# add edge (u, u_typ, pred, dir, v, v_typ)
|
| 232 |
+
edge = (u, rule.root, pred, dir, v, rule.children[0][2].root)
|
| 233 |
+
root.add_edge(edge, eid=eid, labels=True)
|
| 234 |
+
# iterate over each star (rule correct_assertion), and add to the rule (at the root level)
|
| 235 |
+
for root, correct_assertion in roots_to_correct_assertions.items():
|
| 236 |
+
rule.insert_correct_assertion(correct_assertion)
|
| 237 |
+
|
| 238 |
+
def nest_rules(self, verbosity=1000000):
|
| 239 |
+
'''
|
| 240 |
+
Perfrom nesting refinement (Rn).
|
| 241 |
+
|
| 242 |
+
:return: A new Model object with Rn applied to self.
|
| 243 |
+
'''
|
| 244 |
+
def powerset(iterable):
|
| 245 |
+
s = list(iterable)
|
| 246 |
+
return set(chain.from_iterable(combinations(s, r) for r in range(1, len(s) + 1)))
|
| 247 |
+
|
| 248 |
+
self.build_rule_graph()
|
| 249 |
+
|
| 250 |
+
def compose(r1, r2):
|
| 251 |
+
'''
|
| 252 |
+
:r1: a Rule
|
| 253 |
+
:r2: a Rule
|
| 254 |
+
'''
|
| 255 |
+
composed_rule = self.pickle_copy(r1)
|
| 256 |
+
assert(composed_rule.pin_to_leaf(r2))
|
| 257 |
+
composed_rule.filter_errant()
|
| 258 |
+
return composed_rule
|
| 259 |
+
|
| 260 |
+
evaluator = Evaluator(self.graph)
|
| 261 |
+
null_val = evaluator.evaluate(Model(self.graph)) # for log
|
| 262 |
+
best_model = self
|
| 263 |
+
last_model = None
|
| 264 |
+
best_val = evaluator.evaluate(best_model)
|
| 265 |
+
_graph = nx.DiGraph(self.rule_graph.edges())
|
| 266 |
+
seen_pairs = set()
|
| 267 |
+
def checkable(r):
|
| 268 |
+
return r if type(r) is tuple else r.tuplify()
|
| 269 |
+
|
| 270 |
+
edge_to_jaccard_sim = dict()
|
| 271 |
+
for edge in _graph.edges():
|
| 272 |
+
edge_to_jaccard_sim[edge] = edge[0].jaccard_sim(edge[1])
|
| 273 |
+
|
| 274 |
+
num_nested = 0
|
| 275 |
+
while last_model != best_model:
|
| 276 |
+
num_rules = len(best_model.rules)
|
| 277 |
+
rules = set(best_model.rules.keys())
|
| 278 |
+
last_model = best_model
|
| 279 |
+
pairs = _graph.edges()
|
| 280 |
+
pairs = sorted(pairs, key=lambda edge: [edge[0].tuplify()] + [edge[1].tuplify()])
|
| 281 |
+
pairs = sorted(pairs, reverse=True, key=lambda edge: edge_to_jaccard_sim[edge])
|
| 282 |
+
pair_num = 0
|
| 283 |
+
for r1, r2 in pairs:
|
| 284 |
+
pair_num += 1
|
| 285 |
+
if (r1, r2) in seen_pairs or checkable(r1) == checkable(r2):
|
| 286 |
+
continue
|
| 287 |
+
seen_pairs.add((r1, r2))
|
| 288 |
+
# pair is two rules that are candidates for composition
|
| 289 |
+
model_to_test = Model(self.graph)
|
| 290 |
+
candidate = compose(r1, r2)
|
| 291 |
+
if len(candidate.correct_assertions) == 0:
|
| 292 |
+
continue
|
| 293 |
+
approx_L = best_val - evaluator.length_rule(r1) - evaluator.length_rule_assertions(r1, best_model) - evaluator.length_rule(r2) - evaluator.length_rule_assertions(r2, best_model) + evaluator.length_rule(candidate) + evaluator.length_rule_assertions(candidate, best_model)
|
| 294 |
+
if approx_L >= best_val:
|
| 295 |
+
continue
|
| 296 |
+
for rule in rules:
|
| 297 |
+
if checkable(rule) != checkable(r1) and checkable(rule) != checkable(r2):
|
| 298 |
+
model_to_test.add_rule(rule)
|
| 299 |
+
|
| 300 |
+
model_to_test.add_rule(candidate)
|
| 301 |
+
# evaluate the possible new model
|
| 302 |
+
new_val = evaluator.evaluate(model_to_test)
|
| 303 |
+
|
| 304 |
+
if new_val < best_val:
|
| 305 |
+
num_nested += 1
|
| 306 |
+
best_model = model_to_test
|
| 307 |
+
best_val = new_val
|
| 308 |
+
before_n = _graph.number_of_nodes()
|
| 309 |
+
before_m = _graph.number_of_edges()
|
| 310 |
+
_graph = nx.algorithms.minors.contracted_nodes(_graph, r1, r2, self_loops=False)
|
| 311 |
+
assert(_graph.number_of_nodes() == before_n - 1)
|
| 312 |
+
_graph = nx.relabel_nodes(_graph, {r1: candidate})
|
| 313 |
+
for edge in list(_graph.out_edges(candidate)) + list(_graph.in_edges(candidate)):
|
| 314 |
+
if edge not in edge_to_jaccard_sim:
|
| 315 |
+
edge_to_jaccard_sim[edge] = edge[0].jaccard_sim(edge[1])
|
| 316 |
+
|
| 317 |
+
to_remove = list()
|
| 318 |
+
# not all are legal
|
| 319 |
+
for comp, y in _graph.out_edges(candidate): # edges where comp's inner match y's root
|
| 320 |
+
assert(comp == candidate)
|
| 321 |
+
if y.root not in comp.get_inner_nodes():
|
| 322 |
+
to_remove.append((comp, y))
|
| 323 |
+
for y, comp in _graph.in_edges(candidate): # edges where y's inner match comp's root
|
| 324 |
+
assert(comp == candidate)
|
| 325 |
+
if comp.root not in y.get_inner_nodes():
|
| 326 |
+
to_remove.append((y, comp))
|
| 327 |
+
_graph.remove_edges_from(to_remove)
|
| 328 |
+
|
| 329 |
+
assert(_graph.number_of_nodes() == before_n - 1)
|
| 330 |
+
break
|
| 331 |
+
if verbosity > 0 and pair_num % 100 == 0:
|
| 332 |
+
print('{}% of candidate compositions processed.'.format(round((pair_num / len(pairs)) * 100, 2)))
|
| 333 |
+
if verbosity > 0:
|
| 334 |
+
print('{}% of candidate compositions processed.'.format(round((pair_num / len(pairs)) * 100, 2)
|
| 335 |
+
if len(pairs) > 0 else 100))
|
| 336 |
+
print('{} nestings performed.'.format(num_nested))
|
| 337 |
+
return best_model
|
| 338 |
+
|
| 339 |
+
def save(self, fname):
|
| 340 |
+
'''
|
| 341 |
+
Saves the model in json format.
|
| 342 |
+
|
| 343 |
+
:path: path to a json file where model should be saved
|
| 344 |
+
'''
|
| 345 |
+
rules = list()
|
| 346 |
+
for rule in self.rules:
|
| 347 |
+
if type(rule) is tuple:
|
| 348 |
+
parent, children = rule
|
| 349 |
+
rule = Rule(parent, children)
|
| 350 |
+
self.plant_forest(rule)
|
| 351 |
+
rules.append(rule)
|
| 352 |
+
|
| 353 |
+
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
|
| 354 |
+
pickle_outfile = os.path.join(ROOT_DIR, fname + '.pickle')
|
| 355 |
+
with open(pickle_outfile, 'wb') as handle:
|
| 356 |
+
pickle.dump(self, handle)
|
| 357 |
+
|
| 358 |
+
rule_outfile = os.path.join(ROOT_DIR, fname + '.rules')
|
| 359 |
+
with open(rule_outfile, 'w') as f:
|
| 360 |
+
for rule in rules:
|
| 361 |
+
if self.graph.idify:
|
| 362 |
+
f.write('{}\n'.format(rule.tuplify(id_to_node=self.graph.id_to_node, id_to_pred=self.graph.id_to_pred)))
|
| 363 |
+
else:
|
| 364 |
+
f.write('{}\n'.format(rule.tuplify()))
|
| 365 |
+
|
| 366 |
+
def percent_improved(self):
|
| 367 |
+
evaluator = Evaluator(self.graph)
|
| 368 |
+
null_val = evaluator.evaluate(Model(self.graph))
|
| 369 |
+
val = evaluator.evaluate(self)
|
| 370 |
+
# the difference is what percent of the original?
|
| 371 |
+
return ((null_val - val) / null_val) * 100
|
| 372 |
+
|
| 373 |
+
def print_stats(self):
|
| 374 |
+
evaluator = Evaluator(self.graph)
|
| 375 |
+
val = evaluator.evaluate(self)
|
| 376 |
+
print('----- Model stats -----')
|
| 377 |
+
print('L(G,M) = {}'.format(round(val, 2)))
|
| 378 |
+
null_val = evaluator.evaluate(Model(self.graph))
|
| 379 |
+
print('% Bits needed: {}'.format(round((val / null_val) * 100, 2)))
|
| 380 |
+
print('# Rules: {}'.format(len(self.rules)))
|
| 381 |
+
print('% Edges Explained: {}'.format(round(len(self.tensor) / self.graph.m * 100, 2)))
|
| 382 |
+
print('-----------------------')
|
| 383 |
+
|
| 384 |
+
def get_stats(self):
|
| 385 |
+
evaluator = Evaluator(self.graph)
|
| 386 |
+
val = evaluator.evaluate(self)
|
| 387 |
+
null_val = evaluator.evaluate(Model(self.graph))
|
| 388 |
+
return val, val / null_val, len(self.rules), len(self.tensor) / self.graph.m
|
src/research/COINs-KGGeneration/graph_analysis/KGist/rule.py
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from copy import deepcopy
|
| 2 |
+
|
| 3 |
+
class Rule:
|
| 4 |
+
'''
|
| 5 |
+
A class which represents rules as trees.
|
| 6 |
+
Best used for rules after level 1.
|
| 7 |
+
'''
|
| 8 |
+
def __init__(self, root, children=None):
|
| 9 |
+
self.root = root
|
| 10 |
+
self.children = list()
|
| 11 |
+
# a list of trees that match the rule structure all the way down
|
| 12 |
+
# - if empty, then the rule is not a root
|
| 13 |
+
self.correct_assertions = list()
|
| 14 |
+
if children:
|
| 15 |
+
for child in children:
|
| 16 |
+
self.insert(child)
|
| 17 |
+
# store the tuple form or rules for easy (ehh) debugging. Yay!
|
| 18 |
+
self.tuple_rules = [self.tuplify()]
|
| 19 |
+
self.correct_at_depth = dict()
|
| 20 |
+
self.assertions_at_depth = dict()
|
| 21 |
+
|
| 22 |
+
def has_children(self):
|
| 23 |
+
return len(self.children) > 0
|
| 24 |
+
|
| 25 |
+
def instantiated(self):
|
| 26 |
+
return len(self.correct_assertions) > 0
|
| 27 |
+
|
| 28 |
+
def insert(self, branch):
|
| 29 |
+
'''
|
| 30 |
+
Insert a branch into the rule.
|
| 31 |
+
|
| 32 |
+
:branch: (pred, dir, leaf)
|
| 33 |
+
- :pred: the edge type
|
| 34 |
+
- :dir: the direction of the edge
|
| 35 |
+
- :leaf: the node id
|
| 36 |
+
'''
|
| 37 |
+
if type(branch[2]) is tuple:
|
| 38 |
+
pred, dir, leaf = branch
|
| 39 |
+
leaf, _ = leaf
|
| 40 |
+
leaf = Rule(leaf)
|
| 41 |
+
else:
|
| 42 |
+
pred, dir, leaf = branch
|
| 43 |
+
self.children.append((pred, dir, leaf))
|
| 44 |
+
|
| 45 |
+
def insert_correct_assertion(self, correct_assertion):
|
| 46 |
+
'''
|
| 47 |
+
Adds a correct_assertion, which should only be used for roots.
|
| 48 |
+
|
| 49 |
+
:correct_assertion: a CorrectAssertion
|
| 50 |
+
'''
|
| 51 |
+
self.correct_assertions.append(correct_assertion)
|
| 52 |
+
|
| 53 |
+
def get_edges_covered(self):
|
| 54 |
+
covered = set()
|
| 55 |
+
for real in self.correct_assertions:
|
| 56 |
+
covered.update(real.edge_ids)
|
| 57 |
+
return covered
|
| 58 |
+
|
| 59 |
+
def get_labels_covered(self):
|
| 60 |
+
covered = set()
|
| 61 |
+
for real in self.correct_assertions:
|
| 62 |
+
covered.update(real.labels)
|
| 63 |
+
return covered
|
| 64 |
+
|
| 65 |
+
def merge(self, other_rule):
|
| 66 |
+
'''
|
| 67 |
+
Merge two rules with the same roots. For now we assume the correct assertions are identical, which is true a shocking amount of the time.
|
| 68 |
+
'''
|
| 69 |
+
assert(other_rule.root == self.root)
|
| 70 |
+
|
| 71 |
+
self.children.extend(other_rule.children)
|
| 72 |
+
self.correct_assertions = sorted(self.correct_assertions, key=lambda real: real.root)
|
| 73 |
+
other_rule.correct_assertions = sorted(other_rule.correct_assertions, key=lambda real: real.root)
|
| 74 |
+
for real, other_real in zip(self.correct_assertions, other_rule.correct_assertions):
|
| 75 |
+
real.merge(other_real)
|
| 76 |
+
return True
|
| 77 |
+
|
| 78 |
+
def pin_to_leaf(self, leaf):
|
| 79 |
+
'''
|
| 80 |
+
Pins a Rule to a leaf, and does likewise for the rule correct_assertions.
|
| 81 |
+
|
| 82 |
+
:leaf: a Rule object whose root is the label of the leaf to which we should pin it.
|
| 83 |
+
|
| 84 |
+
:return: True if leaf successfully pinned, False otherwise
|
| 85 |
+
'''
|
| 86 |
+
found = False
|
| 87 |
+
# search children for a matching leaf
|
| 88 |
+
for i, child in enumerate(self.children):
|
| 89 |
+
pred, dir, child = child
|
| 90 |
+
if child.root == leaf.root: # pin here
|
| 91 |
+
if self.instantiated():
|
| 92 |
+
for leaf_real in leaf.correct_assertions: # append each leaf correct_assertion
|
| 93 |
+
for real in self.correct_assertions: # pin to each correct_assertion as well, if appropriate
|
| 94 |
+
if leaf_real.root in real.nodes:
|
| 95 |
+
real.compose(leaf_real)
|
| 96 |
+
self.children[i][2].children.extend(leaf.children)
|
| 97 |
+
found = True
|
| 98 |
+
if not found: # try children recursively
|
| 99 |
+
for child in self.children:
|
| 100 |
+
found = child[2].pin_to_leaf(leaf) or found
|
| 101 |
+
return found
|
| 102 |
+
else:
|
| 103 |
+
return found
|
| 104 |
+
|
| 105 |
+
def get_matching_nodes(self, label):
|
| 106 |
+
matches = set()
|
| 107 |
+
frontier = [self]
|
| 108 |
+
while len(frontier) > 0:
|
| 109 |
+
node = frontier.pop()
|
| 110 |
+
if node.root == label:
|
| 111 |
+
matches.add(node)
|
| 112 |
+
for _, _, child in node.children:
|
| 113 |
+
frontier.insert(0, child)
|
| 114 |
+
return matches
|
| 115 |
+
|
| 116 |
+
def get_leaves(self):
|
| 117 |
+
leaves = list()
|
| 118 |
+
def add_leaf(r):
|
| 119 |
+
if not r.has_children():
|
| 120 |
+
leaves.append(r.root)
|
| 121 |
+
else:
|
| 122 |
+
for edge_type, dir, child in r.children:
|
| 123 |
+
add_leaf(child)
|
| 124 |
+
add_leaf(self)
|
| 125 |
+
return leaves
|
| 126 |
+
|
| 127 |
+
def get_inner_nodes(self):
|
| 128 |
+
inner_nodes = set()
|
| 129 |
+
for _, _, child in self.children:
|
| 130 |
+
inner_nodes.add(child.root)
|
| 131 |
+
inner_nodes.update(child.get_inner_nodes())
|
| 132 |
+
return inner_nodes
|
| 133 |
+
|
| 134 |
+
def jaccard_sim(self, other_rule):
|
| 135 |
+
leaves = set()
|
| 136 |
+
for real in self.correct_assertions:
|
| 137 |
+
leaves.update(set(real.nodes.keys()).difference({real.root}))
|
| 138 |
+
roots = set(real.root for real in other_rule.correct_assertions)
|
| 139 |
+
return len(leaves.intersection(roots)) / len(leaves.union(roots)) if len(leaves.union(roots)) > 0 else 0
|
| 140 |
+
|
| 141 |
+
def tuplify(self, id_to_node=None, id_to_pred=None):
|
| 142 |
+
if id_to_node and id_to_pred:
|
| 143 |
+
return (tuple(id_to_node[label] for label in self.root), tuple((id_to_pred[child[0]], child[1], child[2].tuplify(id_to_node, id_to_pred)) for child in self.children))
|
| 144 |
+
return (self.root, tuple((child[0], child[1], child[2].tuplify()) for child in self.children))
|
| 145 |
+
|
| 146 |
+
def get_atoms(self):
|
| 147 |
+
atoms = list()
|
| 148 |
+
for child in self.children:
|
| 149 |
+
atoms.append((self.root, tuple(((child[0], child[1], (child[2].root, ())),))))
|
| 150 |
+
atoms.extend(child[2].get_atoms())
|
| 151 |
+
return atoms
|
| 152 |
+
|
| 153 |
+
def get_preds(self):
|
| 154 |
+
preds = set()
|
| 155 |
+
for pred, dir, child in self.children:
|
| 156 |
+
preds.add(pred)
|
| 157 |
+
preds.update(child.get_preds())
|
| 158 |
+
return preds
|
| 159 |
+
|
| 160 |
+
def max_depth(self):
|
| 161 |
+
if not self.has_children():
|
| 162 |
+
return 0
|
| 163 |
+
return 1 + max(child[2].max_depth() for child in self.children)
|
| 164 |
+
|
| 165 |
+
def min_depth(self):
|
| 166 |
+
if not self.has_children():
|
| 167 |
+
return 0
|
| 168 |
+
return 1 + min(child[2].min_depth() for child in self.children)
|
| 169 |
+
|
| 170 |
+
def get_correct(self, with_removed=False):
|
| 171 |
+
'''
|
| 172 |
+
Correct means that at every level, the correct_assertions align with the rule structure.
|
| 173 |
+
|
| 174 |
+
:return: a list of relization trees that are correct all the way down.
|
| 175 |
+
'''
|
| 176 |
+
|
| 177 |
+
def is_correct(real, real_node, node):
|
| 178 |
+
'''
|
| 179 |
+
:real: a correct_assertion
|
| 180 |
+
:node: a rule node
|
| 181 |
+
|
| 182 |
+
:return: true if the correct_assertion is correct from this node on
|
| 183 |
+
'''
|
| 184 |
+
# the types of children expected of the correct_assertion
|
| 185 |
+
expected_children = list((child[0], child[1], child[2].root) for child in node.children)
|
| 186 |
+
correct = True # innocent until proven guilty
|
| 187 |
+
for pred, dir, child in expected_children:
|
| 188 |
+
if (pred, dir, child) not in real_node.neighbors_of_type:
|
| 189 |
+
correct = False
|
| 190 |
+
break
|
| 191 |
+
if correct:
|
| 192 |
+
# iterate over each child of the rule node
|
| 193 |
+
for pred, dir, child in node.children:
|
| 194 |
+
for real_child in real_node.neighbors_of_type[(pred, dir, child.root)]:
|
| 195 |
+
correct = is_correct(real, real.nodes[real_child], child)
|
| 196 |
+
if not correct:
|
| 197 |
+
break
|
| 198 |
+
if not correct:
|
| 199 |
+
break
|
| 200 |
+
return correct
|
| 201 |
+
|
| 202 |
+
return list(filter(lambda real: is_correct(real, real.nodes[real.root], self), self.correct_assertions))
|
| 203 |
+
|
| 204 |
+
def filter_errant(self):
|
| 205 |
+
'''
|
| 206 |
+
Filter out the correct_assertions that err at some level.
|
| 207 |
+
'''
|
| 208 |
+
# bfs
|
| 209 |
+
self.correct_assertions = self.get_correct()
|
| 210 |
+
|
| 211 |
+
def print(self):
|
| 212 |
+
frontier = [(None, None, self, 0)]
|
| 213 |
+
while len(frontier) > 0:
|
| 214 |
+
pred, dir, rule, depth = frontier.pop()
|
| 215 |
+
if depth == 0:
|
| 216 |
+
print('{}{}'.format(''.join(['\t'] * depth), rule.root))
|
| 217 |
+
else:
|
| 218 |
+
print('{}({},{},{})'.format(''.join(['\t'] * depth), pred, dir, rule.root))
|
| 219 |
+
for pred, dir, child in rule.children:
|
| 220 |
+
frontier.append((pred, dir, child, depth + 1))
|
| 221 |
+
|
| 222 |
+
def plot(self, save_path=None):
|
| 223 |
+
'''
|
| 224 |
+
Create a plot of a rule.
|
| 225 |
+
'''
|
| 226 |
+
from graphviz import Digraph
|
| 227 |
+
|
| 228 |
+
dot = Digraph()
|
| 229 |
+
root = self
|
| 230 |
+
frontier = [self]
|
| 231 |
+
edges = list()
|
| 232 |
+
while len(frontier) > 0:
|
| 233 |
+
node = frontier.pop()
|
| 234 |
+
if node == root:
|
| 235 |
+
dot.attr('node', shape='doublecircle')
|
| 236 |
+
else:
|
| 237 |
+
dot.attr('node', shape='circle')
|
| 238 |
+
node_name = node.root[0].split(':')[-1]
|
| 239 |
+
dot.node(node_name, node_name)
|
| 240 |
+
for pred, delta, child in node.children:
|
| 241 |
+
frontier.insert(0, child)
|
| 242 |
+
node_name = node.root[0].split(':')[-1]
|
| 243 |
+
child_name = child.root[0].split(':')[-1]
|
| 244 |
+
pred = pred.split(':')[-1]
|
| 245 |
+
if delta == 'out':
|
| 246 |
+
edges.append((node_name, pred, child_name))
|
| 247 |
+
else:
|
| 248 |
+
edges.append((child_name, pred, node_name))
|
| 249 |
+
|
| 250 |
+
for edge in edges:
|
| 251 |
+
dot.edge(edge[0], edge[2], label=' {}'.format(edge[1]))
|
| 252 |
+
|
| 253 |
+
save_path = save_path if save_path else '../data/temp/rule_fig'
|
| 254 |
+
dot.render(save_path, view=True)
|
| 255 |
+
|
| 256 |
+
def json_dump(self, outfile=None):
|
| 257 |
+
import json
|
| 258 |
+
data = {'root': self.root,
|
| 259 |
+
'children': list({'pred': pred, 'dir': dir, 'rule': child.json_dump()} for pred, dir, child in self.children)}
|
| 260 |
+
if outfile:
|
| 261 |
+
with open(outfile, 'w') as outfile:
|
| 262 |
+
json.dump(data, outfile, indent=4)
|
| 263 |
+
return data
|
src/research/COINs-KGGeneration/graph_analysis/KGist/searcher.py
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from graph_analysis.KGist.graph import Graph
|
| 2 |
+
from graph_analysis.KGist.model import Model
|
| 3 |
+
from graph_analysis.KGist.evaluator import Evaluator
|
| 4 |
+
import argparse
|
| 5 |
+
import numpy as np
|
| 6 |
+
import itertools
|
| 7 |
+
import functools
|
| 8 |
+
import random
|
| 9 |
+
from math import log2 as log
|
| 10 |
+
import heapq
|
| 11 |
+
from multiprocessing import Pool
|
| 12 |
+
|
| 13 |
+
class Searcher:
|
| 14 |
+
'''
|
| 15 |
+
A class which searches for the optimal model.
|
| 16 |
+
'''
|
| 17 |
+
def __init__(self, graph):
|
| 18 |
+
self.graph = graph
|
| 19 |
+
self.evaluator = Evaluator(graph)
|
| 20 |
+
self.candidates = list(self.graph.candidates.keys())
|
| 21 |
+
|
| 22 |
+
def rank_rules(self):
|
| 23 |
+
'''
|
| 24 |
+
Rank the candidate rules - (Section 4.1.3)
|
| 25 |
+
'''
|
| 26 |
+
# L(G|M_0)
|
| 27 |
+
null_val = self.evaluator.length_graph_with_model(Model(self.graph))[0]
|
| 28 |
+
def reduction_in_error(g):
|
| 29 |
+
'''
|
| 30 |
+
:g: a rule
|
| 31 |
+
'''
|
| 32 |
+
_model = Model(self.graph)
|
| 33 |
+
_model.add_rule(g)
|
| 34 |
+
# compute L(G|M_0) - L(G|M \cup {g})
|
| 35 |
+
red_in_err = null_val - self.evaluator.length_graph_with_model(_model)[0]
|
| 36 |
+
return red_in_err
|
| 37 |
+
self.candidates = sorted(self.candidates,
|
| 38 |
+
reverse=True,
|
| 39 |
+
key=lambda g: (reduction_in_error(g), # reduction in error
|
| 40 |
+
len(self.graph.candidates[g]['ca_to_size']), # number of correct assertions
|
| 41 |
+
g[0])) # rule root labels
|
| 42 |
+
|
| 43 |
+
class BoundedMinHeap:
|
| 44 |
+
'''
|
| 45 |
+
A Min Heap that only allows :bound: items.
|
| 46 |
+
If :bound: is << len(items), then this can be more efficient for finding the top k than sorting the whole list.
|
| 47 |
+
'''
|
| 48 |
+
def __init__(self, bound, key=lambda it: it):
|
| 49 |
+
self.bound = bound
|
| 50 |
+
self.key = key
|
| 51 |
+
self._data = list()
|
| 52 |
+
|
| 53 |
+
def push(self, it):
|
| 54 |
+
if len(self._data) < self.bound:
|
| 55 |
+
heapq.heappush(self._data, (self.key(it), it))
|
| 56 |
+
else:
|
| 57 |
+
heapq.heappushpop(self._data, (self.key(it), it))
|
| 58 |
+
|
| 59 |
+
def get_reversed(self):
|
| 60 |
+
temp = list()
|
| 61 |
+
while len(self._data) > 0:
|
| 62 |
+
temp.append(heapq.heappop(self._data)[1])
|
| 63 |
+
return list(reversed(temp))
|
| 64 |
+
|
| 65 |
+
def build_model_top_k_freq(self, k):
|
| 66 |
+
'''
|
| 67 |
+
Build a model containing the k rules with the most correct assertions.
|
| 68 |
+
'''
|
| 69 |
+
model = Model(self.graph)
|
| 70 |
+
heap = Searcher.BoundedMinHeap(bound=k, key=lambda rule: len(self.graph.candidates[rule]['ca_to_size']))
|
| 71 |
+
for rule in self.candidates:
|
| 72 |
+
heap.push(rule)
|
| 73 |
+
for rule in heap.get_reversed():
|
| 74 |
+
model.add_rule(rule)
|
| 75 |
+
return model
|
| 76 |
+
|
| 77 |
+
def build_model_top_k_coverage(self, k):
|
| 78 |
+
'''
|
| 79 |
+
Build a model containing the k rules that explain the most edges.
|
| 80 |
+
'''
|
| 81 |
+
model = Model(self.graph)
|
| 82 |
+
heap = Searcher.BoundedMinHeap(bound=k, key=lambda rule: sum(list((self.graph.candidates[rule]['ca_to_size']).values())))
|
| 83 |
+
for rule in self.candidates:
|
| 84 |
+
heap.push(rule)
|
| 85 |
+
for rule in heap.get_reversed():
|
| 86 |
+
model.add_rule(rule)
|
| 87 |
+
return model
|
| 88 |
+
|
| 89 |
+
def check_qualify(self, evaluator, verbosity, rule_and_new_labels):
|
| 90 |
+
'''
|
| 91 |
+
Check whether adding more labels to a rule (qualifying it) leads to improvements in MDL terms.
|
| 92 |
+
|
| 93 |
+
:evaluator: an Evaluator object with which to compute MDL scores
|
| 94 |
+
:verbosity: how much to print to the log
|
| 95 |
+
:rule_and_new_labels: (rule, the rule's new labels if qualified)
|
| 96 |
+
|
| 97 |
+
:return: True if the rule is qualified, False if not.
|
| 98 |
+
'''
|
| 99 |
+
rule, new_labels = rule_and_new_labels
|
| 100 |
+
old_rule = rule
|
| 101 |
+
root, children = rule
|
| 102 |
+
rule = (new_labels, children)
|
| 103 |
+
# create M_0
|
| 104 |
+
model = Model(self.graph)
|
| 105 |
+
# create M_0 \cup {g without qualification}
|
| 106 |
+
model.add_rule(old_rule)
|
| 107 |
+
# compute L(G, M_0 \cup {g without qualification})
|
| 108 |
+
# (Note: this computation works because the newly added labels are contained by all correct assertion starting points, so L(G|M) does not change)
|
| 109 |
+
cost_without_qualification = evaluator.length_rule(old_rule) + evaluator.length_rule_assertions(old_rule, model)
|
| 110 |
+
# replace the rule with the qualified version to make M_0 \cup {g with qualification}
|
| 111 |
+
model.rules[rule] = model.rules[old_rule]
|
| 112 |
+
del model.rules[old_rule]
|
| 113 |
+
# compute L(G, M_0 \cup {g with qualification})
|
| 114 |
+
cost_with_qualification = evaluator.length_rule(rule) + evaluator.length_rule_assertions(rule, model)
|
| 115 |
+
|
| 116 |
+
qualified = False
|
| 117 |
+
# if the cost went down, then keep the qualifiers
|
| 118 |
+
if cost_with_qualification < cost_without_qualification:
|
| 119 |
+
# update the data structures so that the new, qualified rules has the same correct assertions as the old, unqualified rule
|
| 120 |
+
self.graph.candidates[rule] = self.graph.candidates[old_rule]
|
| 121 |
+
# delete the data on the old, unqualified rule
|
| 122 |
+
del self.graph.candidates[old_rule]
|
| 123 |
+
return True
|
| 124 |
+
return False
|
| 125 |
+
|
| 126 |
+
def label_qualify(self, verbosity):
|
| 127 |
+
'''
|
| 128 |
+
Qualify rules where appropriate (Section 4.1.1).
|
| 129 |
+
|
| 130 |
+
:verbosity: How often to print progress.
|
| 131 |
+
'''
|
| 132 |
+
num_qualified = 0
|
| 133 |
+
rule_to_new_labels = dict()
|
| 134 |
+
if verbosity > 0:
|
| 135 |
+
print('Qualifying candidate rules (Section 4.1.2).')
|
| 136 |
+
n = len(self.candidates)
|
| 137 |
+
for i, rule in enumerate(self.candidates):
|
| 138 |
+
root = rule[0][0]
|
| 139 |
+
heads = list(self.graph.candidates[rule]['ca_to_size'].keys())
|
| 140 |
+
# if all correct assertions share more labels than the current root label, then we can add this label
|
| 141 |
+
shared_by_all = set(self.graph.labels(heads[0]))
|
| 142 |
+
for head in heads[1:]:
|
| 143 |
+
shared_by_all = shared_by_all.intersection(self.graph.labels(head))
|
| 144 |
+
if shared_by_all == {root}:
|
| 145 |
+
break
|
| 146 |
+
if shared_by_all != {root}:
|
| 147 |
+
rule_to_new_labels[rule] = tuple(sorted(shared_by_all))
|
| 148 |
+
if verbosity > 0 and i > 0 and i % verbosity == 0:
|
| 149 |
+
print('{}% of candidates processed.'.format(round(i / n * 100, 2)))
|
| 150 |
+
if verbosity > 0:
|
| 151 |
+
print('{}% of candidates processed.'.format(round(i / n * 100, 2)))
|
| 152 |
+
|
| 153 |
+
evaluator = Evaluator(self.graph)
|
| 154 |
+
|
| 155 |
+
n = len(rule_to_new_labels.items())
|
| 156 |
+
for i, rule_and_new_labels in enumerate(rule_to_new_labels.items()):
|
| 157 |
+
# check whether the qualifier leads to improvements
|
| 158 |
+
qualified = self.check_qualify(evaluator, verbosity, rule_and_new_labels)
|
| 159 |
+
if qualified:
|
| 160 |
+
num_qualified += 1
|
| 161 |
+
if verbosity > 0 and i > 0 and i % verbosity == 0:
|
| 162 |
+
print('{}'.format(i / n))
|
| 163 |
+
|
| 164 |
+
self.candidates = list(self.graph.candidates.keys())
|
| 165 |
+
if verbosity > 0:
|
| 166 |
+
print('{}% of candidates qualified.'.format(round(num_qualified / n * 100, 2) if n > 0 else 100))
|
| 167 |
+
|
| 168 |
+
def build_model(self, rank='metric', order=['mdl_err', 'coverage', 'lex'], passes=2, label_qualify=True, verbosity=1000000):
|
| 169 |
+
'''
|
| 170 |
+
The core of the algorithm. (Sections 4.1.2-4.2.1)
|
| 171 |
+
'''
|
| 172 |
+
if label_qualify:
|
| 173 |
+
self.label_qualify(verbosity=verbosity)
|
| 174 |
+
|
| 175 |
+
if rank == 'metric':
|
| 176 |
+
self.rank_rules()
|
| 177 |
+
elif rank == 'random':
|
| 178 |
+
print('Random order.')
|
| 179 |
+
random.shuffle(self.candidates)
|
| 180 |
+
# starts null
|
| 181 |
+
model = Model(self.graph)
|
| 182 |
+
|
| 183 |
+
best_val, best_model_length, best_neg_edge, best_neg_node = self.evaluator.evaluate(model, with_lengths=True)
|
| 184 |
+
null_cost = best_val
|
| 185 |
+
if verbosity > 0:
|
| 186 |
+
print('Null encoding cost: {}'.format(round(best_val, 4)))
|
| 187 |
+
num_cans = len(self.candidates)
|
| 188 |
+
tried = set()
|
| 189 |
+
|
| 190 |
+
for _pass in range(1, passes + 1):
|
| 191 |
+
if verbosity > 0:
|
| 192 |
+
print('Starting pass {}.'.format(_pass))
|
| 193 |
+
for i, rule in enumerate(self.candidates):
|
| 194 |
+
# build reverse
|
| 195 |
+
root, child = rule[0], rule[1][0]
|
| 196 |
+
reverse_rule = (child[2][0], ((child[0], 'in' if child[1] == 'out' else 'out', (root, ())),))
|
| 197 |
+
if reverse_rule in self.graph.candidates:
|
| 198 |
+
acc_rule = len(self.graph.candidates[rule]['ca_to_size']) / self.graph.nodes_with_type(rule[0])
|
| 199 |
+
acc_rev_rule = len(self.graph.candidates[reverse_rule]['ca_to_size']) / self.graph.nodes_with_type(reverse_rule[0])
|
| 200 |
+
|
| 201 |
+
if rule in model.rules or reverse_rule in model.rules:
|
| 202 |
+
continue
|
| 203 |
+
|
| 204 |
+
model.add_rule(rule)
|
| 205 |
+
val, model_length, neg_edge, neg_node = self.evaluator.evaluate_change(model, rule, best_model_length)
|
| 206 |
+
model.remove_rule(rule)
|
| 207 |
+
model.add_rule(reverse_rule)
|
| 208 |
+
rev_val, rev_model_length, rev_neg_edge, rev_neg_node = self.evaluator.evaluate_change(model, reverse_rule, best_model_length)
|
| 209 |
+
model.remove_rule(reverse_rule)
|
| 210 |
+
# if the cost didn't go down, remove the rule
|
| 211 |
+
if val <= rev_val < best_val:
|
| 212 |
+
assert(val <= rev_val)
|
| 213 |
+
assert(val < best_val)
|
| 214 |
+
model.add_rule(rule)
|
| 215 |
+
best_val = val
|
| 216 |
+
best_model_length = model_length
|
| 217 |
+
elif rev_val < best_val:
|
| 218 |
+
assert(rev_val < best_val)
|
| 219 |
+
assert(rev_val < val)
|
| 220 |
+
model.add_rule(reverse_rule)
|
| 221 |
+
best_val = rev_val
|
| 222 |
+
best_model_length = rev_model_length
|
| 223 |
+
else:
|
| 224 |
+
acc_rule = len(self.graph.candidates[rule]['ca_to_size']) / self.graph.nodes_with_type(rule[0])
|
| 225 |
+
|
| 226 |
+
if rule in model.rules:
|
| 227 |
+
continue
|
| 228 |
+
|
| 229 |
+
model.add_rule(rule)
|
| 230 |
+
val, model_length, neg_edge, neg_node = self.evaluator.evaluate_change(model, rule, best_model_length)
|
| 231 |
+
|
| 232 |
+
if val < best_val:
|
| 233 |
+
best_val = val
|
| 234 |
+
best_model_length = model_length
|
| 235 |
+
else: # if the cost didn't go down, remove the rule
|
| 236 |
+
model.remove_rule(rule)
|
| 237 |
+
|
| 238 |
+
if verbosity > 0 and i > 0 and i % verbosity == 0:
|
| 239 |
+
print('Percent tried: {}. Num rules: {}. New encoding cost: {}. Percent saved: {}.'.format((i / num_cans) * 100, len(model.rules), best_val, ((null_cost - best_val) / null_cost) * 100))
|
| 240 |
+
if verbosity > 0:
|
| 241 |
+
print('Final number of rules after pass {}: {}'.format(_pass, len(model.rules)))
|
| 242 |
+
|
| 243 |
+
# M*
|
| 244 |
+
return model
|
| 245 |
+
|
| 246 |
+
if __name__ == '__main__':
|
| 247 |
+
'''
|
| 248 |
+
Entry point for the program.
|
| 249 |
+
'''
|
| 250 |
+
parser = argparse.ArgumentParser()
|
| 251 |
+
parser.add_argument('--graph',
|
| 252 |
+
'-g',
|
| 253 |
+
type=str,
|
| 254 |
+
required=True,
|
| 255 |
+
help='the name of the graph to summarize')
|
| 256 |
+
args = parser.parse_args()
|
| 257 |
+
graph = Graph(args.graph)
|
src/research/COINs-KGGeneration/graph_analysis/METIS/libmetis.so
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2aa000b0481594c6b8c5e9cc2f4b751c5d23f62a66f8963210275f629539bbc7
|
| 3 |
+
size 499408
|
src/research/COINs-KGGeneration/graph_analysis/METIS/metis.dll
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:5226f4d336778185e1410f7bfb3a01f13298fc0711e1aa797d3487ba80ffa1f8
|
| 3 |
+
size 186880
|
src/research/COINs-KGGeneration/graph_analysis/__init__.py
ADDED
|
File without changes
|
src/research/COINs-KGGeneration/graph_analysis/main.py
ADDED
|
@@ -0,0 +1,566 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
import itertools
|
| 3 |
+
import re
|
| 4 |
+
from glob import glob
|
| 5 |
+
from os import makedirs, remove
|
| 6 |
+
from typing import Dict, List, Tuple
|
| 7 |
+
|
| 8 |
+
import pandas as pd
|
| 9 |
+
from pyarrow.fs import copy_files
|
| 10 |
+
from tensorboardX import SummaryWriter
|
| 11 |
+
from tqdm import tqdm
|
| 12 |
+
|
| 13 |
+
from graph_analysis.metrics import \
|
| 14 |
+
Connectivity, Graph, Heterogeneity, Importance, MetricSetView, Subgraphing, Summarization, metric_set_to_dashboard
|
| 15 |
+
from graph_analysis.stats import \
|
| 16 |
+
estimate_and_test_comparison, estimate_and_test_pareto, estimate_and_test_uniform, metric_set_histogram
|
| 17 |
+
from graph_data.cluster import cluster_dir, cluster_dir_path, hdfs_glob, hdfs_mkdirs
|
| 18 |
+
from graph_data.load_data import Dataset, FreeBase, HighEnergyPhysicsCitations, NELL, OGBBioKG, PatentCitations, \
|
| 19 |
+
RedditHyperlinks, Swisscom, SwisscomBig, SwisscomCommunity, SwisscomOverlappingRegion, SwisscomSubgraphOverlap, \
|
| 20 |
+
Transport, WordNet
|
| 21 |
+
from graph_data.serialization import save_object
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def store_metric_sets(metric_set_dict: Dict[str, List[MetricSetView]], filename: str):
|
| 25 |
+
save_object(metric_set_dict, f"{filename}.gz")
|
| 26 |
+
copy_files(f"{filename}.gz", f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/{filename}.gz")
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def store_results_table(table: pd.DataFrame, filename: str):
|
| 30 |
+
table.to_csv(
|
| 31 |
+
f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/{filename}.csv",
|
| 32 |
+
sep=",", header=True, index=False, mode="w", encoding="utf-8"
|
| 33 |
+
)
|
| 34 |
+
with cluster_dir.open_output_stream(
|
| 35 |
+
f"{cluster_dir_path}/results-{subgraph_roots}/{filename}.md"
|
| 36 |
+
) as results_file:
|
| 37 |
+
results_file.write(table.to_markdown(index=False).encode("utf-8"))
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def compute_metrics_from_datasets(datasets: List[Dataset], datasets_loading_args: List[Tuple],
|
| 41 |
+
collect_metric_sets: bool = False,
|
| 42 |
+
run_subgraphing_summarization: bool = True,
|
| 43 |
+
write_to_dashboard: bool = True) -> Tuple[pd.DataFrame,
|
| 44 |
+
pd.DataFrame,
|
| 45 |
+
Dict[str, List[MetricSetView]]]:
|
| 46 |
+
scalar_tables = []
|
| 47 |
+
dist_tables = []
|
| 48 |
+
collected_metric_sets = {}
|
| 49 |
+
for dataset, loading_args in tqdm(zip(datasets, datasets_loading_args),
|
| 50 |
+
desc="Processing datasets for metrics", total=len(datasets), leave=False):
|
| 51 |
+
if dataset.name == "swisscom-big" and hdfs_glob("data/swisscom", f"relations_{subgraph_roots}"):
|
| 52 |
+
dataset.node_names_map = pd.read_csv(
|
| 53 |
+
f"hdfs://sbd{cluster_dir_path}/data/swisscom/node_names_{subgraph_roots}.csv",
|
| 54 |
+
header=0, index_col=0, squeeze=True, encoding="utf-8"
|
| 55 |
+
)
|
| 56 |
+
dataset.node_data = pd.read_csv(
|
| 57 |
+
f"hdfs://sbd{cluster_dir_path}/data/swisscom/nodes_{subgraph_roots}.csv",
|
| 58 |
+
header=0, index_col=None, parse_dates=["time", ], encoding="utf-8"
|
| 59 |
+
)
|
| 60 |
+
dataset.edge_data = pd.read_csv(
|
| 61 |
+
f"hdfs://sbd{cluster_dir_path}/data/swisscom/relations_{subgraph_roots}.csv",
|
| 62 |
+
header=0, index_col=None, parse_dates=["time", ], encoding="utf-8"
|
| 63 |
+
)
|
| 64 |
+
else:
|
| 65 |
+
dataset.load_from_disk(*loading_args)
|
| 66 |
+
if dataset.name == "swisscom-big":
|
| 67 |
+
dataset.node_names_map.to_csv(
|
| 68 |
+
f"hdfs://sbd{cluster_dir_path}/data/swisscom/node_names_{subgraph_roots}.csv",
|
| 69 |
+
header=True, index=True, encoding="utf-8")
|
| 70 |
+
dataset.node_data.to_csv(f"hdfs://sbd{cluster_dir_path}/data/swisscom/nodes_{subgraph_roots}.csv",
|
| 71 |
+
header=True, index=False, encoding="utf-8")
|
| 72 |
+
dataset.edge_data.to_csv(f"hdfs://sbd{cluster_dir_path}/data/swisscom/relations_{subgraph_roots}.csv",
|
| 73 |
+
header=True, index=False, encoding="utf-8")
|
| 74 |
+
|
| 75 |
+
if all(s not in dataset.name for s in ["swisscom-big", "swisscom-community", "swisscom-region"]):
|
| 76 |
+
dataset.time_sort_and_numerize()
|
| 77 |
+
dashboard = None
|
| 78 |
+
if write_to_dashboard:
|
| 79 |
+
makedirs(f"results-{subgraph_roots}/{dataset.name}", exist_ok=True)
|
| 80 |
+
hdfs_mkdirs(f"results-{subgraph_roots}/{dataset.name}")
|
| 81 |
+
new_run_id = len(hdfs_glob(f"results-{subgraph_roots}/{dataset.name}", "")) \
|
| 82 |
+
- len(hdfs_glob(f"results-{subgraph_roots}/{dataset.name}", ".csv")) + 1
|
| 83 |
+
dashboard = SummaryWriter(f"results-{subgraph_roots}/{dataset.name}/{new_run_id}")
|
| 84 |
+
|
| 85 |
+
num_nodes, num_node_types, num_relations = \
|
| 86 |
+
len(dataset.node_data), len(dataset.node_types_map), len(dataset.relation_names_map)
|
| 87 |
+
graph = Graph(dataset.name)
|
| 88 |
+
metric_sets = [Heterogeneity(graph, dashboard, num_node_types, num_relations),
|
| 89 |
+
Connectivity(graph, dashboard, num_nodes),
|
| 90 |
+
Importance(graph, dashboard, num_nodes)]
|
| 91 |
+
if run_subgraphing_summarization:
|
| 92 |
+
metric_sets.append(Subgraphing(graph, dashboard, num_nodes, 1 / num_nodes, 1, 250))
|
| 93 |
+
metric_sets.append(Summarization(graph, dashboard, num_nodes, True, False, 0.95, 250, 5,
|
| 94 |
+
f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}"))
|
| 95 |
+
last_batch_time = None
|
| 96 |
+
for batch_time, nodes, edges in dataset.get_graph_data_batch_generator(pd.Timedelta(150 * 365, "d")):
|
| 97 |
+
graph.update_graph(nodes, edges)
|
| 98 |
+
for metric_set in tqdm(metric_sets, desc="Computing metric sets", leave=False):
|
| 99 |
+
metric_set.recursive_updates(nodes, edges)
|
| 100 |
+
metric_set.compute_metrics()
|
| 101 |
+
if write_to_dashboard:
|
| 102 |
+
metric_set.update_dashboard_visuals(batch_time)
|
| 103 |
+
last_batch_time = batch_time
|
| 104 |
+
for metric_set in metric_sets:
|
| 105 |
+
metric_set.update_dashboard_table(last_batch_time, update_dashboard=write_to_dashboard)
|
| 106 |
+
relabel_distribution_table_supports(metric_set.dist_table,
|
| 107 |
+
dataset.node_names_map,
|
| 108 |
+
dataset.node_types_map,
|
| 109 |
+
dataset.relation_names_map)
|
| 110 |
+
scalar_tables.append(metric_set.scalar_table)
|
| 111 |
+
dist_tables.append(metric_set.dist_table)
|
| 112 |
+
if collect_metric_sets:
|
| 113 |
+
collected_metric_sets.setdefault(metric_set.metric_type, [])
|
| 114 |
+
collected_metric_sets[metric_set.metric_type].append(metric_set.simplified_view())
|
| 115 |
+
dataset.unload_from_memory()
|
| 116 |
+
if run_subgraphing_summarization:
|
| 117 |
+
kgist_rule_graph = pd.read_csv(
|
| 118 |
+
f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/{dataset.name}/kgist_rule_graph.csv",
|
| 119 |
+
header=0, index_col=None, encoding="utf-8"
|
| 120 |
+
)
|
| 121 |
+
relabel_kgist_rule_graph_edges(kgist_rule_graph, dataset.node_types_map, dataset.relation_names_map)
|
| 122 |
+
kgist_rule_graph.to_csv(
|
| 123 |
+
f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/{dataset.name}/kgist_rule_graph.csv",
|
| 124 |
+
header=True, index=False, encoding="utf-8"
|
| 125 |
+
)
|
| 126 |
+
node_names_map_reversed = dataset.node_names_map.reset_index(name="index").set_index("index")["n"]
|
| 127 |
+
node_types_map_reversed = dataset.node_types_map.reset_index(name="index").set_index("index")["type"]
|
| 128 |
+
relation_names_map_reversed = dataset.relation_names_map.reset_index(name="index").set_index("index")["r"]
|
| 129 |
+
node_reader = pd.read_csv(
|
| 130 |
+
f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/{dataset.name}/dedensified_graph_nodes.csv",
|
| 131 |
+
header=0, index_col=None, chunksize=10000, encoding="utf-8"
|
| 132 |
+
)
|
| 133 |
+
edge_reader = pd.read_csv(
|
| 134 |
+
f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/{dataset.name}/dedensified_graph_relations.csv",
|
| 135 |
+
header=0, index_col=None, chunksize=10000, encoding="utf-8"
|
| 136 |
+
)
|
| 137 |
+
compressor_nodes_all = []
|
| 138 |
+
first_chunk = True
|
| 139 |
+
for dedensified_nodes in node_reader:
|
| 140 |
+
compressor_nodes_all.extend(
|
| 141 |
+
list(dedensified_nodes[dedensified_nodes.type.astype(str).str.contains("compressor")].n)
|
| 142 |
+
)
|
| 143 |
+
relabel_dedensified_graph_nodes(dedensified_nodes, num_nodes,
|
| 144 |
+
node_names_map_reversed,
|
| 145 |
+
node_types_map_reversed,
|
| 146 |
+
relation_names_map_reversed)
|
| 147 |
+
dedensified_nodes.to_csv(
|
| 148 |
+
f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/{dataset.name}/"
|
| 149 |
+
f"dedensified_graph_nodes_relabeled.csv",
|
| 150 |
+
mode="w" if first_chunk else "a", header=first_chunk, index=False, encoding="utf-8"
|
| 151 |
+
)
|
| 152 |
+
first_chunk = False
|
| 153 |
+
node_reader.close()
|
| 154 |
+
first_chunk = True
|
| 155 |
+
for dedensified_edges in edge_reader:
|
| 156 |
+
relabel_dedensified_graph_edges(dedensified_edges, compressor_nodes_all, num_nodes,
|
| 157 |
+
node_names_map_reversed,
|
| 158 |
+
relation_names_map_reversed)
|
| 159 |
+
dedensified_edges.to_csv(
|
| 160 |
+
f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/{dataset.name}/"
|
| 161 |
+
f"dedensified_graph_relations_relabeled.csv",
|
| 162 |
+
mode="w" if first_chunk else "a", header=first_chunk, index=False, encoding="utf-8"
|
| 163 |
+
)
|
| 164 |
+
first_chunk = False
|
| 165 |
+
edge_reader.close()
|
| 166 |
+
sp_tree_path_dist = pd.read_csv(
|
| 167 |
+
f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/{dataset.name}/spanning_tree_path_summary.csv",
|
| 168 |
+
header=0, index_col=None, encoding="utf-8"
|
| 169 |
+
)
|
| 170 |
+
relabel_spanning_tree_paths(sp_tree_path_dist, dataset.node_types_map, dataset.relation_names_map)
|
| 171 |
+
sp_tree_path_dist.to_csv(
|
| 172 |
+
f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/{dataset.name}/spanning_tree_path_summary.csv",
|
| 173 |
+
header=True, index=False, encoding="utf-8"
|
| 174 |
+
)
|
| 175 |
+
if num_nodes < 100000:
|
| 176 |
+
harp_coarsened_nodes = pd.read_csv(
|
| 177 |
+
f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/{dataset.name}/harp_coarsened_nodes.csv",
|
| 178 |
+
header=0, index_col=None, encoding="utf-8"
|
| 179 |
+
)
|
| 180 |
+
harp_coarsened_edges = pd.read_csv(
|
| 181 |
+
f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/{dataset.name}/harp_coarsened_edges.csv",
|
| 182 |
+
header=0, index_col=None, encoding="utf-8"
|
| 183 |
+
)
|
| 184 |
+
harp_node_hierarchy = pd.read_csv(
|
| 185 |
+
f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/{dataset.name}/harp_node_hierarchy.csv",
|
| 186 |
+
header=0, index_col=None, encoding="utf-8"
|
| 187 |
+
)
|
| 188 |
+
relabel_harp_coarsened_graph(harp_coarsened_nodes, harp_coarsened_edges, harp_node_hierarchy,
|
| 189 |
+
dataset.node_names_map, dataset.node_types_map, dataset.relation_names_map)
|
| 190 |
+
harp_coarsened_nodes.to_csv(
|
| 191 |
+
f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/{dataset.name}/harp_coarsened_nodes.csv",
|
| 192 |
+
header=True, index=False, encoding="utf-8"
|
| 193 |
+
)
|
| 194 |
+
harp_coarsened_edges.to_csv(
|
| 195 |
+
f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/{dataset.name}/harp_coarsened_edges.csv",
|
| 196 |
+
header=True, index=False, encoding="utf-8"
|
| 197 |
+
)
|
| 198 |
+
harp_node_hierarchy.to_csv(
|
| 199 |
+
f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/{dataset.name}/harp_node_hierarchy.csv",
|
| 200 |
+
header=True, index=False, encoding="utf-8"
|
| 201 |
+
)
|
| 202 |
+
if write_to_dashboard:
|
| 203 |
+
dashboard.close()
|
| 204 |
+
copy_files(f"results-{subgraph_roots}/{dataset.name}",
|
| 205 |
+
f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/{dataset.name}")
|
| 206 |
+
run_id = len(hdfs_glob(f"results-{subgraph_roots}/{dataset.name}", "")) \
|
| 207 |
+
- len(hdfs_glob(f"results-{subgraph_roots}/{dataset.name}", ".csv"))
|
| 208 |
+
for tensorboard_file in glob(f"results-{subgraph_roots}/{dataset.name}/{run_id}/*"):
|
| 209 |
+
remove(tensorboard_file)
|
| 210 |
+
|
| 211 |
+
scalar_tables = pd.concat(scalar_tables, ignore_index=True).sort_values(["Metric", "Dataset", "Value"],
|
| 212 |
+
ascending=[True, True, False],
|
| 213 |
+
ignore_index=True)
|
| 214 |
+
dist_tables = pd.concat(dist_tables, ignore_index=True).sort_values(["Metric", "Dataset", "Value"],
|
| 215 |
+
ascending=[True, True, False],
|
| 216 |
+
ignore_index=True)
|
| 217 |
+
return scalar_tables, dist_tables, collected_metric_sets
|
| 218 |
+
|
| 219 |
+
|
| 220 |
+
def relabel_distribution_table_supports(dist_table: pd.DataFrame,
|
| 221 |
+
node_names_map: pd.Series,
|
| 222 |
+
node_types_map: pd.Series,
|
| 223 |
+
relation_names_map: pd.Series):
|
| 224 |
+
node_names_map_reversed = node_names_map.reset_index(name="index").set_index("index")["n"]
|
| 225 |
+
node_types_map_reversed = node_types_map.reset_index(name="index").set_index("index")["type"]
|
| 226 |
+
relation_names_map_reversed = relation_names_map.reset_index(name="index").set_index("index")["r"]
|
| 227 |
+
|
| 228 |
+
node_type_dist = dist_table.loc[dist_table.Metric == "NodeTypeDist", "Support"]
|
| 229 |
+
node_type_dist = node_type_dist.map(node_types_map_reversed)
|
| 230 |
+
dist_table.loc[dist_table.Metric == "NodeTypeDist", "Support"] = node_type_dist
|
| 231 |
+
|
| 232 |
+
relation_type_dist = dist_table.loc[dist_table.Metric == "RelationDist", "Support"]
|
| 233 |
+
relation_type_dist = relation_type_dist.map(relation_names_map_reversed)
|
| 234 |
+
dist_table.loc[dist_table.Metric == "RelationDist", "Support"] = relation_type_dist
|
| 235 |
+
|
| 236 |
+
label_interaction_dist = dist_table.loc[dist_table.Metric == "LabelInteractionDist", "Support"]
|
| 237 |
+
label_interaction_dist = label_interaction_dist.map(
|
| 238 |
+
lambda triplet: f"{node_types_map_reversed[triplet[0]]} -> "
|
| 239 |
+
f"{relation_names_map_reversed[triplet[1]]} -> "
|
| 240 |
+
f"{node_types_map_reversed[triplet[2]]}"
|
| 241 |
+
)
|
| 242 |
+
dist_table.loc[dist_table.Metric == "LabelInteractionDist", "Support"] = label_interaction_dist
|
| 243 |
+
|
| 244 |
+
non_node_support_dists = ["NodeTypeDist", "RelationDist", "LabelInteractionDist", "WCC", "SCC",
|
| 245 |
+
"DisjointCommunitySizeDist", "OverlappingCommunitySizeDist", "OverlappingRegionSizeDist",
|
| 246 |
+
"3MotifsDist", "4MotifsDist", "SpanningTreePathDist"]
|
| 247 |
+
other_dists = dist_table.loc[~dist_table.Metric.isin(non_node_support_dists), "Support"]
|
| 248 |
+
other_dists = other_dists.map(node_names_map_reversed)
|
| 249 |
+
dist_table.loc[~dist_table.Metric.isin(non_node_support_dists), "Support"] = other_dists
|
| 250 |
+
|
| 251 |
+
|
| 252 |
+
def relabel_kgist_rule_graph_edges(rule_graph_edge_table: pd.DataFrame,
|
| 253 |
+
node_types_map: pd.Series,
|
| 254 |
+
relation_names_map: pd.Series):
|
| 255 |
+
node_types_map_reversed = node_types_map.reset_index(name="index").set_index("index")["type"]
|
| 256 |
+
relation_names_map_reversed = relation_names_map.reset_index(name="index").set_index("index")["r"]
|
| 257 |
+
|
| 258 |
+
s_type = rule_graph_edge_table.loc[:, "s_type"].map(node_types_map_reversed)
|
| 259 |
+
rule_graph_edge_table.loc[:, "s_type"] = s_type
|
| 260 |
+
r = rule_graph_edge_table.loc[:, "r"].map(relation_names_map_reversed)
|
| 261 |
+
rule_graph_edge_table.loc[:, "r"] = r
|
| 262 |
+
t_type = rule_graph_edge_table.loc[:, "t_type"].map(node_types_map_reversed)
|
| 263 |
+
rule_graph_edge_table.loc[:, "t_type"] = t_type
|
| 264 |
+
|
| 265 |
+
|
| 266 |
+
def relabel_dedensified_graph_nodes(node_data: pd.DataFrame, num_non_compressors: int,
|
| 267 |
+
node_names_map_reversed: pd.Series,
|
| 268 |
+
node_types_map_reversed: pd.Series,
|
| 269 |
+
relation_names_map_reversed: pd.Series):
|
| 270 |
+
compressor_nodes = node_data.type.astype(str).str.contains("compressor")
|
| 271 |
+
|
| 272 |
+
node_types = node_data.loc[~compressor_nodes, "type"].astype(int)
|
| 273 |
+
node_types = node_types.map(node_types_map_reversed)
|
| 274 |
+
node_data.loc[~compressor_nodes, "type"] = node_types
|
| 275 |
+
node_types_compressors = node_data.loc[compressor_nodes, "type"]
|
| 276 |
+
node_types_compressors = node_types_compressors.map(
|
| 277 |
+
lambda x: f"compressor-{relation_names_map_reversed[int(x.split('-')[1])]}"
|
| 278 |
+
)
|
| 279 |
+
node_data.loc[compressor_nodes, "type"] = node_types_compressors
|
| 280 |
+
|
| 281 |
+
node_names = node_data.loc[~compressor_nodes, "n"]
|
| 282 |
+
node_names = node_names.map(node_names_map_reversed)
|
| 283 |
+
node_data.loc[~compressor_nodes, "n"] = node_names
|
| 284 |
+
node_names_compressors = node_data.loc[compressor_nodes, "n"]
|
| 285 |
+
node_names_compressors = node_names_compressors.map(lambda x: f"compressor-{x - num_non_compressors}")
|
| 286 |
+
node_data.loc[compressor_nodes, "n"] = node_names_compressors
|
| 287 |
+
|
| 288 |
+
|
| 289 |
+
def relabel_dedensified_graph_edges(edge_data: pd.DataFrame, compressor_nodes: list, num_non_compressors: int,
|
| 290 |
+
node_names_map_reversed: pd.Series,
|
| 291 |
+
relation_names_map_reversed: pd.Series):
|
| 292 |
+
edge_data.r = edge_data.r.map(relation_names_map_reversed)
|
| 293 |
+
|
| 294 |
+
edges_s_names = edge_data.loc[~edge_data.source.isin(compressor_nodes), "source"]
|
| 295 |
+
edges_s_names = edges_s_names.map(node_names_map_reversed)
|
| 296 |
+
edge_data.loc[~edge_data.source.isin(compressor_nodes), "source"] = edges_s_names
|
| 297 |
+
edges_s_names_compressors = edge_data.loc[edge_data.source.isin(compressor_nodes), "source"]
|
| 298 |
+
edges_s_names_compressors = edges_s_names_compressors.map(lambda x: f"compressor-{x - num_non_compressors}")
|
| 299 |
+
edge_data.loc[edge_data.source.isin(compressor_nodes), "source"] = edges_s_names_compressors
|
| 300 |
+
edges_t_names = edge_data.loc[~edge_data.target.isin(compressor_nodes), "target"]
|
| 301 |
+
edges_t_names = edges_t_names.map(node_names_map_reversed)
|
| 302 |
+
edge_data.loc[~edge_data.target.isin(compressor_nodes), "target"] = edges_t_names
|
| 303 |
+
edges_t_names_compressors = edge_data.loc[edge_data.target.isin(compressor_nodes), "target"]
|
| 304 |
+
edges_t_names_compressors = edges_t_names_compressors.map(lambda x: f"compressor-{x - num_non_compressors}")
|
| 305 |
+
edge_data.loc[edge_data.target.isin(compressor_nodes), "target"] = edges_t_names_compressors
|
| 306 |
+
|
| 307 |
+
|
| 308 |
+
def map_neo4j_like_str(string, node_types_map_reversed, relation_names_map_reversed):
|
| 309 |
+
chars = re.split(r':\d+', string)
|
| 310 |
+
nums = re.findall(r':\d+', string)
|
| 311 |
+
types = [f":{node_types_map_reversed[int(num[1:])]}"
|
| 312 |
+
if i % 2 == 0 else f":{relation_names_map_reversed[int(num[1:])]}"
|
| 313 |
+
for i, num in enumerate(nums)]
|
| 314 |
+
mapped_path = ""
|
| 315 |
+
for char, t in zip(chars, types):
|
| 316 |
+
mapped_path += char
|
| 317 |
+
mapped_path += t
|
| 318 |
+
mapped_path += chars[-1]
|
| 319 |
+
return mapped_path
|
| 320 |
+
|
| 321 |
+
|
| 322 |
+
def relabel_spanning_tree_paths(spanning_tree_path_table: pd.DataFrame,
|
| 323 |
+
node_types_map: pd.Series,
|
| 324 |
+
relation_names_map: pd.Series):
|
| 325 |
+
node_types_map_reversed = node_types_map.reset_index(name="index").set_index("index")["type"]
|
| 326 |
+
relation_names_map_reversed = relation_names_map.reset_index(name="index").set_index("index")["r"]
|
| 327 |
+
spanning_tree_path_table.Path = spanning_tree_path_table.Path.apply(map_neo4j_like_str,
|
| 328 |
+
args=(node_types_map_reversed,
|
| 329 |
+
relation_names_map_reversed))
|
| 330 |
+
|
| 331 |
+
|
| 332 |
+
def relabel_harp_coarsened_graph(node_data: pd.DataFrame, edge_data: pd.DataFrame, node_hierarchy: pd.DataFrame,
|
| 333 |
+
node_names_map: pd.Series,
|
| 334 |
+
node_types_map: pd.Series,
|
| 335 |
+
relation_names_map: pd.Series):
|
| 336 |
+
node_names_map_reversed = node_names_map.reset_index(name="index").set_index("index")["n"]
|
| 337 |
+
node_types_map_reversed = node_types_map.reset_index(name="index").set_index("index")["type"]
|
| 338 |
+
relation_names_map_reversed = relation_names_map.reset_index(name="index").set_index("index")["r"]
|
| 339 |
+
|
| 340 |
+
map_super_node = lambda x: str(node_names_map_reversed[x]) if x in node_names_map_reversed else str(x)
|
| 341 |
+
node_data.n = node_data.n.apply(map_super_node)
|
| 342 |
+
node_data.type = node_data.type.apply(lambda types: "|".join([node_types_map_reversed[t]
|
| 343 |
+
for t in sorted(eval(types))]))
|
| 344 |
+
edge_data.s = edge_data.s.apply(map_super_node)
|
| 345 |
+
edge_data.r = edge_data.r.map(relation_names_map_reversed)
|
| 346 |
+
edge_data.t = edge_data.t.apply(map_super_node)
|
| 347 |
+
node_hierarchy.node = node_hierarchy.node.apply(map_super_node)
|
| 348 |
+
|
| 349 |
+
|
| 350 |
+
def store_analyze_subgraph_results(subgraphs_name: str, dataset_names_map: pd.Series,
|
| 351 |
+
scalar_tables: pd.DataFrame,
|
| 352 |
+
dist_tables: pd.DataFrame,
|
| 353 |
+
metric_sets: Dict[str, List[MetricSetView]],
|
| 354 |
+
node_types_map: pd.Series, relation_names_map: pd.Series) -> List[MetricSetView]:
|
| 355 |
+
store_results_table(scalar_tables, f"scalars_{subgraphs_name.replace('-', '_')}")
|
| 356 |
+
store_results_table(dist_tables, f"distributions_{subgraphs_name.replace('-', '_')}")
|
| 357 |
+
store_metric_sets(metric_sets, f"metric_sets_{subgraphs_name.replace('-', '_')}")
|
| 358 |
+
|
| 359 |
+
subgraphs_histograms, subgraphs_metric_sums = metric_set_histogram(metric_sets, subgraphs_name)
|
| 360 |
+
makedirs(f"results-{subgraph_roots}/{subgraphs_name}", exist_ok=True)
|
| 361 |
+
hdfs_mkdirs(f"results-{subgraph_roots}/{subgraphs_name}")
|
| 362 |
+
new_run_id = len(hdfs_glob(f"results-{subgraph_roots}/{subgraphs_name}", "")) + 1
|
| 363 |
+
dashboard = SummaryWriter(f"results-{subgraph_roots}/{subgraphs_name}/{new_run_id}")
|
| 364 |
+
last_batch_time = pd.Timestamp.now()
|
| 365 |
+
subgraphs_histogram_table = []
|
| 366 |
+
|
| 367 |
+
for i in range(len(metric_sets)):
|
| 368 |
+
scalar_table_hist, dist_table_hist, _ = metric_set_to_dashboard(subgraphs_histograms[i])
|
| 369 |
+
dashboard.add_text(f"{subgraphs_histograms[i][1]}/Scalars", scalar_table_hist.to_markdown(index=False),
|
| 370 |
+
0, walltime=last_batch_time.timestamp())
|
| 371 |
+
dashboard.add_text(f"{subgraphs_histograms[i][1]}/Distributions", dist_table_hist.to_markdown(index=False),
|
| 372 |
+
0, walltime=last_batch_time.timestamp())
|
| 373 |
+
subgraphs_histogram_table.append(dist_table_hist)
|
| 374 |
+
subgraphs_histogram_table = pd.concat(subgraphs_histogram_table, ignore_index=True)
|
| 375 |
+
relabel_distribution_table_supports(subgraphs_histogram_table, dataset_names_map,
|
| 376 |
+
node_types_map, relation_names_map)
|
| 377 |
+
store_results_table(subgraphs_histogram_table, f"{subgraphs_name.replace('-', '_')}_histograms")
|
| 378 |
+
uniform_tables_subgraphs = estimate_and_test_uniform(subgraphs_histograms, subgraphs_metric_sums)
|
| 379 |
+
store_results_table(uniform_tables_subgraphs, f"{subgraphs_name.replace('-', '_')}_uniform_tests")
|
| 380 |
+
|
| 381 |
+
return subgraphs_histograms
|
| 382 |
+
|
| 383 |
+
|
| 384 |
+
if __name__ == "__main__":
|
| 385 |
+
parser = argparse.ArgumentParser()
|
| 386 |
+
parser.add_argument("-s", "--sites", action="store_true",
|
| 387 |
+
help="Whether to subgraph from customer sites instead of organizations.")
|
| 388 |
+
args = parser.parse_args()
|
| 389 |
+
global subgraph_roots
|
| 390 |
+
subgraph_roots = "sites" if args.sites else "orgs"
|
| 391 |
+
entrypoints = pd.concat([
|
| 392 |
+
pd.read_csv(f"hdfs://sbd{customer_orgs_file}", header=0, squeeze=True, encoding="utf-8")
|
| 393 |
+
for customer_orgs_file in hdfs_glob("data/swisscom", f"customer_{subgraph_roots}_")
|
| 394 |
+
], ignore_index=True).drop_duplicates().sort_values(ignore_index=True)
|
| 395 |
+
swisscom_subgraphs = [Swisscom(entrypoint) for entrypoint in entrypoints]
|
| 396 |
+
|
| 397 |
+
dataset_names_map = {subgraph.name: i for i, subgraph in enumerate(swisscom_subgraphs)}
|
| 398 |
+
dataset_names_map = pd.Series(dataset_names_map, name="index").sort_values()
|
| 399 |
+
dataset_names_map.index.name = "n"
|
| 400 |
+
|
| 401 |
+
swisscom_subgraphs_histograms = store_analyze_subgraph_results(
|
| 402 |
+
"swisscom-subgraphs", dataset_names_map,
|
| 403 |
+
*compute_metrics_from_datasets(swisscom_subgraphs, [(), ] * len(swisscom_subgraphs), True, False, False),
|
| 404 |
+
swisscom_subgraphs[0].node_types_map, swisscom_subgraphs[0].relation_names_map
|
| 405 |
+
)
|
| 406 |
+
|
| 407 |
+
node_appearance = {}
|
| 408 |
+
for k in tqdm(range(len(swisscom_subgraphs)), desc="Processing subgraphs for overlaps", leave=False):
|
| 409 |
+
swisscom_subgraphs[k].load_from_disk()
|
| 410 |
+
for node in swisscom_subgraphs[k].node_data.n:
|
| 411 |
+
node_appearance.setdefault(node, [])
|
| 412 |
+
node_appearance[node].append(k)
|
| 413 |
+
swisscom_subgraphs[k].unload_from_memory()
|
| 414 |
+
|
| 415 |
+
subgraph_overlaps = {}
|
| 416 |
+
for node, appearances in tqdm(node_appearance.items(), desc="Processing nodes for overlaps", leave=False):
|
| 417 |
+
if len(appearances) > 1:
|
| 418 |
+
for overlap in itertools.combinations(appearances, 2):
|
| 419 |
+
subgraph_overlaps.setdefault(overlap, 0)
|
| 420 |
+
subgraph_overlaps[overlap] += 1
|
| 421 |
+
|
| 422 |
+
node_appearance = {n: list(map(lambda s: swisscom_subgraphs[s].name, subgraphs))
|
| 423 |
+
for n, subgraphs in node_appearance.items()}
|
| 424 |
+
node_appearance = pd.Series(node_appearance, name="subgraphs")
|
| 425 |
+
node_appearance.index.name = "n"
|
| 426 |
+
node_appearance.to_csv(
|
| 427 |
+
f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/nodes_in_which_swisscom_subgraphs.csv",
|
| 428 |
+
sep=",", header=True, index=True, mode="w", encoding="utf-8"
|
| 429 |
+
)
|
| 430 |
+
node_appearance = {}
|
| 431 |
+
|
| 432 |
+
swisscom_subgraphs_overlaps = []
|
| 433 |
+
swisscom_subgraphs_overlaps_loading_args = []
|
| 434 |
+
dataset_names_map = {}
|
| 435 |
+
i = 0
|
| 436 |
+
for (j, k), overlap_size in tqdm(subgraph_overlaps.items(), desc="Processing subgraph overlaps", leave=False):
|
| 437 |
+
if overlap_size >= 100 and i < 1000:
|
| 438 |
+
subgraph_overlap = SwisscomSubgraphOverlap(swisscom_subgraphs[j].customer_org,
|
| 439 |
+
swisscom_subgraphs[k].customer_org)
|
| 440 |
+
swisscom_subgraphs_overlaps.append(subgraph_overlap)
|
| 441 |
+
swisscom_subgraphs_overlaps_loading_args.append((swisscom_subgraphs[j], swisscom_subgraphs[k]))
|
| 442 |
+
dataset_names_map[subgraph_overlap.name] = i
|
| 443 |
+
i += 1
|
| 444 |
+
subgraph_overlaps = {}
|
| 445 |
+
|
| 446 |
+
if len(swisscom_subgraphs_overlaps) > 0:
|
| 447 |
+
dataset_names_map = pd.Series(dataset_names_map, name="index").sort_values()
|
| 448 |
+
dataset_names_map.index.name = "n"
|
| 449 |
+
|
| 450 |
+
swisscom_subgraphs_overlaps_histograms = store_analyze_subgraph_results(
|
| 451 |
+
"swisscom-subgraphs-overlaps", dataset_names_map,
|
| 452 |
+
*compute_metrics_from_datasets(swisscom_subgraphs_overlaps,
|
| 453 |
+
swisscom_subgraphs_overlaps_loading_args,
|
| 454 |
+
True, False, False),
|
| 455 |
+
swisscom_subgraphs_overlaps[0].node_types_map, swisscom_subgraphs_overlaps[0].relation_names_map
|
| 456 |
+
)
|
| 457 |
+
|
| 458 |
+
swisscom_big_graph = SwisscomBig()
|
| 459 |
+
datasets = [swisscom_big_graph, RedditHyperlinks(), HighEnergyPhysicsCitations(), PatentCitations(),
|
| 460 |
+
OGBBioKG(), FreeBase(), WordNet(), NELL()]
|
| 461 |
+
loading_args = [(swisscom_subgraphs,), (), (), (), (), (), (), ()]
|
| 462 |
+
transport_cities = [path.split("/")[-1] for path in hdfs_glob("data/transport", "") if "." not in path]
|
| 463 |
+
for city in transport_cities:
|
| 464 |
+
datasets.append(Transport(city))
|
| 465 |
+
loading_args.append(())
|
| 466 |
+
|
| 467 |
+
scalar_tables, dist_tables, metric_sets = compute_metrics_from_datasets(datasets, loading_args,
|
| 468 |
+
collect_metric_sets=True)
|
| 469 |
+
store_results_table(scalar_tables, "scalars")
|
| 470 |
+
store_results_table(dist_tables, "distributions")
|
| 471 |
+
store_metric_sets(metric_sets, "metric_sets")
|
| 472 |
+
|
| 473 |
+
pareto_tables = estimate_and_test_pareto(metric_sets)
|
| 474 |
+
store_results_table(pareto_tables, "pareto_tests")
|
| 475 |
+
|
| 476 |
+
if hdfs_glob("data/swisscom", f"relations_{subgraph_roots}"):
|
| 477 |
+
swisscom_big_graph.node_names_map = pd.read_csv(
|
| 478 |
+
f"hdfs://sbd{cluster_dir_path}/data/swisscom/node_names_{subgraph_roots}.csv",
|
| 479 |
+
header=0, index_col=0, squeeze=True, encoding="utf-8"
|
| 480 |
+
)
|
| 481 |
+
swisscom_big_graph.node_data = pd.read_csv(
|
| 482 |
+
f"hdfs://sbd{cluster_dir_path}/data/swisscom/nodes_{subgraph_roots}.csv",
|
| 483 |
+
header=0, index_col=None, parse_dates=["time", ], encoding="utf-8"
|
| 484 |
+
)
|
| 485 |
+
swisscom_big_graph.edge_data = pd.read_csv(
|
| 486 |
+
f"hdfs://sbd{cluster_dir_path}/data/swisscom/relations_{subgraph_roots}.csv",
|
| 487 |
+
header=0, index_col=None, parse_dates=["time", ], encoding="utf-8"
|
| 488 |
+
)
|
| 489 |
+
else:
|
| 490 |
+
swisscom_big_graph.load_from_disk(swisscom_subgraphs)
|
| 491 |
+
swisscom_community_membership = metric_sets["Subgraphing"][0][2]["DisjointCommunityMembership"][-1]
|
| 492 |
+
swisscom_num_communities = metric_sets["Subgraphing"][0][2]["DisjointCommunityNumber"][-1]
|
| 493 |
+
swisscom_communities = []
|
| 494 |
+
dataset_names_map = {}
|
| 495 |
+
i = 0
|
| 496 |
+
for community_tuple in tqdm(swisscom_big_graph.get_community_generator(swisscom_community_membership,
|
| 497 |
+
swisscom_num_communities),
|
| 498 |
+
desc="Processing disjoint communities", total=swisscom_num_communities, leave=False):
|
| 499 |
+
community_id, community_node_names_map, community_nodes, community_edges = community_tuple
|
| 500 |
+
swisscom_community = SwisscomCommunity(community_id)
|
| 501 |
+
swisscom_community.node_names_map = community_node_names_map
|
| 502 |
+
swisscom_community.node_data = community_nodes
|
| 503 |
+
swisscom_community.edge_data = community_edges
|
| 504 |
+
if len(swisscom_community.edge_data) > 0:
|
| 505 |
+
swisscom_communities.append(swisscom_community)
|
| 506 |
+
dataset_names_map[swisscom_community.name] = i
|
| 507 |
+
i += 1
|
| 508 |
+
dataset_names_map = pd.Series(dataset_names_map, name="index").sort_values()
|
| 509 |
+
dataset_names_map.index.name = "n"
|
| 510 |
+
|
| 511 |
+
swisscom_communities_histograms = store_analyze_subgraph_results(
|
| 512 |
+
"swisscom-communities", dataset_names_map,
|
| 513 |
+
*compute_metrics_from_datasets(swisscom_communities, [(), ] * len(swisscom_communities), True, False, False),
|
| 514 |
+
swisscom_communities[0].node_types_map, swisscom_communities[0].relation_names_map
|
| 515 |
+
)
|
| 516 |
+
|
| 517 |
+
swisscom_overlapping_community_membership = metric_sets["Subgraphing"][0][2]["OverlappingCommunityMembership"][-1]
|
| 518 |
+
swisscom_overlapping_regions = []
|
| 519 |
+
dataset_names_map = {}
|
| 520 |
+
i = 0
|
| 521 |
+
for region_tuple in tqdm(
|
| 522 |
+
swisscom_big_graph.get_overlapping_region_generator(swisscom_overlapping_community_membership),
|
| 523 |
+
desc="Processing overlapping regions", leave=False
|
| 524 |
+
):
|
| 525 |
+
community_id, community_id_2, region_node_names_map, region_nodes, region_edges = region_tuple
|
| 526 |
+
swisscom_region = SwisscomOverlappingRegion(community_id, community_id_2)
|
| 527 |
+
swisscom_region.node_names_map = region_node_names_map
|
| 528 |
+
swisscom_region.node_data = region_nodes
|
| 529 |
+
swisscom_region.edge_data = region_edges
|
| 530 |
+
if len(swisscom_region.edge_data) > 0:
|
| 531 |
+
swisscom_overlapping_regions.append(swisscom_region)
|
| 532 |
+
dataset_names_map[swisscom_region.name] = i
|
| 533 |
+
i += 1
|
| 534 |
+
swisscom_big_graph.unload_from_memory()
|
| 535 |
+
if len(swisscom_overlapping_regions) > 0:
|
| 536 |
+
dataset_names_map = pd.Series(dataset_names_map, name="index").sort_values()
|
| 537 |
+
dataset_names_map.index.name = "n"
|
| 538 |
+
|
| 539 |
+
swisscom_regions_histograms = store_analyze_subgraph_results(
|
| 540 |
+
"swisscom-overlapping-regions", dataset_names_map,
|
| 541 |
+
*compute_metrics_from_datasets(swisscom_overlapping_regions, [(), ] * len(swisscom_overlapping_regions),
|
| 542 |
+
True, False, False),
|
| 543 |
+
swisscom_overlapping_regions[0].node_types_map, swisscom_overlapping_regions[0].relation_names_map
|
| 544 |
+
)
|
| 545 |
+
|
| 546 |
+
comparison_tables = estimate_and_test_comparison(metric_sets, linear_comparison=True)
|
| 547 |
+
store_results_table(comparison_tables, "comparisons")
|
| 548 |
+
|
| 549 |
+
histogram_metric_sets = {}
|
| 550 |
+
for metric_set in (swisscom_subgraphs_histograms + swisscom_communities_histograms):
|
| 551 |
+
histogram_metric_sets.setdefault(metric_set[1], [])
|
| 552 |
+
histogram_metric_sets[metric_set[1]].append(metric_set)
|
| 553 |
+
comparison_tables_subgraphs_communities = estimate_and_test_comparison(histogram_metric_sets,
|
| 554 |
+
linear_comparison=False)
|
| 555 |
+
store_results_table(comparison_tables_subgraphs_communities, "comparisons_subgraphs_communities")
|
| 556 |
+
|
| 557 |
+
if len(swisscom_subgraphs_overlaps) > 0 and len(swisscom_overlapping_regions) > 0:
|
| 558 |
+
histogram_metric_sets = {}
|
| 559 |
+
for metric_set in (swisscom_subgraphs_overlaps_histograms + swisscom_regions_histograms):
|
| 560 |
+
histogram_metric_sets.setdefault(metric_set[1], [])
|
| 561 |
+
histogram_metric_sets[metric_set[1]].append(metric_set)
|
| 562 |
+
comparison_tables_overlaps = estimate_and_test_comparison(histogram_metric_sets,
|
| 563 |
+
linear_comparison=False)
|
| 564 |
+
store_results_table(comparison_tables_overlaps, "comparisons_overlaps")
|
| 565 |
+
|
| 566 |
+
copy_files(f"results-{subgraph_roots}/", f"hdfs://sbd{cluster_dir_path}/results-{subgraph_roots}/")
|
src/research/COINs-KGGeneration/graph_analysis/metrics.py
ADDED
|
@@ -0,0 +1,950 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import itertools
|
| 2 |
+
from abc import ABC, abstractmethod
|
| 3 |
+
from collections import Counter
|
| 4 |
+
from math import sqrt
|
| 5 |
+
from os import makedirs
|
| 6 |
+
from typing import Dict, List, Optional, Tuple, Union
|
| 7 |
+
|
| 8 |
+
import igraph
|
| 9 |
+
import networkx as nx
|
| 10 |
+
import numpy as np
|
| 11 |
+
import pandas as pd
|
| 12 |
+
import seaborn as sns
|
| 13 |
+
from karateclub.community_detection.overlapping import EgoNetSplitter
|
| 14 |
+
from matplotlib import pyplot as plt
|
| 15 |
+
from pymetis import part_graph
|
| 16 |
+
from scipy.linalg import eig
|
| 17 |
+
from scipy.sparse import csr_matrix, triu
|
| 18 |
+
from scipy.sparse.linalg import eigs
|
| 19 |
+
from tensorboardX import SummaryWriter
|
| 20 |
+
from tqdm import tqdm
|
| 21 |
+
|
| 22 |
+
import graph_analysis.KGist.graph
|
| 23 |
+
import graph_analysis.KGist.searcher
|
| 24 |
+
|
| 25 |
+
sns.set(context="paper", style="darkgrid", font_scale=3.5)
|
| 26 |
+
|
| 27 |
+
MetricSetValues = Dict[str, List[Union[float, np.ndarray, csr_matrix]]]
|
| 28 |
+
MetricSetView = Tuple[str, str, MetricSetValues]
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
def metric_set_to_dashboard(metric_set: MetricSetView, top_k=5):
|
| 32 |
+
graph_dataset_name, metrics_type, metric_set_values = metric_set
|
| 33 |
+
scalar_table = []
|
| 34 |
+
dist_table = []
|
| 35 |
+
motif_figures = {}
|
| 36 |
+
for metric_name, values in metric_set_values.items():
|
| 37 |
+
last_value = values[-1]
|
| 38 |
+
if type(last_value) not in [np.ndarray, csr_matrix]:
|
| 39 |
+
scalar_table.append((metric_name, graph_dataset_name, last_value))
|
| 40 |
+
else:
|
| 41 |
+
if "Membership" in metric_name:
|
| 42 |
+
continue
|
| 43 |
+
top_k_probs = np.argsort(-last_value, axis=None)
|
| 44 |
+
if len(top_k_probs) > top_k:
|
| 45 |
+
top_k_probs = top_k_probs[:top_k]
|
| 46 |
+
top_k_probs = np.unravel_index(top_k_probs, last_value.shape)
|
| 47 |
+
for support_values, support_prob in zip(np.stack(top_k_probs, axis=1), last_value[top_k_probs]):
|
| 48 |
+
support_values = tuple(support_values)
|
| 49 |
+
if len(support_values) == 1:
|
| 50 |
+
support_values = support_values[0]
|
| 51 |
+
dist_table.append((metric_name, graph_dataset_name, support_values, support_prob))
|
| 52 |
+
if "MotifsDist" in metric_name:
|
| 53 |
+
support_motifs = [
|
| 54 |
+
all_3_motifs[motif] if "3" in metric_name else all_4_motifs[motif]
|
| 55 |
+
for motif in np.stack(top_k_probs, axis=1)[:, 0]
|
| 56 |
+
]
|
| 57 |
+
figure, ax = plt.subplots(1, top_k, figsize=(9 * top_k, 9))
|
| 58 |
+
figure.suptitle(metric_name)
|
| 59 |
+
for k in range(top_k):
|
| 60 |
+
ax[k].set_title(f"{round(last_value[top_k_probs][k], 4)}")
|
| 61 |
+
ax[k].set_xticks([])
|
| 62 |
+
ax[k].set_yticks([])
|
| 63 |
+
motif = support_motifs[k].to_networkx(nx.DiGraph)
|
| 64 |
+
nx.draw(motif, ax=ax[k], pos=nx.circular_layout(motif),
|
| 65 |
+
node_size=3000, arrowstyle="->", arrowsize=30, linewidths=5, width=5)
|
| 66 |
+
figure.tight_layout()
|
| 67 |
+
motif_figures[f"{metrics_type}/{'3Motifs' if '3' in metric_name else '4Motifs'}"] = figure
|
| 68 |
+
scalar_table = pd.DataFrame.from_records(scalar_table, columns=["Metric", "Dataset", "Value"])
|
| 69 |
+
dist_table = pd.DataFrame.from_records(dist_table, columns=["Metric", "Dataset", "Support", "Value"])
|
| 70 |
+
return scalar_table, dist_table, motif_figures
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
class Graph:
|
| 74 |
+
def __init__(self, dataset_name: str):
|
| 75 |
+
self.dataset_name = dataset_name
|
| 76 |
+
self.graph: igraph.Graph = igraph.Graph(directed=True, vertex_attrs={"type": []}, edge_attrs={"r": []})
|
| 77 |
+
|
| 78 |
+
def update_graph(self, node_batch: pd.DataFrame, edge_batch: pd.DataFrame):
|
| 79 |
+
self.graph.add_vertices(len(node_batch), {"type": node_batch.type.values})
|
| 80 |
+
self.graph.add_edges(edge_batch[["s", "t"]].itertuples(index=False, name=None), {"r": edge_batch.r.values})
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
class MetricSet(ABC):
|
| 84 |
+
@abstractmethod
|
| 85 |
+
def __init__(self, graph: Graph, dashboard: Optional[SummaryWriter], metric_type: str, *args, **kwargs):
|
| 86 |
+
self.graph = graph
|
| 87 |
+
self.dashboard = dashboard
|
| 88 |
+
self.metric_type = metric_type
|
| 89 |
+
self.metric_values: MetricSetValues = {}
|
| 90 |
+
self.metric_is_recursive: Dict[str, bool] = {}
|
| 91 |
+
self.current_step = 0
|
| 92 |
+
self.scalar_table: pd.DataFrame = None
|
| 93 |
+
self.dist_table: pd.DataFrame = None
|
| 94 |
+
pass
|
| 95 |
+
|
| 96 |
+
def simplified_view(self) -> MetricSetView:
|
| 97 |
+
return self.graph.dataset_name, self.metric_type, self.metric_values
|
| 98 |
+
|
| 99 |
+
def __repr__(self) -> str:
|
| 100 |
+
return repr(self.simplified_view())
|
| 101 |
+
|
| 102 |
+
@abstractmethod
|
| 103 |
+
def recursive_updates(self, node_batch: pd.DataFrame, edge_batch: pd.DataFrame):
|
| 104 |
+
pass
|
| 105 |
+
|
| 106 |
+
@abstractmethod
|
| 107 |
+
def compute_metric(self, metric_name) -> np.ndarray:
|
| 108 |
+
pass
|
| 109 |
+
|
| 110 |
+
def compute_metrics(self):
|
| 111 |
+
for metric_name, is_recursive in self.metric_is_recursive.items():
|
| 112 |
+
if not is_recursive:
|
| 113 |
+
self.metric_values[metric_name].append(self.compute_metric(metric_name))
|
| 114 |
+
self.current_step += 1
|
| 115 |
+
|
| 116 |
+
def update_dashboard_visuals(self, batch_time):
|
| 117 |
+
for metric_name, values in self.metric_values.items():
|
| 118 |
+
curr_value = values[self.current_step]
|
| 119 |
+
if type(curr_value) not in [np.ndarray, csr_matrix]:
|
| 120 |
+
self.dashboard.add_scalar(f"{self.metric_type}/{metric_name}", curr_value, self.current_step,
|
| 121 |
+
walltime=batch_time.timestamp())
|
| 122 |
+
elif curr_value.ndim == 1:
|
| 123 |
+
if "Membership" in metric_name:
|
| 124 |
+
continue
|
| 125 |
+
curr_value = -np.sort(-curr_value)
|
| 126 |
+
bucket_limits = np.arange(1, len(curr_value) + 1)
|
| 127 |
+
if len(curr_value) > 10000:
|
| 128 |
+
subsample_indices = np.linspace(0, len(curr_value) - 1, num=10000, dtype=int)
|
| 129 |
+
curr_value = curr_value[subsample_indices]
|
| 130 |
+
bucket_limits = np.array(list(subsample_indices[1:]) + [len(curr_value), ])
|
| 131 |
+
self.dashboard.add_histogram_raw(f"{self.metric_type}/{metric_name}",
|
| 132 |
+
np.nanmin(curr_value), np.nanmax(curr_value), len(curr_value),
|
| 133 |
+
np.nansum(curr_value), np.nansum(curr_value ** 2), bucket_limits,
|
| 134 |
+
curr_value, self.current_step, walltime=batch_time.timestamp())
|
| 135 |
+
|
| 136 |
+
def update_dashboard_table(self, last_batch_time=None, top_k=5, update_dashboard=True):
|
| 137 |
+
if last_batch_time is None:
|
| 138 |
+
last_batch_time = pd.Timestamp.now()
|
| 139 |
+
scalar_table, dist_table, motif_figures = metric_set_to_dashboard(self.simplified_view(), top_k)
|
| 140 |
+
for dashboard_tag, motif_figure in motif_figures.items():
|
| 141 |
+
self.dashboard.add_figure(dashboard_tag, motif_figure,
|
| 142 |
+
self.current_step, walltime=last_batch_time.timestamp())
|
| 143 |
+
self.scalar_table = scalar_table
|
| 144 |
+
self.dist_table = dist_table
|
| 145 |
+
if update_dashboard:
|
| 146 |
+
self.dashboard.add_text(f"{self.metric_type}/Scalars", self.scalar_table.to_markdown(index=False),
|
| 147 |
+
self.current_step, walltime=last_batch_time.timestamp())
|
| 148 |
+
self.dashboard.add_text(f"{self.metric_type}/Distributions", self.dist_table.to_markdown(index=False),
|
| 149 |
+
self.current_step, walltime=last_batch_time.timestamp())
|
| 150 |
+
|
| 151 |
+
|
| 152 |
+
class Heterogeneity(MetricSet):
|
| 153 |
+
def __init__(self, graph, dashboard, num_type, num_r):
|
| 154 |
+
super().__init__(graph, dashboard, "Heterogeneity")
|
| 155 |
+
self.metric_values = {
|
| 156 |
+
"NumNodes": [0, ],
|
| 157 |
+
"NumEdges": [0, ],
|
| 158 |
+
"EdgeDensity": [0, ],
|
| 159 |
+
"NodeTypeDist": [np.zeros(num_type), ],
|
| 160 |
+
"RelationDist": [np.zeros(num_r), ],
|
| 161 |
+
"LabelInteractionDist": [np.zeros((num_type, num_r, num_type)), ],
|
| 162 |
+
"NodeTypeAssortativity": [0, ],
|
| 163 |
+
}
|
| 164 |
+
self.metric_is_recursive = {
|
| 165 |
+
"NumNodes": True,
|
| 166 |
+
"NumEdges": True,
|
| 167 |
+
"EdgeDensity": True,
|
| 168 |
+
"NodeTypeDist": True,
|
| 169 |
+
"RelationDist": False,
|
| 170 |
+
"LabelInteractionDist": True,
|
| 171 |
+
"NodeTypeAssortativity": False,
|
| 172 |
+
}
|
| 173 |
+
self.type_index = pd.Index(range(num_type), name="type")
|
| 174 |
+
self.label_index = pd.MultiIndex.from_product((range(num_type), range(num_r), range(num_type)),
|
| 175 |
+
names=("s_type", "r", "t_type"))
|
| 176 |
+
|
| 177 |
+
def recursive_updates(self, node_batch: pd.DataFrame, edge_batch: pd.DataFrame):
|
| 178 |
+
prev_num_nodes = self.metric_values["NumNodes"][self.current_step]
|
| 179 |
+
prev_num_edges = self.metric_values["NumEdges"][self.current_step]
|
| 180 |
+
prev_type_dist = self.metric_values["NodeTypeDist"][self.current_step]
|
| 181 |
+
prev_label_dist = self.metric_values["LabelInteractionDist"][self.current_step]
|
| 182 |
+
|
| 183 |
+
self.metric_values["NumNodes"].append(prev_num_nodes + len(node_batch))
|
| 184 |
+
self.metric_values["NumEdges"].append(prev_num_edges + len(edge_batch))
|
| 185 |
+
self.metric_values["EdgeDensity"].append((prev_num_edges + len(edge_batch))
|
| 186 |
+
/ (prev_num_nodes + len(node_batch)) ** 2)
|
| 187 |
+
type_counts = prev_type_dist * prev_num_nodes + node_batch.type.value_counts().reindex(self.type_index,
|
| 188 |
+
fill_value=0).values
|
| 189 |
+
self.metric_values["NodeTypeDist"].append(type_counts / (prev_num_nodes + len(node_batch)))
|
| 190 |
+
label_batch = edge_batch.assign(
|
| 191 |
+
s_type=self.graph.graph.vs(edge_batch.s)["type"],
|
| 192 |
+
t_type=self.graph.graph.vs(edge_batch.t)["type"],
|
| 193 |
+
)[["s_type", "r", "t_type"]]
|
| 194 |
+
new_label_counts = label_batch.value_counts().reindex(self.label_index,
|
| 195 |
+
fill_value=0).values.reshape(prev_label_dist.shape)
|
| 196 |
+
label_counts = prev_label_dist * prev_num_edges + new_label_counts
|
| 197 |
+
self.metric_values["LabelInteractionDist"].append(label_counts / (prev_num_edges + len(edge_batch)))
|
| 198 |
+
|
| 199 |
+
def compute_metric(self, metric_name):
|
| 200 |
+
if metric_name == "RelationDist":
|
| 201 |
+
return np.nansum(self.metric_values["LabelInteractionDist"][self.current_step + 1], axis=(0, 2))
|
| 202 |
+
elif metric_name == "NodeTypeAssortativity":
|
| 203 |
+
return self.graph.graph.assortativity_nominal(types="type",
|
| 204 |
+
directed=True) if len(self.type_index) > 1 else 1
|
| 205 |
+
|
| 206 |
+
|
| 207 |
+
class Connectivity(MetricSet):
|
| 208 |
+
def __init__(self, graph, dashboard, num_nodes):
|
| 209 |
+
super().__init__(graph, dashboard, "Connectivity")
|
| 210 |
+
self.metric_values = {
|
| 211 |
+
"OutDegree": [np.zeros(num_nodes), ],
|
| 212 |
+
"InDegree": [np.zeros(num_nodes), ],
|
| 213 |
+
"Degree": [np.zeros(num_nodes), ],
|
| 214 |
+
"WCC": [np.zeros(num_nodes), ],
|
| 215 |
+
"SCC": [np.zeros(num_nodes), ],
|
| 216 |
+
"GiantWCC": [0, ],
|
| 217 |
+
"GiantSCC": [0, ],
|
| 218 |
+
"AveragePathLength": [0, ],
|
| 219 |
+
"Diameter": [0, ],
|
| 220 |
+
"Clustering": [np.zeros(num_nodes), ],
|
| 221 |
+
"AverageClustering": [0, ],
|
| 222 |
+
"DegreeAssortativity": [0, ],
|
| 223 |
+
"AlgebraicConnectivity": [0, ],
|
| 224 |
+
}
|
| 225 |
+
self.metric_is_recursive = {
|
| 226 |
+
"OutDegree": True,
|
| 227 |
+
"InDegree": True,
|
| 228 |
+
"Degree": True,
|
| 229 |
+
"WCC": True,
|
| 230 |
+
"SCC": True,
|
| 231 |
+
"GiantWCC": False,
|
| 232 |
+
"GiantSCC": False,
|
| 233 |
+
"AveragePathLength": False,
|
| 234 |
+
"Diameter": False,
|
| 235 |
+
"Clustering": False,
|
| 236 |
+
"AverageClustering": False,
|
| 237 |
+
"DegreeAssortativity": False,
|
| 238 |
+
"AlgebraicConnectivity": False,
|
| 239 |
+
}
|
| 240 |
+
self.node_index = pd.Index(range(num_nodes), name="n")
|
| 241 |
+
|
| 242 |
+
def recursive_updates(self, node_batch: pd.DataFrame, edge_batch: pd.DataFrame):
|
| 243 |
+
prev_e_count = self.graph.graph.ecount()
|
| 244 |
+
prev_out_degree = self.metric_values["OutDegree"][self.current_step]
|
| 245 |
+
prev_in_degree = self.metric_values["InDegree"][self.current_step]
|
| 246 |
+
|
| 247 |
+
s_counts = edge_batch.s.value_counts().reindex(self.node_index, fill_value=0).values
|
| 248 |
+
new_s_counts = prev_e_count * prev_out_degree + s_counts
|
| 249 |
+
self.metric_values["OutDegree"].append(new_s_counts / self.graph.graph.ecount())
|
| 250 |
+
|
| 251 |
+
t_counts = edge_batch.t.value_counts().reindex(self.node_index, fill_value=0).values
|
| 252 |
+
new_t_counts = prev_e_count * prev_in_degree + t_counts
|
| 253 |
+
self.metric_values["InDegree"].append(new_t_counts / self.graph.graph.ecount())
|
| 254 |
+
|
| 255 |
+
self.metric_values["Degree"].append((new_s_counts + new_t_counts) / (2 * self.graph.graph.ecount()))
|
| 256 |
+
|
| 257 |
+
wcc = self.graph.graph.clusters(mode="weak").sizes()
|
| 258 |
+
wcc_padded = np.zeros(len(self.node_index))
|
| 259 |
+
wcc_padded[:len(wcc)] = wcc / np.nansum(wcc)
|
| 260 |
+
self.metric_values["WCC"].append(wcc_padded)
|
| 261 |
+
|
| 262 |
+
scc = self.graph.graph.clusters(mode="strong").sizes()
|
| 263 |
+
scc_padded = np.zeros(len(self.node_index))
|
| 264 |
+
scc_padded[:len(scc)] = scc / np.nansum(scc)
|
| 265 |
+
self.metric_values["SCC"].append(scc_padded)
|
| 266 |
+
|
| 267 |
+
def compute_metric(self, metric_name):
|
| 268 |
+
if metric_name == "GiantWCC":
|
| 269 |
+
return np.nanmax(self.metric_values["WCC"][self.current_step + 1])
|
| 270 |
+
elif metric_name == "GiantSCC":
|
| 271 |
+
return np.nanmax(self.metric_values["SCC"][self.current_step + 1])
|
| 272 |
+
elif metric_name == "AveragePathLength":
|
| 273 |
+
return self.graph.graph.average_path_length(directed=True, unconn=True)
|
| 274 |
+
elif metric_name == "Diameter":
|
| 275 |
+
return self.graph.graph.diameter(directed=True, unconn=True)
|
| 276 |
+
elif metric_name == "Clustering":
|
| 277 |
+
clustering = self.graph.graph.transitivity_local_undirected(mode="zero")
|
| 278 |
+
clustering_padded = np.zeros(len(self.node_index))
|
| 279 |
+
clustering_norm = np.nansum(clustering)
|
| 280 |
+
clustering_padded[:len(clustering)] = (clustering / clustering_norm) if clustering_norm > 0 else clustering
|
| 281 |
+
return clustering_padded
|
| 282 |
+
elif metric_name == "AverageClustering":
|
| 283 |
+
return self.graph.graph.transitivity_undirected(mode="zero")
|
| 284 |
+
elif metric_name == "DegreeAssortativity":
|
| 285 |
+
return self.graph.graph.assortativity_degree(directed=True)
|
| 286 |
+
elif metric_name == "AlgebraicConnectivity":
|
| 287 |
+
A = self.graph.graph.clusters("weak").giant()
|
| 288 |
+
num_nodes = A.vcount()
|
| 289 |
+
D_ind = np.arange(num_nodes)
|
| 290 |
+
D = A.degree()
|
| 291 |
+
D = csr_matrix((D, (D_ind, D_ind)))
|
| 292 |
+
A = A.get_adjacency_sparse()
|
| 293 |
+
L = D - A
|
| 294 |
+
if num_nodes > 3:
|
| 295 |
+
return abs(eigs(L.asfptype(), k=2, which="SM", return_eigenvectors=False, tol=1e-4)[0])
|
| 296 |
+
else:
|
| 297 |
+
eigvals = np.abs(eig(L.asfptype().toarray("C"))[0])
|
| 298 |
+
eigvals = np.sort(eigvals)
|
| 299 |
+
return eigvals[1] if num_nodes > 1 else 0
|
| 300 |
+
|
| 301 |
+
|
| 302 |
+
class Importance(MetricSet):
|
| 303 |
+
def __init__(self, graph, dashboard, num_nodes):
|
| 304 |
+
super().__init__(graph, dashboard, "Importance")
|
| 305 |
+
self.metric_values = {
|
| 306 |
+
"ClosenessCentrality": [np.zeros(num_nodes), ],
|
| 307 |
+
"BetweennessCentrality": [np.zeros(num_nodes), ],
|
| 308 |
+
"HubScore": [np.zeros(num_nodes), ],
|
| 309 |
+
"AuthorityScore": [np.zeros(num_nodes), ],
|
| 310 |
+
"PageRank": [np.zeros(num_nodes), ],
|
| 311 |
+
"MaxCloseness": [0, ],
|
| 312 |
+
"MaxBetweenness": [0, ],
|
| 313 |
+
"MaxHubScore": [0, ],
|
| 314 |
+
"MaxAuthorityScore": [0, ],
|
| 315 |
+
"MaxPageRank": [0, ],
|
| 316 |
+
}
|
| 317 |
+
self.metric_is_recursive = {
|
| 318 |
+
"ClosenessCentrality": True,
|
| 319 |
+
"BetweennessCentrality": True,
|
| 320 |
+
"HubScore": True,
|
| 321 |
+
"AuthorityScore": True,
|
| 322 |
+
"PageRank": True,
|
| 323 |
+
"MaxCloseness": False,
|
| 324 |
+
"MaxBetweenness": False,
|
| 325 |
+
"MaxHubScore": False,
|
| 326 |
+
"MaxAuthorityScore": False,
|
| 327 |
+
"MaxPageRank": False,
|
| 328 |
+
}
|
| 329 |
+
self.num_nodes = num_nodes
|
| 330 |
+
|
| 331 |
+
def recursive_updates(self, node_batch: pd.DataFrame, edge_batch: pd.DataFrame):
|
| 332 |
+
closeness = self.graph.graph.harmonic_centrality(mode="all", cutoff=10)
|
| 333 |
+
closeness_padded = np.zeros(self.num_nodes)
|
| 334 |
+
closeness_norm = np.nansum(closeness)
|
| 335 |
+
closeness_padded[:len(closeness)] = \
|
| 336 |
+
(closeness / closeness_norm) if closeness_norm > 0 else closeness
|
| 337 |
+
self.metric_values["ClosenessCentrality"].append(closeness_padded)
|
| 338 |
+
|
| 339 |
+
betweenness = self.graph.graph.betweenness(directed=True, cutoff=10)
|
| 340 |
+
betweenness_padded = np.zeros(self.num_nodes)
|
| 341 |
+
betweenness_norm = np.nansum(betweenness)
|
| 342 |
+
betweenness_padded[:len(betweenness)] = \
|
| 343 |
+
(betweenness / betweenness_norm) if betweenness_norm > 0 else betweenness
|
| 344 |
+
self.metric_values["BetweennessCentrality"].append(betweenness_padded)
|
| 345 |
+
|
| 346 |
+
hub_score = self.graph.graph.hub_score()
|
| 347 |
+
hub_score_padded = np.zeros(self.num_nodes)
|
| 348 |
+
hub_score_padded[:len(hub_score)] = hub_score / np.nansum(hub_score)
|
| 349 |
+
self.metric_values["HubScore"].append(hub_score_padded)
|
| 350 |
+
|
| 351 |
+
authority_score = self.graph.graph.authority_score()
|
| 352 |
+
authority_score_padded = np.zeros(self.num_nodes)
|
| 353 |
+
authority_score_padded[:len(authority_score)] = authority_score / np.nansum(authority_score)
|
| 354 |
+
self.metric_values["AuthorityScore"].append(authority_score_padded)
|
| 355 |
+
|
| 356 |
+
pagerank = self.graph.graph.pagerank(directed=True)
|
| 357 |
+
pagerank_padded = np.zeros(self.num_nodes)
|
| 358 |
+
pagerank_padded[:len(pagerank)] = pagerank / np.nansum(pagerank)
|
| 359 |
+
self.metric_values["PageRank"].append(pagerank_padded)
|
| 360 |
+
|
| 361 |
+
def compute_metric(self, metric_name):
|
| 362 |
+
if metric_name == "MaxCloseness":
|
| 363 |
+
return np.nanmax(self.metric_values["ClosenessCentrality"][self.current_step + 1])
|
| 364 |
+
elif metric_name == "MaxBetweenness":
|
| 365 |
+
return np.nanmax(self.metric_values["BetweennessCentrality"][self.current_step + 1])
|
| 366 |
+
elif metric_name == "MaxHubScore":
|
| 367 |
+
return np.nanmax(self.metric_values["HubScore"][self.current_step + 1])
|
| 368 |
+
elif metric_name == "MaxAuthorityScore":
|
| 369 |
+
return np.nanmax(self.metric_values["AuthorityScore"][self.current_step + 1])
|
| 370 |
+
elif metric_name == "MaxPageRank":
|
| 371 |
+
return np.nanmax(self.metric_values["PageRank"][self.current_step + 1])
|
| 372 |
+
|
| 373 |
+
|
| 374 |
+
def get_all_motifs(k: int) -> List[igraph.Graph]:
|
| 375 |
+
possible_graph_edges = [(s, t) for s in range(k) for t in range(k) if s != t]
|
| 376 |
+
all_subgraphs_edges = [np.array(combination)
|
| 377 |
+
for num_edges in range(k - 1, len(possible_graph_edges) + 1)
|
| 378 |
+
for combination in itertools.combinations(possible_graph_edges, num_edges)]
|
| 379 |
+
all_motifs = []
|
| 380 |
+
for possible_edges in all_subgraphs_edges:
|
| 381 |
+
possible_new_motif = igraph.Graph(k, directed=True)
|
| 382 |
+
possible_new_motif.add_edges(possible_edges)
|
| 383 |
+
if not possible_new_motif.is_connected("weak"):
|
| 384 |
+
continue
|
| 385 |
+
is_isomorphic = False
|
| 386 |
+
for motif in all_motifs:
|
| 387 |
+
is_isomorphic = is_isomorphic or possible_new_motif.isomorphic(motif)
|
| 388 |
+
if not is_isomorphic:
|
| 389 |
+
all_motifs.append(possible_new_motif)
|
| 390 |
+
return all_motifs
|
| 391 |
+
|
| 392 |
+
|
| 393 |
+
all_3_motifs = get_all_motifs(3)
|
| 394 |
+
all_4_motifs = get_all_motifs(4)
|
| 395 |
+
|
| 396 |
+
|
| 397 |
+
def get_esa_frequencies(graph: igraph.Graph, num_samples: int = 10000):
|
| 398 |
+
def sampled_edges_to_boundary(sampled_edges):
|
| 399 |
+
return set(np.concatenate(sampled_edges))
|
| 400 |
+
|
| 401 |
+
def expand_boundary(boundary, sampled_edges, prob):
|
| 402 |
+
cut = [edge.tuple for edge in di_graph.es.select(_source_in=boundary, _target_notin=boundary)]
|
| 403 |
+
cut.extend([edge.tuple for edge in di_graph.es.select(_source_notin=boundary, _target_in=boundary)])
|
| 404 |
+
cut_size = len(cut)
|
| 405 |
+
if cut_size > 0:
|
| 406 |
+
prob *= 1 / cut_size
|
| 407 |
+
new_edge_id = np.random.choice(cut_size, size=1, replace=False)[0]
|
| 408 |
+
sampled_edges.append(cut[new_edge_id])
|
| 409 |
+
else:
|
| 410 |
+
prob = 0
|
| 411 |
+
return sampled_edges_to_boundary(sampled_edges), sampled_edges, prob
|
| 412 |
+
|
| 413 |
+
di_graph = graph.copy().simplify()
|
| 414 |
+
num_edges = di_graph.ecount()
|
| 415 |
+
scores_3_motifs = np.zeros(len(all_3_motifs))
|
| 416 |
+
scores_4_motifs = np.zeros(len(all_4_motifs))
|
| 417 |
+
initial_edge_ids = np.random.choice(num_edges, size=num_samples, replace=True)
|
| 418 |
+
for i in tqdm(range(num_samples), desc="Processing ESA samples", leave=False):
|
| 419 |
+
prob = 1 / num_edges
|
| 420 |
+
sampled_edges = [di_graph.es[initial_edge_ids[i]].tuple, ]
|
| 421 |
+
boundary = sampled_edges_to_boundary(sampled_edges) # 2 nodes
|
| 422 |
+
boundary, sampled_edges, prob = expand_boundary(boundary, sampled_edges, prob) # 3 nodes
|
| 423 |
+
subgraph = di_graph.subgraph(boundary)
|
| 424 |
+
motif = [j for j, motif in enumerate(all_3_motifs) if subgraph.isomorphic(motif)]
|
| 425 |
+
scores_3_motifs[motif] += (1 / prob if prob > 0 else 0)
|
| 426 |
+
boundary, sampled_edges, prob = expand_boundary(boundary, sampled_edges, prob) # 4 nodes
|
| 427 |
+
subgraph = di_graph.subgraph(boundary)
|
| 428 |
+
motif = [j for j, motif in enumerate(all_4_motifs) if subgraph.isomorphic(motif)]
|
| 429 |
+
scores_4_motifs[motif] += (1 / prob if prob > 0 else 0)
|
| 430 |
+
|
| 431 |
+
total_score_3, total_score_4 = np.nansum(scores_3_motifs), np.nansum(scores_4_motifs)
|
| 432 |
+
return scores_3_motifs / total_score_3, scores_4_motifs / total_score_4
|
| 433 |
+
|
| 434 |
+
|
| 435 |
+
def get_sp_tree(graph: igraph.Graph) -> igraph.Graph:
|
| 436 |
+
pageranks_nodes = np.array(graph.pagerank(directed=True))
|
| 437 |
+
edge_frame = graph.get_edge_dataframe()
|
| 438 |
+
graph.es["weight"] = -pageranks_nodes[edge_frame.source.values] - pageranks_nodes[edge_frame.target.values]
|
| 439 |
+
del edge_frame, pageranks_nodes
|
| 440 |
+
sp_tree = graph.spanning_tree()
|
| 441 |
+
del graph.es["weight"]
|
| 442 |
+
return sp_tree
|
| 443 |
+
|
| 444 |
+
|
| 445 |
+
class Subgraphing(MetricSet):
|
| 446 |
+
def __init__(self, graph, dashboard, num_nodes, community_method,
|
| 447 |
+
community_resolution_disjoint, community_resolution_overlapping, num_esa_samples):
|
| 448 |
+
super().__init__(graph, dashboard, "Subgraphing")
|
| 449 |
+
self.num_nodes = num_nodes
|
| 450 |
+
self.community_method = community_method
|
| 451 |
+
self.community_resolution_disjoint = \
|
| 452 |
+
community_resolution_disjoint if community_resolution_disjoint > 0 else 1 / num_nodes
|
| 453 |
+
self.community_resolution_overlapping = community_resolution_overlapping
|
| 454 |
+
self.num_esa_samples = num_esa_samples
|
| 455 |
+
self.node_index = pd.Index(range(num_nodes), name="n")
|
| 456 |
+
self.egonet_splitter = EgoNetSplitter(community_resolution_overlapping)
|
| 457 |
+
|
| 458 |
+
self.metric_values = {
|
| 459 |
+
"DisjointCommunityMembership": [np.zeros(num_nodes), ],
|
| 460 |
+
"DisjointCommunityNumber": [0, ],
|
| 461 |
+
"DisjointCommunitySizeDist": [np.zeros(num_nodes), ],
|
| 462 |
+
"GiantDisjointCommunity": [0, ],
|
| 463 |
+
"DisjointCommunityCutSize": [0, ],
|
| 464 |
+
"DisjointCommunityModularity": [0, ],
|
| 465 |
+
"OverlappingCommunityMembership": [csr_matrix((num_nodes, 0)), ],
|
| 466 |
+
"OverlappingCommunityNumber": [0, ],
|
| 467 |
+
"OverlappingCommunitySizeDist": [np.zeros(num_nodes), ],
|
| 468 |
+
"GiantOverlappingCommunity": [0, ],
|
| 469 |
+
"OverlappingRegionSizeDist": [np.zeros(1), ],
|
| 470 |
+
"GiantOverlappingRegion": [0, ],
|
| 471 |
+
"3MotifsDist": [np.zeros(len(all_3_motifs)), ],
|
| 472 |
+
"4MotifsDist": [np.zeros(len(all_4_motifs)), ],
|
| 473 |
+
"MostFrequent3Motif": [0, ],
|
| 474 |
+
"MostFrequent4Motif": [0, ],
|
| 475 |
+
}
|
| 476 |
+
self.metric_is_recursive = {
|
| 477 |
+
"DisjointCommunityMembership": True,
|
| 478 |
+
"DisjointCommunityNumber": False,
|
| 479 |
+
"DisjointCommunitySizeDist": True,
|
| 480 |
+
"GiantDisjointCommunity": False,
|
| 481 |
+
"DisjointCommunityCutSize": True,
|
| 482 |
+
"DisjointCommunityModularity": False,
|
| 483 |
+
"OverlappingCommunityMembership": True,
|
| 484 |
+
"OverlappingCommunityNumber": True,
|
| 485 |
+
"OverlappingCommunitySizeDist": True,
|
| 486 |
+
"GiantOverlappingCommunity": False,
|
| 487 |
+
"OverlappingRegionSizeDist": True,
|
| 488 |
+
"GiantOverlappingRegion": False,
|
| 489 |
+
"3MotifsDist": True,
|
| 490 |
+
"4MotifsDist": True,
|
| 491 |
+
"MostFrequent3Motif": False,
|
| 492 |
+
"MostFrequent4Motif": False
|
| 493 |
+
}
|
| 494 |
+
|
| 495 |
+
def recursive_updates(self, node_batch: pd.DataFrame, edge_batch: pd.DataFrame):
|
| 496 |
+
if self.community_method != "random":
|
| 497 |
+
disjoint_partitioning = np.zeros(self.num_nodes, dtype=int)
|
| 498 |
+
wcc = self.graph.graph.clusters("weak")
|
| 499 |
+
wcc_membership, wcc_sizes = np.array(wcc.membership), wcc.sizes()
|
| 500 |
+
nodes_in_larger_wcc = np.zeros(self.num_nodes, dtype=bool)
|
| 501 |
+
small_wcc_community, small_wcc_nodes = 0, 0
|
| 502 |
+
for i, wcc_size in enumerate(wcc_sizes):
|
| 503 |
+
nodes_in_wcc = wcc_membership == i
|
| 504 |
+
if wcc_size < sqrt(self.num_nodes):
|
| 505 |
+
if small_wcc_nodes + wcc_size > sqrt(self.num_nodes):
|
| 506 |
+
small_wcc_community += 1
|
| 507 |
+
small_wcc_nodes = 0
|
| 508 |
+
disjoint_partitioning[nodes_in_wcc] = small_wcc_community
|
| 509 |
+
small_wcc_nodes += wcc_size
|
| 510 |
+
else:
|
| 511 |
+
nodes_in_larger_wcc[nodes_in_wcc] = True
|
| 512 |
+
nodes_in_larger_wcc = nodes_in_larger_wcc.nonzero()[0]
|
| 513 |
+
if self.community_method == "leiden":
|
| 514 |
+
if len(nodes_in_larger_wcc) != self.num_nodes:
|
| 515 |
+
graph_larger_wcc = self.graph.graph.subgraph(nodes_in_larger_wcc)
|
| 516 |
+
larger_wcc_comms = graph_larger_wcc.as_undirected(mode="each").community_leiden(
|
| 517 |
+
"CPM", resolution_parameter=self.community_resolution_disjoint,
|
| 518 |
+
n_iterations=-1 if self.num_nodes <= 100000 else 2
|
| 519 |
+
)
|
| 520 |
+
disjoint_partitioning[nodes_in_larger_wcc] = (np.array(larger_wcc_comms.membership)
|
| 521 |
+
+ small_wcc_community + 1)
|
| 522 |
+
del graph_larger_wcc
|
| 523 |
+
else:
|
| 524 |
+
disjoint_partitioning = self.graph.graph.as_undirected(mode="each").community_leiden(
|
| 525 |
+
"CPM", resolution_parameter=self.community_resolution_disjoint,
|
| 526 |
+
n_iterations=-1 if self.num_nodes <= 100000 else 2
|
| 527 |
+
)
|
| 528 |
+
disjoint_partitioning = np.array(disjoint_partitioning.membership)
|
| 529 |
+
edges = self.graph.graph.get_edge_dataframe()
|
| 530 |
+
cut_size = np.sum(disjoint_partitioning[edges.source] != disjoint_partitioning[edges.target])
|
| 531 |
+
self.metric_values["DisjointCommunityCutSize"].append(cut_size)
|
| 532 |
+
del wcc, wcc_membership, wcc_sizes, nodes_in_larger_wcc
|
| 533 |
+
elif self.community_method == "metis":
|
| 534 |
+
if len(nodes_in_larger_wcc) != self.num_nodes:
|
| 535 |
+
graph_larger_wcc = self.graph.graph.subgraph(nodes_in_larger_wcc)
|
| 536 |
+
graph_metis = graph_larger_wcc.get_adjlist(mode="all")
|
| 537 |
+
cut_size, larger_wcc_comms = part_graph(adjacency=graph_metis,
|
| 538 |
+
nparts=int(sqrt(self.num_nodes)) - small_wcc_community)
|
| 539 |
+
disjoint_partitioning[nodes_in_larger_wcc] = np.array(larger_wcc_comms) + small_wcc_community + 1
|
| 540 |
+
del graph_larger_wcc
|
| 541 |
+
else:
|
| 542 |
+
graph_metis = self.graph.graph.get_adjlist(mode="all")
|
| 543 |
+
cut_size, disjoint_partitioning = part_graph(adjacency=graph_metis, nparts=int(sqrt(self.num_nodes)))
|
| 544 |
+
disjoint_partitioning = np.array(disjoint_partitioning)
|
| 545 |
+
self.metric_values["DisjointCommunityCutSize"].append(cut_size)
|
| 546 |
+
del wcc, wcc_membership, wcc_sizes, nodes_in_larger_wcc
|
| 547 |
+
elif self.community_method == "random":
|
| 548 |
+
disjoint_partitioning = np.random.choice(int(sqrt(self.num_nodes)), size=self.num_nodes)
|
| 549 |
+
edges = self.graph.graph.get_edge_dataframe()
|
| 550 |
+
cut_size = np.sum(disjoint_partitioning[edges.source] != disjoint_partitioning[edges.target])
|
| 551 |
+
self.metric_values["DisjointCommunityCutSize"].append(cut_size)
|
| 552 |
+
else:
|
| 553 |
+
raise ValueError("Invalid community detection method!")
|
| 554 |
+
|
| 555 |
+
self.metric_values["DisjointCommunityMembership"].append(disjoint_partitioning)
|
| 556 |
+
disjoint_sizes = np.unique(disjoint_partitioning, return_counts=True)[1]
|
| 557 |
+
disjoint_sizes_padded = np.zeros(self.num_nodes)
|
| 558 |
+
disjoint_sizes_padded[:len(disjoint_sizes)] = disjoint_sizes / np.nansum(disjoint_sizes)
|
| 559 |
+
self.metric_values["DisjointCommunitySizeDist"].append(disjoint_sizes_padded)
|
| 560 |
+
|
| 561 |
+
self.egonet_splitter.fit(self.graph.graph.clusters(mode="weak").giant().as_undirected().to_networkx())
|
| 562 |
+
M_id = [(node, community)
|
| 563 |
+
for node, communities in self.egonet_splitter.get_memberships().items()
|
| 564 |
+
for community in communities]
|
| 565 |
+
M_id = np.array(M_id)
|
| 566 |
+
M = csr_matrix((np.ones(len(M_id)), (M_id[:, 0], M_id[:, 1])))
|
| 567 |
+
self.metric_values["OverlappingCommunityMembership"].append(M)
|
| 568 |
+
|
| 569 |
+
overlapping_sizes = np.array(M.sum(axis=0))[0]
|
| 570 |
+
self.metric_values["OverlappingCommunityNumber"].append(len(overlapping_sizes))
|
| 571 |
+
self.metric_values["OverlappingCommunitySizeDist"].append(overlapping_sizes / np.nansum(overlapping_sizes))
|
| 572 |
+
|
| 573 |
+
overlapping_regions = triu(M.T @ M, k=1).data
|
| 574 |
+
overlapping_regions = overlapping_regions[overlapping_regions > 1]
|
| 575 |
+
overlapping_regions /= np.nansum(overlapping_regions)
|
| 576 |
+
self.metric_values["OverlappingRegionSizeDist"].append(
|
| 577 |
+
overlapping_regions if len(overlapping_regions) > 0 else np.zeros(1)
|
| 578 |
+
)
|
| 579 |
+
|
| 580 |
+
motif_dists = get_esa_frequencies(self.graph.graph, self.num_esa_samples)
|
| 581 |
+
self.metric_values["3MotifsDist"].append(motif_dists[0])
|
| 582 |
+
self.metric_values["4MotifsDist"].append(motif_dists[1])
|
| 583 |
+
|
| 584 |
+
def compute_metric(self, metric_name):
|
| 585 |
+
if metric_name == "DisjointCommunityNumber":
|
| 586 |
+
return np.nanmax(self.metric_values["DisjointCommunityMembership"][self.current_step + 1]) + 1
|
| 587 |
+
elif metric_name == "GiantDisjointCommunity":
|
| 588 |
+
return np.nanmax(self.metric_values["DisjointCommunitySizeDist"][self.current_step + 1])
|
| 589 |
+
elif metric_name == "DisjointCommunityModularity":
|
| 590 |
+
return self.graph.graph.modularity(
|
| 591 |
+
self.metric_values["DisjointCommunityMembership"][self.current_step + 1]
|
| 592 |
+
)
|
| 593 |
+
elif metric_name == "GiantOverlappingCommunity":
|
| 594 |
+
return np.nanmax(self.metric_values["OverlappingCommunitySizeDist"][self.current_step + 1])
|
| 595 |
+
elif metric_name == "GiantOverlappingRegion":
|
| 596 |
+
return np.nanmax(self.metric_values["OverlappingRegionSizeDist"][self.current_step + 1])
|
| 597 |
+
elif metric_name == "MostFrequent3Motif":
|
| 598 |
+
return np.nanmax(self.metric_values["3MotifsDist"][self.current_step + 1])
|
| 599 |
+
elif metric_name == "MostFrequent4Motif":
|
| 600 |
+
return np.nanmax(self.metric_values["4MotifsDist"][self.current_step + 1])
|
| 601 |
+
|
| 602 |
+
|
| 603 |
+
def rule_to_edge_list_r(rule, edge_list):
|
| 604 |
+
root, children = rule if type(rule) is tuple else (rule.root, rule.children)
|
| 605 |
+
if len(children) == 0:
|
| 606 |
+
return []
|
| 607 |
+
new_edges = []
|
| 608 |
+
for r, direction, child_rule in children:
|
| 609 |
+
child_root, _ = child_rule if type(child_rule) is tuple else (child_rule.root, child_rule.children)
|
| 610 |
+
new_edges.extend([(root_type, r, child_root_type) if direction == "out" else (child_root_type, r, root_type)
|
| 611 |
+
for root_type in root for child_root_type in child_root])
|
| 612 |
+
new_edges.extend(rule_to_edge_list_r(child_rule, edge_list))
|
| 613 |
+
return edge_list + new_edges
|
| 614 |
+
|
| 615 |
+
|
| 616 |
+
def rule_to_edge_list(rule):
|
| 617 |
+
return rule_to_edge_list_r(rule, [])
|
| 618 |
+
|
| 619 |
+
|
| 620 |
+
def dedensify(graph: igraph.Graph, degree_threshold: float = 0.95):
|
| 621 |
+
num_nodes = graph.vcount()
|
| 622 |
+
in_degrees = np.sort(graph.indegree())
|
| 623 |
+
degree_percentile = np.percentile(in_degrees, 100 * degree_threshold)
|
| 624 |
+
high_degree_nodes = in_degrees >= degree_percentile
|
| 625 |
+
if np.sum(high_degree_nodes) > 100000:
|
| 626 |
+
high_degree_nodes[:-100000] = False
|
| 627 |
+
high_degree_nodes = set(np.nonzero(high_degree_nodes)[0])
|
| 628 |
+
|
| 629 |
+
high_degree_neighbourhoods = {}
|
| 630 |
+
edge_frame = graph.get_edge_dataframe()
|
| 631 |
+
neighbourhoods = edge_frame.groupby(["source", "r"])["target"].agg(list).to_dict()
|
| 632 |
+
for (n, r), neighbourhood in tqdm(neighbourhoods.items(), desc="Processing node neighbourhoods", leave=False):
|
| 633 |
+
h = tuple(sorted(high_degree_nodes.intersection(set(neighbourhood))))
|
| 634 |
+
if len(h) > 0:
|
| 635 |
+
high_degree_neighbourhoods.setdefault((r, h), [])
|
| 636 |
+
high_degree_neighbourhoods[(r, h)].append(n)
|
| 637 |
+
num_compressor_nodes = 0
|
| 638 |
+
compressor_nodes, edges_to_add, edges_to_delete = [], [], set()
|
| 639 |
+
for (r, h), m in tqdm(high_degree_neighbourhoods.items(),
|
| 640 |
+
desc="Processing high-degree node neighbourhoods", leave=False):
|
| 641 |
+
edges_to_delete_batch = edge_frame.index[edge_frame.source.isin(m)
|
| 642 |
+
& edge_frame.target.isin(h)
|
| 643 |
+
& (edge_frame.r == r)].values.tolist()
|
| 644 |
+
num_edges_to_delete = len(edges_to_delete_batch)
|
| 645 |
+
edges_to_add_batch = [(source, num_nodes + num_compressor_nodes, r) for source in m]
|
| 646 |
+
edges_to_add_batch.extend([(num_nodes + num_compressor_nodes, target, r) for target in h])
|
| 647 |
+
num_edges_to_add = len(edges_to_add_batch)
|
| 648 |
+
if num_edges_to_add < num_edges_to_delete:
|
| 649 |
+
compressor_nodes.append(f"compressor-{r}")
|
| 650 |
+
edges_to_delete.update(edges_to_delete_batch)
|
| 651 |
+
edges_to_add.extend(edges_to_add_batch)
|
| 652 |
+
num_compressor_nodes += 1
|
| 653 |
+
edge_frame.drop(index=edges_to_delete, inplace=True)
|
| 654 |
+
edge_frame = pd.concat((edge_frame,
|
| 655 |
+
pd.DataFrame(edges_to_add, columns=["source", "target", "r"])), ignore_index=True)
|
| 656 |
+
node_frame = pd.concat((graph.get_vertex_dataframe(),
|
| 657 |
+
pd.DataFrame(compressor_nodes, columns=["type", ])), ignore_index=True)
|
| 658 |
+
return (num_compressor_nodes / (num_nodes + num_compressor_nodes),
|
| 659 |
+
(graph.ecount() - len(edges_to_delete)) / graph.ecount()), \
|
| 660 |
+
node_frame.reset_index().rename(columns={"index": "n"}), edge_frame
|
| 661 |
+
|
| 662 |
+
|
| 663 |
+
def path_summary(graph):
|
| 664 |
+
def path_summary_r(root, summaries, path, visited):
|
| 665 |
+
out_children = []
|
| 666 |
+
if root in out_neighbourhoods:
|
| 667 |
+
out_children = out_neighbourhoods[root].to_dict()
|
| 668 |
+
out_children = [(r, child)
|
| 669 |
+
for r, children in out_children.items()
|
| 670 |
+
for child in children if not visited[child]]
|
| 671 |
+
in_children = []
|
| 672 |
+
if root in in_neighbourhoods:
|
| 673 |
+
in_children = in_neighbourhoods[root].to_dict()
|
| 674 |
+
in_children = [(r, child)
|
| 675 |
+
for r, children in in_children.items()
|
| 676 |
+
for child in children if not visited[child]]
|
| 677 |
+
if len(out_children) + len(in_children) == 0:
|
| 678 |
+
return Counter([path, ])
|
| 679 |
+
new_summaries = Counter()
|
| 680 |
+
new_visited = visited
|
| 681 |
+
for r_child, child in out_children:
|
| 682 |
+
t_type_child = node_types.loc[child, "type"]
|
| 683 |
+
new_visited[child] = 1
|
| 684 |
+
progress_bar.update()
|
| 685 |
+
out_stub = f"-[:{r_child}]->(:{t_type_child})"
|
| 686 |
+
out_stub_repeated = f"-[:{r_child}*1..]->(:{t_type_child})"
|
| 687 |
+
repeated = path.endswith(f"{out_stub}{out_stub}")
|
| 688 |
+
repeated_again = path.endswith(f"{out_stub}{out_stub_repeated}")
|
| 689 |
+
new_path = path[
|
| 690 |
+
:-len(out_stub if repeated else out_stub_repeated)
|
| 691 |
+
] + out_stub_repeated if repeated or repeated_again else f"{path}{out_stub}"
|
| 692 |
+
new_summaries += path_summary_r(child, summaries, new_path, new_visited)
|
| 693 |
+
for r_child, child in in_children:
|
| 694 |
+
s_type_child = node_types.loc[child, "type"]
|
| 695 |
+
new_visited[child] = 1
|
| 696 |
+
progress_bar.update()
|
| 697 |
+
in_stub = f"<-[:{r_child}]-(:{s_type_child})"
|
| 698 |
+
in_stub_repeated = f"<-[:{r_child}*1..]-(:{s_type_child})"
|
| 699 |
+
repeated = path.endswith(f"{in_stub}{in_stub}")
|
| 700 |
+
repeated_again = path.endswith(f"{in_stub}{in_stub_repeated}")
|
| 701 |
+
new_path = path[
|
| 702 |
+
:-len(in_stub if repeated else in_stub_repeated)
|
| 703 |
+
] + in_stub_repeated if repeated or repeated_again else f"{path}{in_stub}"
|
| 704 |
+
new_summaries += path_summary_r(child, summaries, new_path, new_visited)
|
| 705 |
+
return summaries + new_summaries
|
| 706 |
+
|
| 707 |
+
sp_tree = get_sp_tree(graph.clusters("weak").giant())
|
| 708 |
+
num_sp_nodes = sp_tree.vcount()
|
| 709 |
+
node_types = sp_tree.get_vertex_dataframe()
|
| 710 |
+
sp_tree = sp_tree.get_edge_dataframe()
|
| 711 |
+
out_neighbourhoods = sp_tree.groupby(["source", "r"])["target"].agg(list)
|
| 712 |
+
in_neighbourhoods = sp_tree.groupby(["target", "r"])["source"].agg(list)
|
| 713 |
+
del sp_tree
|
| 714 |
+
root_visited = np.zeros(num_sp_nodes)
|
| 715 |
+
root_visited[0] = 1
|
| 716 |
+
progress_bar = tqdm(desc="Processing nodes for spanning tree paths", total=num_sp_nodes, leave=False)
|
| 717 |
+
progress_bar.update()
|
| 718 |
+
summaries = path_summary_r(0, Counter(), f"(:{node_types.loc[0, 'type']})", root_visited)
|
| 719 |
+
progress_bar.close()
|
| 720 |
+
return summaries
|
| 721 |
+
|
| 722 |
+
|
| 723 |
+
def edge_collapsing(node_data, edge_data, node_hierarchy: dict, total_nodes):
|
| 724 |
+
node_collapsing_map = {}
|
| 725 |
+
all_edge_nodes = []
|
| 726 |
+
edge_collapsing_subset = []
|
| 727 |
+
curr_node_id = total_nodes
|
| 728 |
+
for i, edge in tqdm(edge_data.iterrows(), total=len(edge_data), desc="Collapsing edges", leave=False):
|
| 729 |
+
if edge.s not in all_edge_nodes and edge.t not in all_edge_nodes:
|
| 730 |
+
edge_collapsing_subset.append(i)
|
| 731 |
+
all_edge_nodes.extend([edge.s, edge.t])
|
| 732 |
+
node_collapsing_map[edge.s] = curr_node_id
|
| 733 |
+
node_collapsing_map[edge.t] = curr_node_id
|
| 734 |
+
curr_node_id += 1
|
| 735 |
+
edge_collapsing_subset = edge_data.loc[edge_collapsing_subset].reset_index(drop=True)
|
| 736 |
+
|
| 737 |
+
new_node_data = pd.DataFrame(columns=["n", "type"])
|
| 738 |
+
new_edge_data = edge_data.copy()
|
| 739 |
+
|
| 740 |
+
node_s_types: pd.Series = edge_collapsing_subset.merge(node_data, left_on="s", right_on="n", how="left").type
|
| 741 |
+
node_t_types = edge_collapsing_subset.merge(node_data, left_on="t", right_on="n", how="left").type
|
| 742 |
+
new_node_data = new_node_data.assign(
|
| 743 |
+
n=np.arange(total_nodes, curr_node_id),
|
| 744 |
+
type=node_s_types.combine(node_t_types, lambda s, t: s | t),
|
| 745 |
+
)
|
| 746 |
+
node_hierarchy.update(node_collapsing_map)
|
| 747 |
+
uncollapsed_nodes = node_data[~node_data.n.isin(all_edge_nodes)]
|
| 748 |
+
for node in uncollapsed_nodes.n:
|
| 749 |
+
node_collapsing_map[node] = node
|
| 750 |
+
node_collapsing_map = pd.Series(node_collapsing_map, name="n")
|
| 751 |
+
|
| 752 |
+
new_node_data = pd.concat((new_node_data, uncollapsed_nodes), ignore_index=True)
|
| 753 |
+
|
| 754 |
+
new_edge_data.s = new_edge_data.s.map(node_collapsing_map.rename("s"))
|
| 755 |
+
new_edge_data.t = new_edge_data.t.map(node_collapsing_map.rename("t"))
|
| 756 |
+
new_edge_data = new_edge_data.drop_duplicates(ignore_index=True)
|
| 757 |
+
new_edge_data = new_edge_data[new_edge_data.s != new_edge_data.t]
|
| 758 |
+
|
| 759 |
+
return new_node_data, new_edge_data, node_hierarchy, curr_node_id
|
| 760 |
+
|
| 761 |
+
|
| 762 |
+
def star_collapsing(node_data, edge_data, node_hierarchy, total_nodes, min_star_degree=5):
|
| 763 |
+
degrees = edge_data.s.value_counts().add(edge_data.t.value_counts(), fill_value=0)
|
| 764 |
+
star_nodes = degrees[degrees >= min_star_degree].index
|
| 765 |
+
del degrees
|
| 766 |
+
|
| 767 |
+
node_collapsing_map = {}
|
| 768 |
+
new_node_data = []
|
| 769 |
+
curr_node_id = total_nodes
|
| 770 |
+
for node in tqdm(star_nodes, desc="Collapsing stars", leave=False):
|
| 771 |
+
for _, star_neighbours in enumerate((
|
| 772 |
+
edge_data.loc[edge_data.s == node, ["t", "r"]].rename(columns={"t": "n"}),
|
| 773 |
+
edge_data.loc[edge_data.t == node, ["s", "r"]].rename(columns={"s": "n"})
|
| 774 |
+
)):
|
| 775 |
+
for i in range(1, len(star_neighbours), 2):
|
| 776 |
+
node_1, node_2 = star_neighbours.iloc[i - 1], star_neighbours.iloc[i]
|
| 777 |
+
if node_1.n not in node_collapsing_map and node_2.n not in node_collapsing_map:
|
| 778 |
+
node_collapsing_map[node_1.n] = curr_node_id
|
| 779 |
+
node_collapsing_map[node_2.n] = curr_node_id
|
| 780 |
+
node_1_type = node_data.loc[node_data.n == node_1.n, "type"].iloc[0]
|
| 781 |
+
node_2_type = node_data.loc[node_data.n == node_2.n, "type"].iloc[0]
|
| 782 |
+
new_node_data.append((
|
| 783 |
+
curr_node_id,
|
| 784 |
+
node_1_type | node_2_type
|
| 785 |
+
))
|
| 786 |
+
curr_node_id += 1
|
| 787 |
+
node_hierarchy.update(node_collapsing_map)
|
| 788 |
+
uncollapsed_nodes = node_data[~node_data.n.isin(node_collapsing_map.keys())]
|
| 789 |
+
for node in uncollapsed_nodes.n:
|
| 790 |
+
node_collapsing_map[node] = node
|
| 791 |
+
node_collapsing_map = pd.Series(node_collapsing_map, name="n")
|
| 792 |
+
new_node_data = pd.DataFrame(new_node_data, columns=["n", "type"])
|
| 793 |
+
new_node_data = pd.concat((new_node_data, uncollapsed_nodes), ignore_index=True)
|
| 794 |
+
|
| 795 |
+
new_edge_data = edge_data.copy()
|
| 796 |
+
new_edge_data.s = new_edge_data.s.map(node_collapsing_map.rename("s"))
|
| 797 |
+
new_edge_data.t = new_edge_data.t.map(node_collapsing_map.rename("t"))
|
| 798 |
+
new_edge_data = new_edge_data.drop_duplicates(ignore_index=True)
|
| 799 |
+
new_edge_data = new_edge_data[new_edge_data.s != new_edge_data.t]
|
| 800 |
+
|
| 801 |
+
return new_node_data, new_edge_data, node_hierarchy, curr_node_id
|
| 802 |
+
|
| 803 |
+
|
| 804 |
+
class Summarization(MetricSet):
|
| 805 |
+
def __init__(self, graph, dashboard, num_nodes, kgist_merge_rules, kgist_nest_rules,
|
| 806 |
+
dedensification_degree_threshold, harp_node_threshold, harp_min_star_degree, results_path):
|
| 807 |
+
super().__init__(graph, dashboard, "Summarization")
|
| 808 |
+
self.num_nodes = num_nodes
|
| 809 |
+
self.kgist_merge_rules = kgist_merge_rules
|
| 810 |
+
self.kgist_nest_rules = kgist_nest_rules
|
| 811 |
+
self.dedensification_degree_threshold = dedensification_degree_threshold
|
| 812 |
+
self.harp_node_threshold = harp_node_threshold
|
| 813 |
+
self.harp_min_star_degree = harp_min_star_degree
|
| 814 |
+
self.results_path = results_path
|
| 815 |
+
|
| 816 |
+
self.metric_values = {
|
| 817 |
+
"KGistMDL": [0, ],
|
| 818 |
+
"KGistCompressionRatio": [0, ],
|
| 819 |
+
"KGistNumRules": [0, ],
|
| 820 |
+
"KGistEdgesExplained": [0, ],
|
| 821 |
+
"DedensificationNodeDecompressionRatio": [0, ],
|
| 822 |
+
"DedensificationEdgeCompressionRatio": [0, ],
|
| 823 |
+
"SpanningTreeNumPaths": [0, ],
|
| 824 |
+
"SpanningTreePathDist": [np.zeros(num_nodes), ],
|
| 825 |
+
"SpanningTreeTopPath": [0, ],
|
| 826 |
+
"HARPNodeCompressionRatio": [0, ],
|
| 827 |
+
"HARPEdgeCompressionRatio": [0, ],
|
| 828 |
+
}
|
| 829 |
+
self.metric_is_recursive = {
|
| 830 |
+
"KGistMDL": False,
|
| 831 |
+
"KGistCompressionRatio": False,
|
| 832 |
+
"KGistNumRules": False,
|
| 833 |
+
"KGistEdgesExplained": False,
|
| 834 |
+
"DedensificationNodeDecompressionRatio": False,
|
| 835 |
+
"DedensificationEdgeCompressionRatio": False,
|
| 836 |
+
"SpanningTreeNumPaths": True,
|
| 837 |
+
"SpanningTreePathDist": True,
|
| 838 |
+
"SpanningTreeTopPath": False,
|
| 839 |
+
"HARPNodeCompressionRatio": True,
|
| 840 |
+
"HARPEdgeCompressionRatio": True,
|
| 841 |
+
}
|
| 842 |
+
|
| 843 |
+
self.kgist_stats = None
|
| 844 |
+
self.dedensification_stats = None
|
| 845 |
+
|
| 846 |
+
def recursive_updates(self, node_batch: pd.DataFrame, edge_batch: pd.DataFrame):
|
| 847 |
+
makedirs("graph_analysis/KGist/data", exist_ok=True)
|
| 848 |
+
self.graph.graph.get_vertex_dataframe().reset_index().to_csv(
|
| 849 |
+
f"graph_analysis/KGist/data/{self.graph.dataset_name}_labels.txt",
|
| 850 |
+
sep=" ", header=False, index=False, encoding="utf-8"
|
| 851 |
+
)
|
| 852 |
+
self.graph.graph.get_edge_dataframe()[["source", "r", "target"]].to_csv(
|
| 853 |
+
f"graph_analysis/KGist/data/{self.graph.dataset_name}.txt",
|
| 854 |
+
sep=" ", header=False, index=False, encoding="utf-8"
|
| 855 |
+
)
|
| 856 |
+
kgist_graph = graph_analysis.KGist.graph.Graph(self.graph.dataset_name, idify=False, verbose=False)
|
| 857 |
+
kgist_searcher = graph_analysis.KGist.searcher.Searcher(kgist_graph)
|
| 858 |
+
kgist_model = kgist_searcher.build_model(verbosity=0)
|
| 859 |
+
if self.kgist_merge_rules:
|
| 860 |
+
kgist_model = kgist_model.merge_rules(verbosity=0)
|
| 861 |
+
if self.kgist_nest_rules:
|
| 862 |
+
kgist_model = kgist_model.nest_rules(verbosity=0)
|
| 863 |
+
self.kgist_stats = kgist_model.get_stats()
|
| 864 |
+
kgist_rule_graph_edge_list = []
|
| 865 |
+
for rule in kgist_model.rules:
|
| 866 |
+
kgist_rule_graph_edge_list.extend(rule_to_edge_list(rule))
|
| 867 |
+
kgist_rule_graph_edge_list = pd.DataFrame(kgist_rule_graph_edge_list, columns=["s_type", "r", "t_type"])
|
| 868 |
+
kgist_rule_graph_edge_list.apply(pd.to_numeric)
|
| 869 |
+
kgist_rule_graph_edge_list.to_csv(
|
| 870 |
+
f"{self.results_path}/{self.graph.dataset_name}/kgist_rule_graph.csv",
|
| 871 |
+
header=True, index=False, encoding="utf-8"
|
| 872 |
+
)
|
| 873 |
+
|
| 874 |
+
self.dedensification_stats, dedensified_node_data, dedensified_edge_data = \
|
| 875 |
+
dedensify(self.graph.graph, self.dedensification_degree_threshold)
|
| 876 |
+
dedensified_node_data.to_csv(
|
| 877 |
+
f"{self.results_path}/{self.graph.dataset_name}/dedensified_graph_nodes.csv",
|
| 878 |
+
header=True, index=False, encoding="utf-8"
|
| 879 |
+
)
|
| 880 |
+
dedensified_edge_data.to_csv(
|
| 881 |
+
f"{self.results_path}/{self.graph.dataset_name}/dedensified_graph_relations.csv",
|
| 882 |
+
header=True, index=False, encoding="utf-8"
|
| 883 |
+
)
|
| 884 |
+
|
| 885 |
+
sp_tree_path_dist = path_summary(self.graph.graph)
|
| 886 |
+
sp_tree_path_dist = pd.DataFrame(sp_tree_path_dist.items(),
|
| 887 |
+
columns=["Path", "Probability"]).set_index("Path").squeeze("columns")
|
| 888 |
+
sp_tree_path_dist = sp_tree_path_dist.sort_values(ascending=False) / np.nansum(sp_tree_path_dist)
|
| 889 |
+
sp_tree_path_dist.to_csv(
|
| 890 |
+
f"{self.results_path}/{self.graph.dataset_name}/spanning_tree_path_summary.csv",
|
| 891 |
+
header=True, index=True, encoding="utf-8"
|
| 892 |
+
)
|
| 893 |
+
sp_tree_path_dist_padded = np.zeros(self.num_nodes)
|
| 894 |
+
sp_tree_path_dist_padded[:len(sp_tree_path_dist)] = sp_tree_path_dist.values
|
| 895 |
+
self.metric_values["SpanningTreePathDist"].append(sp_tree_path_dist_padded)
|
| 896 |
+
self.metric_values["SpanningTreeNumPaths"].append(len(sp_tree_path_dist))
|
| 897 |
+
|
| 898 |
+
if self.num_nodes < 100000:
|
| 899 |
+
coarsened_graph = (
|
| 900 |
+
self.graph.graph.get_vertex_dataframe().reset_index().rename(columns={"vertex ID": "n"}),
|
| 901 |
+
self.graph.graph.get_edge_dataframe().rename(columns={"source": "s", "target": "t"}),
|
| 902 |
+
{},
|
| 903 |
+
self.num_nodes
|
| 904 |
+
)
|
| 905 |
+
coarsened_graph[0].type = coarsened_graph[0].type.apply(lambda t: {t})
|
| 906 |
+
num_edges_before = len(coarsened_graph[1])
|
| 907 |
+
while len(coarsened_graph[0]) > self.harp_node_threshold:
|
| 908 |
+
num_coarsened_nodes_before = len(coarsened_graph[0])
|
| 909 |
+
coarsened_graph = star_collapsing(*coarsened_graph, self.harp_min_star_degree)
|
| 910 |
+
coarsened_graph = edge_collapsing(*coarsened_graph)
|
| 911 |
+
num_coarsened_nodes_after = len(coarsened_graph[0])
|
| 912 |
+
if num_coarsened_nodes_before - num_coarsened_nodes_after < 10:
|
| 913 |
+
break
|
| 914 |
+
|
| 915 |
+
self.metric_values["HARPNodeCompressionRatio"].append(len(coarsened_graph[0]) / self.num_nodes)
|
| 916 |
+
self.metric_values["HARPEdgeCompressionRatio"].append(len(coarsened_graph[1]) / num_edges_before)
|
| 917 |
+
|
| 918 |
+
coarsened_graph[0].sort_values(["n", ], ignore_index=True).to_csv(
|
| 919 |
+
f"{self.results_path}/{self.graph.dataset_name}/harp_coarsened_nodes.csv",
|
| 920 |
+
header=True, index=False, encoding="utf-8"
|
| 921 |
+
)
|
| 922 |
+
coarsened_graph[1].sort_values(["s", "t"], ignore_index=True).to_csv(
|
| 923 |
+
f"{self.results_path}/{self.graph.dataset_name}/harp_coarsened_edges.csv",
|
| 924 |
+
header=True, index=False, encoding="utf-8"
|
| 925 |
+
)
|
| 926 |
+
node_hierarchy = pd.DataFrame(list(coarsened_graph[2].items()), columns=["node", "supernode"])
|
| 927 |
+
node_hierarchy = node_hierarchy.sort_values(["node", ], ignore_index=True)
|
| 928 |
+
node_hierarchy.to_csv(
|
| 929 |
+
f"{self.results_path}/{self.graph.dataset_name}/harp_node_hierarchy.csv",
|
| 930 |
+
header=True, index=False, encoding="utf-8"
|
| 931 |
+
)
|
| 932 |
+
else:
|
| 933 |
+
self.metric_values["HARPNodeCompressionRatio"].append(0)
|
| 934 |
+
self.metric_values["HARPEdgeCompressionRatio"].append(0)
|
| 935 |
+
|
| 936 |
+
def compute_metric(self, metric_name) -> np.ndarray:
|
| 937 |
+
if metric_name == "KGistMDL":
|
| 938 |
+
return self.kgist_stats[0]
|
| 939 |
+
elif metric_name == "KGistCompressionRatio":
|
| 940 |
+
return self.kgist_stats[1]
|
| 941 |
+
elif metric_name == "KGistNumRules":
|
| 942 |
+
return self.kgist_stats[2]
|
| 943 |
+
elif metric_name == "KGistEdgesExplained":
|
| 944 |
+
return self.kgist_stats[3]
|
| 945 |
+
elif metric_name == "DedensificationNodeDecompressionRatio":
|
| 946 |
+
return self.dedensification_stats[0]
|
| 947 |
+
elif metric_name == "DedensificationEdgeCompressionRatio":
|
| 948 |
+
return self.dedensification_stats[1]
|
| 949 |
+
elif metric_name == "SpanningTreeTopPath":
|
| 950 |
+
return np.nanmax(self.metric_values["SpanningTreePathDist"][self.current_step + 1])
|
src/research/COINs-KGGeneration/graph_analysis/stats.py
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Dict, List, Tuple
|
| 2 |
+
|
| 3 |
+
import numpy as np
|
| 4 |
+
import pandas as pd
|
| 5 |
+
from scipy.sparse import csr_matrix
|
| 6 |
+
from scipy.stats import chisquare, kstest, ttest_ind_from_stats
|
| 7 |
+
from tqdm import tqdm
|
| 8 |
+
|
| 9 |
+
from graph_analysis.metrics import MetricSetView
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def metric_set_histogram(metric_sets: Dict[str, List[MetricSetView]], aggregate_name: str) -> Tuple[List[MetricSetView],
|
| 13 |
+
List[Dict[str,
|
| 14 |
+
float]]]:
|
| 15 |
+
metric_sets_histogram = []
|
| 16 |
+
metric_sets_sum = []
|
| 17 |
+
for metrics_type, metric_set_list in metric_sets.items():
|
| 18 |
+
metric_set_histogram = [aggregate_name, f"{metrics_type}Histogram"]
|
| 19 |
+
metric_names = metric_set_list[0][2].keys()
|
| 20 |
+
metric_set_collected_scalars = {metric_name: [metric_set[2][metric_name][-1]
|
| 21 |
+
for metric_set in metric_set_list
|
| 22 |
+
if type(metric_set[2][metric_name][-1])
|
| 23 |
+
not in [np.ndarray, csr_matrix]]
|
| 24 |
+
for metric_name in metric_names}
|
| 25 |
+
metric_set_histogram.append({f"{metric_name}Dist": [np.array(metric_values) / sum(metric_values), ]
|
| 26 |
+
for metric_name, metric_values in metric_set_collected_scalars.items()
|
| 27 |
+
if len(metric_values) > 0})
|
| 28 |
+
metric_sets_histogram.append(tuple(metric_set_histogram))
|
| 29 |
+
metric_sets_sum.append({f"{metric_name}Dist": sum(metric_values)
|
| 30 |
+
for metric_name, metric_values in metric_set_collected_scalars.items()
|
| 31 |
+
if len(metric_values) > 0})
|
| 32 |
+
return metric_sets_histogram, metric_sets_sum
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def estimate_and_test_pareto(metric_sets: Dict[str, List[MetricSetView]]):
|
| 36 |
+
pareto_test_table = []
|
| 37 |
+
for metrics_type, metric_set_list in metric_sets.items():
|
| 38 |
+
for graph_dataset_name, _, metric_set_values in metric_set_list:
|
| 39 |
+
for metric_name, metric_values in metric_set_values.items():
|
| 40 |
+
metric_values = metric_values[-1]
|
| 41 |
+
if "Membership" in metric_name:
|
| 42 |
+
continue
|
| 43 |
+
if type(metric_values) is not np.ndarray:
|
| 44 |
+
continue
|
| 45 |
+
x = metric_values[metric_values > 0]
|
| 46 |
+
n = len(x)
|
| 47 |
+
if n == 0:
|
| 48 |
+
continue
|
| 49 |
+
pareto_min_hat = np.min(x)
|
| 50 |
+
pareto_alpha_hat = n / np.sum(np.log(x / pareto_min_hat)) if (np.max(x) != pareto_min_hat
|
| 51 |
+
and n > 1) else 0
|
| 52 |
+
pareto_cdf = 1 - ((pareto_min_hat / x) ** pareto_alpha_hat)
|
| 53 |
+
pareto_p_value = kstest(x, pareto_cdf, alternative="two-sided").pvalue
|
| 54 |
+
pareto_test_table.append((metric_name, graph_dataset_name, pareto_alpha_hat, pareto_p_value))
|
| 55 |
+
pareto_test_table = pd.DataFrame(pareto_test_table, columns=["Metric", "Dataset", "ParetoAlpha", "ParetoPValue"])
|
| 56 |
+
return pareto_test_table
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
def estimate_and_test_uniform(metric_set_histograms: List[MetricSetView], metric_sets_sums: List[Dict[str, float]]):
|
| 60 |
+
uniform_test_table = []
|
| 61 |
+
for metric_set, metric_set_sums in zip(metric_set_histograms, metric_sets_sums):
|
| 62 |
+
for metric_name, metric_values in metric_set[2].items():
|
| 63 |
+
metric_values = metric_values[-1]
|
| 64 |
+
if "Membership" in metric_name:
|
| 65 |
+
continue
|
| 66 |
+
if type(metric_values) is not np.ndarray:
|
| 67 |
+
continue
|
| 68 |
+
x = metric_values[metric_values > 0]
|
| 69 |
+
n = len(x)
|
| 70 |
+
if n == 0:
|
| 71 |
+
continue
|
| 72 |
+
rel_entropy = (-np.sum(x * np.log(x)) / np.log(n)) if n > 1 else 1
|
| 73 |
+
uniform_p_value = chisquare(x * metric_set_sums[metric_name]).pvalue if n > 1 else 1
|
| 74 |
+
uniform_test_table.append((metric_name, metric_set[0], rel_entropy, uniform_p_value))
|
| 75 |
+
uniform_test_table = pd.DataFrame(uniform_test_table,
|
| 76 |
+
columns=["Metric", "Dataset", "RelativeEntropy", "UniformPValue"])
|
| 77 |
+
return uniform_test_table
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def estimate_and_test_comparison(metric_sets: Dict[str, List[MetricSetView]],
|
| 81 |
+
linear_comparison: bool,
|
| 82 |
+
num_bootstrap_samples: int = 100):
|
| 83 |
+
def prepare_for_kde(x, y, sample_size=10000):
|
| 84 |
+
n, m = len(x), len(y)
|
| 85 |
+
if n > sample_size:
|
| 86 |
+
subsample_indices = np.linspace(0, n - 1, num=sample_size, dtype=int)
|
| 87 |
+
x = x[subsample_indices]
|
| 88 |
+
x /= np.sum(x)
|
| 89 |
+
n = sample_size
|
| 90 |
+
if m > sample_size:
|
| 91 |
+
subsample_indices = np.linspace(0, m - 1, num=sample_size, dtype=int)
|
| 92 |
+
y = y[subsample_indices]
|
| 93 |
+
y /= np.sum(y)
|
| 94 |
+
m = sample_size
|
| 95 |
+
xy = np.concatenate((x, y), axis=None).reshape((-1, 1))
|
| 96 |
+
dists = np.abs(xy.reshape(-1, 1) - xy.reshape(1, -1))
|
| 97 |
+
sigma = 0.5 * np.nanmedian(dists)
|
| 98 |
+
sigma = 1e-8 if sigma == 0 else sigma
|
| 99 |
+
return n, m, xy, sigma
|
| 100 |
+
|
| 101 |
+
def gaussian_kernel(x, y, sigma):
|
| 102 |
+
dists = np.abs(x.reshape(-1, 1) - y.reshape(1, -1))
|
| 103 |
+
return np.exp(-(dists ** 2) / (2 * sigma ** 2))
|
| 104 |
+
|
| 105 |
+
def compute_mmd(n, m, xy, sigma):
|
| 106 |
+
k = gaussian_kernel(xy, xy, sigma)
|
| 107 |
+
k_x, k_y, k_xy = np.mean(k[:n, :n]), np.mean(k[-m:, -m:]), np.mean(k[:n, -m:])
|
| 108 |
+
mmd = k_x + k_y - 2 * k_xy
|
| 109 |
+
return mmd
|
| 110 |
+
|
| 111 |
+
comparison_matrices = []
|
| 112 |
+
for metrics_type, metric_set_list in metric_sets.items():
|
| 113 |
+
num_datasets = len(metric_set_list)
|
| 114 |
+
if linear_comparison:
|
| 115 |
+
dataset_indices = [(0, j) for j in range(1, num_datasets)]
|
| 116 |
+
else:
|
| 117 |
+
dataset_indices = [(i, j) for i in range(num_datasets) for j in range(i + 1, num_datasets)]
|
| 118 |
+
for i, j in dataset_indices:
|
| 119 |
+
metric_set, metric_set_2 = metric_set_list[i], metric_set_list[j]
|
| 120 |
+
if metric_set[0] == metric_set_2[0]:
|
| 121 |
+
continue
|
| 122 |
+
for metric_name in metric_set[2].keys():
|
| 123 |
+
metric_values = metric_set[2][metric_name][-1]
|
| 124 |
+
metric_values_2 = metric_set_2[2][metric_name][-1]
|
| 125 |
+
if "Membership" in metric_name:
|
| 126 |
+
continue
|
| 127 |
+
if type(metric_values) is not np.ndarray:
|
| 128 |
+
continue
|
| 129 |
+
metric_values, metric_values_2 = metric_values.flatten(), metric_values_2.flatten()
|
| 130 |
+
metric_values = metric_values[metric_values > 0]
|
| 131 |
+
metric_values_2 = metric_values_2[metric_values_2 > 0]
|
| 132 |
+
n_1, n_2 = len(metric_values), len(metric_values_2)
|
| 133 |
+
if n_1 == 0 or n_2 == 0:
|
| 134 |
+
continue
|
| 135 |
+
if np.max(metric_values) == np.min(metric_values) \
|
| 136 |
+
and np.max(metric_values_2) == np.min(metric_values_2):
|
| 137 |
+
comparison_matrices.append((metric_set[0], metric_set_2[0],
|
| 138 |
+
metric_name, 0, 1, 0, 1))
|
| 139 |
+
continue
|
| 140 |
+
|
| 141 |
+
t_test = ttest_ind_from_stats(np.nanmean(metric_values), np.nanstd(metric_values), n_1,
|
| 142 |
+
np.nanmean(metric_values_2), np.nanstd(metric_values_2), n_2,
|
| 143 |
+
equal_var=False)
|
| 144 |
+
|
| 145 |
+
n, m, xy, sigma = prepare_for_kde(metric_values, metric_values_2)
|
| 146 |
+
mmd_estimate = compute_mmd(n, m, xy, sigma)
|
| 147 |
+
xys = [np.random.permutation(xy) for _ in range(num_bootstrap_samples)]
|
| 148 |
+
mmds_bootstrap_samples = [compute_mmd(n, m, xy, sigma)
|
| 149 |
+
for xy in tqdm(xys, desc=f"Bootstrapping {metric_name} MMD", leave=False)]
|
| 150 |
+
mmds_bootstrap_samples = np.array(mmds_bootstrap_samples)
|
| 151 |
+
mmd_p_value = np.mean(mmd_estimate <= mmds_bootstrap_samples)
|
| 152 |
+
comparison_matrices.append((metric_set[0], metric_set_2[0],
|
| 153 |
+
metric_name, t_test.statistic, t_test.pvalue,
|
| 154 |
+
mmd_estimate, mmd_p_value))
|
| 155 |
+
comparison_matrices = pd.DataFrame(comparison_matrices,
|
| 156 |
+
columns=["Dataset1", "Dataset2", "Metric",
|
| 157 |
+
"TStat", "TTestPValue", "MMD", "MMDPValue"])
|
| 158 |
+
return comparison_matrices
|
src/research/COINs-KGGeneration/graph_completion/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Graph Embedding Methods for Graph Completion
|
| 2 |
+
*Repository containing the implementation of the second version of the Digital Lab model for graph completion and link prediction on the Monty data*
|
| 3 |
+
|
| 4 |
+
---
|
| 5 |
+
|
| 6 |
+
## Abstract
|
| 7 |
+
<div style="text-align: justify"> Knowledge graphs have recently attracted significant attention from both industry and
|
| 8 |
+
academia in scenarios that require exploiting large-scale heterogeneous data collections.
|
| 9 |
+
Knowledge graphs are a type of database where the general structure is a network of
|
| 10 |
+
entities, their semantic types, properties, and relationships. They support reasoning over
|
| 11 |
+
the integrated information as the main application. This process is very closely linked
|
| 12 |
+
to solving the problems of link prediction and query answering for the knowledge graph.
|
| 13 |
+
The most common approach in tackling these tasks is to compute suitable numeric
|
| 14 |
+
representations for each element of the graph, called graph embeddings. </div>
|
| 15 |
+
|
| 16 |
+
## File structure
|
| 17 |
+
```
|
| 18 |
+
.
|
| 19 |
+
├── Results - Graph Preprocessing.ipynb: Jupyter notebook containing the code to generate the network science and graph preprocessing results.
|
| 20 |
+
├── Results - Training & Evaluation.ipynb: Jupyter notebook containing the code to analyse the model training and evaluation results.
|
| 21 |
+
├── database.py: Module implementing the interface for connecting to the Neo4j database and executing the required Cypher queries.
|
| 22 |
+
├── extract_data.py: Script for extracting the Swisscom graph data from the database and preprocessing the obtained files into cleaner formats. Contains also two methods used in the preprocessing of the other data sources as well.
|
| 23 |
+
├── graphs
|
| 24 |
+
│ ├── load_graph.py: Module containing methods for creating graph objects, from an edge dataset or using the algorithm for simulation.
|
| 25 |
+
│ ├── preprocess.py: Module containing the implementation of the context extraction process.
|
| 26 |
+
│ └── random_walks.py: Module containing the implementation of the context extraction process.
|
| 27 |
+
├── load_data.py: Module containing methods for loading graph from disk.
|
| 28 |
+
├── main.py: Model training and evaluation script.
|
| 29 |
+
├── models
|
| 30 |
+
│ ├── autoencoders.py: Module containing the implementation of general autoencoders.
|
| 31 |
+
│ ├── embedding_aggregation_model.py: Module containing the implementation of the new embedding model and its loss function.
|
| 32 |
+
│ ├── evaluate.py: Module containing the implementation of the evaluation procedure.
|
| 33 |
+
│ ├── graph_embedders.py: Module containing the implementation of the embedding models from related work.
|
| 34 |
+
│ ├── helper_layers.py: Module containing implementations of helper layers to the embedding models from previous work.
|
| 35 |
+
│ ├── link_rankers.py: Module containing the implementation of the link prediction models from related work.
|
| 36 |
+
│ ├── loss_terms.py: Module containing the implementation of the specific loss functions utilized by embedding models from related work.
|
| 37 |
+
│ ├── timestamp_prediction.py: Module containing the implementation of timestamp prediction.
|
| 38 |
+
│ └── utils.py: Module containing the implementation of important utility methods required for model training and evaluation.
|
| 39 |
+
├── preprocess.py: Module implementing general pipelines for iteratively cleaning data obtained from the database.
|
| 40 |
+
├── serialization.py: Module containing helper functions for (de)serializing and (de)compressing Python objects from/to local storage.
|
| 41 |
+
└── test.py: Model testing script.
|
| 42 |
+
```
|
| 43 |
+
|
| 44 |
+
## Notes
|
| 45 |
+
|
| 46 |
+
### Prerequisites
|
| 47 |
+
- Python >=3.7 is installed
|
| 48 |
+
- Run ```python -m pip install -r requirements.txt``` from the root folder to install the dependencies
|
| 49 |
+
|
| 50 |
+
### Execution
|
| 51 |
+
- To execute model training and evaluation run ```python main.py --config_file <PATH_TO_YAML_CONFIG_FILE>```
|
| 52 |
+
- Example: ```python main.py --config_file ./config_wordnet.yml```
|
| 53 |
+
- The YAML config file should contain the following model configuration settings:
|
| 54 |
+
- ```dataset_folder_path```: path on disk of the folder where the execution files should be stored, ```str```
|
| 55 |
+
- ```nodes_filepath```: path on disk of the node list file, ```str```
|
| 56 |
+
- ```relations_filepath```: path on disk of the edge list file, ```str```
|
| 57 |
+
- ```simulated_data```: whether a fake graph should be generated instead, ```bool```
|
| 58 |
+
- ```train```: whether a model should be trained or one is already available, ```bool```
|
| 59 |
+
- ```num_nodes```: number of nodes in the graph, or desired number of nodes for the simulated graph, positive ```int```
|
| 60 |
+
- ```num_node_types```: number of node types in the graph, positive ```int```
|
| 61 |
+
- ```num_relation_types```: number of edge types in the graph, positive ```int```
|
| 62 |
+
- ```num_higher_communities```: desired number of higher communities, positive ```int```
|
| 63 |
+
- ```num_lower_communities```: desired number of lower communities, positive ```int```
|
| 64 |
+
- ```random_walk_length```: chosen maximum random walk length, positive ```int```
|
| 65 |
+
- ```context_radius```: chosen context set radius, positive ```int```
|
| 66 |
+
- ```num_epochs```: chosen maximum number of model training epochs, positive ```int```
|
| 67 |
+
- ```batch_size```: chosen number of samples per batch, positive ```int```
|
| 68 |
+
- ```validation_patience```: number of epochs to wait before early stopping, positive ```int```
|
| 69 |
+
- ```verbosity_frequency```: after how many epochs to report training progress, positive ```int```
|
| 70 |
+
- ```validation_size```: fraction of dataset samples that should be dedicated to validation, ```float``` in [0.0, 1.0]
|
| 71 |
+
- ```test_size```: fraction of dataset samples that should be dedicated to testing, ```float``` in [0.0, 1.0]
|
| 72 |
+
- ```use_gpus```: whether to transfer all execution to a GPU if available, ```bool```
|
| 73 |
+
- ```train_coverage```: fraction of train set size that should be covered by the context triplet set, ```float``` in [0.0, 1.0]
|
| 74 |
+
- ```pagerank_importances```: whether to use PageRank or uniform node importances for random walk generation, ```bool```
|
| 75 |
+
- ```walks_relation_specific```: whether to generate relation-specific random walks, ```bool```
|
| 76 |
+
- ```embedding_dim```: chosen embedding dimension, positive ```int```
|
| 77 |
+
- ```community_model```: chosen community and type embedding model from related work, ```str``` in {"transe"<sup>1</sup>, "rotate"<sup>2</sup>, "mlp"<sup>3</sup>, "gatne"<sup>3</sup>, "sacn"<sup>1</sup>}, superscripts denote compatibility with other model settings
|
| 78 |
+
- ```node_models```: chosen model from related work for intra- and inter-community embedding, ```str``` in {"transe"<sup>1</sup>, "rotate"<sup>2</sup>, "mlp"<sup>3</sup>, "gatne"<sup>3</sup>, "sacn"<sup>1</sup>}, superscripts denote compatibility with other model settings
|
| 79 |
+
- ```link_ranker```: chosen edge scoring model from related work, ```str``` in {"transe"<sup>1</sup>, "rotate"<sup>2</sup>, "mlp"<sup>3</sup>, "gatne"<sup>3</sup>, "sacn"<sup>1</sup>}, superscripts denote compatibility with other model settings
|
| 80 |
+
- To simply test a trained model for query answering through an interactive command line, run ```python test.py --config_file <PATH_TO_YAML_CONFIG_FILE>```
|
| 81 |
+
- Type ```query <HEAD_NODE> <RELATION> [<TAIL_NODE_TYPE>]``` to get the model's response to the given relation query;
|
| 82 |
+
- Type ```quit``` to exit the interactive programme.
|
| 83 |
+
|
| 84 |
+
### Diagram of the execution pipeline for main.py
|
| 85 |
+
|
| 86 |
+

|
| 87 |
+
|
| 88 |
+
## Authors
|
| 89 |
+
- Andrej Janchevski, INI-DNA-NB
|
src/research/COINs-KGGeneration/graph_completion/__init__.py
ADDED
|
File without changes
|
src/research/COINs-KGGeneration/graph_completion/configs/freebase.yml
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
seed: 4089853924
|
| 2 |
+
device: cuda:0
|
| 3 |
+
val_size: 0.01
|
| 4 |
+
test_size: 0.02
|
| 5 |
+
mini_batch_size: 256
|
| 6 |
+
lr: 1.0e-3
|
| 7 |
+
weight_decay: 1.0e-6
|
| 8 |
+
val_patience: 50
|
| 9 |
+
val_tolerance: 1.0e-4
|
| 10 |
+
algorithm: transe
|
| 11 |
+
leiden_resolution: 5.0e-3
|
| 12 |
+
loader_hpars:
|
| 13 |
+
dataset_name: freebase
|
| 14 |
+
simulated: false
|
| 15 |
+
sample_source: smore
|
| 16 |
+
sampler_hpars:
|
| 17 |
+
num_negative_samples: 128
|
| 18 |
+
num_neighbours: 10
|
| 19 |
+
random_walk_length: 10
|
| 20 |
+
context_radius: 2
|
| 21 |
+
pagerank_importances: true
|
| 22 |
+
walks_relation_specific: true
|
| 23 |
+
embedder_hpars:
|
| 24 |
+
embedding_dim: 100
|
| 25 |
+
link_ranker_hpars:
|
| 26 |
+
algorithm: transe
|
| 27 |
+
embedding_loss_hpars:
|
| 28 |
+
margin: 1.0
|
| 29 |
+
rotate_alpha: 1.0
|
src/research/COINs-KGGeneration/graph_completion/configs/freebase_betae.yml
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
seed: 123456789
|
| 2 |
+
device: cuda:0
|
| 3 |
+
val_size: 0.01
|
| 4 |
+
test_size: 0.02
|
| 5 |
+
mini_batch_size: 512
|
| 6 |
+
lr: 1.0e-4
|
| 7 |
+
weight_decay: 1.0e-6
|
| 8 |
+
val_patience: 50
|
| 9 |
+
val_tolerance: 1.0e-4
|
| 10 |
+
max_epochs: 60
|
| 11 |
+
validation_freq: 12
|
| 12 |
+
checkpoint_freq: 12000
|
| 13 |
+
algorithm: betae
|
| 14 |
+
leiden_resolution: 5.0e-3
|
| 15 |
+
loader_hpars:
|
| 16 |
+
dataset_name: freebase
|
| 17 |
+
simulated: false
|
| 18 |
+
sample_source: smore
|
| 19 |
+
sampler_hpars:
|
| 20 |
+
query_structure:
|
| 21 |
+
- 1p
|
| 22 |
+
- 2p
|
| 23 |
+
- 3p
|
| 24 |
+
- 2i
|
| 25 |
+
- 3i
|
| 26 |
+
- 2i1p
|
| 27 |
+
- 1p2i
|
| 28 |
+
- 2d
|
| 29 |
+
- 3d
|
| 30 |
+
- 2d1p
|
| 31 |
+
- 1p2b
|
| 32 |
+
- 1p2d
|
| 33 |
+
num_negative_samples: 128
|
| 34 |
+
num_neighbours: 10
|
| 35 |
+
random_walk_length: 10
|
| 36 |
+
context_radius: 2
|
| 37 |
+
pagerank_importances: true
|
| 38 |
+
walks_relation_specific: true
|
| 39 |
+
embedder_hpars:
|
| 40 |
+
embedding_dim: 400
|
| 41 |
+
link_ranker_hpars:
|
| 42 |
+
algorithm: betae
|
| 43 |
+
embedding_loss_hpars:
|
| 44 |
+
margin: 60.0
|
src/research/COINs-KGGeneration/graph_completion/configs/freebase_complex.yml
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
seed: 4089853924
|
| 2 |
+
device: cuda:0
|
| 3 |
+
val_size: 0.01
|
| 4 |
+
test_size: 0.02
|
| 5 |
+
mini_batch_size: 256
|
| 6 |
+
lr: 1.0e-3
|
| 7 |
+
weight_decay: 1.0e-6
|
| 8 |
+
val_patience: 50
|
| 9 |
+
val_tolerance: 1.0e-4
|
| 10 |
+
max_epochs: 50
|
| 11 |
+
validation_freq: 10
|
| 12 |
+
checkpoint_freq: 10000
|
| 13 |
+
algorithm: complex
|
| 14 |
+
leiden_resolution: 5.0e-3
|
| 15 |
+
loader_hpars:
|
| 16 |
+
dataset_name: freebase
|
| 17 |
+
sample_source: smore
|
| 18 |
+
sampler_hpars:
|
| 19 |
+
num_negative_samples: 128
|
| 20 |
+
num_neighbours: 10
|
| 21 |
+
random_walk_length: 10
|
| 22 |
+
context_radius: 2
|
| 23 |
+
pagerank_importances: true
|
| 24 |
+
walks_relation_specific: true
|
| 25 |
+
embedder_hpars:
|
| 26 |
+
embedding_dim: 100
|
| 27 |
+
link_ranker_hpars:
|
| 28 |
+
algorithm: complex
|
| 29 |
+
embedding_loss_hpars:
|
| 30 |
+
margin: 1.0
|
| 31 |
+
rotate_alpha: 1.0
|
src/research/COINs-KGGeneration/graph_completion/configs/freebase_distmult.yml
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
seed: 4089853924
|
| 2 |
+
device: cuda:0
|
| 3 |
+
val_size: 0.01
|
| 4 |
+
test_size: 0.02
|
| 5 |
+
mini_batch_size: 256
|
| 6 |
+
lr: 1.0e-3
|
| 7 |
+
weight_decay: 1.0e-6
|
| 8 |
+
val_patience: 50
|
| 9 |
+
val_tolerance: 1.0e-4
|
| 10 |
+
max_epochs: 50
|
| 11 |
+
validation_freq: 10
|
| 12 |
+
checkpoint_freq: 10000
|
| 13 |
+
algorithm: distmult
|
| 14 |
+
leiden_resolution: 5.0e-3
|
| 15 |
+
loader_hpars:
|
| 16 |
+
dataset_name: freebase
|
| 17 |
+
sample_source: smore
|
| 18 |
+
sampler_hpars:
|
| 19 |
+
num_negative_samples: 128
|
| 20 |
+
num_neighbours: 10
|
| 21 |
+
random_walk_length: 10
|
| 22 |
+
context_radius: 2
|
| 23 |
+
pagerank_importances: true
|
| 24 |
+
walks_relation_specific: true
|
| 25 |
+
embedder_hpars:
|
| 26 |
+
embedding_dim: 100
|
| 27 |
+
link_ranker_hpars:
|
| 28 |
+
algorithm: distmult
|
| 29 |
+
embedding_loss_hpars:
|
| 30 |
+
margin: 1.0
|
| 31 |
+
rotate_alpha: 1.0
|
src/research/COINs-KGGeneration/graph_completion/configs/freebase_gnn.yml
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
seed: 123456789
|
| 2 |
+
device: cuda:0
|
| 3 |
+
val_size: 0.01
|
| 4 |
+
test_size: 0.02
|
| 5 |
+
mini_batch_size: 64
|
| 6 |
+
lr: 1.0e-3
|
| 7 |
+
weight_decay: 1.0e-6
|
| 8 |
+
val_patience: 50
|
| 9 |
+
val_tolerance: 1.0e-4
|
| 10 |
+
max_epochs: 50
|
| 11 |
+
validation_freq: 100
|
| 12 |
+
checkpoint_freq: 10000
|
| 13 |
+
algorithm: kbgat
|
| 14 |
+
leiden_resolution: 5.0e-3
|
| 15 |
+
transe_initialize: true
|
| 16 |
+
loader_hpars:
|
| 17 |
+
dataset_name: freebase
|
| 18 |
+
simulated: false
|
| 19 |
+
sample_source: smore
|
| 20 |
+
sampler_hpars:
|
| 21 |
+
num_negative_samples: 64
|
| 22 |
+
num_neighbours: 10
|
| 23 |
+
random_walk_length: 10
|
| 24 |
+
context_radius: 2
|
| 25 |
+
pagerank_importances: true
|
| 26 |
+
walks_relation_specific: true
|
| 27 |
+
embedder_hpars:
|
| 28 |
+
embedding_dim: 100
|
| 29 |
+
link_ranker_hpars:
|
| 30 |
+
algorithm: kbgat
|
| 31 |
+
sacn_num_conv_channels: 300
|
| 32 |
+
embedding_loss_hpars:
|
| 33 |
+
margin: 9.0
|
| 34 |
+
rotate_alpha: 1.0
|
src/research/COINs-KGGeneration/graph_completion/configs/freebase_gqe.yml
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
seed: 123456789
|
| 2 |
+
device: cuda:0
|
| 3 |
+
val_size: 0.01
|
| 4 |
+
test_size: 0.02
|
| 5 |
+
mini_batch_size: 512
|
| 6 |
+
lr: 1.0e-4
|
| 7 |
+
weight_decay: 1.0e-6
|
| 8 |
+
val_patience: 50
|
| 9 |
+
val_tolerance: 1.0e-4
|
| 10 |
+
max_epochs: 35
|
| 11 |
+
validation_freq: 7
|
| 12 |
+
checkpoint_freq: 7000
|
| 13 |
+
algorithm: gqe
|
| 14 |
+
leiden_resolution: 5.0e-3
|
| 15 |
+
loader_hpars:
|
| 16 |
+
dataset_name: freebase
|
| 17 |
+
simulated: false
|
| 18 |
+
sample_source: smore
|
| 19 |
+
sampler_hpars:
|
| 20 |
+
query_structure:
|
| 21 |
+
- 1p
|
| 22 |
+
- 2p
|
| 23 |
+
- 3p
|
| 24 |
+
- 2i
|
| 25 |
+
- 3i
|
| 26 |
+
- 2i1p
|
| 27 |
+
- 1p2i
|
| 28 |
+
num_negative_samples: 128
|
| 29 |
+
num_neighbours: 10
|
| 30 |
+
random_walk_length: 10
|
| 31 |
+
context_radius: 2
|
| 32 |
+
pagerank_importances: true
|
| 33 |
+
walks_relation_specific: true
|
| 34 |
+
embedder_hpars:
|
| 35 |
+
embedding_dim: 800
|
| 36 |
+
link_ranker_hpars:
|
| 37 |
+
algorithm: gqe
|
| 38 |
+
embedding_loss_hpars:
|
| 39 |
+
margin: 24.0
|
src/research/COINs-KGGeneration/graph_completion/configs/freebase_q2b.yml
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
seed: 1503136574
|
| 2 |
+
device: cuda:0
|
| 3 |
+
val_size: 0.01
|
| 4 |
+
test_size: 0.02
|
| 5 |
+
mini_batch_size: 256
|
| 6 |
+
lr: 1.0e-4
|
| 7 |
+
weight_decay: 1.0e-6
|
| 8 |
+
val_patience: 50
|
| 9 |
+
val_tolerance: 1.0e-4
|
| 10 |
+
max_epochs: 35
|
| 11 |
+
validation_freq: 7
|
| 12 |
+
checkpoint_freq: 7000
|
| 13 |
+
algorithm: q2b
|
| 14 |
+
leiden_resolution: 5.0e-3
|
| 15 |
+
coins_shared_relation_embedding: true
|
| 16 |
+
loader_hpars:
|
| 17 |
+
dataset_name: freebase
|
| 18 |
+
simulated: false
|
| 19 |
+
sample_source: smore
|
| 20 |
+
sampler_hpars:
|
| 21 |
+
query_structure:
|
| 22 |
+
- 1p
|
| 23 |
+
- 2p
|
| 24 |
+
- 3p
|
| 25 |
+
- 2i
|
| 26 |
+
- 3i
|
| 27 |
+
- 2i1p
|
| 28 |
+
- 1p2i
|
| 29 |
+
num_negative_samples: 128
|
| 30 |
+
num_neighbours: 10
|
| 31 |
+
random_walk_length: 10
|
| 32 |
+
context_radius: 2
|
| 33 |
+
pagerank_importances: true
|
| 34 |
+
walks_relation_specific: true
|
| 35 |
+
embedder_hpars:
|
| 36 |
+
embedding_dim: 400
|
| 37 |
+
link_ranker_hpars:
|
| 38 |
+
algorithm: q2b
|
| 39 |
+
embedding_loss_hpars:
|
| 40 |
+
margin: 24.0
|
src/research/COINs-KGGeneration/graph_completion/configs/freebase_rotate.yml
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
seed: 4089853924
|
| 2 |
+
device: cuda:0
|
| 3 |
+
val_size: 0.01
|
| 4 |
+
test_size: 0.02
|
| 5 |
+
mini_batch_size: 256
|
| 6 |
+
lr: 1.0e-3
|
| 7 |
+
weight_decay: 1.0e-6
|
| 8 |
+
val_patience: 50
|
| 9 |
+
val_tolerance: 1.0e-4
|
| 10 |
+
algorithm: rotate
|
| 11 |
+
leiden_resolution: 5.0e-3
|
| 12 |
+
loader_hpars:
|
| 13 |
+
dataset_name: freebase
|
| 14 |
+
simulated: false
|
| 15 |
+
sample_source: smore
|
| 16 |
+
sampler_hpars:
|
| 17 |
+
num_negative_samples: 128
|
| 18 |
+
num_neighbours: 10
|
| 19 |
+
random_walk_length: 10
|
| 20 |
+
context_radius: 2
|
| 21 |
+
pagerank_importances: true
|
| 22 |
+
walks_relation_specific: true
|
| 23 |
+
embedder_hpars:
|
| 24 |
+
embedding_dim: 100
|
| 25 |
+
link_ranker_hpars:
|
| 26 |
+
algorithm: rotate
|
| 27 |
+
embedding_loss_hpars:
|
| 28 |
+
margin: 9.0
|
| 29 |
+
rotate_alpha: 1.0
|
src/research/COINs-KGGeneration/graph_completion/configs/hep.yml
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
seed: 123456789
|
| 2 |
+
device: cuda:0
|
| 3 |
+
val_size: 0.01
|
| 4 |
+
test_size: 0.02
|
| 5 |
+
mini_batch_size: 25
|
| 6 |
+
lr: 1.0e-4
|
| 7 |
+
weight_decay: 1.0e-6
|
| 8 |
+
val_patience: 50
|
| 9 |
+
val_tolerance: 1.0e-4
|
| 10 |
+
algorithm: transe
|
| 11 |
+
coins_alpha: 0.01
|
| 12 |
+
loader_hpars:
|
| 13 |
+
dataset_name: hep
|
| 14 |
+
simulated: false
|
| 15 |
+
sample_source: smore
|
| 16 |
+
sampler_hpars:
|
| 17 |
+
num_negative_samples: 5
|
| 18 |
+
num_neighbours: 10
|
| 19 |
+
random_walk_length: 10
|
| 20 |
+
context_radius: 2
|
| 21 |
+
pagerank_importances: true
|
| 22 |
+
walks_relation_specific: true
|
| 23 |
+
embedder_hpars:
|
| 24 |
+
embedding_dim: 25
|
| 25 |
+
link_ranker_hpars:
|
| 26 |
+
algorithm: transe
|
| 27 |
+
embedding_loss_hpars:
|
| 28 |
+
margin: 1.0
|
src/research/COINs-KGGeneration/graph_completion/configs/nell.yml
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
seed: 3192206669
|
| 2 |
+
device: cuda:0
|
| 3 |
+
val_size: 0.01
|
| 4 |
+
test_size: 0.02
|
| 5 |
+
mini_batch_size: 256
|
| 6 |
+
lr: 1.0e-3
|
| 7 |
+
weight_decay: 1.0e-6
|
| 8 |
+
val_patience: 50
|
| 9 |
+
val_tolerance: 1.0e-4
|
| 10 |
+
max_epochs: 10
|
| 11 |
+
algorithm: transe
|
| 12 |
+
leiden_resolution: 2.0e-5
|
| 13 |
+
loader_hpars:
|
| 14 |
+
dataset_name: nell
|
| 15 |
+
simulated: false
|
| 16 |
+
sample_source: smore
|
| 17 |
+
sampler_hpars:
|
| 18 |
+
num_negative_samples: 128
|
| 19 |
+
num_neighbours: 10
|
| 20 |
+
random_walk_length: 10
|
| 21 |
+
context_radius: 2
|
| 22 |
+
pagerank_importances: true
|
| 23 |
+
walks_relation_specific: true
|
| 24 |
+
embedder_hpars:
|
| 25 |
+
embedding_dim: 100
|
| 26 |
+
link_ranker_hpars:
|
| 27 |
+
algorithm: transe
|
| 28 |
+
embedding_loss_hpars:
|
| 29 |
+
margin: 1.0
|
| 30 |
+
rotate_alpha: 0.5
|
src/research/COINs-KGGeneration/graph_completion/configs/nell_betae.yml
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
seed: 123456789
|
| 2 |
+
device: cuda:0
|
| 3 |
+
val_size: 0.01
|
| 4 |
+
test_size: 0.02
|
| 5 |
+
mini_batch_size: 512
|
| 6 |
+
lr: 1.0e-4
|
| 7 |
+
weight_decay: 1.0e-6
|
| 8 |
+
val_patience: 50
|
| 9 |
+
val_tolerance: 1.0e-4
|
| 10 |
+
max_epochs: 120
|
| 11 |
+
validation_freq: 12
|
| 12 |
+
checkpoint_freq: 12000
|
| 13 |
+
algorithm: betae
|
| 14 |
+
leiden_resolution: 2.0e-5
|
| 15 |
+
loader_hpars:
|
| 16 |
+
dataset_name: nell
|
| 17 |
+
simulated: false
|
| 18 |
+
sample_source: smore
|
| 19 |
+
sampler_hpars:
|
| 20 |
+
query_structure:
|
| 21 |
+
- 1p
|
| 22 |
+
- 2p
|
| 23 |
+
- 3p
|
| 24 |
+
- 2i
|
| 25 |
+
- 3i
|
| 26 |
+
- 2i1p
|
| 27 |
+
- 1p2i
|
| 28 |
+
- 2d
|
| 29 |
+
- 3d
|
| 30 |
+
- 2d1p
|
| 31 |
+
- 1p2b
|
| 32 |
+
- 1p2d
|
| 33 |
+
num_negative_samples: 128
|
| 34 |
+
num_neighbours: 10
|
| 35 |
+
random_walk_length: 10
|
| 36 |
+
context_radius: 2
|
| 37 |
+
pagerank_importances: true
|
| 38 |
+
walks_relation_specific: true
|
| 39 |
+
embedder_hpars:
|
| 40 |
+
embedding_dim: 400
|
| 41 |
+
link_ranker_hpars:
|
| 42 |
+
algorithm: betae
|
| 43 |
+
embedding_loss_hpars:
|
| 44 |
+
margin: 60.0
|