-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' of https://github.com/OpenBioLink/SAFRAN
- Loading branch information
Showing
7 changed files
with
366 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
Evaluate predictions | ||
==================== | ||
|
||
Following scripts can be found in the `python` folder. | ||
|
||
Evaluate a single prediction file | ||
--------------------------------- | ||
|
||
Use this script to evaluate a single prediction file. | ||
|
||
Script name: eval.py | ||
|
||
**Requires:** | ||
|
||
.. code:: bash | ||
pip install scipy tqdm | ||
**Usage:** | ||
|
||
.. code:: bash | ||
python eval.py {path to file containing predictions} {path to testset file} | ||
**Example output:** | ||
|
||
:: | ||
|
||
MRR: 0.389 | ||
Hits@1: 0.298 | ||
Hits@3: 0.371 | ||
Hits@10: 0.537 | ||
|
||
Evaluate an experiment | ||
---------------------- | ||
|
||
Use this script if you want to evaluate multiple datasets containing multiple prediction files at once (Multiple datasets -> Multiple prediction files). | ||
|
||
Script name: eval_experiment.py | ||
|
||
**Requires:** | ||
|
||
.. code:: bash | ||
pip install scipy tqdm | ||
.. _usage-1: | ||
|
||
**Usage:** | ||
|
||
.. code:: bash | ||
python eval_experiment.py --datasets {list of datasets} --predictions {list of prediction file names} | ||
**File structure:** | ||
|
||
Each dataset should have its own folder. Evaluations are run | ||
|
||
:: | ||
|
||
for each {dataset} in {list of datasets}: | ||
for each {prediction file name} in {list of prediction file name}: | ||
Path to prediction file: f”./{dataset}/predictions/{prediction file name}” | ||
Path to testset file: f”./{dataset}/data/test.txt” | ||
|
||
Example: | ||
|
||
.. code:: bash | ||
python eval_experiment.py --datasets OBL WN18RR --predictions predfile1.txt predfile2.txt | ||
.. code:: text | ||
---- OBL | ||
| | ||
---- predictions | ||
| | ||
---- predfile1.txt | ||
| | ||
---- predfile2.txt | ||
| | ||
---- data | ||
| | ||
---- test.txt | ||
---- WN18RR | ||
| | ||
---- predictions | ||
| | ||
---- predfile1.txt | ||
| | ||
---- predfile2.txt | ||
| | ||
---- data | ||
| | ||
---- test.txt | ||
Output: | ||
|
||
:: | ||
|
||
OBL | ||
predfile1.txt MRR: 0.389 Hits@1: 0.298 Hits@3: 0.371 Hits@10: 0.537 | ||
predfile2.txt MRR: 0.389 Hits@1: 0.298 Hits@3: 0.371 Hits@10: 0.537 | ||
WN18RR | ||
predfile1.txt MRR: 0.389 Hits@1: 0.298 Hits@3: 0.371 Hits@10: 0.537 | ||
predfile2.txt MRR: 0.389 Hits@1: 0.298 Hits@3: 0.371 Hits@10: 0.537 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
|
||
## eval.py | ||
|
||
Script used to evaluate a single prediction file. | ||
|
||
##### Requires: | ||
|
||
``` | ||
pip install scipy tqdm | ||
``` | ||
|
||
##### Usage: | ||
|
||
```bash | ||
python eval.py {path to file containing predictions} {path to testset file} | ||
``` | ||
|
||
##### Example output: | ||
|
||
``` | ||
MRR: 0.389 | ||
Hits@1: 0.298 | ||
Hits@3: 0.371 | ||
Hits@10: 0.537 | ||
``` | ||
|
||
## eval_experiment.py | ||
|
||
Script used to evaluate a experiment (Multiple datasets -> Multiple prediction files) | ||
|
||
##### Requires: | ||
|
||
``` | ||
pip install scipy tqdm | ||
``` | ||
|
||
##### Usage: | ||
|
||
```bash | ||
python eval_experiment.py --datasets {list of datasets} --predictions {list of prediction file names} | ||
``` | ||
|
||
**File structure:** | ||
|
||
Each dataset should have its own folder. Evaluations are run | ||
|
||
```text | ||
for each {dataset} in {list of datasets}: | ||
for each {prediction file name} in {list of prediction file name}: | ||
Path to prediction file: f”./{dataset}/predictions/{prediction file name}” | ||
Path to testset file: f”./{dataset}/data/test.txt” | ||
``` | ||
|
||
Example: | ||
|
||
```bash | ||
python eval_experiment.py --datasets OBL WN18RR --predictions predfile1.txt predfile2.txt | ||
``` | ||
|
||
```text | ||
---- OBL | ||
| | ||
---- predictions | ||
| | ||
---- predfile1.txt | ||
| | ||
---- predfile2.txt | ||
| | ||
---- data | ||
| | ||
---- test.txt | ||
---- WN18RR | ||
| | ||
---- predictions | ||
| | ||
---- predfile1.txt | ||
| | ||
---- predfile2.txt | ||
| | ||
---- data | ||
| | ||
---- test.txt | ||
``` | ||
|
||
## amie_2_anyburl.py | ||
|
||
Converts rules learned by AMIE+ to the format of AnyBURL rules | ||
|
||
**Usage:** | ||
|
||
``` | ||
python amie_2_anyburl.py --from {path to amie rulefile} --to {path to file storing transformed rules, will be created} | ||
``` | ||
|
||
Optionally the flag `--pca` can be set to use pca confidence instead of std confidence. | ||
|
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import os | ||
import math | ||
from scipy.stats import rankdata | ||
from tqdm import tqdm | ||
import sys | ||
|
||
def read_predictions(path): | ||
with open(path, encoding="utf8") as infile: | ||
while True: | ||
triple = infile.readline().strip().split(" ") | ||
if not triple or triple[0] == "": | ||
break | ||
head,rel,tail = triple | ||
pred_heads = infile.readline().strip()[7:].split("\t") | ||
pred_tails = infile.readline().strip()[7:].split("\t") | ||
|
||
confidences_head = [int(x.replace("0.", "").replace("1.","1").ljust(100, "0")) if (not x.startswith("1.") and not x.startswith("1")) else int("1".ljust(101, "0")) for x in pred_heads[1::2]] | ||
confidences_tail = [int(x.replace("0.", "").replace("1.","1").ljust(100, "0")) if (not x.startswith("1.") and not x.startswith("1")) else int("1".ljust(101, "0")) for x in pred_tails[1::2]] | ||
|
||
yield (head, pred_heads[0::2], confidences_head) | ||
yield (tail, pred_tails[0::2], confidences_tail) | ||
|
||
|
||
def get_n_test(path): | ||
content = None | ||
with open(path, encoding="utf8") as infile: | ||
content = infile.readlines() | ||
content = [x.strip() for x in content] | ||
return len(content) | ||
|
||
|
||
def evaluate_policy(path_predictions, n, policy): | ||
hits1 = 0 | ||
hits3 = 0 | ||
hits10 = 0 | ||
mrr = 0.0 | ||
mr = 0 | ||
|
||
for true_entity, prediction, conf in read_predictions(path_predictions): | ||
ranking = rankdata([-x for x in conf], method=policy) | ||
try: | ||
idx = prediction.index(true_entity) | ||
rank = ranking[idx] | ||
|
||
if rank == 1.: | ||
hits1 = hits1 + 1 | ||
if rank <= 3.: | ||
hits3 = hits3 + 1 | ||
if rank <= 10.: | ||
hits10 = hits10 + 1 | ||
mrr = mrr + (1 / rank) | ||
except ValueError: | ||
pass | ||
#return hits1/n, hits3/n, hits10/n, mrr/n | ||
return "MRR: %.3f" % (mrr/n), "Hits@1: %.3f" % (hits1/n), "Hits@3: %.3f" % (hits3/n) , "Hits@10: %.3f" % (hits10/n) | ||
|
||
def evaluate(path_predictions, path_test): | ||
n = get_n_test(path_test) * 2 | ||
#["ordinal", "average", "min", "max", "dense"] | ||
result = evaluate_policy(path_predictions, n, "average") | ||
return "\n".join(result) | ||
|
||
|
||
if __name__ == "__main__": | ||
res = evaluate(sys.argv[1], sys.argv[2]) | ||
print(res) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import os | ||
import math | ||
from scipy.stats import rankdata | ||
from tqdm import tqdm | ||
import argparse | ||
|
||
class ArgParser(argparse.ArgumentParser): | ||
def __init__(self): | ||
super(ArgParser, self).__init__() | ||
|
||
self.add_argument('--datasets', type=str, default=[""], nargs='+', | ||
help='a list of datasets') | ||
self.add_argument('--predictions', type=str, default=[""], nargs='+', | ||
help='a list of prediction file names') | ||
|
||
def parse_args(self): | ||
args = super().parse_args() | ||
return args | ||
|
||
def read_predictions(path): | ||
with open(path, encoding="utf8") as infile: | ||
while True: | ||
triple = infile.readline().strip().split(" ") | ||
if not triple or triple[0] == "": | ||
break | ||
head,rel,tail = triple | ||
pred_heads = infile.readline().strip()[7:].split("\t") | ||
pred_tails = infile.readline().strip()[7:].split("\t") | ||
|
||
confidences_head = [int(x.replace("0.", "0").replace("1.","1").ljust(100, "0")) if (not "E" in x) else int(str(float(x)).replace("0.","0").ljust(100, "0")) for x in pred_heads[1::2]] | ||
confidences_tail = [int(x.replace("0.", "").replace("1.","1").ljust(100, "0")) if (not "E" in x) else int(str(float(x)).replace("0.","0").ljust(100, "0")) for x in pred_tails[1::2]] | ||
|
||
yield (head, pred_heads[0::2], confidences_head) | ||
yield (tail, pred_tails[0::2], confidences_tail) | ||
|
||
|
||
def get_n_test(path): | ||
content = None | ||
with open(path, encoding="utf8") as infile: | ||
content = infile.readlines() | ||
content = [x.strip() for x in content] | ||
return len(content) | ||
|
||
|
||
def evaluate_policy(path_predictions, n, policy): | ||
hits1 = 0 | ||
hits3 = 0 | ||
hits10 = 0 | ||
mrr = 0.0 | ||
mr = 0 | ||
|
||
for true_entity, prediction, conf in read_predictions(path_predictions): | ||
ranking = rankdata([-x for x in conf], method=policy) | ||
try: | ||
idx = prediction.index(true_entity) | ||
rank = ranking[idx] | ||
|
||
if rank == 1.: | ||
hits1 = hits1 + 1 | ||
if rank <= 3.: | ||
hits3 = hits3 + 1 | ||
if rank <= 10.: | ||
hits10 = hits10 + 1 | ||
mrr = mrr + (1 / rank) | ||
except ValueError: | ||
pass | ||
return "MRR: %.3f" % (mrr/n), "Hits@1: %.3f" % (hits1/n), "Hits@3: %.3f" % (hits3/n) , "Hits@10: %.3f" % (hits10/n) | ||
|
||
def evaluate(path_predictions, path_test): | ||
n = get_n_test(path_test) * 2 | ||
#["ordinal", "average", "min", "max", "dense"] | ||
result = evaluate_policy(path_predictions, n, "average") | ||
return " ".join(result) | ||
|
||
|
||
if __name__ == "__main__": | ||
args = ArgParser().parse_args() | ||
|
||
for dataset in args.datasets: | ||
print(dataset) | ||
for eval in args.predictions: | ||
|
||
res = evaluate(f"./{dataset}/predictions/{eval}", f"./{dataset}/data/test.txt") | ||
|
||
print(eval.ljust(25) + res) | ||
|
||
print() | ||
|