| | import sys; |
| |
|
| | import score.core; |
| | from smatch.smatch import get_amr_match; |
| | |
| | def tuples(graph, prefix, values, faith = True): |
| | |
| | |
| | |
| | id = 0; |
| | mapping = dict(); |
| | instances = []; |
| | relations = []; |
| | attributes = []; |
| | n = 0; |
| | for node in graph.nodes: |
| | mapping[node.id] = name = prefix + str(id); |
| | id += 1; |
| | if "anchors" in values and node.anchors is not None: |
| | anchor = score.core.anchor(node); |
| | if graph.input: anchor = score.core.explode(graph.input, anchor); |
| | attributes.append(("anchor", name, str(anchor))); |
| | if "labels" in values and node.label is not None: |
| | instance = node.label; |
| | else: |
| | instance = "__()_{}__".format(prefix, n); |
| | n += 1; |
| | instances.append(("instance", name, instance)); |
| | if "tops" in values and node.is_top: |
| | |
| | |
| | |
| | |
| | |
| | attributes.append(("TOP", name, |
| | node.label if node.label and faith else "")); |
| | if "properties" in values and node.properties and node.values: |
| | for property, value in zip(node.properties, node.values): |
| | attributes.append((property, name, value)); |
| | for edge in graph.edges: |
| | if "edges" in values: |
| | relations.append((edge.lab, mapping[edge.src], mapping[edge.tgt])); |
| | if "attributes" in values: |
| | if edge.attributes and edge.values: |
| | for attribute, value in zip(edge.attributes, edge.values): |
| | relations.append((str((attribute, value)), |
| | mapping[edge.src], mapping[edge.tgt])); |
| | return instances, attributes, relations, n; |
| | |
| | def smatch(gold, system, limit = 20, values = {}, trace = 0, faith = True): |
| | gprefix = "g"; sprefix = "s"; |
| | ginstances, gattributes, grelations, gn \ |
| | = tuples(gold, gprefix, values, faith); |
| | sinstances, sattributes, srelations, sn \ |
| | = tuples(system, sprefix, values, faith); |
| | if trace > 1: |
| | print("gold instances [{}]: {}\ngold attributes [{}]: {}\n" |
| | "gold relations [{}]: {}" |
| | "".format(len(ginstances), ginstances, |
| | len(gattributes), gattributes, |
| | len(grelations), grelations), |
| | file = sys.stderr); |
| | print("system instances [{}]: {}\nsystem attributes [{}]: {}\n" |
| | "system relations [{}]: {}" |
| | "".format(len(sinstances), sinstances, |
| | len(sattributes), sattributes, |
| | len(srelations), srelations), |
| | file = sys.stderr); |
| | correct, gold, system, mapping \ |
| | = get_amr_match(None, None, gold.id, limit = limit, |
| | instance1 = ginstances, attributes1 = gattributes, |
| | relation1 = grelations, prefix1 = gprefix, |
| | instance2 = sinstances, attributes2 = sattributes, |
| | relation2 = srelations, prefix2 = sprefix); |
| | return correct, gold - gn, system - sn, mapping; |
| | |
| | def evaluate(golds, systems, format = "json", limit = 20, |
| | values = {}, trace = 0): |
| | if limit is None or not limit > 0: limit = 20; |
| | if trace > 1: print("RRHC limit: {}".format(limit), file = sys.stderr); |
| | tg = ts = tc = n = 0; |
| | scores = dict() if trace else None; |
| | for gold, system in score.core.intersect(golds, systems): |
| | id = gold.id; |
| | correct, gold, system, mapping \ |
| | = smatch(gold, system, limit, values, trace); |
| | tg += gold; ts += system; tc += correct; |
| | n += 1; |
| | if trace: |
| | if id in scores: |
| | print("smatch.evaluate(): duplicate graph identifier: {}" |
| | "".format(id), file = sys.stderr); |
| | scores[id] = {"g": gold, "s": system, "c": correct}; |
| | if trace > 1: |
| | p, r, f = score.core.fscore(gold, system, correct); |
| | print("G: {}; S: {}; C: {}; P: {}; R: {}; F: {}" |
| | "".format(gold, system, correct, p, r, f), file = sys.stderr); |
| | |
| | p, r, f = score.core.fscore(tg, ts, tc); |
| | result = {"n": n, "g": tg, "s": ts, "c": tc, "p": p, "r": r, "f": f}; |
| | if trace: result["scores"] = scores; |
| | return result; |
| |
|