Использование PhraseMatcher в SpaCy для поиска нескольких типов совпадений

Документация и примеры SpaCy показывают, что класс PhraseMatcher полезен для сопоставления последовательностей токенов в документах. Нужно предоставить словарь последовательностей, которые будут сопоставлены.

В моем приложении у меня есть документы, которые представляют собой наборы токенов и фраз. Существуют сущности разных типов. Данные на удаленном естественном языке (документы представляют собой набор ключевых слов с полуслучайным порядком). Я пытаюсь найти совпадения нескольких типов.

Например:

yellow boots for kids

Как я могу найти совпадения по цветам (например, желтый), по типам продуктов (например, ботинки) и по возрасту (например, дети) с помощью PhraseMatches SpaCy? Это хороший вариант использования? Если разные объекты совпадают (например, цвета совпадают в списке цветов и в списке материалов), возможно ли создать все уникальные случаи?

Я действительно не могу использовать метку последовательности, так как данные слабо структурированы и изобилуют неясностями. У меня есть список объектов (например, цвета, ager, типы продуктов) и связанные списки значений.

Одной из идей будет создание нескольких объектов PhraseMatcher, по одному для каждой сущности, выполнение сопоставлений отдельно, а затем объединение результатов. Каждый тип сущности получит свой собственный словарь. Это звучит просто, но может быть неэффективно, особенно в части слияния. Списки значений довольно велики. Прежде чем идти по этому пути, я хотел бы знать, является ли это хорошей идеей или, возможно, есть более простые способы сделать это с SpaCy.

1 ответ

Решение

Spacy-х PhraseMatcher поддерживает добавление нескольких правил, содержащих несколько шаблонов, и назначение идентификаторов каждому добавляемому правилу сопоставления. Если два правила перекрываются, оба совпадения будут возвращены. Так что вы можете сделать что-то вроде этого:

color_patterns = [nlp(text) for text in ('red', 'green', 'yellow')]
product_patterns = [nlp(text) for text in ('boots', 'coats', 'bag')]
material_patterns = [nlp(text) for text in ('silk', 'yellow fabric')]

matcher = PhraseMatcher(nlp.vocab)
matcher.add('COLOR', None, *color_patterns)
matcher.add('PRODUCT', None, *product_patterns)
matcher.add('MATERIAL', None, *material_patterns)

Когда вы звоните matcher на ваше doc, spaCy вернет список (match_id, start, end) кортежи. Поскольку spaCy хранит все строки в виде целых чисел, match_id Вы получите обратно, тоже будет целым числом - но вы всегда можете получить строковое представление, посмотрев его в словаре StringStoreт.е. nlp.vocab.strings:

doc = nlp("yellow fabric")
matches = matcher(doc)
for match_id, start, end in matches:
    rule_id = nlp.vocab.strings[match_id]  # get the unicode ID, i.e. 'COLOR'
    span = doc[start : end]  # get the matched slice of the doc
    print(rule_id, span.text)

# COLOR yellow
# MATERIAL yellow fabric

Когда вы добавляете правила сопоставления, вы также можете определить on_match функция обратного вызова в качестве второго аргумента Matcher.add, Это часто полезно, если вы хотите инициировать определенные действия - например, сделать одну вещь, если COLOR совпадение найдено, и что-то еще для PRODUCT матч.

Если вы хотите решить эту проблему еще более изящно, вы также можете попытаться объединить свой сопоставитель с настраиваемым компонентом конвейера или настраиваемыми атрибутами. Например, вы можете написать простой компонент, который запускается автоматически при вызове nlp() на ваш текст, находит совпадения и устанавливает Doc._.contains_product или же Token._.is_color приписывать. В документах есть несколько примеров этого, которые должны помочь вам начать работу.

Другие вопросы по тегам