Boîte à outils en langage naturel - Guide rapide

Qu'est-ce que le traitement du langage naturel (PNL)?

La méthode de communication à l'aide de laquelle les humains peuvent parler, lire et écrire est le langage. En d'autres termes, nous, les humains, pouvons penser, faire des plans, prendre des décisions dans notre langage naturel. Ici, la grande question est, à l'ère de l'intelligence artificielle, de l'apprentissage automatique et de l'apprentissage profond, les humains peuvent-ils communiquer en langage naturel avec des ordinateurs / machines? Développer des applications PNL est un énorme défi pour nous car les ordinateurs nécessitent des données structurées, mais d'un autre côté, la parole humaine est non structurée et souvent de nature ambiguë.

Le langage naturel est ce sous-domaine de l'informatique, plus spécifiquement de l'IA, qui permet aux ordinateurs / machines de comprendre, traiter et manipuler le langage humain. En termes simples, la PNL est un moyen pour les machines d'analyser, de comprendre et de tirer un sens des langues naturelles humaines comme l'hindi, l'anglais, le français, le néerlandais, etc.

Comment ça marche?

Avant de plonger dans le fonctionnement de la PNL, nous devons comprendre comment les êtres humains utilisent le langage. Chaque jour, nous, les humains, utilisons des centaines ou des milliers de mots et d'autres humains les interprètent et répondent en conséquence. C'est une simple communication pour les humains, n'est-ce pas? Mais nous savons que les mots sont beaucoup plus profonds que cela et nous tirons toujours un contexte de ce que nous disons et de la façon dont nous disons. C'est pourquoi nous pouvons dire plutôt que de se concentrer sur la modulation de la voix, la PNL s'appuie sur un modèle contextuel.

Comprenons-le avec un exemple -

Man is to woman as king is to what?
We can interpret it easily and answer as follows:
Man relates to king, so woman can relate to queen.
Hence the answer is Queen.

Comment les humains savent ce que signifie ce mot? La réponse à cette question est que nous apprenons par notre expérience. Mais, comment les machines / ordinateurs apprennent-ils la même chose?

Comprenons-le en suivant les étapes faciles -

  • Tout d'abord, nous devons alimenter les machines avec suffisamment de données pour que les machines puissent apprendre de l'expérience.

  • Ensuite, la machine créera des vecteurs de mots, en utilisant des algorithmes d'apprentissage en profondeur, à partir des données que nous avons fournies précédemment ainsi qu'à partir des données environnantes.

  • Ensuite, en effectuant de simples opérations algébriques sur ces vecteurs de mots, la machine serait en mesure de fournir les réponses en tant qu'êtres humains.

Composantes de la PNL

Le diagramme suivant représente les composants du traitement du langage naturel (NLP) -

Traitement morphologique

Le traitement morphologique est le premier composant de la PNL. Il comprend la décomposition de morceaux de langue d'entrée en ensembles de jetons correspondant à des paragraphes, des phrases et des mots. Par exemple, un mot comme“everyday” peut être divisé en deux jetons de sous-mot comme “every-day”.

Analyse syntaxique

L'analyse de syntaxe, le deuxième composant, est l'un des composants les plus importants de la PNL. Les objectifs de ce composant sont les suivants -

  • Pour vérifier qu'une phrase est bien formée ou non.

  • Le décomposer en une structure qui montre les relations syntaxiques entre les différents mots.

  • Par exemple, les phrases comme “The school goes to the student” serait rejeté par l'analyseur de syntaxe.

Analyse sémantique

L'analyse sémantique est le troisième composant de la PNL qui est utilisé pour vérifier la signification du texte. Cela comprend le dessin de la signification exacte, ou nous pouvons dire la signification du dictionnaire à partir du texte. Par exemple, les phrases comme «C'est une glace chaude». serait rejeté par l'analyseur sémantique.

Analyse pragmatique

L'analyse pragmatique est la quatrième composante de la PNL. Il comprend l'ajustement des objets ou événements réels qui existent dans chaque contexte avec des références d'objet obtenues par le composant précédent, c'est-à-dire l'analyse sémantique. Par exemple, les phrases comme“Put the fruits in the basket on the table” peut avoir deux interprétations sémantiques, donc l'analyseur pragmatique choisira entre ces deux possibilités.

Exemples d'applications PNL

La PNL, une technologie émergente, dérive diverses formes d'IA que nous avions l'habitude de voir ces jours-ci. Pour les applications de plus en plus cognitives d'aujourd'hui et de demain, l'utilisation de la PNL pour créer une interface transparente et interactive entre les humains et les machines restera une priorité absolue. Voici quelques-unes des applications très utiles de la PNL.

Traduction automatique

La traduction automatique (MT) est l'une des applications les plus importantes du traitement du langage naturel. La MT est essentiellement un processus de traduction d'une langue source ou d'un texte dans une autre langue. Le système de traduction automatique peut être bilingue ou multilingue.

Lutter contre le spam

En raison de l'énorme augmentation des e-mails indésirables, les filtres anti-spam sont devenus importants car c'est la première ligne de défense contre ce problème. En considérant ses problèmes de faux positifs et de faux négatifs comme les principaux problèmes, la fonctionnalité de la PNL peut être utilisée pour développer un système de filtrage des spams.

La modélisation N-gram, le mot Stemming et la classification bayésienne font partie des modèles PNL existants qui peuvent être utilisés pour le filtrage des spams.

Récupération d'informations et recherche sur le Web

La plupart des moteurs de recherche comme Google, Yahoo, Bing, WolframAlpha, etc. basent leur technologie de traduction automatique (MT) sur des modèles d'apprentissage en profondeur PNL. Ces modèles d'apprentissage en profondeur permettent aux algorithmes de lire du texte sur une page Web, d'interpréter sa signification et de le traduire dans une autre langue.

Synthèse automatique du texte

La synthèse automatique de texte est une technique qui crée un résumé court et précis de documents texte plus longs. Par conséquent, cela nous aide à obtenir des informations pertinentes en moins de temps. En cette ère numérique, nous avons un besoin sérieux de récapitulation automatique du texte car nous avons le flot d'informations sur Internet qui ne va pas s'arrêter. La PNL et ses fonctionnalités jouent un rôle important dans le développement d'une synthèse automatique de texte.

Correction grammaticale

La correction orthographique et grammaticale est une fonctionnalité très utile des logiciels de traitement de texte comme Microsoft Word. Le traitement du langage naturel (NLP) est largement utilisé à cette fin.

Réponse aux questions

La réponse aux questions, une autre application principale du traitement du langage naturel (PNL), se concentre sur la construction de systèmes qui répondent automatiquement à la question posée par l'utilisateur dans son langage naturel.

Analyse des sentiments

L'analyse des sentiments fait partie des autres applications importantes du traitement du langage naturel (PNL). Comme son nom l'indique, l'analyse des sentiments est utilisée pour -

  • Identifiez les sentiments parmi plusieurs articles et

  • Identifiez le sentiment où les émotions ne sont pas exprimées explicitement.

Les entreprises de commerce électronique en ligne comme Amazon, ebay, etc. utilisent l'analyse des sentiments pour identifier l'opinion et le sentiment de leurs clients en ligne. Cela les aidera à comprendre ce que leurs clients pensent de leurs produits et services.

Moteurs vocaux

Les moteurs vocaux comme Siri, Google Voice, Alexa sont basés sur la PNL afin que nous puissions communiquer avec eux dans notre langage naturel.

Implémentation de la PNL

Afin de créer les applications mentionnées ci-dessus, nous devons avoir un ensemble de compétences spécifiques avec une grande compréhension du langage et des outils pour traiter le langage efficacement. Pour y parvenir, nous disposons de différents outils open source. Certains d'entre eux sont open-source tandis que d'autres sont développés par des organisations pour créer leurs propres applications PNL. Voici la liste de quelques outils PNL -

  • Kit d'outils en langage naturel (NLTK)

  • Mallet

  • GATE

  • PNL ouvert

  • UIMA

  • Genism

  • Boîte à outils de Stanford

La plupart de ces outils sont écrits en Java.

Kit d'outils en langage naturel (NLTK)

Parmi les outils NLP mentionnés ci-dessus, NLTK obtient des scores très élevés en ce qui concerne la facilité d'utilisation et l'explication du concept. La courbe d'apprentissage de Python est très rapide et NLTK est écrit en Python, donc NLTK a également un très bon kit d'apprentissage. NLTK a incorporé la plupart des tâches telles que la création de jetons, la racine, la lemmatisation, la ponctuation, le nombre de caractères et le nombre de mots. Il est très élégant et facile à travailler.

Pour installer NLTK, nous devons avoir Python installé sur nos ordinateurs. Vous pouvez aller sur le lien www.python.org/downloads et sélectionner la dernière version pour votre système d'exploitation, c'est-à-dire Windows, Mac et Linux / Unix. Pour un tutoriel de base sur Python, vous pouvez vous référer au lien www.tutorialspoint.com/python3/index.htm .

Maintenant, une fois que Python est installé sur votre système informatique, laissez-nous comprendre comment nous pouvons installer NLTK.

Installation de NLTK

Nous pouvons installer NLTK sur divers OS comme suit -

Sous Windows

Pour installer NLTK sur le système d'exploitation Windows, suivez les étapes ci-dessous -

  • Tout d'abord, ouvrez l'invite de commande Windows et accédez à l'emplacement du pip dossier.

  • Ensuite, entrez la commande suivante pour installer NLTK -

pip3 install nltk

Maintenant, ouvrez le PythonShell à partir du menu Démarrer de Windows et tapez la commande suivante afin de vérifier l'installation de NLTK -

Import nltk

Si vous n'obtenez aucune erreur, vous avez correctement installé NLTK sur votre système d'exploitation Windows avec Python3.

Sur Mac / Linux

Afin d'installer NLTK sur Mac / Linux OS, écrivez la commande suivante -

sudo pip install -U nltk

Si vous n'avez pas installé pip sur votre ordinateur, suivez les instructions ci-dessous pour la première installation pip -

Tout d'abord, mettez à jour l'index du package en suivant la commande suivante -

sudo apt update

Maintenant, tapez la commande suivante pour installer pip pour python 3 -

sudo apt install python3-pip

Par Anaconda

Pour installer NLTK via Anaconda, suivez les étapes ci-dessous -

Tout d'abord, pour installer Anaconda, allez sur le lien www.anaconda.com/distribution/#download-section puis sélectionnez la version de Python que vous devez installer.

Une fois que vous avez Anaconda sur votre système informatique, accédez à son invite de commande et écrivez la commande suivante -

conda install -c anaconda nltk

Vous devez examiner la sortie et entrer «oui». NLTK sera téléchargé et installé dans votre package Anaconda.

Téléchargement de l'ensemble de données et des packages de NLTK

Maintenant, nous avons NLTK installé sur nos ordinateurs, mais pour l'utiliser, nous devons télécharger les ensembles de données (corpus) disponibles. Certains des ensembles de données importants disponibles sontstpwords, guntenberg, framenet_v15 etc.

À l'aide des commandes suivantes, nous pouvons télécharger tous les ensembles de données NLTK -

import nltk
nltk.download()

Vous obtiendrez la fenêtre de téléchargement NLTK suivante.

Maintenant, cliquez sur le bouton de téléchargement pour télécharger les ensembles de données.

Comment exécuter le script NLTK?

Voici l'exemple dans lequel nous implémentons l'algorithme de Porter Stemmer en utilisant PorterStemmerclasse nltk. avec cet exemple, vous seriez en mesure de comprendre comment exécuter le script NLTK.

Tout d'abord, nous devons importer la boîte à outils en langage naturel (nltk).

import nltk

Maintenant, importez le PorterStemmer classe pour implémenter l'algorithme Porter Stemmer.

from nltk.stem import PorterStemmer

Ensuite, créez une instance de la classe Porter Stemmer comme suit -

word_stemmer = PorterStemmer()

Maintenant, saisissez le mot que vous souhaitez extraire. -

word_stemmer.stem('writing')

Production

'write'

word_stemmer.stem('eating')

Production

'eat'

Qu'est-ce que le tokenisation?

Il peut être défini comme le processus consistant à diviser un morceau de texte en parties plus petites, telles que des phrases et des mots. Ces pièces plus petites sont appelées jetons. Par exemple, un mot est un jeton dans une phrase et une phrase est un jeton dans un paragraphe.

Comme nous savons que la PNL est utilisée pour créer des applications telles que l'analyse des sentiments, les systèmes d'assurance qualité, la traduction de la langue, les chatbots intelligents, les systèmes vocaux, etc., par conséquent, pour les construire, il devient essentiel de comprendre le modèle dans le texte. Les jetons, mentionnés ci-dessus, sont très utiles pour trouver et comprendre ces modèles. Nous pouvons considérer la tokenisation comme l'étape de base pour d'autres recettes telles que la racine et la lemmatisation.

Paquet NLTK

nltk.tokenize est le package fourni par le module NLTK pour réaliser le processus de tokenisation.

Tokenizing des phrases en mots

La division de la phrase en mots ou la création d'une liste de mots à partir d'une chaîne est une partie essentielle de toute activité de traitement de texte. Comprenons-le à l'aide de diverses fonctions / modules fournis parnltk.tokenize paquet.

module word_tokenize

word_tokenizemodule est utilisé pour la tokenisation de mots de base. L'exemple suivant utilisera ce module pour diviser une phrase en mots.

Exemple

import nltk
from nltk.tokenize import word_tokenize
word_tokenize('Tutorialspoint.com provides high quality technical tutorials for free.')

Production

['Tutorialspoint.com', 'provides', 'high', 'quality', 'technical', 'tutorials', 'for', 'free', '.']

Classe TreebankWordTokenizer

word_tokenize module, utilisé ci-dessus est essentiellement une fonction wrapper qui appelle la fonction tokenize () comme une instance du TreebankWordTokenizerclasse. Cela donnera le même résultat que celui obtenu en utilisant le module word_tokenize () pour diviser les phrases en mot. Voyons le même exemple implémenté ci-dessus -

Exemple

Tout d'abord, nous devons importer la boîte à outils en langage naturel (nltk).

import nltk

Maintenant, importez le TreebankWordTokenizer classe pour implémenter l'algorithme de tokenizer de mots -

from nltk.tokenize import TreebankWordTokenizer

Ensuite, créez une instance de la classe TreebankWordTokenizer comme suit -

Tokenizer_wrd = TreebankWordTokenizer()

Maintenant, saisissez la phrase que vous souhaitez convertir en jetons -

Tokenizer_wrd.tokenize(
   'Tutorialspoint.com provides high quality technical tutorials for free.'
)

Production

[
   'Tutorialspoint.com', 'provides', 'high', 'quality', 
   'technical', 'tutorials', 'for', 'free', '.'
]

Exemple d'implémentation complet

Voyons l'exemple de mise en œuvre complet ci-dessous

import nltk
from nltk.tokenize import TreebankWordTokenizer
tokenizer_wrd = TreebankWordTokenizer()
tokenizer_wrd.tokenize('Tutorialspoint.com provides high quality technical
tutorials for free.')

Production

[
   'Tutorialspoint.com', 'provides', 'high', 'quality', 
   'technical', 'tutorials','for', 'free', '.'
]

La convention la plus significative d'un tokenizer est de séparer les contractions. Par exemple, si nous utilisons le module word_tokenize () à cette fin, il donnera la sortie comme suit -

Exemple

import nltk
from nltk.tokenize import word_tokenize
word_tokenize('won’t')

Production

['wo', "n't"]]

Ce genre de convention par TreebankWordTokenizerest inacceptable. C'est pourquoi nous avons deux jetons de mots alternatifs, à savoirPunktWordTokenizer et WordPunctTokenizer.

Classe WordPunktTokenizer

Un jeton de mot alternatif qui divise toute la ponctuation en jetons séparés. Comprenons-le avec l'exemple simple suivant -

Exemple

from nltk.tokenize import WordPunctTokenizer
tokenizer = WordPunctTokenizer()
tokenizer.tokenize(" I can't allow you to go home early")

Production

['I', 'can', "'", 't', 'allow', 'you', 'to', 'go', 'home', 'early']

Tokenizing du texte en phrases

Dans cette section, nous allons diviser le texte / paragraphe en phrases. NLTK fournitsent_tokenize module à cet effet.

