Example #1
0
    def backward(self, oia_graph: OIAGraph, ** kwargs):
        """

        @param oia_graph:
        @type oia_graph:
        @param kwargs:
        @type kwargs:
        @return:
        @rtype:
        """

        fixed = False
        for node in list(oia_graph.nodes()):
            if not is_conjunction_without_args(node, oia_graph):
                continue

            relations = [(n, l.label) for n, l in oia_graph.children(node)]

            relations = list(filter(lambda x: x[1].startswith("pred.arg."), relations))

            if not relations:
                continue

            if any(len(list(oia_graph.children(child))) for child, rel in relations):
                # child nodes also has child, not merge
                continue

            merged_words = sum([list(child.words()) for child, rel in relations], [])
            start = min([x for x in merged_words if isinstance(x, int)])
            end = max([x for x in merged_words if isinstance(x, int)])
            new_node = oia_graph.add_spans([(start, end)])

            fixed = True
            for child, rel in relations:
                oia_graph.remove_node(child)

            oia_graph.replace(node, new_node)

            logger.debug("Merging {0} to {1}".format("|".join(oia_graph.node_text(child)
                                                              for child, rel in relations),
                                                     oia_graph.node_text(new_node)))

        return fixed
def graph_match_metric(pred_graph: OIAGraph, truth_graph: OIAGraph):
    """

    :param predict:
    :param truth:
    :return:
    """

    pred_nodes = [pred_graph.node_text(n) for n in pred_graph.nodes()]
    true_nodes = [truth_graph.node_text(n) for n in truth_graph.nodes()]

    node_true_num = len(true_nodes)
    node_pred_num = len(pred_nodes)

    node_match_num = sum(node in true_nodes for node in pred_nodes)

    pred_edges = [(pred_graph.node_text(n1), edge.label.strip("\" "),
                   pred_graph.node_text(n2))
                  for n1, edge, n2 in pred_graph.edges()]
    true_edges = [(truth_graph.node_text(n1), edge.label.strip("\" "),
                   truth_graph.node_text(n2))
                  for n1, edge, n2 in truth_graph.edges()]

    logger.debug(pred_edges)
    logger.debug(true_edges)

    edge_true_num = len(true_edges)
    edge_pred_num = len(pred_edges)

    edge_match_num = sum(edge in true_edges for edge in pred_edges)

    exact_same = node_match_num == node_true_num == node_pred_num and \
                 edge_match_num == edge_true_num == edge_pred_num

    return (node_pred_num, node_true_num, node_match_num), \
           (edge_pred_num, edge_true_num, edge_match_num), exact_same
    def forward(self, oia_graph: OIAGraph, **kwargs):
        """
        split the noun phrase with of in it
        According to the previous merge operation,
        if there is any modification to the part after the of, the noun phrase will be not merged.
        So the noun phrases with of do not have any modification to the second part.
        @param oia_graph:
        @type oia_graph:
        @param kwargs:
        @type kwargs:
        @return:
        @rtype:
        """

        for node in list(oia_graph.nodes()):

            node_words = oia_graph.node_text(node).split(" ")
            try:
                index = node_words.index("of")
            except Exception as e:
                continue

            if len(node_words) == 1:  # that is of
                continue

            of_split_words = []
            current_words = []
            for span in node.spans:
                if isinstance(span, str):
                    current_words.append(span)
                else:
                    start, end = span
                    for idx in range(start, end + 1):
                        if oia_graph.words[idx] == "of":
                            of_split_words.append(current_words)
                            of_split_words.append(idx)
                            current_words = []
                        else:
                            current_words.append(idx)

            if not current_words:
                # of is the ending, warning, maybe something like "because of "
                logger.warning("We found a of at the last of the phrase: " +
                               oia_graph.node_text(node))
                continue

            of_split_words.append(current_words)

            first_part_words = of_split_words[0]
            first_node = oia_graph.add_words(first_part_words)
            previous_node = first_node

            for p, l in list(oia_graph.parents(node)):
                oia_graph.add_relation(p, first_node, l.label)
                oia_graph.remove_relation(p, node)

            children = list(oia_graph.children(node))
            if children:
                logger.warning(
                    "noun of noun has {0} children, be careful!!!".format(
                        len(children)))
                for c, l in children:
                    logger.warning("Child: {} {}".format(
                        l.label, oia_graph.node_text(c)))
                    oia_graph.add_relation(first_node, c, l.label)
                    oia_graph.remove_relation(node, c)

            oia_graph.remove_node(node)

            for of_word, noun_words in more_itertools.chunked(
                    of_split_words[1:], 2):
                of_node = oia_graph.add_words([of_word])
                next_node = oia_graph.add_words(noun_words)

                oia_graph.add_relation(previous_node, of_node, "as:pred.arg.1")
                oia_graph.add_relation(of_node, next_node, "pred.arg.2")
                previous_node = next_node
Example #4
0
    def forward(self, oia_graph: OIAGraph, dep_graph: DependencyGraph=None, **kwargs):
        """
        note that this only process the situation that
        @param oia_graph:
        @type oia_graph:
        @param kwargs:
        @type kwargs:
        @return:
        @rtype:
        """

        for node in list(oia_graph.nodes()):

            node_words = oia_graph.node_text(node).split(" ")

            if not any([x in {"and", "or"} for x in node_words]):
                continue

            if any(["{" in x and "}" in x for x in node_words]):
                continue

            arguments = []
            conjs = []
            current_words = []

            for span in node.spans:
                if isinstance(span, str):
                    current_words.append(span)
                else:
                    start, end = span
                    for idx in range(start, end + 1):
                        if oia_graph.words[idx].lower() in {"and", "or"}:
                            arguments.append(current_words)
                            conjs.append(idx)
                            current_words = []
                        else:
                            current_words.append(idx)

            arguments.append(current_words)

            logger.debug("conj found = {}".format(conjs))
            logger.debug("argument found = {}".format(arguments))

            if all(not arg or all(oia_graph.words[x] in {",", ";", ".", " "} for x in arg) for arg in arguments):  # single words
                continue

            if len(conjs) == 1:
                conj_words = conjs

            else: # len(conjs) >= 2:
                logger.warning("We are processing conjs with more than two args")
                conj_words = ['{1}']
                for idx, conj in enumerate(conjs):
                    conj_words.append(conj)
                    conj_words.append("{{{0}}}".format(idx + 2))

            conj_node = oia_graph.add_words(conj_words)


            for idx, arg in enumerate(arguments):
                arg_node = oia_graph.add_words(arg)
                oia_graph.add_relation(conj_node, arg_node, "pred.arg.{0}".format(idx + 1))


            for p, l in list(oia_graph.parents(node)):
                oia_graph.add_relation(p, conj_node, l.label)
                oia_graph.remove_relation(p, node)

            for c, l in list(oia_graph.children(node)):
                oia_graph.add_relation(conj_node, c, l.label)
                oia_graph.remove_relation(node, c)

            oia_graph.remove_node(node)