web-dev-qa-db-fra.com

Utilisation de PhraseMatcher dans SpaCy pour trouver plusieurs types de correspondance

La documentation et les exemples SpaCy montrent que la classe PhraseMatcher est utile pour faire correspondre des séquences de jetons dans des documents. Il faut fournir un vocabulaire de séquences qui seront appariées.

Dans ma demande, j'ai des documents qui sont des collections de jetons et de phrases. Il existe des entités de différents types. Les données sont en langage naturel à distance (les documents sont plutôt un ensemble de mots-clés avec un ordre semi-aléatoire). J'essaie de trouver des correspondances de plusieurs types.

Par exemple:

yellow boots for kids

Comment puis-je trouver les correspondances pour les couleurs (par exemple le jaune), pour les types de produits (par exemple les bottes) et pour l'âge (par exemple les enfants) en utilisant PhraseCatches de SpaCy? Est-ce un bon cas d'utilisation? Si les différentes entités correspondent au chevauchement (par exemple, la couleur est mise en correspondance dans la liste des couleurs et dans la liste des matériaux), est-il possible de produire tous les cas uniques?

Je ne peux pas vraiment utiliser un tagueur de séquence car les données sont structurées de manière lâche et sont pleines d'ambiguïtés. J'ai une liste d'entités (par exemple couleurs, ager, types de produits) et des listes de valeurs associées.

Une idée serait d'instancier plusieurs objets PhraseMatcher, un pour chaque entité, de faire les correspondances séparément, puis de fusionner les résultats. Chaque type d'entité aura son propre vocabulaire. Cela semble simple mais peut ne pas être efficace, en particulier la partie fusionnée. Les listes de valeurs sont assez grandes. Avant d'emprunter cette voie, je voudrais savoir si c'est une bonne idée ou peut-être qu'il existe des moyens plus simples de le faire avec SpaCy.

10

spaCy PhraseMatcher prend en charge l'ajout de plusieurs règles contenant plusieurs modèles et l'attribution d'ID à chaque règle de correspondance que vous ajoutez. Si deux règles se chevauchent, les deux correspondances seront retournées. Vous pouvez donc faire quelque chose comme ceci:

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)

Lorsque vous appelez le matcher sur votre doc, spaCy retournera une liste de tuples (match_id, start, end). Parce que spaCy stocke toutes les chaînes sous forme d'entiers, le match_id Que vous récupérez sera également un entier - mais vous pouvez toujours obtenir la représentation des chaînes en la recherchant dans le StringStore du vocabulaire, c'est-à-dire 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

Lorsque vous ajoutez des règles de correspondance, vous pouvez également définir une fonction de rappel on_match comme deuxième argument de Matcher.add. Ceci est souvent utile si vous souhaitez déclencher des actions spécifiques - par exemple, faites une chose si une correspondance COLOR est trouvée, et autre chose pour une correspondance PRODUCT.

Si vous souhaitez résoudre ce problème de manière encore plus élégante, vous pouvez également envisager de combiner votre matcher avec un composant de pipeline personnalisé ou attributs personnalisés . Par exemple, vous pouvez écrire un composant simple qui s'exécute automatiquement lorsque vous appelez nlp() sur votre texte, recherche les correspondances et définit un attribut Doc._.contains_product Ou Token._.is_color. Les documents en contiennent quelques exemples qui devraient vous aider à démarrer.

30
Ines Montani