示例#1
0
def load():
    import medspacy
    nlp = medspacy.load(enable=["sentencizer", "tokenizer"])

    # Add components
    from medspacy.target_matcher import TargetMatcher, TargetRule
    target_matcher = TargetMatcher(nlp)
    target_filepath = path.join(RESOURCES_DIR, "target_rules.json")
    target_rules = TargetRule.from_json(target_filepath)
    target_matcher.add(target_rules)
    nlp.add_pipe(target_matcher)

    from medspacy.context import ConTextComponent, ConTextRule
    context_filepath = path.join(RESOURCES_DIR, "context_rules.json")
    context = ConTextComponent(nlp, rules=None, add_attrs=CONTEXT_ATTRS)
    context_rules = ConTextRule.from_json(context_filepath)
    context.add(context_rules)
    nlp.add_pipe(context)

    from medspacy.section_detection import Sectionizer
    # TODO: Add radiology section rules
    sectionizer = Sectionizer(nlp)
    nlp.add_pipe(sectionizer)

    clf = DocumentClassifier(nlp)
    nlp.add_pipe(clf)

    return nlp
 def test_item_modifier_termination(self):
     context = ConTextComponent(nlp, rules=None, terminations=None)
     item = ConTextItem("no evidence of",
                        "NEGATED_EXISTENCE",
                        "FORWARD",
                        terminated_by={"POSITIVE_EXISTENCE", "UNCERTAIN"})
     context.add([item])
     assert item.terminated_by == {"POSITIVE_EXISTENCE", "UNCERTAIN"}
 def test_null_modifier_termination(self):
     context = ConTextComponent(nlp, rules=None, terminations=None)
     item = ConTextItem("no evidence of",
                        "NEGATED_EXISTENCE",
                        "FORWARD",
                        terminated_by=None)
     context.add([item])
     assert item.terminated_by == set()
 def test_rule_modifier_termination(self):
     context = ConTextComponent(nlp, rules=None, terminations=None)
     rule = ConTextRule("no evidence of",
                        "NEGATED_EXISTENCE",
                        "FORWARD",
                        terminated_by={"POSITIVE_EXISTENCE", "UNCERTAIN"})
     context.add([rule])
     assert rule.terminated_by == {"POSITIVE_EXISTENCE", "UNCERTAIN"}
    def test_is_historical(self):
        doc = nlp("History of pneumonia.")
        context = ConTextComponent(nlp, add_attrs=True, rules=None)
        item_data = [ConTextItem("history of", "HISTORICAL", rule="forward")]
        context.add(item_data)
        doc.ents = (doc[-2:-1], )
        context(doc)

        assert doc.ents[0]._.is_historical is True
    def test_is_historical(self):
        doc = nlp("History of pneumonia.")
        context = ConTextComponent(nlp, add_attrs=True, rules=None)
        rules = [ConTextRule("history of", "HISTORICAL", direction="forward")]
        context.add(rules)
        doc.ents = (doc[-2:-1], )
        context(doc)

        assert doc.ents[0]._.is_historical is True
    def test_is_family(self):
        doc = nlp("Family history of breast cancer.")
        context = ConTextComponent(nlp, add_attrs=True, rules=None)
        item_data = [
            ConTextItem("family history of", "FAMILY", rule="forward")
        ]
        context.add(item_data)
        doc.ents = (doc[-3:-1], )
        context(doc)

        assert doc.ents[0]._.is_family is True
    def test_is_negated(self):
        doc = nlp("There is no evidence of pneumonia.")
        context = ConTextComponent(nlp, add_attrs=True, rules=None)
        item_data = [
            ConTextItem("no evidence of", "NEGATED_EXISTENCE", rule="forward")
        ]
        context.add(item_data)
        doc.ents = (doc[-2:-1], )
        context(doc)

        assert doc.ents[0]._.is_negated is True
    def test_is_family(self):
        doc = nlp("Family history of breast cancer.")
        context = ConTextComponent(nlp, add_attrs=True, rules=None)
        rules = [
            ConTextRule("family history of", "FAMILY", direction="forward")
        ]
        context.add(rules)
        doc.ents = (doc[-3:-1], )
        context(doc)

        assert doc.ents[0]._.is_family is True
示例#10
0
 def test_global_allowed_types2(self):
     """Check that if the ConTextComponent does not have allowed_types defined
     and a ConTextItem does, the ConTextItem will not receive the component's
     value.
     """
     context = ConTextComponent(nlp, rules=None, allowed_types=None)
     item = ConTextItem("no evidence of",
                        "NEGATED_EXISTENCE",
                        "FORWARD",
                        allowed_types={"PROBLEM"})
     context.add([item])
     assert item.allowed_types == {"PROBLEM"}
 def test_global_allowed_types1(self):
     """Check that if the ConTextComponent has allowed_types defined
     and a ConTextRule does not, the ConTextRule will receive the component's
     value.
     """
     context = ConTextComponent(nlp, rules=None, allowed_types={"PROBLEM"})
     rule = ConTextRule("no evidence of",
                        "NEGATED_EXISTENCE",
                        "FORWARD",
                        allowed_types=None)
     context.add([rule])
     assert rule.allowed_types == {"PROBLEM"}