Pourquoi est-ce nécessaire?

Une question évidente qui nous est venue à l'esprit est la suivante: lorsque nous avons un tokenizer de mots, pourquoi avons-nous besoin de tokenizer de phrases ou pourquoi avons-nous besoin de tokeniser le texte en phrases. Supposons que nous ayons besoin de compter les mots moyens dans les phrases, comment pouvons-nous faire cela? Pour accomplir cette tâche, nous avons besoin à la fois de tokenisation de phrase et de tokenisation de mot.

Comprenons la différence entre le tokenizer de phrase et de mot à l'aide de l'exemple simple suivant -

Exemple

import nltk
from nltk.tokenize import sent_tokenize
text = "Let us understand the difference between sentence & word tokenizer. 
It is going to be a simple example."
sent_tokenize(text)

Production

[
   "Let us understand the difference between sentence & word tokenizer.", 
   'It is going to be a simple example.'
]

Tokenisation de phrases à l'aide d'expressions régulières

Si vous pensez que la sortie du tokenizer de mots est inacceptable et que vous voulez un contrôle complet sur la façon de tokeniser le texte, nous avons une expression régulière qui peut être utilisée lors de la tokenisation de phrases. NLTK fournitRegexpTokenizer classe pour y parvenir.

Comprenons le concept à l'aide de deux exemples ci-dessous.

Dans le premier exemple, nous utiliserons une expression régulière pour faire correspondre les jetons alphanumériques plus les guillemets simples afin de ne pas diviser les contractions comme “won’t”.

Exemple 1

import nltk
from nltk.tokenize import RegexpTokenizer
tokenizer = RegexpTokenizer("[\w']+")
tokenizer.tokenize("won't is a contraction.")
tokenizer.tokenize("can't is a contraction.")

Production

["won't", 'is', 'a', 'contraction']
["can't", 'is', 'a', 'contraction']

Dans le premier exemple, nous utiliserons une expression régulière pour tokeniser sur les espaces.

Exemple 2

import nltk
from nltk.tokenize import RegexpTokenizer
tokenizer = RegexpTokenizer('/s+' , gaps = True)
tokenizer.tokenize("won't is a contraction.")

Production

["won't", 'is', 'a', 'contraction']

À partir de la sortie ci-dessus, nous pouvons voir que la ponctuation reste dans les jetons. Le paramètre gap = True signifie que le modèle va identifier les espaces à tokeniser. D'un autre côté, si nous utilisons le paramètre gap = False, le modèle sera utilisé pour identifier les jetons qui peuvent être vus dans l'exemple suivant -

import nltk
from nltk.tokenize import RegexpTokenizer
tokenizer = RegexpTokenizer('/s+' , gaps = False)
tokenizer.tokenize("won't is a contraction.")

Production

[ ]

Cela nous donnera la sortie vierge.

Pourquoi former son propre tokenizer de phrase?

C'est une question très importante que si nous avons le tokenizer de phrase par défaut de NLTK alors pourquoi avons-nous besoin de former un tokenizer de phrase? La réponse à cette question réside dans la qualité du tokenizer de phrase par défaut de NLTK. Le tokenizer par défaut du NLTK est essentiellement un tokenizer à usage général. Bien que cela fonctionne très bien, ce n'est peut-être pas un bon choix pour le texte non standard, peut-être notre texte, ou pour un texte qui a une mise en forme unique. Pour tokeniser ce texte et obtenir les meilleurs résultats, nous devons former notre propre tokenizer de phrases.

Exemple d'implémentation

Pour cet exemple, nous utiliserons le corpus webtext. Le fichier texte que nous allons utiliser à partir de ce corpus a le texte formaté comme les boîtes de dialogue ci-dessous -

Guy: How old are you?
Hipster girl: You know, I never answer that question. Because to me, it's about
how mature you are, you know? I mean, a fourteen year old could be more mature
than a twenty-five year old, right? I'm sorry, I just never answer that question.
Guy: But, uh, you're older than eighteen, right?
Hipster girl: Oh, yeah.

Nous avons enregistré ce fichier texte sous le nom de training_tokenizer. NLTK fournit une classe nomméePunktSentenceTokenizeravec l'aide duquel nous pouvons nous entraîner sur du texte brut pour produire un tokenizer de phrase personnalisé. Nous pouvons obtenir du texte brut soit en lisant dans un fichier, soit à partir d'un corpus NLTK en utilisant leraw() méthode.

Voyons l'exemple ci-dessous pour en savoir plus -

Tout d'abord, importez PunktSentenceTokenizer classe de nltk.tokenize paquet -

from nltk.tokenize import PunktSentenceTokenizer

Maintenant, importez webtext corpus de nltk.corpus paquet

from nltk.corpus import webtext

Ensuite, en utilisant raw() méthode, récupérez le texte brut de training_tokenizer.txt fichier comme suit -

text = webtext.raw('C://Users/Leekha/training_tokenizer.txt')

Maintenant, créez une instance de PunktSentenceTokenizer et imprimez les phrases tokenize à partir du fichier texte comme suit -

sent_tokenizer = PunktSentenceTokenizer(text)
sents_1 = sent_tokenizer.tokenize(text)
print(sents_1[0])

Production

White guy: So, do you have any plans for this evening?
print(sents_1[1])
Output:
Asian girl: Yeah, being angry!
print(sents_1[670])
Output:
Guy: A hundred bucks?
print(sents_1[675])
Output:
Girl: But you already have a Big Mac...

Exemple d'implémentation complet

from nltk.tokenize import PunktSentenceTokenizer
from nltk.corpus import webtext
text = webtext.raw('C://Users/Leekha/training_tokenizer.txt')
sent_tokenizer = PunktSentenceTokenizer(text)
sents_1 = sent_tokenizer.tokenize(text)
print(sents_1[0])

Production

White guy: So, do you have any plans for this evening?

Pour comprendre la différence entre le tokenizer de phrase par défaut de NLTK et notre propre tokenizer de phrase entraînée, laissez-nous tokenize le même fichier avec le tokenizer de phrase par défaut ie sent_tokenize ().

from nltk.tokenize import sent_tokenize
   from nltk.corpus import webtext
   text = webtext.raw('C://Users/Leekha/training_tokenizer.txt')
sents_2 = sent_tokenize(text)

print(sents_2[0])
Output:

White guy: So, do you have any plans for this evening?
print(sents_2[675])
Output:
Hobo: Y'know what I'd do if I was rich?

Avec l'aide de la différence dans la sortie, nous pouvons comprendre le concept qui explique pourquoi il est utile de former notre propre tokenizer de phrase.

Que sont les mots vides?

Certains mots courants qui sont présents dans le texte mais qui ne contribuent pas à la signification d'une phrase. Ces mots ne sont pas du tout importants pour la recherche d'informations ou le traitement du langage naturel. Les mots vides les plus courants sont «le» et «a».

Corpus de mots vides NLTK

En fait, le kit d'outils de langage naturel est livré avec un corpus de mots vides contenant des listes de mots pour de nombreuses langues. Comprenons son utilisation à l'aide de l'exemple suivant -

Tout d'abord, importez les mots vides copus du package nltk.corpus -

from nltk.corpus import stopwords

Maintenant, nous utiliserons des mots vides de langues anglaises

english_stops = set(stopwords.words('english'))
words = ['I', 'am', 'a', 'writer']
[word for word in words if word not in english_stops]

Production

['I', 'writer']

Exemple d'implémentation complet

from nltk.corpus import stopwords
english_stops = set(stopwords.words('english'))
words = ['I', 'am', 'a', 'writer']
[word for word in words if word not in english_stops]

Production

['I', 'writer']

Recherche de la liste complète des langues prises en charge

Avec l'aide du script Python suivant, nous pouvons également trouver la liste complète des langages pris en charge par le corpus de mots d'arrêt NLTK -

from nltk.corpus import stopwords
stopwords.fileids()

Production

[
   'arabic', 'azerbaijani', 'danish', 'dutch', 'english', 'finnish', 'french',
   'german', 'greek', 'hungarian', 'indonesian', 'italian', 'kazakh', 'nepali',
   'norwegian', 'portuguese', 'romanian', 'russian', 'slovene', 'spanish',
   'swedish', 'tajik', 'turkish'
]

Qu'est-ce que Wordnet?

Wordnet est une grande base de données lexicale de l'anglais, qui a été créée par Princeton. Il fait partie du corpus NLTK. Les noms, les verbes, les adjectifs et les adverbes sont tous regroupés en un ensemble de synonymes, c'est-à-dire des synonymes cognitifs. Ici, chaque ensemble de synsets exprime une signification distincte. Voici quelques cas d'utilisation de Wordnet -

  • Il peut être utilisé pour rechercher la définition d'un mot
  • On peut trouver des synonymes et des antonymes d'un mot
  • Les relations et les similitudes entre les mots peuvent être explorées à l'aide de Wordnet
  • Homonymie du sens des mots pour ces mots ayant de multiples utilisations et définitions

Comment importer Wordnet?

Wordnet peut être importé à l'aide de la commande suivante -

from nltk.corpus import wordnet

Pour une commande plus compacte, utilisez ce qui suit -

from nltk.corpus import wordnet as wn

Instances Synset

Les synset sont des regroupements de mots synonymes qui expriment le même concept. Lorsque vous utilisez Wordnet pour rechercher des mots, vous obtenez une liste des instances de Synset.

wordnet.synsets (mot)

Pour obtenir une liste de Synsets, nous pouvons rechercher n'importe quel mot dans Wordnet en utilisant wordnet.synsets(word). Par exemple, dans la prochaine recette Python, nous allons rechercher le Synset pour le `` chien '' avec quelques propriétés et méthodes de Synset -

Exemple

Tout d'abord, importez le wordnet comme suit -

from nltk.corpus import wordnet as wn

Maintenant, indiquez le mot pour lequel vous souhaitez rechercher le Synset -

syn = wn.synsets('dog')[0]

Ici, nous utilisons la méthode name () pour obtenir le nom unique du synset qui peut être utilisé pour obtenir directement le Synset -

syn.name()
Output:
'dog.n.01'

Ensuite, nous utilisons la méthode definition () qui nous donnera la définition du mot -

syn.definition()
Output:
'a member of the genus Canis (probably descended from the common wolf) that has
been domesticated by man since prehistoric times; occurs in many breeds'

Une autre méthode est examples () qui nous donnera les exemples liés au mot -

syn.examples()
Output:
['the dog barked all night']

Exemple d'implémentation complet

from nltk.corpus import wordnet as wn
syn = wn.synsets('dog')[0]
syn.name()
syn.definition()
syn.examples()

Obtenir des hypernymes

Les synsets sont organisés dans un arbre d'héritage comme une structure dans laquelle Hypernyms représente des termes plus abstraits tandis que Hyponymsreprésente les termes les plus spécifiques. L'une des choses importantes est que cet arbre peut être retracé jusqu'à un hypernyme racine. Comprenons le concept à l'aide de l'exemple suivant -

from nltk.corpus import wordnet as wn
syn = wn.synsets('dog')[0]
syn.hypernyms()

Production

[Synset('canine.n.02'), Synset('domestic_animal.n.01')]

Ici, nous pouvons voir que canine et domestic_animal sont les hypernymes de «chien».

Maintenant, nous pouvons trouver des hyponymes de `` chien '' comme suit -

syn.hypernyms()[0].hyponyms()

Production

[
   Synset('bitch.n.04'),
   Synset('dog.n.01'),
   Synset('fox.n.01'),
   Synset('hyena.n.01'),
   Synset('jackal.n.01'),
   Synset('wild_dog.n.01'),
   Synset('wolf.n.01')
]

À partir de la sortie ci-dessus, nous pouvons voir que «chien» n'est que l'un des nombreux hyponymes de «domestic_animals».

Pour trouver la racine de tout cela, nous pouvons utiliser la commande suivante -

syn.root_hypernyms()

Production

[Synset('entity.n.01')]

À partir de la sortie ci-dessus, nous pouvons voir qu'il n'a qu'une seule racine.

Exemple d'implémentation complet

from nltk.corpus import wordnet as wn
syn = wn.synsets('dog')[0]
syn.hypernyms()
syn.hypernyms()[0].hyponyms()
syn.root_hypernyms()

Production

[Synset('entity.n.01')]

Lemmes dans Wordnet

En linguistique, la forme canonique ou morphologique d'un mot est appelée un lemme. Pour trouver un synonyme ainsi qu'un antonyme d'un mot, nous pouvons également rechercher des lemmes dans WordNet. Voyons comment.

Recherche de synonymes

En utilisant la méthode lemma (), nous pouvons trouver le nombre de synonymes d'un Synset. Appliquons cette méthode sur le synset 'chien' -

Exemple

from nltk.corpus import wordnet as wn
syn = wn.synsets('dog')[0]
lemmas = syn.lemmas()
len(lemmas)

Production

3

La sortie ci-dessus montre que «chien» a trois lemmes.

Obtenir le nom du premier lemme comme suit -

lemmas[0].name()
Output:
'dog'

Obtenir le nom du deuxième lemme comme suit -

lemmas[1].name()
Output:
'domestic_dog'

Obtenir le nom du troisième lemme comme suit -

lemmas[2].name()
Output:
'Canis_familiaris'

En fait, un Synset représente un groupe de lemmes qui ont tous une signification similaire tandis qu'un lemme représente une forme de mot distincte.

Trouver des Antonymes

Dans WordNet, certains lemmes ont également des antonymes. Par exemple, le mot «bon» a un total de 27 synets, parmi lesquels 5 ont des lemmes avec des antonymes. Trouvons les antonymes (quand le mot «bon» est utilisé comme nom et quand le mot «bon» est utilisé comme adjectif).

Exemple 1

from nltk.corpus import wordnet as wn
   syn1 = wn.synset('good.n.02')
   antonym1 = syn1.lemmas()[0].antonyms()[0]
antonym1.name()

Production

'evil'

antonym1.synset().definition()

Production

'the quality of being morally wrong in principle or practice'

L'exemple ci-dessus montre que le mot «bien», lorsqu'il est utilisé comme nom, a le premier antonyme «mal».

Exemple 2

from nltk.corpus import wordnet as wn
   syn2 = wn.synset('good.a.01')
   antonym2 = syn2.lemmas()[0].antonyms()[0]
antonym2.name()

Production

'bad'

antonym2.synset().definition()

Production

'having undesirable or negative qualities’

L'exemple ci-dessus montre que le mot «bon», lorsqu'il est utilisé comme adjectif, a le premier antonyme «mauvais».

Qu'est-ce que la tige?

La tige est une technique utilisée pour extraire la forme de base des mots en supprimant les affixes. C'est comme couper les branches d'un arbre jusqu'à ses tiges. Par exemple, la racine des motseating, eats, eaten est eat.

Les moteurs de recherche utilisent la racine pour indexer les mots. C'est pourquoi, plutôt que de stocker toutes les formes d'un mot, un moteur de recherche ne peut stocker que les tiges. De cette manière, l'extraction réduit la taille de l'index et augmente la précision de la récupération.

Divers algorithmes de Stemming

En NLTK, stemmerI, qui ont stem()méthode, l'interface a tous les souches que nous allons couvrir ensuite. Comprenons-le avec le schéma suivant

Algorithme de dérivation de Porter

C'est l'un des algorithmes de dérivation les plus courants qui est essentiellement conçu pour supprimer et remplacer les suffixes bien connus de mots anglais.

Classe PorterStemmer

NLTK a PorterStemmerclasse à l'aide de laquelle nous pouvons facilement implémenter les algorithmes de Porter Stemmer pour le mot que nous voulons dériver. Cette classe connaît plusieurs formes de mots et suffixes réguliers à l'aide desquels elle peut transformer le mot d'entrée en une racine finale. La racine résultante est souvent un mot plus court ayant la même signification de racine. Voyons un exemple -

Tout d'abord, nous devons importer la boîte à outils en langage naturel (nltk).

import nltk

Maintenant, importez le PorterStemmer classe pour implémenter l'algorithme Porter Stemmer.

from nltk.stem import PorterStemmer

Ensuite, créez une instance de la classe Porter Stemmer comme suit -

word_stemmer = PorterStemmer()

Maintenant, saisissez le mot que vous souhaitez extraire.

word_stemmer.stem('writing')

Production

