Простой и прямолинейный подход для тех, кто хочет увидеть быстрые результаты при попытке выполнить распознавание именованных объектов (NER) и извлечение отношений (RE) с помощью python.

Посмотрите Создание пользовательских моделей распознавания именованных объектов, если вы заинтересованы в создании наборов данных для алгоритмов машинного обучения.

pip install extr
text = 'Walk; Mountcastle to 3B; Odor to 2B'

Определить именованные объекты

Нам нужно определить каждую именованную сущность и шаблон, существующий в тексте. RegExLabel принимает метку объекта и список выражений, чтобы найти эти метки в тексте.

from extr import RegEx, \
                 RegExLabel

kb = {
  'BASE': ['1B', '2B', '3B'],
}

entity_patterns = [
  RegExLabel(
    label='PLAYER',
    regexes=[
      RegEx([r'\b[A-Z]\w+(?=\s+to\b)'])
    ]
  ),
  RegExLabel('EVENT', [
    RegEx([r'\b(?:walk|single|double|triple)\b'], re.IGNORECASE)
  ]),
]

Извлечение именованных объектов из текста (NER)

Метод create_entity_extractor централизует для нас шаблоны и базу знаний. Передача нашего текста объекту возвращает сущности.

from extr.entities import create_entity_extractor

entity_extractor = create_entity_extractor(entity_patterns, kb)
entities = entity_extractor.get_entities(text)

## [
##   <Entity label="BASE" text="2B" span=(33, 35)>,
##   <Entity label="PLAYER" text="Odor" span=(25, 29)>,
##   <Entity label="BASE" text="3B" span=(21, 23)>,
##   <Entity label="PLAYER" text="Mountcastle" span=(6, 17)>,
##   <Entity label="EVENT" text="Walk" span=(0, 4)>
## ]




Определить отношения

Ниже мы просто определим одно отношение: r(e1=PERSON, e2=BASE) = is_on. Мы будем использовать это соотношение, чтобы определить, куда продвинулись игроки за игру. Отношения немного сложнее, но RegExRelationLabelBuilder делает их более интуитивными. Мы можем определить шаблоны, в которых e1 находится перед e2 или наоборот.

from extr.relations import RegExRelationLabelBuilder

player_to_base_relationship = RegExRelationLabelBuilder('is_on') \
  .add_e1_to_e2(
    'PLAYER', ## e1
    [
        ## define how the relationship exists in nature
        r'\s+to\s+',
    ],
    'BASE' ## e2
  ) \
  .build()

relations_to_extract = [
  player_to_base_relationship
]

Извлечь отношения (RE)

from extr.entities import EntityAnnotator
from extr.relations import RelationExtractor

annotations = EntityAnnotator().annotate(text, entities)
relations = RelationExtractor(relations_to_extract).extract(annotations)

## [
##   <Relation e1="Mountcastle" r="is_on" e2="3B">,
##   <Relation e1="Odor" r="is_on" e2="2B">
## ]