Handson de quelques tâches courantes en NLP

Actualité ekino -

Après la théorie, la pratique...

Article paru le :
Simple NLP tasks tutorial
Article paru le :

This post is also available in english.

 

Introduction et mise en place de l’environnement

Dans ce post, nous allons dérouler quelques exemples de tâches courantes en Natural Language Processing (NLP), en mettant en parallèle deux librairies Python (en) couramment utilisées : NLTK (en) et SpaCy (en). Pour plus d’informations sur ces librairies et le NLP en général, on pourra se référer aux posts précédents : Introduction au NLP Partie I et Partie II.

Pour reproduire ces exemples, il est conseillé d’utiliser un environnement Anaconda (en) en Python 3.5 :

Pour plus de facilité, on pourra travailler dans un notebook Jupyter (en). Il faut donc installer le package jupyter ainsi que spacy et nltk puis lancer le serveur notebook.

Le notebook s’ouvre alors dans le navigateur et on accède au tableau de bord. Puis on crée un nouveau notebook (en Python 3) :

Figure 1. Impression écran illustrant la création d'un nouveau notebook jupyter en python 3.

Pour faire tourner les exemples, il suffit de les coller dans les cellules du notebook.

Figure 2. Impression écran de la cellule d'un notebook jupyter.

Puis d’exécuter les cellules.

Figure 3. Impression écran illustrant la façon de lancer une cellule dans un notebook jupyter.

Pour pouvoir utiliser les modèles SpaCy, il faut d’abord les télécharger. Il est possible de le faire via le notebook :

Chacun des exemples ayant été écrit de manière à pouvoir être exécuté indépendamment, certaines parties (importation de librairie, création de pipeline, création de phrases,…) sont répétées à chaque fois. Cependant, ces répétitions sont inutiles si tous les exemples sont exécutés les uns à la suite des autres.

Les exemples sont aussi compilés dans un notebook Jupyter disponible sur GitHub.

 

Transformation de texte

Segmentation de texte en phrases

Notre premier exemple concerne un problème qui peut sembler simple en apparence, la segmentation d’un texte en phrases (en).

Avec SpaCy

Output :

Avec NLTK

Output :

Segmentation de texte en tokens

Il est possible de segmenter un texte de façon plus fine, en tokens (en). Ces tokens peuvent être des mots, des n-grammes, de la ponctuation, des symboles ou des chiffres.

Avec SpaCy

Output :

Avec NLTK

Output :

Dans certaines applications de NLP, il est parfois plus significatif d’utiliser un ensemble de tokens successifs plutôt qu’un seul token. Par exemple, si le mot “New-York” est présent dans un texte, une tokenisation classique va le séparer en trois tokens distincts “New”, “-” et “York”, lui faisant ainsi perdre du sens. Pour pallier à ce genre de problème, il est possible de segmenter le texte en n-grammes (n tokens successifs). NLTK contrairement à SpaCy permet de générer des n-grammes à partir d’une liste de tokens.

Output :

Output :

 

Extraction d’informations

Part-Of-Speech-Tagging (POS-Tagging)

Le POS-Tagging consiste à associer un mot à sa classe morphosyntaxique (nom, verbe, adjectif,…).

Avec SpaCy

Output :

Output :

La signification des différents tags français et anglais est disponible dans la bibliographie.

Avec NLTK

Output :

Reconnaissance d’entités nommées

La reconnaissance d’entités nommées (en) (ou Named-Entity Recognition, NER en anglais) permet de reconnaître les mots d’un texte qui correspondent à des concepts catégorisables (noms de personnes, lieux, organisations,…).

Avec SpaCy

SpaCy compte 17 types d’entités reconnues (en) : PERSON, NORP, FACILITY, ORG, GPE, LOC, PRODUCT, EVENT, WORK_OF_ART, LANGUAGE, DATE, TIME, PERCENT, MONEY, QUANTITY, ORDINAL et CARDINAL.

Output :

Avec NLTK