'write'

word_stemmer.stem('eating')

Production

'eat'

Exemple d'implémentation complet

import nltk
from nltk.stem import PorterStemmer
word_stemmer = PorterStemmer()
word_stemmer.stem('writing')

Production

'write'

Algorithme de dérivation Lancaster

Il a été développé à l'Université de Lancaster et c'est un autre algorithme de dérivation très courant.

Classe LancasterStemmer

NLTK a LancasterStemmerclasse à l'aide de laquelle nous pouvons facilement implémenter des algorithmes Lancaster Stemmer pour le mot que nous voulons dériver. Voyons un exemple -

Tout d'abord, nous devons importer la boîte à outils en langage naturel (nltk).

import nltk

Maintenant, importez le LancasterStemmer classe pour implémenter l'algorithme Lancaster Stemmer

from nltk.stem import LancasterStemmer

Ensuite, créez une instance de LancasterStemmer classe comme suit -

Lanc_stemmer = LancasterStemmer()

Maintenant, saisissez le mot que vous souhaitez extraire.

Lanc_stemmer.stem('eats')

Production

'eat'

Exemple d'implémentation complet

import nltk
from nltk.stem import LancatserStemmer
Lanc_stemmer = LancasterStemmer()
Lanc_stemmer.stem('eats')

Production

'eat'

Algorithme de dérivation d'expression régulière

Avec l'aide de cet algorithme de tige, nous pouvons construire notre propre tige.

Classe RegexpStemmer

NLTK a RegexpStemmerclasse à l'aide de laquelle nous pouvons facilement implémenter des algorithmes d'expressions régulières Stemmer. Il prend essentiellement une seule expression régulière et supprime tout préfixe ou suffixe qui correspond à l'expression. Voyons un exemple -

Tout d'abord, nous devons importer la boîte à outils en langage naturel (nltk).

import nltk

Maintenant, importez le RegexpStemmer classe pour implémenter l'algorithme Regular Expression Stemmer.

from nltk.stem import RegexpStemmer

Ensuite, créez une instance de RegexpStemmer class et fournit le suffixe ou le préfixe que vous souhaitez supprimer du mot comme suit -

Reg_stemmer = RegexpStemmer(‘ing’)

Maintenant, saisissez le mot que vous souhaitez extraire.

Reg_stemmer.stem('eating')

Production

'eat'

Reg_stemmer.stem('ingeat')

Production

'eat'
Reg_stemmer.stem('eats')

Production

'eat'

Exemple d'implémentation complet

import nltk
from nltk.stem import RegexpStemmer
Reg_stemmer = RegexpStemmer()
Reg_stemmer.stem('ingeat')

Production

'eat'

Algorithme de tige de boule de neige

C'est un autre algorithme de dérivation très utile.

SnowballStemmer classe

NLTK a SnowballStemmerclasse à l'aide de laquelle nous pouvons facilement implémenter les algorithmes Snowball Stemmer. Il prend en charge 15 langues non anglaises. Pour utiliser cette classe steaming, nous devons créer une instance avec le nom du langage que nous utilisons, puis appeler la méthode stem (). Voyons un exemple -

Tout d'abord, nous devons importer la boîte à outils en langage naturel (nltk).

import nltk

Maintenant, importez le SnowballStemmer classe pour implémenter l'algorithme Snowball Stemmer

from nltk.stem import SnowballStemmer

Voyons les langues qu'il prend en charge -

SnowballStemmer.languages

Production

(
   'arabic',
   'danish',
   'dutch',
   'english',
   'finnish',
   'french',
   'german',
   'hungarian',
   'italian',
   'norwegian',
   'porter',
   'portuguese',
   'romanian',
   'russian',
   'spanish',
   'swedish'
)

Ensuite, créez une instance de la classe SnowballStemmer avec la langue que vous souhaitez utiliser. Ici, nous créons la tige de la langue «française».

French_stemmer = SnowballStemmer(‘french’)

Maintenant, appelez la méthode stem () et entrez le mot que vous souhaitez extraire.

French_stemmer.stem (‘Bonjoura’)

Production

'bonjour'

Exemple d'implémentation complet

import nltk
from nltk.stem import SnowballStemmer
French_stemmer = SnowballStemmer(‘french’)
French_stemmer.stem (‘Bonjoura’)

Production

'bonjour'

Qu'est-ce que la lemmatisation?

La technique de lemmatisation est comme la racine. La sortie que nous obtiendrons après la lemmatisation est appelée «lemme», qui est un mot racine plutôt qu'une racine racine, la sortie de la racine. Après la lemmatisation, nous obtiendrons un mot valide qui signifie la même chose.

NLTK fournit WordNetLemmatizer classe qui est une fine enveloppe autour du wordnetcorpus. Cette classe utilisemorphy() fonction à la WordNet CorpusReaderclasse pour trouver un lemme. Comprenons-le avec un exemple -

Exemple

Tout d'abord, nous devons importer la boîte à outils en langage naturel (nltk).

import nltk

Maintenant, importez le WordNetLemmatizer classe pour implémenter la technique de lemmatisation.

from nltk.stem import WordNetLemmatizer

Ensuite, créez une instance de WordNetLemmatizer classe.

lemmatizer = WordNetLemmatizer()

Maintenant, appelez la méthode lemmatize () et entrez le mot dont vous voulez trouver le lemme.

lemmatizer.lemmatize('eating')

Production

'eating'
lemmatizer.lemmatize('books')

Production

'book'

Exemple d'implémentation complet

import nltk
from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
lemmatizer.lemmatize('books')

Production

'book'

Différence entre la tige et la lemmatisation

Comprenons la différence entre Stemming et Lemmatization à l'aide de l'exemple suivant -

import nltk
from nltk.stem import PorterStemmer
word_stemmer = PorterStemmer()
word_stemmer.stem('believes')

Production

believ

import nltk
from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
lemmatizer.lemmatize(' believes ')

Production

believ

La sortie des deux programmes indique la différence majeure entre la tige et la lemmatisation. PorterStemmerla classe coupe le «es» du mot. D'autre part,WordNetLemmatizerclass trouve un mot valide. En termes simples, la technique du radical ne regarde que la forme du mot tandis que la technique de la lemmatisation se penche sur le sens du mot. Cela signifie qu'après l'application de la lemmatisation, nous obtiendrons toujours un mot valide.

La radicalisation et la lemmatisation peuvent être considérées comme une sorte de compression linguistique. Dans le même sens, le remplacement de mot peut être considéré comme une normalisation de texte ou une correction d'erreur.

Mais pourquoi avons-nous besoin d'un remplacement de mot? Supposons que si nous parlons de tokenisation, alors il y a des problèmes de contractions (comme je ne peux pas, je ne veux pas, etc.). Donc, pour gérer ces problèmes, nous avons besoin d'un remplacement de mot. Par exemple, nous pouvons remplacer les contractions par leurs formes développées.

Remplacement de mot à l'aide d'une expression régulière

Tout d'abord, nous allons remplacer les mots qui correspondent à l'expression régulière. Mais pour cela, nous devons avoir une compréhension de base des expressions régulières ainsi que du module python re. Dans l'exemple ci-dessous, nous remplacerons la contraction par leurs formes développées (par exemple «ne peut pas» sera remplacé par «ne peut pas»), tout cela en utilisant des expressions régulières.

Exemple

Tout d'abord, importez le package nécessaire pour travailler avec des expressions régulières.

import re
from nltk.corpus import wordnet

Ensuite, définissez les modèles de remplacement de votre choix comme suit -

R_patterns = [
   (r'won\'t', 'will not'),
   (r'can\'t', 'cannot'),
   (r'i\'m', 'i am'),
   r'(\w+)\'ll', '\g<1> will'),
   (r'(\w+)n\'t', '\g<1> not'),
   (r'(\w+)\'ve', '\g<1> have'),
   (r'(\w+)\'s', '\g<1> is'),
   (r'(\w+)\'re', '\g<1> are'),
]

Maintenant, créez une classe qui peut être utilisée pour remplacer des mots -

class REReplacer(object):
   def __init__(self, pattern = R_patterns):
      self.pattern = [(re.compile(regex), repl) for (regex, repl) in patterns]
   def replace(self, text):
      s = text
      for (pattern, repl) in self.pattern:
         s = re.sub(pattern, repl, s)
      return s

Enregistrez ce programme python (disons repRE.py) et exécutez-le à partir de l'invite de commande python. Après l'avoir exécuté, importez la classe REReplacer lorsque vous souhaitez remplacer des mots. Voyons comment.

from repRE import REReplacer
rep_word = REReplacer()
rep_word.replace("I won't do it")
Output:
'I will not do it'
rep_word.replace("I can’t do it")
Output:
'I cannot do it'

Exemple d'implémentation complet

import re
from nltk.corpus import wordnet
R_patterns = [
   (r'won\'t', 'will not'),
   (r'can\'t', 'cannot'),
   (r'i\'m', 'i am'),
   r'(\w+)\'ll', '\g<1> will'),
   (r'(\w+)n\'t', '\g<1> not'),
   (r'(\w+)\'ve', '\g<1> have'),
   (r'(\w+)\'s', '\g<1> is'),
   (r'(\w+)\'re', '\g<1> are'),
]
class REReplacer(object):
def __init__(self, patterns=R_patterns):
   self.patterns = [(re.compile(regex), repl) for (regex, repl) in patterns]
def replace(self, text):
   s = text
   for (pattern, repl) in self.patterns:
      s = re.sub(pattern, repl, s)
   return s

Maintenant, une fois que vous avez enregistré le programme ci-dessus et que vous l'avez exécuté, vous pouvez importer la classe et l'utiliser comme suit -

from replacerRE import REReplacer
rep_word = REReplacer()
rep_word.replace("I won't do it")

Production

'I will not do it'

Remplacement avant traitement de texte

L'une des pratiques courantes lors de l'utilisation du traitement du langage naturel (PNL) consiste à nettoyer le texte avant le traitement de texte. Dans ce souci, nous pouvons également utiliser notreREReplacer classe créée ci-dessus dans l'exemple précédent, comme étape préliminaire avant le traitement de texte, c'est-à-dire la tokenisation.

Exemple

from nltk.tokenize import word_tokenize
from replacerRE import REReplacer
rep_word = REReplacer()
word_tokenize("I won't be able to do this now")
Output:
['I', 'wo', "n't", 'be', 'able', 'to', 'do', 'this', 'now']
word_tokenize(rep_word.replace("I won't be able to do this now"))
Output:
['I', 'will', 'not', 'be', 'able', 'to', 'do', 'this', 'now']

Dans la recette Python ci-dessus, nous pouvons facilement comprendre la différence entre la sortie du mot tokenizer sans et avec l'utilisation de l'expression régulière replace.

Suppression des caractères répétitifs

Sommes-nous strictement grammaticaux dans notre langage courant? Non nous ne sommes pas. Par exemple, nous écrivons parfois «Hiiiiiiiiiiii Mohan» afin de souligner le mot «Hi». Mais le système informatique ne sait pas que «Hiiiiiiiiiiii» est une variante du mot «Salut». Dans l'exemple ci-dessous, nous allons créer une classe nomméerep_word_removal qui peut être utilisé pour supprimer les mots répétés.

Exemple

Tout d'abord, importez le package nécessaire pour travailler avec des expressions régulières

import re
from nltk.corpus import wordnet

Maintenant, créez une classe qui peut être utilisée pour supprimer les mots qui se répètent -

class Rep_word_removal(object):
   def __init__(self):
      self.repeat_regexp = re.compile(r'(\w*)(\w)\2(\w*)')
      self.repl = r'\1\2\3'
   def replace(self, word):
      if wordnet.synsets(word):
      return word
   repl_word = self.repeat_regexp.sub(self.repl, word)
   if repl_word != word:
      return self.replace(repl_word)
   else:
      return repl_word

Enregistrez ce programme python (disons removerepeat.py) et exécutez-le à partir de l'invite de commande python. Après l'avoir exécuté, importezRep_word_removalclasse lorsque vous souhaitez supprimer les mots qui se répètent. Voyons comment?

from removalrepeat import Rep_word_removal
rep_word = Rep_word_removal()
rep_word.replace ("Hiiiiiiiiiiiiiiiiiiiii")
Output:
'Hi'
rep_word.replace("Hellooooooooooooooo")
Output:
'Hello'

Exemple d'implémentation complet

import re
from nltk.corpus import wordnet
class Rep_word_removal(object):
   def __init__(self):
      self.repeat_regexp = re.compile(r'(\w*)(\w)\2(\w*)')
      self.repl = r'\1\2\3'
   def replace(self, word):
      if wordnet.synsets(word):
         return word
   replace_word = self.repeat_regexp.sub(self.repl, word)
   if replace_word != word:
      return self.replace(replace_word)
   else:
      return replace_word

Maintenant, une fois que vous avez enregistré le programme ci-dessus et que vous l'avez exécuté, vous pouvez importer la classe et l'utiliser comme suit -

from removalrepeat import Rep_word_removal
rep_word = Rep_word_removal()
rep_word.replace ("Hiiiiiiiiiiiiiiiiiiiii")

Production

'Hi'

Remplacement de mots par des synonymes courants

En travaillant avec la PNL, notamment dans le cas de l'analyse fréquentielle et de l'indexation de texte, il est toujours avantageux de compresser le vocabulaire sans perdre de sens car cela économise beaucoup de mémoire. Pour y parvenir, nous devons définir la mise en correspondance d'un mot avec ses synonymes. Dans l'exemple ci-dessous, nous allons créer une classe nomméeword_syn_replacer qui peut être utilisé pour remplacer les mots par leurs synonymes communs.

Exemple

Tout d'abord, importez le package nécessaire re pour travailler avec des expressions régulières.

import re
from nltk.corpus import wordnet

Ensuite, créez la classe qui prend un mappage de remplacement de mot -

class word_syn_replacer(object):
   def __init__(self, word_map):
   self.word_map = word_map
def replace(self, word):
   return self.word_map.get(word, word)

Enregistrez ce programme python (disons replacesyn.py) et exécutez-le à partir de l'invite de commande python. Après l'avoir exécuté, importezword_syn_replacerclasse lorsque vous souhaitez remplacer des mots par des synonymes courants. Voyons comment.

