Аннотировать текст с помощью БИО-схемы с помощью spaCy - PullRequest
0 голосов
/ 25 февраля 2019

Мне нужно аннотировать текстовый корпус с помощью BIO-схемы, основанной на методе правил (у меня есть заранее определенный список токенов и их тегов).Я использую класс spaCy EntityRuler для этой задачи.Мой вопрос заключается в том, существует ли аккуратный и эффективный способ внедрения тегов BIO с помощью spaCy?Кроме того, я изо всех сил пытаюсь внедрить многоточечный тег BIO:

 'He used sodium-bicarb 5 gr' -> 
['O', 'O', 'B-DRUG', 'I-DRUG', 'I-DRUG', 'B-STRENGTH', 'I-STRENGTH')

У меня есть простой (основанный на правилах) скрипт для тегирования сущностей, которые меня интересуют:

import numpy as np
import pandas as pd
import spacy
from spacy.pipeline import EntityRuler

nlp = spacy.load('en')
ruler = EntityRuler(nlp).from_disk('drug_patterns.jsonl')
nlp.add_pipe(ruler, before='ner')


text = 'He has been prescribed ipratropium-albuterol a small dose of 20mg, denzapine and amil-co'
doc = nlp(text)

for ent in doc.ents:
    print(ent.text, ent.start_char, ent.end_char, ent.label_)

Вывод:

ipratropium 23 34 DRUG
20mg 61 65 STRENGTH
denzapine 67 76 DRUG
amil-co 81 88 DRUG

Итак, я не уверен, как разбить 'amil-co' на три тега 'B-DRUG, I-DRUG and I-DRUG'.

В идеале, я хотел бы получить следующую аннотацию:

    token          BIO
0   He             O
1   has            O
2   been           O
3   prescribed     O
4   ipratropium    B-DRUG
5   -              I-DRUG
6   albuterol      I-DRUG
7   a              O
8   small          O
9   dose           O
10  of             O
11  20             B-STRENGTH
12  mg             I-STRENGTH
13  ,              O
14  denzapine      B-DRUG
15  and            O
16  amil           B-DRUG
17  -              I-DRUG
18  co             I-DRUG
19  .              O

Также , в моем словаре drug_patterns.json, у меня может быть один и тот же длинный токен, появляющийся более одного раза:

{"label": "DRUG", "pattern": [{"lower": "ipratropium"}]}
{"label": "DRUG", "pattern": [{"lower": "ipratropium"}, {"lower": "bromide"}]}
{"label": "DRUG", "pattern": [{"lower": "ipratropium"}, {"lower": "-"}, {"lower": "albuterol"}]}

, который вместовесь ipratropium-albuterol выберет только первый (самый короткий) токен ipratropium (как показано в выводе).Есть ли простой способ сказать spaCy выбрать самый длинный токен?

Любые идеи будут высоко оценены.

1 Ответ

0 голосов
/ 25 февраля 2019

Ну, это было смущающее простое решение, но, надеюсь, оно может быть интересным для других.Просто используйте .ent_iob_ и .ent_type_ атрибуты токенов.А именно:

pd.DataFrame([(e.text, e.ent_iob_, e.ent_type_) for e in doc])


    0   1   2
0   He  O   
1   has O   
2   been    O   
3   prescribed  O   
4   ipratropium B   DRUG
5   -   O   
6   albuterol   O   
7   a   O   
8   small   O   
9   dose    O   
10  of  O   
11  20  B   STRENGTH
12  mg  I   STRENGTH
13  ,   O   
14  denzapine   B   DRUG
15  and O   
16  amil    B   DRUG
17  -   I   DRUG
18  co  I   DRUG
19  .   O   

, и тогда можно легко объединить последние два столбца в соответствующем формате с дефисом.SpaCy великолепен!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...