示例#12
0
    def test_terminate_stops_forward_modifier(self):
        context = ConTextComponent(nlp, rules=None)

        item = ConTextItem("no evidence of", "NEGATED_EXISTENCE", "FORWARD")
        item2 = ConTextItem("but", "TERMINATE", "TERMINATE")
        context.add([item, item2])
        doc = nlp("No evidence of chf but she has pneumonia.")
        doc.ents = (Span(doc, 3, 4, "PROBLEM"), Span(doc, 7, 8, "PROBLEM"))
        context(doc)
        chf, pneumonia = doc.ents
        assert len(chf._.modifiers) > 0
        assert len(pneumonia._.modifiers) == 0
示例#13
0
    def test_terminate_stops_backward_modifier(self):
        context = ConTextComponent(nlp, rules=None)

        item = ConTextItem("is ruled out", "NEGATED_EXISTENCE", "BACKWARD")
        item2 = ConTextItem("but", "CONJ", "TERMINATE")
        context.add([item, item2])
        doc = nlp("Pt has chf but pneumonia is ruled out")
        doc.ents = (Span(doc, 2, 3, "PROBLEM"), Span(doc, 4, 5, "PROBLEM"))
        context(doc)
        chf, pneumonia = doc.ents
        assert len(chf._.modifiers) == 0
        assert len(pneumonia._.modifiers) > 0
    def test_regex_pattern(self):
        rules = [
            ConTextRule("no history of",
                        "NEGATED_EXISTENCE",
                        direction="FORWARD",
                        pattern="no (history|hx) of"),
        ]
        context = ConTextComponent(nlp, rules=None)
        context.add(rules)

        doc = nlp("No history of afib. No hx of MI.")
        context(doc)
        assert len(doc._.context_graph.modifiers) == 2
 def test_global_allowed_types2(self):
     """Check that if both the ConTextComponent and a ConTextRule have allowed_types defined,
     the ConTextRule will not receive the component's value.
     """
     context = ConTextComponent(nlp,
                                rules=None,
                                allowed_types={"TREATMENT"})
     rule = ConTextRule("no evidence of",
                        "NEGATED_EXISTENCE",
                        "FORWARD",
                        allowed_types={"PROBLEM"})
     context.add([rule])
     assert rule.allowed_types == {"PROBLEM"}
示例#16
0
    def test_is_negated(self):
        doc = nlp("There is no evidence of pneumonia.")
        context = ConTextComponent(nlp, add_attrs=True, rules=None)
        rules = [
            ConTextRule("no evidence of",
                        "NEGATED_EXISTENCE",
                        direction="forward")
        ]
        context.add(rules)
        doc.ents = (Span(doc, 5, 6, "CONDITION"), )
        context(doc)

        assert doc.ents[0]._.is_negated is True
示例#17
0
    def test_prune_false(self):
        rules = [
            ConTextRule("history of", "HISTORICAL", direction="FORWARD"),
            ConTextRule("no history of",
                        "NEGATED_EXISTENCE",
                        direction="FORWARD"),
        ]
        context = ConTextComponent(nlp, rules=None, prune=False)
        context.add(rules)

        doc = nlp("No history of afib.")
        context(doc)

        assert len(doc._.context_graph.modifiers) == 2
示例#18
0
    def test_on_modifies_false(self):
        def on_modifies(target, modifier, span_between):
            return False

        context = ConTextComponent(nlp, rules=None)
        item = ConTextItem("no evidence of",
                           "NEGATED_EXISTENCE",
                           on_modifies=on_modifies)
        context.add([item])
        doc = nlp("There is no evidence of pneumonia or chf.")
        doc.ents = (doc[5:6], doc[7:8])
        context(doc)

        for ent in doc.ents:
            assert len(ent._.modifiers) == 0
示例#19
0
 def test_custom_patterns_json(self):
     """Test that rules are loaded from a json"""
     context = ConTextComponent(
         nlp,
         rules="other",
         rule_list=os.path.abspath("resources/context_rules.json"))
     assert context.item_data
示例#20
0
    def test_custom_terminate_stops_forward_modifier(self):
        doc = nlp("negative for flu, positive for pneumonia.")
        context = ConTextComponent(nlp, rules=None)

        item = ConTextItem("negative for",
                           "NEGATED_EXISTENCE",
                           rule="FORWARD",
                           terminated_by={"POSITIVE_EXISTENCE"})
        item2 = ConTextItem("positive for",
                            "POSITIVE_EXISTENCE",
                            rule="FORWARD")
        context.add([item, item2])
        doc.ents = (Span(doc, 2, 3, "PROBLEM"), Span(doc, 6, 7))
        flu, pneumonia = doc.ents
        context(doc)
        assert len(flu._.modifiers) == 1
        assert len(pneumonia._.modifiers) == 1
