Extraire des entités du texte avec Stanford NLP à partir de zéro

Cet article est destiné à ceux qui n'ont jamais travaillé avec Stanford nlp et confrontés à la nécessité de l'étudier et de l'appliquer dès que possible.

Ce logiciel est assez courant et, en particulier, notre société - BaltInfoCom - utilise ce programme.

Vous devez d'abord comprendre une chose simple: Stanford NLP fonctionne sur le principe d'annoter des mots, c'est-à-dire une ou plusieurs annotations, telles que POS (Part of Speech - part of speech), NER (Named-Entity Recognizing - Named Entity), et etc.

La première chose qu'un débutant voit lorsqu'il se rend sur le site Web de Stanford NLP dans la section " démarrage rapide " est la conception suivante:

Properties props = new Properties(); props.setProperty("annotators", "tokenize,ssplit,pos,lemma,ner,regexner,parse,depparse,coref"); StanfordCoreNLP pipeline = new StanfordCoreNLP(props); // create a document object CoreDocument document = new CoreDocument(text); // annnotate the document pipeline.annotate(document); 

Ici StanfordCoreNLP est un convoyeur, à l'entrée duquel notre texte est pré-emballé dans un objet CoreDocument. StanfordCoreNLP, c'est l'objet le plus important et le plus souvent utilisé dans toute la structure, avec lequel tout le travail principal est effectué.

Tout d'abord, nous définissons les paramètres dans StanfordCoreNLP et indiquons la mise en œuvre des actions dont nous avons besoin. De plus, toutes les combinaisons possibles de ces paramètres peuvent être trouvées sur le site officiel à ce lien.

  • tokenize - en conséquence, tokenization
  • ssplit - fractionnement en une phrase
  • pos - définition d'une partie du discours
  • lemme - ajouter à chaque mot sa forme initiale
  • ner - définition des entités nommées, telles que "Organisation", "Visage", etc.
  • regexner - définir des entités nommées à l'aide d'expressions régulières
  • analyse - analyse de chaque mot en fonction de la sémantique (sexe, nombre, etc.)
  • depparse - dépendances syntaxiques entre les mots d'une phrase
  • coref- recherche des références à la même entité nommée dans le texte, par exemple, "Mary" et "she"

Voici un exemple de la façon dont les annotateurs (parse et depparse) fonctionnent ensemble:

image

Si vous ne comprenez pas les annotations sur les jetons, vous trouverez sur ces sites leurs significations: significations des connexions dans les phrases , significations des parties du discours .

Pour chacun de ces paramètres, vous pouvez trouver des indicateurs supplémentaires pour un réglage plus précis ici dans la section "Annotateurs".

Ces constructions sont définies si vous souhaitez utiliser les modèles Stanford NLP intégrés, mais vous pouvez également les définir manuellement à l'aide de la méthode addAnnotator (Annotator ...) ou en reconstituant les paramètres avant de créer l'objet StanfordCoreNLP.

Maintenant, comment extraire des entités nommées du texte. Pour ce faire, Stanford NLP a trois classes basées sur des expressions régulières intégrées et une classe pour marquer les jetons à travers le modèle.

Classes d'expression régulière:

  • TokensRegexAnnotator - annotateur qui fonctionne selon les règles - SequenceMatchRules .
    Prenons un exemple de mappage pour celui-ci, basé sur ces règles.

     ner = { type: "CLASS", value: "edu.stanford.nlp.ling.CoreAnnotations$NamedEntityTagAnnotation" } $EMAIL = "/.*([A-z0-9-]+?)(@)([A-z0-9-]+?).*/" { ruleType: "tokens", pattern: (([]) ($EMAIL)), action: (Annotate($0, ner, "MAIL")), priority:0 } 

    La première ligne indique quel type de balises nous remplirons ce modèle.
    Dans le second, nous créons une variable qui, selon les règles, doit commencer par le caractère «$» et se trouver au début de la ligne.

    Après cela, créez un bloc dans lequel nous définissons le type de règles. Ensuite, un modèle de comparaison (dans notre cas, nous disons que nous avons besoin de «[]» - tout jeton après lequel notre variable $ EMAIL va. Après cela, nous définissons l'action, dans notre cas, nous voulons annoter le jeton.

    Veuillez noter que dans l'exemple, «[]» et «$ EMAIL» sont placés entre parenthèses car $ 0 indique le groupe de capture que nous voulons mettre en évidence dans le modèle trouvé, tandis que le groupe de capture signifie un groupe entre parenthèses. Si vous définissez 0, alors dans la phrase «sobaka@mail.ru mail», tous les jetons seront annotés comme «MAIL». Si vous définissez 1 (c'est-à-dire le premier groupe de capture), seul le mot "courrier" sera annoté; si 2, alors seulement sobaka@mail.ru.

    Pour les situations où, selon deux règles, le même jeton peut être défini différemment, vous pouvez définir la priorité de la règle par rapport à l'autre. Par exemple, dans le cas de la phrase suivante - «Maison 25 $», il peut y avoir deux règles contradictoires, selon l'une desquelles le nombre 25 sera déterminé comme le numéro de la maison, et selon la seconde - comme sa valeur.
  • RegexNERAnnotator - Cet annotateur fonctionne à l'aide de RegexNERSequenceClassifier .

    La cartographie pour lui est la suivante

     regex1 TYPE overwritableType1,Type2... priority 

    Ici regex1 est une expression régulière au format TokenSequencePattern .

    TYPE est le nom de l'entité nommée.
    overwritableType1, Type2 ... - types que nous pouvons remplacer en cas de situation litigieuse.
    Priorité - priorité pour les litiges décrits ci-dessus.
    Veuillez noter que dans ce mappage, toutes les colonnes doivent être séparées par des tabulations.
  • TokensRegexNERAnnotator
    Cet annotateur diffère du précédent en ce qu'il utilise la bibliothèque TokensRegex pour les expressions régulières, la même que le premier annotateur, ce qui vous permet d'utiliser des règles plus souples pour la correspondance; ainsi que la possibilité d'enregistrer des valeurs de balise autres que la balise NER.
    Le mappage est compilé selon les règles de RegexNERAnnotator

Marquage de texte dans un modèle à l'aide de NERClassifierCombiner
Pour utiliser cette classe, vous devez d'abord avoir ou former votre modèle.

Comment faire cela peut être trouvé ici ;
Une fois que vous avez formé le modèle, il ne reste plus qu'à créer un NERClassifierCombiner, indiquant le chemin d'accès au modèle et à appeler la méthode classify.

 NERClassifierCombiner classifier = new NERClassifierCombiner(false, false, serialized_model); String text = "Some lucky people working in BaltInfoCom Org."; List<List<CoreLabel>> out = classifier.classify(text); 

Une liste complète des annotateurs est disponible ici .

En plus de ce qui précède, si vous devez utiliser Stanford NLP pour la langue russe, je peux vous conseiller de venir ici . Il existe des modèles pour identifier les parties du discours (pos-tagger) et pour identifier les relations dans les phrases (analyseur de dépendance).

Types de tags représentés ici:
russian-ud-pos.tagger est juste un tagueur,
russian-ud-mfmini.tagger - avec la liste principale des caractéristiques morphologiques,
russian-ud-mf.tagger - avec une liste complète des caractéristiques morphologiques, dont un exemple de cartographie peut être consulté ici .

Source: https://habr.com/ru/post/fr414175/


All Articles