Il existe 9 types d’entités dans NLTK : ORGANIZATION, PERSON, LOCATION, DATE, TIME, MONEY, PERCENT, FACILITY et GPE. Plus de détails sur ces catégories sont disponibles dans le paragraphe 5 du chapitre 7 du livre NLTK donné en référence.

Output :

 

NLTK versus SpaCy

Fonctionnement

SpaCy et NLTK ont une façon très différente de traiter un texte. NLTK traite des chaînes de caractères alors que SpaCy a une approche plus orientée objet. En effet, NLTK fournit un ensemble de fonctions permettant d’effectuer une tâche de NLP (pos_tag() pour le POS-Tagging, sent_tokenize() pour la segmentation de phrases, word_tokenize() pour la tokenisation,…). Ces fonctions prennent en général une chaîne de caractères ou une liste de chaînes de caractères en paramètre d’entrée et renvoient également une chaîne ou une liste de chaînes. Il suffit donc à l’utilisateur de déterminer la fonction correspondant à la tâche qu’il veut effectuer puis de lui fournir son texte sous forme de chaîne de caractères.

Figure 4. Illustration du fonctionnement de NLTK pour le POS-Tagging.

SpaCy fonctionne différemment. Le texte, sous forme de chaîne de caractères, doit passer par un “language processing pipeline” spécifique à la langue du texte (l’anglais, le français, l’espagnol et l’allemand sont pour l’instant supportées par SpaCy). En sortie du pipeline, on obtient un objet Doc (en) qui est un conteneur permettant d’accéder aux annotations linguistiques. Chaque élément ou ensemble d’éléments d’un Doc est également représenté par un objet possédant des attributs, des méthodes et des propriétés qui permettent d’accéder aux informations linguistiques souhaitées. Cette approche est donc beaucoup plus moderne et “pythonic” que celle utilisée par NLTK.

Figure 5. Illustration du fonctionnement de SpaCy pour le POS-Tagging.

Retour sur les exemples

Revenons sur les exemples déroulés précédemment en comparant les résultats obtenus par les deux librairies.

  • Le premier exemple porte sur la segmentation d’un texte en phrases. SpaCy permet de segmenter un texte écrit en langue anglaise, française, espagnole ou allemande. Pour NLTK, le package nltk.tokenize (en) fournit plusieurs outils pour la segmentation en phrases, notamment la fonction sent_tokenize() qui dispose d’un paramètre « language » supportant la plupart des langues européennes (en). Si l’on revient sur notre exemple, on voit que NLTK segmente bien les trois phrases du texte alors que SpaCy ne sépare pas correctement les deux premières phrases.

 

  • Le deuxième exemple concerne la segmentation d’une phrase en tokens. Comme pour la segmentation en phrase, c’est le package nltk.tokenize qui regroupe les outils de segmentation en tokens pour NLTK et en particulier la fonction word_tokenize() qui dispose du même paramètre « language ». Si l’on regarde notre exemple, on voit que la seule différence notable entre les résultats, est le traitement de “++”. NLTK le considère comme un token à part entière alors que SpaCy sépare les deux symboles “+” pour retourner deux tokens distincts.

 

  • L’exemple suivant porte sur le POS-Tagging. Seule SpaCy propose d’autres langues que l’anglais (français, espagnol et allemand). Pour ce qui est du tagging pour la langue anglaise, les deux librairies s’appuie sur la Penn Treebank (en). Encore une fois, il y a une légère différence de résultat entre les deux librairies pour l’exemple fourni : le mot “to” est tagué “TO” (tag signifiant “to de l’infinitif”) avec NLTK et “IN” (tag signifiant conjonction, conjonction de subordination ou préposition) avec SpaCy. Il semble donc que NLTK se trompe ici.

 

  • Pour le dernier exemple, on s’intéresse à la reconnaissance d’entités nommées. Comme précédemment, seule SpaCy propose une alternative à l’anglais puisqu’il existe un modèle de NER en allemand. Les modèles français et espagnol ne sont pas encore disponibles. Un deuxième avantage pour SpaCy par rapport à NLTK est le nombre de catégories des entités : 17 pour SpaCy contre 9 pour NLTK. La phrase de notre exemple utilise trois entités dont les catégories sont communes aux deux libraries : PERSON, DATE etGPE. Si SpaCy reconnaît bien ces trois entités, NLTK ne reconnaît pas l’entité DATE.

