This is following on from our discussion in #48.
First off, I think the default CLI should be a very simple wrapper for the Evaluate class, so it doesn't need to be much more complicated than (note I didn't test any of this):
./nervaluate/cli.py:
import typer
from nervaluate import Evaluator
app = typer.Typer()
app.command()
def evaluate(
true_path: str = typer.Argument(help="Path to true entity labels"),
pred_path: str = typer.Argument(help="Path to predicted entity labels"),
tags: str = typer.Argument(
None, help="Comma separated list of tags to include in the evaluation"
),
loader: str = typer.Option(
None,
help="Optional loader when not using prodigy style spans. One of [list, conll]",
),
by_tag: bool = typer.Option(
None,
help="If set, will return tag level results instead of aggregated results.",
),
pretty: bool = typer.Option(
None,
help="If set, will print the results in a pretty format instead of returning the raw json",
),
):
tags_list = tags.split(",")
evaluator = Evaluator(true_path, pred_path, tags=tags_list, loader=loader)
results, results_by_tag = evaluator.evaluate()
if by_tag:
output = results_by_tag
else:
output = results
if pretty:
pass
# Some code from wasabi to print a pretty table https://pypi.org/project/wasabi/
else:
return output
if __name__ == "__main__":
app()
For handling predictions directly from a spacy/prodigy model, I think we should implement a typer command that does what @Eleni170 implemented in f2841e2. So it would be something like:
@app.command()
def predict(
model_path: str=typer.Argument(help="Path to spaCy model"),
data_path: str=typer.Argument(
help="Path to data in prodigy format (including the raw text)"
),
by_tag: bool = typer.Option(
None,
help="If set, will return tag level results instead of aggregated results.",
),
pretty: bool = typer.Option(
None,
help="If set, will print the results in a pretty format instead of returning the raw json",
),
):
spacy_model = spacy.load(model_path)
true = []
pred = []
tags = {}
with open(data_path) as f:
for line in f:
pattern = json.loads(line)
text = pattern["text"]
meta = pattern["meta"]
labels = check_labels(meta)
for label in labels:
tags[label] = ''
true.append(meta)
doc = spacy_model(text)
pred.append(create_prodigy_spans(doc))
# Maybe we want also to pass tags to the CLI as above but default to all tags as below if nothing is passed.
evaluator = Evaluator(true, pred, tags=list(tags.keys()))
global_results, aggregation_results = evaluator.evaluate()
# Similar logic as above to print results to console either as raw json or pretty printed.
Let me know what you think! @Eleni170 @nsorros
This is following on from our discussion in #48.
First off, I think the default CLI should be a very simple wrapper for the Evaluate class, so it doesn't need to be much more complicated than (note I didn't test any of this):
./nervaluate/cli.py:
For handling predictions directly from a spacy/prodigy model, I think we should implement a typer command that does what @Eleni170 implemented in f2841e2. So it would be something like:
Let me know what you think! @Eleni170 @nsorros