from replacesyn import word_syn_replacer
rep_syn = word_syn_replacer ({‘bday’: ‘birthday’)
rep_syn.replace(‘bday’)

Production

'birthday'

Exemple d'implémentation complet

import re
from nltk.corpus import wordnet
class word_syn_replacer(object):
   def __init__(self, word_map):
   self.word_map = word_map
def replace(self, word):
   return self.word_map.get(word, word)

Maintenant, une fois que vous avez enregistré le programme ci-dessus et que vous l'avez exécuté, vous pouvez importer la classe et l'utiliser comme suit -

from replacesyn import word_syn_replacer
rep_syn = word_syn_replacer ({‘bday’: ‘birthday’)
rep_syn.replace(‘bday’)

Production

'birthday'

L'inconvénient de la méthode ci-dessus est que nous devrions avoir à coder en dur les synonymes dans un dictionnaire Python. Nous avons deux meilleures alternatives sous la forme de fichiers CSV et YAML. Nous pouvons enregistrer notre vocabulaire de synonymes dans l'un des fichiers mentionnés ci-dessus et pouvons construireword_mapdictionnaire d'eux. Comprenons le concept à l'aide d'exemples.

Utilisation du fichier CSV

Afin d'utiliser le fichier CSV à cette fin, le fichier doit avoir deux colonnes, la première colonne se compose de mot et la deuxième colonne comprend les synonymes destinés à le remplacer. Sauvegardons ce fichier soussyn.csv. Dans l'exemple ci-dessous, nous allons créer une classe nommée CSVword_syn_replacer qui s'étendra word_syn_replacer dans replacesyn.py fichier et sera utilisé pour construire le word_map dictionnaire de syn.csv fichier.

Exemple

Tout d'abord, importez les packages nécessaires.

import csv

Ensuite, créez la classe qui prend un mappage de remplacement de mot -

class CSVword_syn_replacer(word_syn_replacer):
   def __init__(self, fname):
      word_map = {}
      for line in csv.reader(open(fname)):
         word, syn = line
         word_map[word] = syn
      super(Csvword_syn_replacer, self).__init__(word_map)

Après l'avoir exécuté, importez CSVword_syn_replacerclasse lorsque vous souhaitez remplacer des mots par des synonymes courants. Voyons comment?

from replacesyn import CSVword_syn_replacer
rep_syn = CSVword_syn_replacer (‘syn.csv’)
rep_syn.replace(‘bday’)

Production

'birthday'

Exemple d'implémentation complet

import csv
class CSVword_syn_replacer(word_syn_replacer):
def __init__(self, fname):
word_map = {}
for line in csv.reader(open(fname)):
   word, syn = line
   word_map[word] = syn
super(Csvword_syn_replacer, self).__init__(word_map)

Maintenant, une fois que vous avez enregistré le programme ci-dessus et que vous l'avez exécuté, vous pouvez importer la classe et l'utiliser comme suit -

from replacesyn import CSVword_syn_replacer
rep_syn = CSVword_syn_replacer (‘syn.csv’)
rep_syn.replace(‘bday’)

Production

'birthday'

Utilisation du fichier YAML

Comme nous avons utilisé le fichier CSV, nous pouvons également utiliser le fichier YAML pour cela (nous devons avoir PyYAML installé). Sauvegardons le fichier soussyn.yaml. Dans l'exemple ci-dessous, nous allons créer une classe nommée YAMLword_syn_replacer qui s'étendra word_syn_replacer dans replacesyn.py fichier et sera utilisé pour construire le word_map dictionnaire de syn.yaml fichier.

Exemple

Tout d'abord, importez les packages nécessaires.

import yaml

Ensuite, créez la classe qui prend un mappage de remplacement de mot -

class YAMLword_syn_replacer(word_syn_replacer):
   def __init__(self, fname):
   word_map = yaml.load(open(fname))
   super(YamlWordReplacer, self).__init__(word_map)

Après l'avoir exécuté, importez YAMLword_syn_replacerclasse lorsque vous souhaitez remplacer des mots par des synonymes courants. Voyons comment?

from replacesyn import YAMLword_syn_replacer
rep_syn = YAMLword_syn_replacer (‘syn.yaml’)
rep_syn.replace(‘bday’)

Production

'birthday'

Exemple d'implémentation complet

import yaml
class YAMLword_syn_replacer(word_syn_replacer):
def __init__(self, fname):
   word_map = yaml.load(open(fname))
   super(YamlWordReplacer, self).__init__(word_map)

Maintenant, une fois que vous avez enregistré le programme ci-dessus et que vous l'avez exécuté, vous pouvez importer la classe et l'utiliser comme suit -

from replacesyn import YAMLword_syn_replacer
rep_syn = YAMLword_syn_replacer (‘syn.yaml’)
rep_syn.replace(‘bday’)

Production

'birthday'

Remplacement d'Antonyme

Comme nous savons qu'un antonyme est un mot ayant une signification opposée à un autre mot, et le contraire du remplacement de synonyme est appelé remplacement d'antonyme. Dans cette section, nous traiterons du remplacement des antonymes, c'est-à-dire du remplacement des mots par des antonymes non ambigus en utilisant WordNet. Dans l'exemple ci-dessous, nous allons créer une classe nomméeword_antonym_replacer qui ont deux méthodes, l'une pour remplacer le mot et l'autre pour supprimer les négations.

Exemple

Tout d'abord, importez les packages nécessaires.

from nltk.corpus import wordnet

Ensuite, créez la classe nommée word_antonym_replacer -

class word_antonym_replacer(object):
   def replace(self, word, pos=None):
      antonyms = set()
      for syn in wordnet.synsets(word, pos=pos):
         for lemma in syn.lemmas():
            for antonym in lemma.antonyms():
               antonyms.add(antonym.name())
      if len(antonyms) == 1:
         return antonyms.pop()
      else:
         return None
   def replace_negations(self, sent):
      i, l = 0, len(sent)
      words = []
      while i < l:
         word = sent[i]
         if word == 'not' and i+1 < l:
            ant = self.replace(sent[i+1])
            if ant:
               words.append(ant)
               i += 2
               continue
         words.append(word)
         i += 1
      return words

Enregistrez ce programme python (disons replaceantonym.py) et exécutez-le à partir de l'invite de commande python. Après l'avoir exécuté, importezword_antonym_replacerclasse lorsque vous souhaitez remplacer des mots par leurs antonymes non ambigus. Voyons comment.

from replacerantonym import word_antonym_replacer
rep_antonym = word_antonym_replacer ()
rep_antonym.replace(‘uglify’)

Production

['beautify'']
sentence = ["Let us", 'not', 'uglify', 'our', 'country']
rep_antonym.replace _negations(sentence)

Production

["Let us", 'beautify', 'our', 'country']

Exemple d'implémentation complet

nltk.corpus import wordnet
class word_antonym_replacer(object):
def replace(self, word, pos=None):
   antonyms = set()
   for syn in wordnet.synsets(word, pos=pos):
      for lemma in syn.lemmas():
      for antonym in lemma.antonyms():
         antonyms.add(antonym.name())
   if len(antonyms) == 1:
      return antonyms.pop()
   else:
      return None
def replace_negations(self, sent):
   i, l = 0, len(sent)
   words = []
   while i < l:
      word = sent[i]
      if word == 'not' and i+1 < l:
         ant = self.replace(sent[i+1])
         if ant:
            words.append(ant)
            i += 2
            continue
      words.append(word)
      i += 1
   return words

Maintenant, une fois que vous avez enregistré le programme ci-dessus et que vous l'avez exécuté, vous pouvez importer la classe et l'utiliser comme suit -

from replacerantonym import word_antonym_replacer
rep_antonym = word_antonym_replacer ()
rep_antonym.replace(‘uglify’)
sentence = ["Let us", 'not', 'uglify', 'our', 'country']
rep_antonym.replace _negations(sentence)

Production

["Let us", 'beautify', 'our', 'country']

Qu'est-ce qu'un corpus?

Un corpus est une grande collection, au format structuré, de textes lisibles par machine qui ont été produits dans un cadre de communication naturel. Le mot Corpora est le pluriel de Corpus. Le corpus peut être dérivé de plusieurs manières comme suit -

  • Du texte qui était à l'origine électronique
  • À partir des transcriptions de la langue parlée
  • De la reconnaissance optique de caractères et ainsi de suite

La représentativité du corpus, l'équilibre du corpus, l'échantillonnage, la taille du corpus sont les éléments qui jouent un rôle important lors de la conception du corpus. Certains des corpus les plus populaires pour les tâches PNL sont TreeBank, PropBank, VarbNet et WordNet.

Comment créer un corpus personnalisé?

Lors du téléchargement de NLTK, nous avons également installé le package de données NLTK. Ainsi, nous avons déjà installé le paquet de données NLTK sur notre ordinateur. Si nous parlons de Windows, nous supposerons que ce package de données est installé àC:\natural_language_toolkit_data et si nous parlons de Linux, Unix et Mac OS X, nous supposerons que ce paquet de données est installé à /usr/share/natural_language_toolkit_data.

Dans la recette Python suivante, nous allons créer des corpus personnalisés qui doivent se trouver dans l'un des chemins définis par NLTK. Il en est ainsi car il peut être trouvé par NLTK. Afin d'éviter tout conflit avec le paquet de données officiel NLTK, créons un répertoire natural_language_toolkit_data personnalisé dans notre répertoire personnel.

import os, os.path
path = os.path.expanduser('~/natural_language_toolkit_data')
if not os.path.exists(path):
   os.mkdir(path)
os.path.exists(path)

Production

True

Maintenant, vérifions si nous avons le répertoire natural_language_toolkit_data dans notre répertoire personnel ou non -

import nltk.data
path in nltk.data.path

Production

True

Comme nous avons la sortie True, cela signifie que nous avons nltk_data répertoire dans notre répertoire personnel.

Maintenant, nous allons créer un fichier de liste de mots, nommé wordfile.txt et placez-le dans un dossier, nommé corpus dans nltk_data annuaire (~/nltk_data/corpus/wordfile.txt) et le chargera en utilisant nltk.data.load -

import nltk.data
nltk.data.load(‘corpus/wordfile.txt’, format = ‘raw’)

Production

b’tutorialspoint\n’

Lecteurs Corpus

NLTK fournit diverses classes CorpusReader. Nous allons les couvrir dans les recettes python suivantes

Créer un corpus de listes de mots

NLTK a WordListCorpusReaderclasse qui donne accès au fichier contenant une liste de mots. Pour la recette Python suivante, nous devons créer un fichier de liste de mots qui peut être CSV ou un fichier texte normal. Par exemple, nous avons créé un fichier nommé 'list' qui contient les données suivantes -

tutorialspoint
Online
Free
Tutorials

Maintenant, instancions un WordListCorpusReader classe produisant la liste des mots à partir de notre fichier créé ‘list’.

from nltk.corpus.reader import WordListCorpusReader
reader_corpus = WordListCorpusReader('.', ['list'])
reader_corpus.words()

Production

['tutorialspoint', 'Online', 'Free', 'Tutorials']

Créer un corpus de mots étiqueté POS

NLTK a TaggedCorpusReaderclasse à l'aide de laquelle nous pouvons créer un corpus de mots étiqueté POS. En fait, le marquage POS est le processus d'identification de la balise de partie de discours d'un mot.

L'un des formats les plus simples pour un corpus étiqueté est de la forme 'mot / étiquette' comme après un extrait du corpus brun -

The/at-tl expense/nn and/cc time/nn involved/vbn are/ber
astronomical/jj ./.

Dans l'extrait ci-dessus, chaque mot a une étiquette qui désigne son POS. Par exemple,vb fait référence à un verbe.

Maintenant, instancions un TaggedCorpusReaderclasse produisant des mots étiquetés POS forment le fichier ‘list.pos’, qui contient l'extrait ci-dessus.

from nltk.corpus.reader import TaggedCorpusReader
reader_corpus = TaggedCorpusReader('.', r'.*\.pos')
reader_corpus.tagged_words()

Production

[('The', 'AT-TL'), ('expense', 'NN'), ('and', 'CC'), ...]

Création d'un corpus de phrases fragmentées

NLTK a ChnkedCorpusReaderclasse à l'aide de laquelle nous pouvons créer un corpus de phrases Chunked. En fait, un morceau est une courte phrase dans une phrase.

Par exemple, nous avons l'extrait suivant du tagged treebank corpus -

[Earlier/JJR staff-reduction/NN moves/NNS] have/VBP trimmed/VBN about/
IN [300/CD jobs/NNS] ,/, [the/DT spokesman/NN] said/VBD ./.

Dans l'extrait ci-dessus, chaque morceau est une phrase nominale, mais les mots qui ne sont pas entre crochets font partie de l'arbre de phrase et ne font pas partie d'un sous-arbre de phrase nominale.

Maintenant, instancions un ChunkedCorpusReader classe produisant une phrase fragmentée à partir du fichier ‘list.chunk’, qui contient l'extrait ci-dessus.

from nltk.corpus.reader import ChunkedCorpusReader
reader_corpus = TaggedCorpusReader('.', r'.*\.chunk')
reader_corpus.chunked_words()

Production

[
   Tree('NP', [('Earlier', 'JJR'), ('staff-reduction', 'NN'), ('moves', 'NNS')]),
   ('have', 'VBP'), ...
]

Créer un corpus de texte catégorisé

NLTK a CategorizedPlaintextCorpusReaderclasse à l'aide de laquelle nous pouvons créer un corpus de texte catégorisé. C'est très utile dans le cas où nous avons un grand corpus de texte et que nous voulons le catégoriser dans des sections séparées.

Par exemple, le corpus brun comprend plusieurs catégories différentes. Découvrons-les à l'aide du code Python suivant -

from nltk.corpus import brown^M
brown.categories()

Production

[
   'adventure', 'belles_lettres', 'editorial', 'fiction', 'government',
   'hobbies', 'humor', 'learned', 'lore', 'mystery', 'news', 'religion',
   'reviews', 'romance', 'science_fiction'
]

L'un des moyens les plus simples de catégoriser un corpus est d'avoir un fichier pour chaque catégorie. Par exemple, voyons les deux extraits dumovie_reviews corpus -

movie_pos.txt

La fine ligne rouge est imparfaite mais elle provoque.

movie_neg.txt

Une production à gros budget et sur papier glacé ne peut pas compenser le manque de spontanéité qui imprègne leur émission de télévision.

Donc, à partir de deux fichiers ci-dessus, nous avons deux catégories à savoir pos et neg.

Maintenant, instancions un CategorizedPlaintextCorpusReader classe.

from nltk.corpus.reader import CategorizedPlaintextCorpusReader
reader_corpus = CategorizedPlaintextCorpusReader('.', r'movie_.*\.txt',
cat_pattern = r'movie_(\w+)\.txt')
reader_corpus.categories()
reader_corpus.fileids(categories = [‘neg’])
reader_corpus.fileids(categories = [‘pos’])

Production

['neg', 'pos']
['movie_neg.txt']
['movie_pos.txt']

Qu'est-ce que le marquage POS?

Le marquage, une sorte de classification, est l'attribution automatique de la description des jetons. Nous appelons le descripteur s 'tag', qui représente une des parties du discours (noms, verbe, adverbes, adjectifs, pronoms, conjonction et leurs sous-catégories), des informations sémantiques, etc.

D'un autre côté, si nous parlons de balisage de partie de parole (POS), il peut être défini comme le processus de conversion d'une phrase sous la forme d'une liste de mots, en une liste de tuples. Ici, les tuples sont sous la forme de (mot, balise). Nous pouvons également appeler le marquage POS un processus d'attribution d'une des parties du discours au mot donné.

Le tableau suivant représente la notification de point de vente la plus fréquemment utilisée dans le corpus Penn Treebank -

Sr.Non Marque La description
1 NNP Nom propre, singulier
2 NNPS Nom propre, pluriel
3 PDT Pré-déterminant
4 POS Fin possessive
5 PRP Pronom personnel
6 PRP $ Pronom possessif
sept RB Adverbe
8 RBR Adverbe, comparatif
9 RBS Adverbe, superlatif
dix RP Particule
11 SYM Symbole (mathématique ou scientifique)
12 À à
13 UH Interjection
14 VB Verbe, forme de base
15 VBD Verbe, passé
16 VBG Verbe, gérondif / participe présent
17 VBN Verbe, passé
18 WP Pronom Wh
19 WP $ Pronom wh possessif
20 WRB Wh-adverbe
21 # Signe dièse
22 $ Signe dollar
23 . Ponctuation finale de la phrase
24 , Virgule
25 : Colon, point-virgule
26 ( Caractère crochet gauche
27 ) Caractère crochet droit
28 " Guillemet double simple
29 ' Guillemet simple ouvert à gauche
30 " Guillemet double ouvert à gauche
31 ' Guillemet simple fermé à droite
32 " Guillemet double ouvert à droite

Exemple

Comprenons-le avec une expérience Python -

import nltk
from nltk import word_tokenize
sentence = "I am going to school"
print (nltk.pos_tag(word_tokenize(sentence)))

Production

[('I', 'PRP'), ('am', 'VBP'), ('going', 'VBG'), ('to', 'TO'), ('school', 'NN')]

Pourquoi le marquage POS?

L'étiquetage des points de vente est une partie importante de la PNL car il constitue la condition préalable à une analyse PNL plus approfondie comme suit -

  • Chunking
  • Analyse syntaxique
  • Extraction d'informations
  • Traduction automatique
  • Analyse des sentiments
  • Analyse grammaticale et désambiguïsation du sens des mots

TaggerI - Classe de base

Tous les tagueurs résident dans le package nltk.tag de NLTK. La classe de base de ces tagueurs estTaggerI, signifie que tous les tagueurs héritent de cette classe.

Methods - La classe TaggerI a les deux méthodes suivantes qui doivent être implémentées par toutes ses sous-classes -

  • tag() method - Comme son nom l'indique, cette méthode prend une liste de mots en entrée et renvoie une liste de mots étiquetés en sortie.

  • evaluate() method - Avec l'aide de cette méthode, nous pouvons évaluer la précision du tagger.

La base de l'étiquetage des points de vente

La ligne de base ou l'étape de base du marquage POS est Default Tagging, qui peut être effectuée à l'aide de la classe DefaultTagger de NLTK. Le balisage par défaut attribue simplement la même balise POS à chaque jeton. Le balisage par défaut fournit également une base de référence pour mesurer les améliorations de précision.

Classe DefaultTagger

Le balisage par défaut est effectué en utilisant DefaultTagging class, qui prend le seul argument, c'est-à-dire la balise que nous voulons appliquer.

Comment ça marche?

Comme indiqué précédemment, tous les tagueurs sont hérités de TaggerIclasse. leDefaultTagger est hérité de SequentialBackoffTagger qui est une sous-classe de TaggerI class. Comprenons-le avec le diagramme suivant -

Comme faisant partie de SeuentialBackoffTagger, la DefaultTagger doit implémenter la méthode choose_tag () qui prend les trois arguments suivants.

  • Liste des jetons
  • Index du jeton actuel
  • Liste des jetons précédents, c'est-à-dire l'historique

Exemple

import nltk
from nltk.tag import DefaultTagger
exptagger = DefaultTagger('NN')
exptagger.tag(['Tutorials','Point'])

Production

[('Tutorials', 'NN'), ('Point', 'NN')]

Dans cet exemple, nous avons choisi une balise de nom car ce sont les types de mots les plus courants. De plus,DefaultTagger est également plus utile lorsque nous choisissons la balise POS la plus courante.

Évaluation de la précision

le DefaultTaggerest également la référence pour évaluer l'exactitude des étiqueteurs. C'est la raison pour laquelle nous pouvons l'utiliser avecevaluate()méthode de mesure de la précision. leevaluate() La méthode prend une liste de jetons étiquetés comme un étalon-or pour évaluer le marqueur.

Voici un exemple dans lequel nous avons utilisé notre tagger par défaut, nommé exptagger, créé ci-dessus, pour évaluer l'exactitude d'un sous-ensemble de treebank phrases marquées corpus -

Exemple

import nltk
from nltk.tag import DefaultTagger
exptagger = DefaultTagger('NN')
from nltk.corpus import treebank
testsentences = treebank.tagged_sents() [1000:]
exptagger.evaluate (testsentences)

Production

0.13198749536374715

La sortie ci-dessus montre qu'en choisissant NN pour chaque étiquette, nous pouvons réaliser des tests de précision d'environ 13% sur 1000 entrées du treebank corpus.

Marquer une liste de phrases

Plutôt que de baliser une seule phrase, les NLTK TaggerI classe nous fournit également un tag_sents()méthode à l'aide de laquelle nous pouvons étiqueter une liste de phrases. Voici l'exemple dans lequel nous avons tagué deux phrases simples

Exemple

import nltk
from nltk.tag import DefaultTagger
exptagger = DefaultTagger('NN')
exptagger.tag_sents([['Hi', ','], ['How', 'are', 'you', '?']])

Production

[
   [
      ('Hi', 'NN'), 
      (',', 'NN')
   ], 
   [
      ('How', 'NN'), 
      ('are', 'NN'),
      ('you', 'NN'), 
      ('?', 'NN')
   ]
]

Dans l'exemple ci-dessus, nous avons utilisé notre tagger par défaut créé précédemment nommé exptagger.

Démarquer une phrase

Nous pouvons également décomposer une phrase. NLTK fournit la méthode nltk.tag.untag () à cet effet. Il prendra une phrase étiquetée comme entrée et fournira une liste de mots sans étiquettes. Voyons un exemple -

Exemple

import nltk
from nltk.tag import untag
untag([('Tutorials', 'NN'), ('Point', 'NN')])

Production

['Tutorials', 'Point']

Qu'est-ce que Unigram Tagger?

Comme son nom l'indique, unigram tagger est un tagger qui n'utilise qu'un seul mot comme contexte pour déterminer le tag POS (Part-of-Speech). En termes simples, Unigram Tagger est un tagger basé sur le contexte dont le contexte est un seul mot, c'est-à-dire Unigram.

Comment ça marche?

NLTK fournit un module nommé UnigramTaggerdans ce but. Mais avant de plonger dans son fonctionnement, comprenons la hiérarchie à l'aide du diagramme suivant -

D'après le diagramme ci-dessus, il est entendu que UnigramTagger est hérité de NgramTagger qui est une sous-classe de ContextTagger, qui hérite de SequentialBackoffTagger.

Le fonctionnement de UnigramTagger est expliqué à l'aide des étapes suivantes -

  • Comme nous l'avons vu, UnigramTagger hérite de ContextTagger, il implémente un context()méthode. Cecontext() La méthode prend les trois mêmes arguments que choose_tag() méthode.

  • Le résultat de context()method sera le mot token qui sera ensuite utilisé pour créer le modèle. Une fois le modèle créé, le mot token est également utilisé pour rechercher la meilleure balise.

  • De cette façon, UnigramTagger construira un modèle de contexte à partir de la liste des phrases marquées.

Formation d'un tagueur Unigram

NLTK UnigramTaggerpeuvent être formés en fournissant une liste de phrases marquées au moment de l'initialisation. Dans l'exemple ci-dessous, nous allons utiliser les phrases balisées du corpus treebank. Nous utiliserons les 2500 premières phrases de ce corpus.

Exemple

Importez d'abord le module UniframTagger de nltk -

from nltk.tag import UnigramTagger

Ensuite, importez le corpus que vous souhaitez utiliser. Ici, nous utilisons le corpus treebank -

from nltk.corpus import treebank

Maintenant, prenez les phrases à des fins de formation. Nous prenons les 2500 premières phrases à des fins de formation et les marquerons -

train_sentences = treebank.tagged_sents()[:2500]

Ensuite, appliquez UnigramTagger sur les phrases utilisées à des fins de formation -

Uni_tagger = UnigramTagger(train_sentences)

Prenez quelques phrases, soit égales ou moins prises à des fins de formation, soit 2500, à des fins de test. Ici, nous prenons les premiers 1500 à des fins de test -

test_sentences = treebank.tagged_sents()[1500:]
Uni_tagger.evaluate(test_sents)

Production

0.8942306156033808

Ici, nous avons obtenu une précision d'environ 89% pour un tagueur qui utilise la recherche d'un seul mot pour déterminer la balise POS.

Exemple d'implémentation complet

from nltk.tag import UnigramTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Uni_tagger = UnigramTagger(train_sentences)
test_sentences = treebank.tagged_sents()[1500:]
Uni_tagger.evaluate(test_sentences)

Production

0.8942306156033808

Remplacer le modèle de contexte

À partir du diagramme ci-dessus montrant la hiérarchie pour UnigramTagger, nous connaissons tous les tagueurs qui héritent de ContextTagger, au lieu de former le leur, peuvent prendre un modèle pré-construit. Ce modèle pré-construit est simplement un mappage de dictionnaire Python d'une clé de contexte à une balise. Et pourUnigramTagger, les clés de contexte sont des mots individuels tandis que pour d'autres NgramTagger sous-classes, ce seront des tuples.

Nous pouvons remplacer ce modèle de contexte en passant un autre modèle simple au UnigramTaggerclasse au lieu de passer l'ensemble de formation. Comprenons-le à l'aide d'un exemple simple ci-dessous -

Exemple

from nltk.tag import UnigramTagger
from nltk.corpus import treebank
Override_tagger = UnigramTagger(model = {‘Vinken’ : ‘NN’})
Override_tagger.tag(treebank.sents()[0])

Production

[
   ('Pierre', None),
   ('Vinken', 'NN'),
   (',', None),
   ('61', None),
   ('years', None),
   ('old', None),
   (',', None),
   ('will', None),
   ('join', None),
   ('the', None),
   ('board', None),
   ('as', None),
   ('a', None),
   ('nonexecutive', None),
   ('director', None),
   ('Nov.', None),
   ('29', None),
   ('.', None)
]

Comme notre modèle contient 'Vinken' comme seule clé de contexte, vous pouvez observer à partir de la sortie ci-dessus que seul ce mot a une balise et tous les autres mots ont None comme balise.

Définition d'un seuil de fréquence minimum

Pour décider quelle balise est la plus probable pour un contexte donné, le ContextTaggerla classe utilise la fréquence d'occurrence. Il le fera par défaut même si le mot de contexte et la balise n'apparaissent qu'une seule fois, mais nous pouvons définir un seuil de fréquence minimum en passant uncutoff valeur à la UnigramTaggerclasse. Dans l'exemple ci-dessous, nous transmettons la valeur limite dans la recette précédente dans laquelle nous avons formé un UnigramTagger -

Exemple

from nltk.tag import UnigramTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Uni_tagger = UnigramTagger(train_sentences, cutoff = 4)
test_sentences = treebank.tagged_sents()[1500:]
Uni_tagger.evaluate(test_sentences)

Production

0.7357651629613641

Combiner des tagueurs

Combiner des étiqueteurs ou enchaîner des étiqueteurs les uns avec les autres est l'une des caractéristiques importantes de NLTK. Le concept principal derrière la combinaison des marqueurs est que, dans le cas où un marqueur ne sait pas comment étiqueter un mot, il serait passé au marqueur chaîné. Pour atteindre cet objectif,SequentialBackoffTagger nous fournit le Backoff tagging fonctionnalité.

Balisage d'interruption

Comme indiqué précédemment, le balisage d'interruption est l'une des caractéristiques importantes de SequentialBackoffTagger, ce qui nous permet de combiner des tagueurs de telle sorte que si un tagueur ne sait pas comment taguer un mot, le mot serait passé au tagger suivant et ainsi de suite jusqu'à ce qu'il n'y ait plus de taggeurs backoff à vérifier.

Comment ça marche?

En fait, chaque sous-classe de SequentialBackoffTaggerpeut prendre un argument de mot-clé «backoff». La valeur de cet argument de mot-clé est une autre instance d'unSequentialBackoffTagger. Maintenant chaque fois que çaSequentialBackoffTaggerclass est initialisée, une liste interne de taggers backoff (avec elle-même comme premier élément) sera créée. De plus, si un tagger backoff est donné, la liste interne de ces taggers backoff sera ajoutée.

Dans l'exemple ci-dessous, nous prenons DefaulTagger comme tagger backoff dans la recette Python ci-dessus avec laquelle nous avons formé le UnigramTagger.

Exemple

Dans cet exemple, nous utilisons DefaulTaggeren tant que tagueur de backoff. Chaque fois que leUnigramTagger ne peut pas marquer un mot, backoff tagger, ie DefaulTagger, dans notre cas, le marquera avec «NN».

from nltk.tag import UnigramTagger
from nltk.tag import DefaultTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
back_tagger = DefaultTagger('NN')
Uni_tagger = UnigramTagger(train_sentences, backoff = back_tagger)
test_sentences = treebank.tagged_sents()[1500:]
Uni_tagger.evaluate(test_sentences)

Production

0.9061975746536931

À partir de la sortie ci-dessus, vous pouvez observer qu'en ajoutant un tagger backoff, la précision est augmentée d'environ 2%.

Sauver les tagueurs avec du cornichon

Comme nous l'avons vu, la formation d'un tagueur est très lourde et prend également du temps. Pour gagner du temps, nous pouvons choisir un tagueur entraîné pour l'utiliser plus tard. Dans l'exemple ci-dessous, nous allons faire cela à notre tagueur déjà entraîné nommé‘Uni_tagger’.

Exemple

import pickle
f = open('Uni_tagger.pickle','wb')
pickle.dump(Uni_tagger, f)
f.close()
f = open('Uni_tagger.pickle','rb')
Uni_tagger = pickle.load(f)

Classe NgramTagger

À partir du diagramme hiérarchique présenté dans l'unité précédente, UnigramTagger est hérité de NgarmTagger class mais nous avons encore deux sous-classes de NgarmTagger classe -

Sous-classe BigramTagger

En fait, un ngram est une sous-séquence de n éléments, donc, comme son nom l'indique, BigramTaggerla sous-classe examine les deux éléments. Le premier élément est le mot étiqueté précédent et le deuxième élément est le mot étiqueté actuel.

Sous-classe TrigramTagger

Sur la même note de BigramTagger, TrigramTagger la sous-classe examine les trois éléments, c'est-à-dire deux mots étiquetés précédents et un mot étiqueté courant.

Pratiquement si nous postulons BigramTagger et TrigramTaggersous-classes individuellement comme nous l'avons fait avec la sous-classe UnigramTagger, elles fonctionnent toutes les deux très mal. Voyons dans les exemples ci-dessous:

Utilisation de la sous-classe BigramTagger

from nltk.tag import BigramTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Bi_tagger = BigramTagger(train_sentences)
test_sentences = treebank.tagged_sents()[1500:]
Bi_tagger.evaluate(test_sentences)

Production

0.44669191071913594

Utilisation de la sous-classe TrigramTagger

from nltk.tag import TrigramTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Tri_tagger = TrigramTagger(train_sentences)
test_sentences = treebank.tagged_sents()[1500:]
Tri_tagger.evaluate(test_sentences)

Production

0.41949863394526193

Vous pouvez comparer les performances de UnigramTagger, que nous avons utilisé précédemment (donne une précision d'environ 89%) avec BigramTagger (donne une précision d'environ 44%) et TrigramTagger (donne une précision d'environ 41%). La raison en est que les tagueurs Bigram et Trigram ne peuvent pas apprendre le contexte à partir du ou des premiers mots d'une phrase. D'autre part, la classe UnigramTagger ne se soucie pas du contexte précédent et devine la balise la plus courante pour chaque mot, donc capable d'avoir une précision de base élevée.

Combiner des taggers ngram

À partir des exemples ci-dessus, il est évident que les tagueurs Bigram et Trigram peuvent contribuer lorsque nous les combinons avec le marquage backoff. Dans l'exemple ci-dessous, nous combinons des taggers Unigram, Bigram et Trigram avec un marquage backoff. Le concept est le même que la recette précédente tout en combinant l'UnigramTagger avec le tagger backoff. La seule différence est que nous utilisons la fonction nommée backoff_tagger () de tagger_util.py, donnée ci-dessous, pour l'opération de backoff.

def backoff_tagger(train_sentences, tagger_classes, backoff=None):
   for cls in tagger_classes:
      backoff = cls(train_sentences, backoff=backoff)
   return backoff

Exemple

from tagger_util import backoff_tagger
from nltk.tag import UnigramTagger
from nltk.tag import BigramTagger
from nltk.tag import TrigramTagger
from nltk.tag import DefaultTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
back_tagger = DefaultTagger('NN')
Combine_tagger = backoff_tagger(train_sentences,
[UnigramTagger, BigramTagger, TrigramTagger], backoff = back_tagger)
test_sentences = treebank.tagged_sents()[1500:]
Combine_tagger.evaluate(test_sentences)

Production

0.9234530029238365

À partir de la sortie ci-dessus, nous pouvons voir qu'il augmente la précision d'environ 3%.

Affixer Tagger

Une autre classe importante de la sous-classe ContextTagger est AffixTagger. Dans la classe AffixTagger, le contexte est soit le préfixe, soit le suffixe d'un mot. C'est la raison pour laquelle la classe AffixTagger peut apprendre des balises basées sur des sous-chaînes de longueur fixe du début ou de la fin d'un mot.

Comment ça marche?

Son fonctionnement dépend de l'argument nommé affix_length qui spécifie la longueur du préfixe ou du suffixe. La valeur par défaut est 3. Mais comment distingue-t-il si la classe AffixTagger a appris le préfixe ou le suffixe du mot?

  • affix_length=positive - Si la valeur de affix_lenght est positive, cela signifie que la classe AffixTagger apprendra les préfixes des mots.

  • affix_length=negative - Si la valeur de affix_lenght est négative, cela signifie que la classe AffixTagger apprendra les suffixes des mots.

Pour être plus clair, dans l'exemple ci-dessous, nous utiliserons la classe AffixTagger sur des phrases treebank étiquetées.

Exemple

Dans cet exemple, AffixTagger apprendra le préfixe du mot car nous ne spécifions aucune valeur pour l'argument affix_length. L'argument prendra la valeur par défaut 3 -

from nltk.tag import AffixTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Prefix_tagger = AffixTagger(train_sentences)
test_sentences = treebank.tagged_sents()[1500:]
Prefix_tagger.evaluate(test_sentences)

Production

0.2800492099250667

Voyons dans l'exemple ci-dessous quelle sera la précision lorsque nous fournirons la valeur 4 à l'argument affix_length -

from nltk.tag import AffixTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Prefix_tagger = AffixTagger(train_sentences, affix_length=4 )
test_sentences = treebank.tagged_sents()[1500:]
Prefix_tagger.evaluate(test_sentences)

Production

0.18154947354966527

Exemple

Dans cet exemple, AffixTagger apprendra le suffixe du mot car nous spécifierons une valeur négative pour l'argument affix_length.

from nltk.tag import AffixTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Suffix_tagger = AffixTagger(train_sentences, affix_length = -3)
test_sentences = treebank.tagged_sents()[1500:]
Suffix_tagger.evaluate(test_sentences)

Production

0.2800492099250667

Brill Tagger

Brill Tagger est un tagueur basé sur la transformation. NLTK fournitBrillTagger classe qui est le premier tagueur qui n'est pas une sous-classe de SequentialBackoffTagger. En face, une série de règles pour corriger les résultats d'un tagueur initial est utilisée parBrillTagger.

Comment ça marche?

Former un BrillTagger classe utilisant BrillTaggerTrainer on définit la fonction suivante -

def train_brill_tagger(initial_tagger, train_sentences, **kwargs) -

templates = [
   brill.Template(brill.Pos([-1])),
   brill.Template(brill.Pos([1])),
   brill.Template(brill.Pos([-2])),
   brill.Template(brill.Pos([2])),
   brill.Template(brill.Pos([-2, -1])),
   brill.Template(brill.Pos([1, 2])),
   brill.Template(brill.Pos([-3, -2, -1])),
   brill.Template(brill.Pos([1, 2, 3])),
   brill.Template(brill.Pos([-1]), brill.Pos([1])),
   brill.Template(brill.Word([-1])),
   brill.Template(brill.Word([1])),
   brill.Template(brill.Word([-2])),
   brill.Template(brill.Word([2])),
   brill.Template(brill.Word([-2, -1])),
   brill.Template(brill.Word([1, 2])),
   brill.Template(brill.Word([-3, -2, -1])),
   brill.Template(brill.Word([1, 2, 3])),
   brill.Template(brill.Word([-1]), brill.Word([1])),
]
trainer = brill_trainer.BrillTaggerTrainer(initial_tagger, templates, deterministic=True)
return trainer.train(train_sentences, **kwargs)

Comme on peut le voir, cette fonction nécessite initial_tagger et train_sentences. Il faut uninitial_tagger et une liste de modèles, qui implémente le BrillTemplateinterface. leBrillTemplate l'interface se trouve dans le nltk.tbl.templatemodule. L'une de ces implémentations estbrill.Template classe.

Le rôle principal du tagueur basé sur la transformation est de générer des règles de transformation qui corrigent la sortie du tagger initial pour être plus en ligne avec les phrases d'apprentissage. Voyons le flux de travail ci-dessous -

Exemple

Pour cet exemple, nous utiliserons combine_tagger que nous avons créé en peignant les tagueurs (dans la recette précédente) à partir d'une chaîne backoff de NgramTagger classes, comme initial_tagger. Tout d'abord, évaluons le résultat en utilisantCombine.tagger puis utilisez-le comme initial_tagger pour former le tagueur de barbue.

from tagger_util import backoff_tagger
from nltk.tag import UnigramTagger
from nltk.tag import BigramTagger
from nltk.tag import TrigramTagger
from nltk.tag import DefaultTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
back_tagger = DefaultTagger('NN')
Combine_tagger = backoff_tagger(
   train_sentences, [UnigramTagger, BigramTagger, TrigramTagger], backoff = back_tagger
)
test_sentences = treebank.tagged_sents()[1500:]
Combine_tagger.evaluate(test_sentences)

Production

0.9234530029238365

Maintenant, voyons le résultat de l'évaluation lorsque Combine_tagger est utilisé en tant que initial_tagger pour former le géniteur de barbue -

from tagger_util import train_brill_tagger
brill_tagger = train_brill_tagger(combine_tagger, train_sentences)
brill_tagger.evaluate(test_sentences)

Production

0.9246832510505041

On peut remarquer que BrillTagger classe a une précision légèrement accrue sur Combine_tagger.

Exemple d'implémentation complet

from tagger_util import backoff_tagger
from nltk.tag import UnigramTagger
from nltk.tag import BigramTagger
from nltk.tag import TrigramTagger
from nltk.tag import DefaultTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
back_tagger = DefaultTagger('NN')
Combine_tagger = backoff_tagger(train_sentences,
[UnigramTagger, BigramTagger, TrigramTagger], backoff = back_tagger)
test_sentences = treebank.tagged_sents()[1500:]
Combine_tagger.evaluate(test_sentences)
from tagger_util import train_brill_tagger
brill_tagger = train_brill_tagger(combine_tagger, train_sentences)
brill_tagger.evaluate(test_sentences)

Production

0.9234530029238365
0.9246832510505041

Tagger TnT

TnT Tagger, signifie Trigrams'nTags, est un tagueur statistique basé sur des modèles de Markov du second ordre.

Comment ça marche?

Nous pouvons comprendre le fonctionnement du tagueur TnT à l'aide des étapes suivantes -

  • Basé d'abord sur les données d'entraînement, TnT tegger maintient plusieurs FreqDist et ConditionalFreqDist instances.

  • Après cela, les unigrammes, les bigrammes et les trigrammes seront comptés par ces distributions de fréquences.

  • Désormais, lors de l'étiquetage, en utilisant des fréquences, il calculera les probabilités d'étiquettes possibles pour chaque mot.

C'est pourquoi au lieu de construire une chaîne de backoff de NgramTagger, il utilise tous les modèles ngram ensemble pour choisir la meilleure balise pour chaque mot. Évaluons la précision avec le tagger TnT dans l'exemple suivant -

from nltk.tag import tnt
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
tnt_tagger = tnt.TnT()
tnt_tagger.train(train_sentences)
test_sentences = treebank.tagged_sents()[1500:]
tnt_tagger.evaluate(test_sentences)

Production

0.9165508316157791

Nous avons une précision légèrement inférieure à celle obtenue avec Brill Tagger.

Veuillez noter que nous devons appeler train() avant evaluate() sinon nous obtiendrons une précision de 0%.

L'analyse et sa pertinence en PNL

Le mot 'analyse' dont l'origine est du mot latin ‘pars’ (ce qui signifie ‘part’), est utilisé pour tirer une signification exacte ou une signification du dictionnaire à partir du texte. Elle est également appelée analyse syntaxique ou analyse syntaxique. En comparant les règles de la grammaire formelle, l'analyse syntaxique vérifie la signification du texte. La phrase comme «Donnez-moi de la glace chaude», par exemple, serait rejetée par l'analyseur syntaxique ou syntaxique.

En ce sens, nous pouvons définir l'analyse syntaxique ou syntaxique ou l'analyse syntaxique comme suit -

Il peut être défini comme le processus d'analyse des chaînes de symboles en langage naturel conformément aux règles de la grammaire formelle.

Nous pouvons comprendre la pertinence de l'analyse en PNL à l'aide des points suivants -

  • L'analyseur est utilisé pour signaler toute erreur de syntaxe.

  • Il aide à récupérer des erreurs courantes afin que le traitement du reste du programme puisse être poursuivi.

  • L'arbre d'analyse est créé à l'aide d'un analyseur.

  • L'analyseur est utilisé pour créer une table de symboles, qui joue un rôle important dans la PNL.

  • Parser est également utilisé pour produire des représentations intermédiaires (IR).

Analyse approfondie vs peu profonde

Analyse approfondie Analyse peu profonde
Dans l'analyse approfondie, la stratégie de recherche donnera une structure syntaxique complète à une phrase. Il s'agit d'analyser une partie limitée des informations syntaxiques de la tâche donnée.
Il convient aux applications PNL complexes. Il peut être utilisé pour des applications NLP moins complexes.
Les systèmes de dialogue et la synthèse sont des exemples d'applications NLP où l'analyse approfondie est utilisée. L'extraction d'informations et l'exploration de texte sont des exemples d'applications NLP où l'analyse approfondie est utilisée.
Il est également appelé analyse complète. Il est également appelé segmentation.

Différents types d'analyseurs

Comme discuté, un analyseur est essentiellement une interprétation procédurale de la grammaire. Il trouve un arbre optimal pour la phrase donnée après une recherche dans l'espace d'une variété d'arbres. Voyons quelques-uns des analyseurs disponibles ci-dessous -

Analyseur de descente récursive

L'analyse par descente récursive est l'une des formes d'analyse les plus simples. Voici quelques points importants sur l'analyseur de descente récursive -

  • Il suit un processus descendant.

  • Il tente de vérifier que la syntaxe du flux d'entrée est correcte ou non.

  • Il lit la phrase d'entrée de gauche à droite.

  • Une opération nécessaire pour l'analyseur de descente récursive est de lire les caractères du flux d'entrée et de les faire correspondre avec les terminaux de la grammaire.

Analyseur de réduction de décalage

Voici quelques points importants sur l'analyseur de réduction de décalage -

  • Il suit un processus ascendant simple.

  • Il essaie de trouver une séquence de mots et d'expressions qui correspondent au côté droit d'une production grammaticale et les remplace par le côté gauche de la production.

  • La tentative ci-dessus pour trouver une séquence de mots se poursuit jusqu'à ce que la phrase entière soit réduite.

  • En d'autres termes simples, l'analyseur de réduction de décalage commence par le symbole d'entrée et tente de construire l'arborescence de l'analyseur jusqu'au symbole de début.

Analyseur de graphiques

Voici quelques points importants sur l'analyseur de graphiques -

  • Il est principalement utile ou adapté aux grammaires ambiguës, y compris les grammaires des langues naturelles.

  • Il applique la programmation dynamique aux problèmes d'analyse.

  • En raison de la programmation dynamique, les résultats hypothétiques partiels sont stockés dans une structure appelée «graphique».

  • Le «graphique» peut également être réutilisé.

Analyseur de regexp

L'analyse des expressions rationnelles est l'une des techniques d'analyse les plus utilisées. Voici quelques points importants sur l'analyseur Regexp -

  • Comme son nom l'indique, il utilise une expression régulière définie sous forme de grammaire au-dessus d'une chaîne balisée POS.

  • Il utilise essentiellement ces expressions régulières pour analyser les phrases d'entrée et générer un arbre d'analyse à partir de cela.

Exemple

Voici un exemple de travail de Regexp Parser -

import nltk
sentence = [
   ("a", "DT"),
   ("clever", "JJ"),
   ("fox","NN"),
   ("was","VBP"),
   ("jumping","VBP"),
   ("over","IN"),
   ("the","DT"),
   ("wall","NN")
]
grammar = "NP:{<DT>?<JJ>*<NN>}" 
Reg_parser = nltk.RegexpParser(grammar)
Reg_parser.parse(sentence)
Output = Reg_parser.parse(sentence)
Output.draw()

Production

Analyse des dépendances

Dependency Parsing (DP), un mécanisme d'analyse moderne, dont le concept principal est que chaque unité linguistique, c'est-à-dire les mots, se rapporte les uns aux autres par un lien direct. Ces liens directs sont en fait‘dependencies’en linguistique. Par exemple, le diagramme suivant montre la grammaire des dépendances pour la phrase“John can hit the ball”.

Forfait NLTK

Nous avons suivi les deux façons de faire l'analyse des dépendances avec NLTK -

Analyseur de dépendances probabiliste et projectif

C'est la première façon dont nous pouvons faire l'analyse des dépendances avec NLTK. Mais cet analyseur a la restriction de l'entraînement avec un ensemble limité de données d'entraînement.

Analyseur de Stanford

C'est une autre façon de faire l'analyse des dépendances avec NLTK. L'analyseur de Stanford est un analyseur de dépendances à la pointe de la technologie. NLTK a un wrapper autour de lui. Pour l'utiliser, nous devons télécharger deux choses suivantes -

L' analyseur Stanford CoreNLP .

Modèle de langue pour la langue souhaitée. Par exemple, modèle de langue anglaise.

Exemple

Une fois que vous avez téléchargé le modèle, nous pouvons l'utiliser via NLTK comme suit -

from nltk.parse.stanford import StanfordDependencyParser
path_jar = 'path_to/stanford-parser-full-2014-08-27/stanford-parser.jar'
path_models_jar = 'path_to/stanford-parser-full-2014-08-27/stanford-parser-3.4.1-models.jar'
dep_parser = StanfordDependencyParser(
   path_to_jar = path_jar, path_to_models_jar = path_models_jar
)
result = dep_parser.raw_parse('I shot an elephant in my sleep')
depndency = result.next()
list(dependency.triples())

Production

[
   ((u'shot', u'VBD'), u'nsubj', (u'I', u'PRP')),
   ((u'shot', u'VBD'), u'dobj', (u'elephant', u'NN')),
   ((u'elephant', u'NN'), u'det', (u'an', u'DT')),
   ((u'shot', u'VBD'), u'prep', (u'in', u'IN')),
   ((u'in', u'IN'), u'pobj', (u'sleep', u'NN')),
   ((u'sleep', u'NN'), u'poss', (u'my', u'PRP$'))
]

Qu'est-ce que Chunking?

Le chunking, l'un des processus importants du traitement du langage naturel, est utilisé pour identifier des parties du discours (POS) et des phrases courtes. En d'autres termes simples, avec le découpage, nous pouvons obtenir la structure de la phrase. Il est également appelépartial parsing.

Motifs de morceaux et fentes

Chunk patternssont les modèles de balises de partie de discours (POS) qui définissent le type de mots qui composent un morceau. Nous pouvons définir des modèles de blocs à l'aide d'expressions régulières modifiées.

De plus, nous pouvons également définir des modèles pour les types de mots qui ne devraient pas être dans un morceau et ces mots non groupés sont appelés chinks.

Exemple d'implémentation

Dans l'exemple ci-dessous, avec le résultat de l'analyse de la phrase “the book has many chapters”, il existe une grammaire pour les phrases nominales qui combine à la fois un morceau et un motif de fente -

import nltk
sentence = [
   ("the", "DT"),
   ("book", "NN"),
   ("has","VBZ"),
   ("many","JJ"),
   ("chapters","NNS")
]
chunker = nltk.RegexpParser(
   r'''
   NP:{<DT><NN.*><.*>*<NN.*>}
   }<VB.*>{
   '''
)
chunker.parse(sentence)
Output = chunker.parse(sentence)
Output.draw()

Production

Comme vu ci-dessus, le modèle pour spécifier un morceau consiste à utiliser des accolades comme suit -

{<DT><NN>}

Et pour spécifier une faille, nous pouvons inverser les accolades comme suit -

}<VB>{.

Maintenant, pour un type de phrase particulier, ces règles peuvent être combinées dans une grammaire.

Extraction d'informations

Nous avons parcouru des taggers ainsi que des analyseurs qui peuvent être utilisés pour construire un moteur d'extraction d'informations. Voyons un pipeline d'extraction d'informations de base -

L'extraction d'informations a de nombreuses applications, notamment -

  • L'intelligence d'entreprise
  • Reprendre la récolte
  • Analyse des médias
  • Détection des sentiments
  • Recherche de brevets
  • Analyse des e-mails

Reconnaissance des entités nommées (NER)

La reconnaissance d'entités nommées (NER) est en fait un moyen d'extraire certaines des entités les plus courantes telles que les noms, les organisations, l'emplacement, etc. et suit le pipeline fourni dans la figure ci-dessus.

Exemple

Import nltk
file = open (
   # provide here the absolute path for the file of text for which we want NER
)
data_text = file.read()
sentences = nltk.sent_tokenize(data_text)
tokenized_sentences = [nltk.word_tokenize(sentence) for sentence in sentences]
tagged_sentences = [nltk.pos_tag(sentence) for sentence in tokenized_sentences]
for sent in tagged_sentences:
print nltk.ne_chunk(sent)

Une partie de la reconnaissance d'entité nommée modifiée (NER) peut également être utilisée pour extraire des entités telles que les noms de produits, les entités biomédicales, le nom de marque et bien plus encore.

Extraction de relation

L'extraction de relations, une autre opération d'extraction d'informations couramment utilisée, est le processus d'extraction des différentes relations entre diverses entités. Il peut y avoir différentes relations comme l'héritage, les synonymes, analogues, etc., dont la définition dépend du besoin d'information. Par exemple, supposons que si nous voulons rechercher l'écriture d'un livre, alors la paternité serait une relation entre le nom de l'auteur et le nom du livre.

Exemple

Dans l'exemple suivant, nous utilisons le même pipeline IE, comme indiqué dans le diagramme ci-dessus, que nous avons utilisé jusqu'à la relation d'entité nommée (NER) et l'étendons avec un modèle de relation basé sur les balises NER.

import nltk
import re
IN = re.compile(r'.*\bin\b(?!\b.+ing)')
for doc in nltk.corpus.ieer.parsed_docs('NYT_19980315'):
for rel in nltk.sem.extract_rels('ORG', 'LOC', doc, corpus = 'ieer',
pattern = IN):
print(nltk.sem.rtuple(rel))

Production

[ORG: 'WHYY'] 'in' [LOC: 'Philadelphia']
[ORG: 'McGlashan & Sarrail'] 'firm in' [LOC: 'San Mateo']
[ORG: 'Freedom Forum'] 'in' [LOC: 'Arlington']
[ORG: 'Brookings Institution'] ', the research group in' [LOC: 'Washington']
[ORG: 'Idealab'] ', a self-described business incubator based in' [LOC: 'Los Angeles']
[ORG: 'Open Text'] ', based in' [LOC: 'Waterloo']
[ORG: 'WGBH'] 'in' [LOC: 'Boston']
[ORG: 'Bastille Opera'] 'in' [LOC: 'Paris']
[ORG: 'Omnicom'] 'in' [LOC: 'New York']
[ORG: 'DDB Needham'] 'in' [LOC: 'New York']
[ORG: 'Kaplan Thaler Group'] 'in' [LOC: 'New York']
[ORG: 'BBDO South'] 'in' [LOC: 'Atlanta']
[ORG: 'Georgia-Pacific'] 'in' [LOC: 'Atlanta']

Dans le code ci-dessus, nous avons utilisé un corpus intégré nommé ieer. Dans ce corpus, les phrases sont étiquetées jusqu'à la relation d'entité nommée (NER). Ici, nous avons seulement besoin de spécifier le modèle de relation que nous voulons et le type de NER que nous voulons que la relation définisse. Dans notre exemple, nous avons défini la relation entre une organisation et un emplacement. Nous avons extrait toutes les combinaisons de ces modèles.

Pourquoi transformer Chunks?

Jusqu'à présent, nous avons des morceaux ou des phrases de phrases, mais que sommes-nous censés en faire. L'une des tâches importantes est de les transformer. Mais pourquoi? Il s'agit de faire ce qui suit -

  • correction grammaticale et
  • réorganiser les phrases

Filtrer les mots insignifiants / inutiles

Supposons que si vous voulez juger de la signification d'une phrase, il existe de nombreux mots couramment utilisés tels que «le», «a», qui sont insignifiants ou inutiles. Par exemple, voyez la phrase suivante -

'Le film était bien'.

Ici, les mots les plus significatifs sont «film» et «bon». D'autres mots, «le» et «était» sont tous deux inutiles ou insignifiants. C'est parce que sans eux aussi, nous pouvons obtenir le même sens de la phrase. 'Bon film'.

Dans la recette python suivante, nous allons apprendre à supprimer les mots inutiles / insignifiants et à conserver les mots significatifs à l'aide de balises POS.

Exemple

Tout d'abord, en regardant à travers treebankcorpus pour les mots vides, nous devons décider quelles balises de partie de discours sont significatives et lesquelles ne le sont pas. Voyons le tableau suivant de mots et balises insignifiants -

Mot Marque
une DT
Tout PDT
Un DT
Et CC
Ou CC
Cette WDT
le DT

Dans le tableau ci-dessus, nous pouvons voir autre que CC, toutes les autres balises se terminent par DT, ce qui signifie que nous pouvons filtrer les mots insignifiants en regardant le suffixe de la balise.

Pour cet exemple, nous allons utiliser une fonction nommée filter()qui prend un seul morceau et renvoie un nouveau morceau sans aucun mot étiqueté insignifiant. Cette fonction filtre toutes les balises qui se terminent par DT ou CC.

Exemple

import nltk
def filter(chunk, tag_suffixes=['DT', 'CC']):
   significant = []
   for word, tag in chunk:
      ok = True
      for suffix in tag_suffixes:
         if tag.endswith(suffix):
            ok = False
            break
      if ok:
         significant.append((word, tag))
   return (significant)

Maintenant, utilisons cette fonction filter () dans notre recette Python pour supprimer les mots insignifiants -

from chunk_parse import filter
filter([('the', 'DT'),('good', 'JJ'),('movie', 'NN')])

Production

[('good', 'JJ'), ('movie', 'NN')]

Correction verbale

Plusieurs fois, dans le langage du monde réel, nous voyons des formes verbales incorrectes. Par exemple, "ça va?" n'est pas correcte. La forme verbale n'est pas correcte dans cette phrase. La phrase devrait être «ça va? NLTK nous fournit le moyen de corriger ces erreurs en créant des mappages de correction verbale. Ces mappages de correction sont utilisés selon qu'il existe un nom au pluriel ou au singulier dans le bloc.

Exemple

Pour implémenter la recette Python, nous devons d'abord définir les mappages de correction des verbes. Créons deux mappages comme suit -

Plural to Singular mappings

plural= {
   ('is', 'VBZ'): ('are', 'VBP'),
   ('was', 'VBD'): ('were', 'VBD')
}

Singular to Plural mappings

singular = {
   ('are', 'VBP'): ('is', 'VBZ'),
   ('were', 'VBD'): ('was', 'VBD')
}

Comme vu ci-dessus, chaque mappage a un verbe étiqueté qui correspond à un autre verbe étiqueté. Les mappages initiaux de notre exemple couvrent les bases des mappagesis to are, was to were, et vice versa.

Ensuite, nous définirons une fonction nommée verbs(), dans lequel vous pouvez passer un chink avec une forme verbale incorrecte et récupérer un morceau corrigé. Pour le faire,verb() fonction utilise une fonction d'assistance nommée index_chunk() qui recherchera dans le bloc la position du premier mot marqué.

Voyons ces fonctions -

def index_chunk(chunk, pred, start = 0, step = 1):
   l = len(chunk)
   end = l if step > 0 else -1
   for i in range(start, end, step):
      if pred(chunk[i]):
         return i
      return None
def tag_startswith(prefix):
   def f(wt):
      return wt[1].startswith(prefix)
   return f

def verbs(chunk):
   vbidx = index_chunk(chunk, tag_startswith('VB'))
   if vbidx is None:
      return chunk
   verb, vbtag = chunk[vbidx]
   nnpred = tag_startswith('NN')
   nnidx = index_chunk(chunk, nnpred, start = vbidx+1)
   if nnidx is None:
      nnidx = index_chunk(chunk, nnpred, start = vbidx-1, step = -1)
   if nnidx is None:
      return chunk
   noun, nntag = chunk[nnidx]
   if nntag.endswith('S'):
      chunk[vbidx] = plural.get((verb, vbtag), (verb, vbtag))
   else:
      chunk[vbidx] = singular.get((verb, vbtag), (verb, vbtag))
   return chunk

Enregistrez ces fonctions dans un fichier Python dans votre répertoire local où Python ou Anaconda est installé et exécutez-le. Je l'ai sauvegardé sousverbcorrect.py.

Maintenant, appelons verbs() fonction sur un point de vente étiqueté is you fine morceau -

from verbcorrect import verbs
verbs([('is', 'VBZ'), ('you', 'PRP$'), ('fine', 'VBG')])

Production

[('are', 'VBP'), ('you', 'PRP$'), ('fine','VBG')]

Éliminer la voix passive des phrases

Une autre tâche utile consiste à éliminer la voix passive des phrases. Cela peut être fait en échangeant les mots autour d'un verbe. Par exemple,‘the tutorial was great’ peut être transformé en ‘the great tutorial’.

Exemple

Pour y parvenir, nous définissons une fonction nommée eliminate_passive()qui échangera le côté droit du bloc avec le côté gauche en utilisant le verbe comme point de pivot. Afin de trouver le verbe sur lequel pivoter, il utilisera également leindex_chunk() fonction définie ci-dessus.

def eliminate_passive(chunk):
   def vbpred(wt):
      word, tag = wt
      return tag != 'VBG' and tag.startswith('VB') and len(tag) > 2
   vbidx = index_chunk(chunk, vbpred)
   if vbidx is None:
      return chunk
   return chunk[vbidx+1:] + chunk[:vbidx]

Maintenant, appelons eliminate_passive() fonction sur un point de vente étiqueté the tutorial was great morceau -

from passiveverb import eliminate_passive
eliminate_passive(
   [
      ('the', 'DT'), ('tutorial', 'NN'), ('was', 'VBD'), ('great', 'JJ')
   ]
)

Production

[('great', 'JJ'), ('the', 'DT'), ('tutorial', 'NN')]

Échange de noms cardinaux

Comme nous le savons, un mot cardinal tel que 5, est étiqueté comme CD dans un morceau. Ces mots cardinaux apparaissent souvent avant ou après un nom, mais à des fins de normalisation, il est utile de toujours les mettre avant le nom. Par exemple, la dateJanuary 5 peut être écrit comme 5 January. Comprenons-le avec l'exemple suivant.

Exemple

Pour y parvenir, nous définissons une fonction nommée swapping_cardinals()qui échangera tout cardinal qui se produit immédiatement après un nom avec le nom. Avec cela, le cardinal apparaîtra immédiatement avant le nom. Afin de faire une comparaison d'égalité avec la balise donnée, il utilise une fonction d'assistance que nous avons nomméetag_eql().

def tag_eql(tag):
   def f(wt):
      return wt[1] == tag
   return f

Maintenant, nous pouvons définir swapping_cardinals () -

def swapping_cardinals (chunk):
   cdidx = index_chunk(chunk, tag_eql('CD'))
   if not cdidx or not chunk[cdidx-1][1].startswith('NN'):
      return chunk
   noun, nntag = chunk[cdidx-1]
   chunk[cdidx-1] = chunk[cdidx]
   chunk[cdidx] = noun, nntag
   return chunk

Maintenant, appelons swapping_cardinals() fonction à une date “January 5” -

from Cardinals import swapping_cardinals()
swapping_cardinals([('Janaury', 'NNP'), ('5', 'CD')])

Production

[('10', 'CD'), ('January', 'NNP')]
10 January

Voici les deux raisons de transformer les arbres -

  • Pour modifier l'arborescence d'analyse approfondie et
  • Pour aplatir les arbres d'analyse profonds

Conversion d'un arbre ou d'un sous-arbre en phrase

La première recette que nous allons discuter ici est de reconvertir un arbre ou un sous-arbre en une phrase ou une chaîne de blocs. C'est très simple, voyons dans l'exemple suivant -

Exemple

from nltk.corpus import treebank_chunk
tree = treebank_chunk.chunked_sents()[2]
' '.join([w for w, t in tree.leaves()])

Production

'Rudolph Agnew , 55 years old and former chairman of Consolidated Gold Fields
PLC , was named a nonexecutive director of this British industrial
conglomerate .'

Aplatissement profond des arbres

Les arbres profonds de phrases imbriquées ne peuvent pas être utilisés pour entraîner un morceau, nous devons donc les aplatir avant de les utiliser. Dans l'exemple suivant, nous allons utiliser la 3e phrase analysée, qui est un arbre profond de phrases imbriquées, de latreebank corpus.

Exemple

Pour y parvenir, nous définissons une fonction nommée deeptree_flat()cela prendra un seul arbre et renverra un nouvel arbre qui ne conserve que les arbres de niveau le plus bas. Afin de faire la plupart du travail, il utilise une fonction d'assistance que nous avons nomméechildtree_flat().

from nltk.tree import Tree
def childtree_flat(trees):
   children = []
   for t in trees:
      if t.height() < 3:
         children.extend(t.pos())
      elif t.height() == 3:
         children.append(Tree(t.label(), t.pos()))
      else:
         children.extend(flatten_childtrees([c for c in t]))
   return children
def deeptree_flat(tree):
   return Tree(tree.label(), flatten_childtrees([c for c in tree]))

Maintenant, appelons deeptree_flat() fonction sur la 3e phrase analysée, qui est un arbre profond de phrases imbriquées, de la treebankcorpus. Nous avons enregistré ces fonctions dans un fichier nommé deeptree.py.

from deeptree import deeptree_flat
from nltk.corpus import treebank
deeptree_flat(treebank.parsed_sents()[2])

Production

Tree('S', [Tree('NP', [('Rudolph', 'NNP'), ('Agnew', 'NNP')]),
(',', ','), Tree('NP', [('55', 'CD'), 
('years', 'NNS')]), ('old', 'JJ'), ('and', 'CC'),
Tree('NP', [('former', 'JJ'), 
('chairman', 'NN')]), ('of', 'IN'), Tree('NP', [('Consolidated', 'NNP'), 
('Gold', 'NNP'), ('Fields', 'NNP'), ('PLC', 
'NNP')]), (',', ','), ('was', 'VBD'), 
('named', 'VBN'), Tree('NP-SBJ', [('*-1', '-NONE-')]), 
Tree('NP', [('a', 'DT'), ('nonexecutive', 'JJ'), ('director', 'NN')]),
('of', 'IN'), Tree('NP', 
[('this', 'DT'), ('British', 'JJ'), 
('industrial', 'JJ'), ('conglomerate', 'NN')]), ('.', '.')])

Construire un arbre peu profond

Dans la section précédente, nous aplatissons un arbre profond de phrases imbriquées en ne conservant que les sous-arbres de niveau le plus bas. Dans cette section, nous allons garder uniquement les sous-arbres de plus haut niveau c'est-à-dire pour construire l'arbre peu profond. Dans l'exemple suivant, nous allons utiliser la 3e phrase analysée, qui est un arbre profond de phrases imbriquées, de latreebank corpus.

Exemple

Pour y parvenir, nous définissons une fonction nommée tree_shallow() cela éliminera tous les sous-arbres imbriqués en ne conservant que les étiquettes de sous-arborescence supérieures.

from nltk.tree import Tree
def tree_shallow(tree):
   children = []
   for t in tree:
      if t.height() < 3:
         children.extend(t.pos())
      else:
         children.append(Tree(t.label(), t.pos()))
   return Tree(tree.label(), children)

Maintenant, appelons tree_shallow()fonction sur la troisième phrase analysée, qui est un arbre profond de phrases imbriquées, de latreebankcorpus. Nous avons enregistré ces fonctions dans un fichier nommé shallowtree.py.

from shallowtree import shallow_tree
from nltk.corpus import treebank
tree_shallow(treebank.parsed_sents()[2])

Production

Tree('S', [Tree('NP-SBJ-1', [('Rudolph', 'NNP'), ('Agnew', 'NNP'), (',', ','), 
('55', 'CD'), ('years', 'NNS'), ('old', 'JJ'), ('and', 'CC'), 
('former', 'JJ'), ('chairman', 'NN'), ('of', 'IN'), ('Consolidated', 'NNP'), 
('Gold', 'NNP'), ('Fields', 'NNP'), ('PLC', 'NNP'), (',', ',')]), 
Tree('VP', [('was', 'VBD'), ('named', 'VBN'), ('*-1', '-NONE-'), ('a', 'DT'), 
('nonexecutive', 'JJ'), ('director', 'NN'), ('of', 'IN'), ('this', 'DT'), 
('British', 'JJ'), ('industrial', 'JJ'), ('conglomerate', 'NN')]), ('.', '.')])

Nous pouvons voir la différence en obtenant la hauteur des arbres -

from nltk.corpus import treebank
tree_shallow(treebank.parsed_sents()[2]).height()

Production

3

from nltk.corpus import treebank
treebank.parsed_sents()[2].height()

Production

9

Conversion d'étiquettes d'arbre

Dans les arbres d'analyse, il existe une variété de Treeles types d'étiquettes qui ne sont pas présents dans les arborescences de blocs. Mais tout en utilisant l'arborescence d'analyse pour former un bloc, nous aimerions réduire cette variété en convertissant certaines des étiquettes d'arbre en types d'étiquettes plus courants. Par exemple, nous avons deux sous-arbres NP alternatifs, à savoir NP-SBL et NP-TMP. Nous pouvons convertir les deux en NP. Voyons comment le faire dans l'exemple suivant.

Exemple

Pour y parvenir, nous définissons une fonction nommée tree_convert() qui prend les deux arguments suivants -

  • Arbre à convertir
  • Un mappage de conversion d'étiquette

Cette fonction renverra une nouvelle arborescence avec toutes les étiquettes correspondantes remplacées en fonction des valeurs du mappage.

from nltk.tree import Tree
def tree_convert(tree, mapping):
   children = []
   for t in tree:
      if isinstance(t, Tree):
         children.append(convert_tree_labels(t, mapping))
      else:
         children.append(t)
   label = mapping.get(tree.label(), tree.label())
   return Tree(label, children)

Maintenant, appelons tree_convert() fonction sur la 3e phrase analysée, qui est un arbre profond de phrases imbriquées, de la treebankcorpus. Nous avons enregistré ces fonctions dans un fichier nomméconverttree.py.

from converttree import tree_convert
from nltk.corpus import treebank
mapping = {'NP-SBJ': 'NP', 'NP-TMP': 'NP'}
convert_tree_labels(treebank.parsed_sents()[2], mapping)

Production

Tree('S', [Tree('NP-SBJ-1', [Tree('NP', [Tree('NNP', ['Rudolph']), 
Tree('NNP', ['Agnew'])]), Tree(',', [',']), 
Tree('UCP', [Tree('ADJP', [Tree('NP', [Tree('CD', ['55']), 
Tree('NNS', ['years'])]), 
Tree('JJ', ['old'])]), Tree('CC', ['and']), 
Tree('NP', [Tree('NP', [Tree('JJ', ['former']), 
Tree('NN', ['chairman'])]), Tree('PP', [Tree('IN', ['of']), 
Tree('NP', [Tree('NNP', ['Consolidated']), 
Tree('NNP', ['Gold']), Tree('NNP', ['Fields']), 
Tree('NNP', ['PLC'])])])])]), Tree(',', [','])]), 
Tree('VP', [Tree('VBD', ['was']),Tree('VP', [Tree('VBN', ['named']), 
Tree('S', [Tree('NP', [Tree('-NONE-', ['*-1'])]), 
Tree('NP-PRD', [Tree('NP', [Tree('DT', ['a']), 
Tree('JJ', ['nonexecutive']), Tree('NN', ['director'])]), 
Tree('PP', [Tree('IN', ['of']), Tree('NP', 
[Tree('DT', ['this']), Tree('JJ', ['British']), Tree('JJ', ['industrial']), 
Tree('NN', ['conglomerate'])])])])])])]), Tree('.', ['.'])])

Qu'est-ce que la classification de texte?

La classification de texte, comme son nom l'indique, est le moyen de catégoriser des morceaux de texte ou des documents. Mais ici se pose la question de savoir pourquoi nous devons utiliser des classificateurs de texte? Après avoir examiné l'utilisation des mots dans un document ou un morceau de texte, les classificateurs pourront décider quelle étiquette de classe devrait lui être attribuée.

Classificateur binaire

Comme son nom l'indique, le classificateur binaire décidera entre deux étiquettes. Par exemple, positif ou négatif. En cela, le texte ou le document peut être une étiquette ou une autre, mais pas les deux.

Classificateur multi-étiquettes

Contrairement au classificateur binaire, le classificateur multi-étiquettes peut attribuer une ou plusieurs étiquettes à un morceau de texte ou de document.

Ensemble de fonctionnalités étiqueté vs non étiqueté

Un mappage clé-valeur des noms d'entités aux valeurs d'entités est appelé un ensemble d'entités. Les ensembles de fonctionnalités étiquetés ou les données d'entraînement sont très importants pour l'apprentissage de la classification afin de pouvoir classer ultérieurement les ensembles de fonctionnalités non étiquetés.

Ensemble de fonctionnalités étiqueté Ensemble de fonctionnalités sans étiquette
C'est un tuple qui ressemble à (feat, label). C'est un exploit en soi.
C'est une instance avec une étiquette de classe connue. Sans étiquette associée, nous pouvons l'appeler une instance.
Utilisé pour entraîner un algorithme de classification. Une fois entraîné, l'algorithme de classification peut classer un ensemble de fonctionnalités sans étiquette.

Extraction d'entités de texte

L'extraction d'entités de texte, comme son nom l'indique, est le processus de transformation d'une liste de mots en un ensemble de caractéristiques utilisables par un classificateur. Nous devons transformer notre texte en‘dict’ ensembles de fonctionnalités de style, car Natural Language Tool Kit (NLTK) attend ‘dict’ ensembles de fonctionnalités de style.

Modèle Bag of Words (BoW)

BoW, l'un des modèles les plus simples de la PNL, est utilisé pour extraire les caractéristiques d'un morceau de texte ou d'un document afin qu'il puisse être utilisé dans la modélisation comme dans les algorithmes de ML. Il construit essentiellement un ensemble de fonctionnalités de présence de mots à partir de tous les mots d'une instance. Le concept derrière cette méthode est qu'elle ne se soucie pas du nombre de fois qu'un mot apparaît ou de l'ordre des mots, elle ne se soucie que de la présence ou non du mot dans une liste de mots.

Exemple

Pour cet exemple, nous allons définir une fonction nommée bow () -

def bow(words):
   return dict([(word, True) for word in words])

Maintenant, appelons bow()fonction sur les mots. Nous avons enregistré ces fonctions dans un fichier nommé bagwords.py.

from bagwords import bow
bow(['we', 'are', 'using', 'tutorialspoint'])

Production

{'we': True, 'are': True, 'using': True, 'tutorialspoint': True}

Classificateurs de formation

Dans les sections précédentes, nous avons appris à extraire des fonctionnalités du texte. Alors maintenant, nous pouvons former un classificateur. Le premier et le plus simple classificateur estNaiveBayesClassifier classe.

Classificateur Naïve Bayes

Pour prédire la probabilité qu'un ensemble d'entités donné appartienne à une étiquette particulière, il utilise le théorème de Bayes. La formule du théorème de Bayes est la suivante.

$$P(A|B)=\frac{P(B|A)P(A)}{P(B)}$$

Ici,

P(A|B) - On l'appelle aussi la probabilité postérieure, c'est-à-dire la probabilité que le premier événement, c'est-à-dire A, se produise étant donné que le second événement, c'est-à-dire B, s'est produit.

P(B|A) - C'est la probabilité que le deuxième événement, c'est-à-dire B, se produise après le premier événement, c'est-à-dire que A s'est produit.

P(A), P(B) - On l'appelle aussi probabilité a priori, c'est-à-dire la probabilité qu'un premier événement, c'est-à-dire A ou un deuxième événement, c'est-à-dire B, se produise.

Pour former le classificateur Naïve Bayes, nous utiliserons le movie_reviewscorpus de NLTK. Ce corpus comprend deux catégories de texte, à savoir:pos et neg. Ces catégories font d'un classificateur formé sur elles un classificateur binaire. Chaque fichier du corpus est composé de deux fichiers, l'un est une critique de film positive et l'autre une critique de film négative. Dans notre exemple, nous allons utiliser chaque fichier comme une seule instance à la fois pour l'entraînement et le test du classificateur.

Exemple

Pour la formation du classificateur, nous avons besoin d'une liste d'ensembles de fonctionnalités étiquetés, qui seront sous la forme [(featureset, label)]. Ici lefeatureset variable est une dict et label est le label de classe connu pour le featureset. Nous allons créer une fonction nomméelabel_corpus() qui prendra un corpus nommé movie_reviewset aussi une fonction nommée feature_detector, qui est par défaut bag of words. Il construira et retournera un mappage de la forme, {label: [featureset]}. Ensuite, nous utiliserons ce mappage pour créer une liste d'instances d'entraînement et d'instances de test étiquetées.

import collections

def label_corpus(corp, feature_detector=bow):
   label_feats = collections.defaultdict(list)
   for label in corp.categories():
      for fileid in corp.fileids(categories=[label]):
         feats = feature_detector(corp.words(fileids=[fileid]))
         label_feats[label].append(feats)
   return label_feats

Avec l'aide de la fonction ci-dessus, nous obtiendrons un mappage {label:fetaureset}. Nous allons maintenant définir une autre fonction nomméesplit qui prendra un mappage retourné de label_corpus() et divise chaque liste d'ensembles de fonctionnalités en formation étiquetée ainsi qu'en instances de test.

def split(lfeats, split=0.75):
   train_feats = []
   test_feats = []
   for label, feats in lfeats.items():
      cutoff = int(len(feats) * split)
      train_feats.extend([(feat, label) for feat in feats[:cutoff]])
      test_feats.extend([(feat, label) for feat in feats[cutoff:]])
   return train_feats, test_feats

Maintenant, utilisons ces fonctions sur notre corpus, ie movie_reviews -

from nltk.corpus import movie_reviews
from featx import label_feats_from_corpus, split_label_feats
movie_reviews.categories()

Production

['neg', 'pos']

Exemple

lfeats = label_feats_from_corpus(movie_reviews)
lfeats.keys()

Production

dict_keys(['neg', 'pos'])

Exemple

train_feats, test_feats = split_label_feats(lfeats, split = 0.75)
len(train_feats)

Production

1500

Exemple

len(test_feats)

Production

500

Nous l'avons vu dans movie_reviewscorpus, il y a 1000 fichiers pos et 1000 fichiers neg. Nous nous retrouvons également avec 1500 instances de formation étiquetées et 500 instances de test étiquetées.

Maintenant, entraînons-nous NaïveBayesClassifier en utilisant son train() méthode de classe -

from nltk.classify import NaiveBayesClassifier
NBC = NaiveBayesClassifier.train(train_feats)
NBC.labels()

Production

['neg', 'pos']

Classificateur d'arbre de décision

Un autre classificateur important est le classificateur d'arbre de décision. Ici pour l'entraîner leDecisionTreeClassifierclass créera une structure arborescente. Dans cette arborescence, chaque nœud correspond à un nom de fonction et les branches correspondent aux valeurs de fonction. Et en bas des branches, nous arriverons aux feuilles de l'arbre, c'est-à-dire aux étiquettes de classification.

Pour former le classificateur d'arbre de décision, nous utiliserons les mêmes fonctionnalités de formation et de test, c'est-à-dire train_feats et test_feats, variables que nous avons créées à partir de movie_reviews corpus.

Exemple

Pour former ce classificateur, nous appellerons DecisionTreeClassifier.train() méthode de classe comme suit -

from nltk.classify import DecisionTreeClassifier
decisiont_classifier = DecisionTreeClassifier.train(
   train_feats, binary = True, entropy_cutoff = 0.8, 
   depth_cutoff = 5, support_cutoff = 30
)
accuracy(decisiont_classifier, test_feats)

Production

0.725

Classificateur d'entropie maximum

Un autre classificateur important est MaxentClassifier qui est également connu comme un conditional exponential classifier ou logistic regression classifier. Ici pour l'entraîner, leMaxentClassifier class convertira les ensembles d'entités étiquetés en vecteurs à l'aide du codage.

Pour former le classificateur d'arbre de décision, nous utiliserons les mêmes fonctionnalités de formation et de test, c'est-à-dire train_featset test_feats, variables que nous avons créées à partir de movie_reviews corpus.

Exemple

Pour former ce classificateur, nous appellerons MaxentClassifier.train() méthode de classe comme suit -

from nltk.classify import MaxentClassifier
maxent_classifier = MaxentClassifier
.train(train_feats,algorithm = 'gis', trace = 0, max_iter = 10, min_lldelta = 0.5)
accuracy(maxent_classifier, test_feats)

Production

0.786

Classificateur Scikit-learn

L'une des meilleures bibliothèques d'apprentissage automatique (ML) est Scikit-learn. Il contient en fait toutes sortes d'algorithmes de ML à des fins diverses, mais ils ont tous le même modèle de conception d'ajustement comme suit -

  • Adapter le modèle aux données
  • Et utilisez ce modèle pour faire des prédictions

Plutôt que d'accéder directement aux modèles scikit-learn, nous allons ici utiliser les NLTK SklearnClassifierclasse. Cette classe est une classe wrapper autour d'un modèle scikit-learn pour le rendre conforme à l'interface Classifier de NLTK.

Nous suivrons les étapes suivantes pour former un SklearnClassifier classe -

Step 1 - Nous allons d'abord créer des fonctionnalités d'entraînement comme nous l'avons fait dans les recettes précédentes.

Step 2 - Maintenant, choisissez et importez un algorithme Scikit-learn.

Step 3 - Ensuite, nous devons construire un SklearnClassifier classe avec l'algorithme choisi.

Step 4 - Enfin, nous nous formerons SklearnClassifier cours avec nos fonctionnalités de formation.

Implémentons ces étapes dans la recette Python ci-dessous -

from nltk.classify.scikitlearn import SklearnClassifier
from sklearn.naive_bayes import MultinomialNB
sklearn_classifier = SklearnClassifier(MultinomialNB())
sklearn_classifier.train(train_feats)
<SklearnClassifier(MultinomialNB(alpha = 1.0,class_prior = None,fit_prior = True))>
accuracy(sk_classifier, test_feats)

Production

0.885

Mesure de la précision et du rappel

Lors de la formation de divers classificateurs, nous avons également mesuré leur précision. Mais à part la précision, il existe un certain nombre d'autres métriques qui sont utilisées pour évaluer les classificateurs. Deux de ces métriques sontprecision et recall.

Exemple

Dans cet exemple, nous allons calculer la précision et le rappel de la classe NaiveBayesClassifier que nous avons formée précédemment. Pour ce faire, nous allons créer une fonction nommée metrics_PR () qui prendra deux arguments, l'un est le classificateur entraîné et l'autre les fonctionnalités de test étiquetées. Les deux arguments sont les mêmes que ceux que nous avons passés lors du calcul de la précision des classificateurs -

import collections
from nltk import metrics
def metrics_PR(classifier, testfeats):
   refsets = collections.defaultdict(set)
   testsets = collections.defaultdict(set)
   for i, (feats, label) in enumerate(testfeats):
      refsets[label].add(i)
      observed = classifier.classify(feats)
         testsets[observed].add(i)
   precisions = {}
   recalls = {}
   for label in classifier.labels():
   precisions[label] = metrics.precision(refsets[label],testsets[label])
   recalls[label] = metrics.recall(refsets[label], testsets[label])
   return precisions, recalls

Appelons cette fonction pour trouver la précision et rappeler -

from metrics_classification import metrics_PR
nb_precisions, nb_recalls = metrics_PR(nb_classifier,test_feats)
nb_precisions['pos']

Production

0.6713532466435213

Exemple

nb_precisions['neg']

Production

0.9676271186440678

Exemple

nb_recalls['pos']

Production

0.96

Exemple

nb_recalls['neg']

Production

0.478

Combinaison de classificateur et de vote

La combinaison des classificateurs est l'un des meilleurs moyens d'améliorer les performances de classification. Et le vote est l'un des meilleurs moyens de combiner plusieurs classificateurs. Pour voter, nous avons besoin d'un nombre impair de classificateurs. Dans la recette Python suivante, nous allons combiner trois classificateurs, à savoir la classe NaiveBayesClassifier, la classe DecisionTreeClassifier et la classe MaxentClassifier.

Pour ce faire, nous allons définir une fonction nommée vote_classifiers () comme suit.

import itertools
from nltk.classify import ClassifierI
from nltk.probability import FreqDist
class Voting_classifiers(ClassifierI):
   def __init__(self, *classifiers):
      self._classifiers = classifiers
      self._labels = sorted(set(itertools.chain(*[c.labels() for c in classifiers])))
   def labels(self):
      return self._labels
   def classify(self, feats):
      counts = FreqDist()
      for classifier in self._classifiers:
         counts[classifier.classify(feats)] += 1
      return counts.max()

Appelons cette fonction pour combiner trois classificateurs et trouver la précision -

from vote_classification import Voting_classifiers
combined_classifier = Voting_classifiers(NBC, decisiont_classifier, maxent_classifier)
combined_classifier.labels()

Production

['neg', 'pos']

Exemple

accuracy(combined_classifier, test_feats)

Production

0.948

À partir de la sortie ci-dessus, nous pouvons voir que les classificateurs combinés ont la plus haute précision que les classificateurs individuels.