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.