Autres tâches

D’autres applications non traitées en exemples sont disponibles grâce à ces deux librairies :

  • La lemmatisation (en). Elle consiste à prendre la forme canonique d’un mot, son lemme. Pour l’instant, SpaCy possède le lemme des mots uniquement pour son modèle anglais. De même, NLTK n’a qu’un lemmatiser anglais d’implémenté, basé sur Wordnet (en), il s’agit de la fonction WordNetLemmatizer() (en) présente dans le package nltk.stem (en).

 

  • Le stemming (en). Il consiste à prendre la racine du mot. Seule NLTK permet de faire du  stemming grâce au package nltk.stem. Ce package propose un stemmer pour la langue arabe (ISRI), deux stemmer pour l’anglais (algorithme Lancaster et algorithme Porter), un stemmer qu’il est possible de customiser grâce à des regex (regexp), un stemmer pour le portugais (RSLP) et un ensemble de stemmer (Snowball) qui couvre plusieurs langues (français, danois, néerlandais, anglais, finlandais, allemand, hongrois, italien, norvégien, portugais, roumain, russe, espagnol et suédois).

 

  • L’analyse de sentiments. L’analyse de sentiments fait partie des fonctions toujours en développement dans SpaCy. En effet, il existe bien un attribut « sentiment » mais celui-ci est pour le moment vide quelque soit le modèle linguistique utilisé. Dans NLTK, on trouve trois packages utiles. Le premier package est nltk.sentiment (en). Il est composé de plusieurs sous-modules :
      • nltk.sentiment.vader (en) offre un outil d’analyse de sentiments déjà implémenté appelé VADER (en). La fonction polarity_scores() de ce module permet, pour un texte donné, d’obtenir un score pour chaque polarité (positive, négative et neutre).

     

      • nltk.sentiment.sentiment_analyzer (en). Ce module est un outil permettant d’implémenter et de faciliter les tâches d’analyse de sentiments en utilisant les fonctionnalités et les classifieurs présents dans NLTK. Il propose des fonctions pour l’extraction de features, l’apprentissage et l’évaluation d’un modèle de classification,….

     

    • nltk.sentiment.util (en) rassemble des méthodes utilitaires (conversion et parsing de fichiers, écriture d’une analyse dans un fichier,…).

 

Les deux autrespackages complètent le premier dans la construction de modèles de classification pour l’analyse de sentiments, en fournissant des jeux de données dans nltk.corpus (en) (les corpora de données disponibles dans NLTK sont répertoriés dans le chapitre 2 du livre NLTK donné en référece) et un ensemble de classifieurs dans nltk.classify (en). Parmi les jeux de données pouvant être utilisés, on peut citer subjectivity (il contient 5000 phrases labellisées “subjective” et 5000 phrases labellisées “objective”), twitters_samples (il contient un ensemble de tweets annotés positif/négatif) et movie_reviews (il contient 2000 revues de films annotées positive/négative). Les classifieurs proposés sont ConditionalExponentialClassifier, DecisionTreeClassifier,MaxentClassifier,NaiveBayesClassifieret WekaClassifier.

 

Conclusion

Ces quelques exemples simples ne sont qu’un aperçu de ce qu’il est possible de faire en NLP grâce aux deux librairies présentées. Même si SpaCy semble de plus en plus utilisée, les deux librairies restent complémentaires, chacune offrant des outils que l’autre n’a pas ou qui sont plus développés chez l’une par rapport à l’autre. Si la langue anglaise est privilégiée, on peut espérer que des fonctionnalités se développent prochainement pour les autres langues, notamment dans SpaCy.

 

Bibliographie

 

Crédit images

L’ensemble des illustrations sont sous licence CC0 (en).