示例#21
0
 def test_registers_attributes(self):
     """Test that the default ConText attributes are set on ."""
     doc = nlp("There is consolidation.")
     doc.ents = (doc[-2:-1], )
     context = ConTextComponent(nlp)
     doc = context(doc)
     assert hasattr(doc._, "context_graph")
     assert hasattr(doc.ents[0]._, "modifiers")
示例#22
0
    def test_pseudo_modifier(self):
        rules = [
            ConTextRule("negative", "NEGATED_EXISTENCE"),
            ConTextRule("negative attitude",
                        "PSEUDO_NEGATED_EXISTENCE",
                        direction="PSEUDO"),
        ]
        context = ConTextComponent(nlp, rules=None)
        context.add(rules)

        doc = nlp("She has a negative attitude about her treatment.")
        doc.ents = (Span(doc, 7, 8, "CONDITION"), )
        context(doc)

        assert len(doc.ents[0]._.modifiers) == 0
        assert len(doc._.context_graph.modifiers) == 1
        assert doc._.context_graph.modifiers[
            0].category == "PSEUDO_NEGATED_EXISTENCE"
示例#23
0
 def test_context_window_no_max_scope_fails(self):
     "Test that if use_context_window is True but max_scope is None, the instantiation will fail"
     with pytest.raises(ValueError) as exception_info:
         context = ConTextComponent(nlp,
                                    max_scope=None,
                                    use_context_window=True)
     exception_info.match(
         "If 'use_context_window' is True, 'max_scope' must be an integer greater 1, not None"
     )
示例#24
0
    def test_pseudo_modifier(self):
        item_data = [
            ConTextItem("negative", "NEGATED_EXISTENCE"),
            ConTextItem("negative attitude",
                        "PSEUDO_NEGATED_EXISTENCE",
                        rule="PSEUDO"),
        ]
        context = ConTextComponent(nlp, rules=None)
        context.add(item_data)

        doc = nlp("She has a negative attitude about her treatment.")
        doc.ents = (doc[-2:-1], )
        context(doc)

        assert len(doc.ents[0]._.modifiers) == 0
        assert len(doc._.context_graph.modifiers) == 1
        assert doc._.context_graph.modifiers[
            0].category == "PSEUDO_NEGATED_EXISTENCE"
示例#25
0
    def test_custom_attributes_value1(self):
        custom_attrs = {
            "NEGATED_EXISTENCE": {
                "is_negated": True
            },
        }
        try:
            Span.set_extension("is_negated", default=False)
        except:
            pass
        context = ConTextComponent(nlp, add_attrs=custom_attrs)
        context.add(
            [ConTextItem("no evidence of", "NEGATED_EXISTENCE", "FORWARD")])
        doc = nlp("There is no evidence of pneumonia.")
        doc.ents = (doc[-2:-1], )
        context(doc)

        assert doc.ents[0]._.is_negated is True
示例#26
0
 def test_custom_patterns_json(self):
     """Test that rules are loaded from a json"""
     if os.path.exists("./resources/context_rules.json"):
         filepath = "./resources/context_rules.json"
     else:
         filepath = "../../resources/context_rules.json"
     context = ConTextComponent(nlp,
                                rules="other",
                                rule_list=os.path.abspath(filepath))
     assert context.rules
示例#27
0
 def test_custom_attribute_error(self):
     """Test that a custom spacy attribute which has not been set
     will throw a ValueError.
     """
     custom_attrs = {
         "FAKE_MODIFIER": {
             "non_existent_attribute": True
         },
     }
     with pytest.raises(ValueError):
         ConTextComponent(nlp, add_attrs=custom_attrs)
    def test_custom_attributes_value2(self):
        custom_attrs = {
            "FAMILY": {
                "is_family": True
            },
        }
        try:
            Span.set_extension("is_family", default=False)
        except:
            pass
        context = ConTextComponent(nlp, add_attrs=custom_attrs)
        context.add([
            ConTextRule("no evidence of", "DEFINITE_NEGATED_EXISTENCE",
                        "FORWARD")
        ])
        doc = nlp("There is no evidence of pneumonia.")
        doc.ents = (doc[-2:-1], )
        context(doc)

        assert doc.ents[0]._.is_family is False
示例#29
0
 def test_custom_attributes_mapping(self):
     custom_attrs = {
         "NEGATED_EXISTENCE": {
             "is_negated": True
         },
     }
     try:
         Span.set_extension("is_negated", default=False)
     except:
         pass
     context = ConTextComponent(nlp, add_attrs=custom_attrs)
     assert context.context_attributes_mapping == custom_attrs
示例#30
0
    def test_simple_callback(self, capsys):
        context = ConTextComponent(nlp, rules=None)

        def simple_callback(matcher, doc, i, matches):
            match_id, start, end = matches[i]
            span = doc[start:end]
            print("Matched on span:", span)

        context.add([
            ConTextItem(
                "no evidence of",
                "NEGATED_EXISTENCE",
                "FORWARD",
                on_match=simple_callback,
            )
        ])

        doc = nlp("There is no evidence of pneumonia.")
        context(doc)
        captured = capsys.readouterr()
        assert captured.out == "Matched on span: no evidence of\n"