AI avec Python - Package NLTK

Dans ce chapitre, nous allons apprendre comment démarrer avec le package de boîte à outils en langage naturel.

Prérequis

Si nous voulons créer des applications avec un traitement en langage naturel, le changement de contexte rend la tâche plus difficile. Le facteur de contexte influence la manière dont la machine comprend une phrase particulière. Par conséquent, nous devons développer des applications en langage naturel en utilisant des approches d'apprentissage automatique afin que la machine puisse également comprendre la façon dont un humain peut comprendre le contexte.

Pour créer de telles applications, nous utiliserons le package Python appelé NLTK (Natural Language Toolkit Package).

Importer NLTK

Nous devons installer NLTK avant de l'utiliser. Il peut être installé à l'aide de la commande suivante -

pip install nltk

Pour créer un package conda pour NLTK, utilisez la commande suivante -

conda install -c anaconda nltk

Maintenant, après avoir installé le package NLTK, nous devons l'importer via l'invite de commande python. Nous pouvons l'importer en écrivant la commande suivante sur l'invite de commande Python -

>>> import nltk

Téléchargement des données de NLTK

Maintenant, après l'importation de NLTK, nous devons télécharger les données requises. Cela peut être fait à l'aide de la commande suivante sur l'invite de commande Python -

>>> nltk.download()

Installation d'autres packages nécessaires

Pour créer des applications de traitement du langage naturel à l'aide de NLTK, nous devons installer les packages nécessaires. Les packages sont les suivants -

gensim

C'est une bibliothèque de modélisation sémantique robuste qui est utile pour de nombreuses applications. Nous pouvons l'installer en exécutant la commande suivante -

pip install gensim

modèle

Il est utilisé pour faire gensimle package fonctionne correctement. Nous pouvons l'installer en exécutant la commande suivante

pip install pattern

Concept de tokenisation, de stemming et de lemmatisation

Dans cette section, nous comprendrons ce qu'est la tokenisation, la racine et la lemmatisation.

Tokenisation

Il peut être défini comme le processus de fractionnement du texte donné, c'est-à-dire la séquence de caractères en unités plus petites appelées jetons. Les jetons peuvent être des mots, des chiffres ou des signes de ponctuation. Il est également appelé segmentation de mots. Voici un exemple simple de tokenisation -

Input - La mangue, la banane, l'ananas et la pomme sont tous des fruits.

Output -

Le processus de rupture du texte donné peut être effectué à l'aide de la localisation des limites des mots. La fin d'un mot et le début d'un nouveau mot sont appelés limites de mots. Le système d'écriture et la structure typographique des mots influencent les frontières.

Dans le module Python NLTK, nous avons différents packages liés à la tokenisation que nous pouvons utiliser pour diviser le texte en jetons selon nos besoins. Certains des packages sont les suivants -

package sent_tokenize

Comme son nom l'indique, ce package divisera le texte d'entrée en phrases. Nous pouvons importer ce package à l'aide du code Python suivant -

from nltk.tokenize import sent_tokenize

package word_tokenize

Ce package divise le texte d'entrée en mots. Nous pouvons importer ce package à l'aide du code Python suivant -

from nltk.tokenize import word_tokenize

Package WordPunctTokenizer

Ce package divise le texte d'entrée en mots ainsi que les signes de ponctuation. Nous pouvons importer ce package à l'aide du code Python suivant -

from nltk.tokenize import WordPuncttokenizer

Tige

En travaillant avec des mots, nous rencontrons de nombreuses variations pour des raisons grammaticales. Le concept de variations signifie ici que nous devons traiter différentes formes des mêmes mots commedemocracy, democratic, et democratization. Il est très nécessaire que les machines comprennent que ces différents mots ont la même forme de base. De cette façon, il serait utile d'extraire les formes de base des mots pendant que nous analysons le texte.

Nous pouvons y parvenir en stoppant. De cette façon, nous pouvons dire que la radicalisation est le processus heuristique d'extraction des formes de base des mots en coupant les extrémités des mots.

Dans le module Python NLTK, nous avons différents packages liés à la tige. Ces packages peuvent être utilisés pour obtenir les formes de mot de base. Ces packages utilisent des algorithmes. Certains des packages sont les suivants -

Forfait PorterStemmer

Ce package Python utilise l'algorithme de Porter pour extraire le formulaire de base. Nous pouvons importer ce package à l'aide du code Python suivant -

from nltk.stem.porter import PorterStemmer

Par exemple, si nous donnons le mot ‘writing’ en tant que contribution à cela, nous obtiendrons le mot ‘write’ après la tige.

Forfait LancasterStemmer

Ce package Python utilisera l'algorithme de Lancaster pour extraire le formulaire de base. Nous pouvons importer ce package à l'aide du code Python suivant -

from nltk.stem.lancaster import LancasterStemmer

Par exemple, si nous donnons le mot ‘writing’ en tant que contribution à cela, nous obtiendrons le mot ‘write’ après la tige.

Forfait SnowballStemmer

Ce package Python utilisera l'algorithme de la boule de neige pour extraire le formulaire de base. Nous pouvons importer ce package à l'aide du code Python suivant -

from nltk.stem.snowball import SnowballStemmer

Par exemple, si nous donnons le mot ‘writing’ en tant que contribution à cela, nous obtiendrons le mot ‘write’ après la tige.

Tous ces algorithmes ont un niveau de rigueur différent. Si nous comparons ces trois embouts, les embouts Porter sont les moins stricts et Lancaster est le plus strict. La tige de boule de neige est bonne à utiliser en termes de vitesse et de rigueur.

Lemmatisation

On peut également extraire la forme de base des mots par lemmatisation. Il accomplit essentiellement cette tâche en utilisant un vocabulaire et une analyse morphologique des mots, visant normalement à supprimer uniquement les fins flexionnelles. Ce type de forme de base de tout mot est appelé lemme.

La principale différence entre la radicalisation et la lemmatisation est l'utilisation du vocabulaire et l'analyse morphologique des mots. Une autre différence est que la racine réduit le plus souvent les mots liés par dérivation alors que la lemmatisation ne fait généralement que réduire les différentes formes flexionnelles d'un lemme. Par exemple, si nous fournissons le mot vu comme mot d'entrée, la racine pourrait renvoyer le mot «s» mais la lemmatisation tenterait de renvoyer le mot soit voir soit voir selon que l'utilisation du jeton était un verbe ou un nom.

Dans le module Python NLTK, nous avons le package suivant lié au processus de lemmatisation que nous pouvons utiliser pour obtenir les formes de base du mot -

Package WordNetLemmatizer

Ce package Python extraira la forme de base du mot selon qu'il est utilisé comme nom ou comme verbe. Nous pouvons importer ce package à l'aide du code Python suivant -

from nltk.stem import WordNetLemmatizer

Chunking: diviser les données en morceaux

C'est l'un des processus importants du traitement du langage naturel. Le travail principal de la segmentation est d'identifier les parties du discours et les phrases courtes comme les phrases nominales. Nous avons déjà étudié le processus de tokenisation, la création de tokens. La segmentation est essentiellement l'étiquetage de ces jetons. En d'autres termes, la segmentation nous montrera la structure de la phrase.

Dans la section suivante, nous découvrirons les différents types de Chunking.

Types de segmentation

Il existe deux types de segmentation. Les types sont les suivants -

Chunking up

Dans ce processus de découpage, l'objet, les choses, etc. évoluent vers un caractère plus général et le langage devient plus abstrait. Il y a plus de chances d'accord. Dans ce processus, nous effectuons un zoom arrière. Par exemple, si nous décomposons la question «à quoi servent les voitures»? Nous pouvons obtenir la réponse «transport».

Réduire

Dans ce processus de découpage, l'objet, les choses, etc. évoluent vers une plus grande spécificité et le langage est plus pénétré. La structure plus profonde serait examinée en morceaux. Dans ce processus, nous effectuons un zoom avant. Par exemple, si nous réduisons la question «Parlez spécifiquement d'une voiture»? Nous obtiendrons des informations plus petites sur la voiture.

Example

Dans cet exemple, nous allons faire du segment Noun-Phrase, une catégorie de segmentation qui trouvera les morceaux de phrases nominales dans la phrase, en utilisant le module NLTK en Python -

Follow these steps in python for implementing noun phrase chunking −

Step 1- Dans cette étape, nous devons définir la grammaire de la segmentation. Il comprendrait les règles que nous devons suivre.

Step 2- Dans cette étape, nous devons créer un analyseur de blocs. Il analyserait la grammaire et donnerait la sortie.

Step 3 - Dans cette dernière étape, la sortie est produite dans un format arborescent.

Importons le package NLTK nécessaire comme suit -

import nltk

Maintenant, nous devons définir la phrase. Ici, DT signifie le déterminant, VBP signifie le verbe, JJ signifie l'adjectif, IN signifie la préposition et NN signifie le nom.

sentence=[("a","DT"),("clever","JJ"),("fox","NN"),("was","VBP"),
          ("jumping","VBP"),("over","IN"),("the","DT"),("wall","NN")]

Maintenant, nous devons donner la grammaire. Ici, nous allons donner la grammaire sous forme d'expression régulière.

grammar = "NP:{<DT>?<JJ>*<NN>}"

Nous devons définir un analyseur qui analysera la grammaire.

parser_chunking = nltk.RegexpParser(grammar)

L'analyseur analyse la phrase comme suit -

parser_chunking.parse(sentence)

Ensuite, nous devons obtenir la sortie. La sortie est générée dans la variable simple appeléeoutput_chunk.

Output_chunk = parser_chunking.parse(sentence)

Lors de l'exécution du code suivant, nous pouvons dessiner notre sortie sous la forme d'un arbre.

output.draw()

Modèle Bag of Word (BoW)

Bag of Word (BoW), un modèle de traitement du langage naturel, est essentiellement utilisé pour extraire les caractéristiques du texte afin que le texte puisse être utilisé dans la modélisation, comme dans les algorithmes d'apprentissage automatique.

Maintenant, la question se pose de savoir pourquoi nous devons extraire les fonctionnalités du texte. C'est parce que les algorithmes d'apprentissage automatique ne peuvent pas fonctionner avec des données brutes et qu'ils ont besoin de données numériques pour pouvoir en extraire des informations significatives. La conversion de données textuelles en données numériques est appelée extraction d'entités ou codage d'entités.

Comment ça fonctionne

Il s'agit d'une approche très simple pour extraire les fonctionnalités du texte. Supposons que nous ayons un document texte et que nous voulions le convertir en données numériques ou disons vouloir en extraire les caractéristiques, puis tout d'abord ce modèle extrait un vocabulaire de tous les mots du document. Ensuite, en utilisant une matrice de termes de document, il construira un modèle. De cette manière, BoW représente le document comme un sac de mots uniquement. Toute information sur l'ordre ou la structure des mots dans le document est supprimée.

Concept de matrice de termes de document

L'algorithme BoW construit un modèle en utilisant la matrice des termes du document. Comme son nom l'indique, la matrice des termes du document est la matrice des différents nombres de mots présents dans le document. À l'aide de cette matrice, le document texte peut être représenté comme une combinaison pondérée de divers mots. En définissant le seuil et en choisissant les mots les plus significatifs, nous pouvons construire un histogramme de tous les mots des documents pouvant être utilisés comme vecteur de caractéristiques. Voici un exemple pour comprendre le concept de matrice de termes de document -

Example

Supposons que nous ayons les deux phrases suivantes -

  • Sentence 1 - Nous utilisons le modèle Bag of Words.

  • Sentence 2 - Le modèle Bag of Words est utilisé pour extraire les fonctionnalités.

Maintenant, en considérant ces deux phrases, nous avons les 13 mots distincts suivants -

  • we
  • are
  • using
  • the
  • bag
  • of
  • words
  • model
  • is
  • used
  • for
  • extracting
  • features

Maintenant, nous devons construire un histogramme pour chaque phrase en utilisant le nombre de mots dans chaque phrase -

  • Sentence 1 - [1,1,1,1,1,1,1,1,0,0,0,0,0]

  • Sentence 2 - [0,0,0,1,1,1,1,1,1,1,1,1,1]

De cette façon, nous avons les vecteurs de caractéristiques qui ont été extraits. Chaque vecteur de caractéristiques est de 13 dimensions car nous avons 13 mots distincts.

Concept des statistiques

Le concept des statistiques est appelé TermFrequency-Inverse Document Frequency (tf-idf). Chaque mot est important dans le document. Les statistiques nous aident à comprendre l'importance de chaque mot.

Fréquence des termes (tf)

C'est la mesure de la fréquence à laquelle chaque mot apparaît dans un document. Il peut être obtenu en divisant le nombre de chaque mot par le nombre total de mots dans un document donné.

Fréquence inverse des documents (idf)

C'est la mesure de l'unicité d'un mot par rapport à ce document dans l'ensemble de documents donné. Pour calculer idf et formuler un vecteur de caractéristiques distinctives, nous devons réduire le poids des mots courants comme le et peser les mots rares.

Construire un modèle de sac de mots en NLTK

Dans cette section, nous définirons une collection de chaînes en utilisant CountVectorizer pour créer des vecteurs à partir de ces phrases.

Importons le package nécessaire -

from sklearn.feature_extraction.text import CountVectorizer

Définissez maintenant l'ensemble des phrases.

Sentences = ['We are using the Bag of Word model', 'Bag of Word model is
           used for extracting the features.']

vectorizer_count = CountVectorizer()

features_text = vectorizer.fit_transform(Sentences).todense()

print(vectorizer.vocabulary_)

Le programme ci-dessus génère la sortie comme indiqué ci-dessous. Cela montre que nous avons 13 mots distincts dans les deux phrases ci-dessus -

{'we': 11, 'are': 0, 'using': 10, 'the': 8, 'bag': 1, 'of': 7,
 'word': 12, 'model': 6, 'is': 5, 'used': 9, 'for': 4, 'extracting': 2, 'features': 3}

Ce sont les vecteurs de caractéristiques (texte sous forme numérique) qui peuvent être utilisés pour l'apprentissage automatique.

Résoudre les problèmes

Dans cette section, nous allons résoudre quelques problèmes connexes.

Prédiction de catégorie

Dans un ensemble de documents, non seulement les mots mais la catégorie des mots sont également importants; dans quelle catégorie de texte appartient un mot particulier. Par exemple, nous voulons prédire si une phrase donnée appartient à la catégorie email, news, sports, ordinateur, etc. Dans l'exemple suivant, nous allons utiliser tf-idf pour formuler un vecteur de caractéristiques afin de trouver la catégorie de documents. Nous utiliserons les données de 20 jeux de données de groupes de discussion de sklearn.

Nous devons importer les packages nécessaires -

from sklearn.datasets import fetch_20newsgroups
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer

Définissez la carte des catégories. Nous utilisons cinq catégories différentes appelées Religion, Autos, Sports, Electronique et Espace.

category_map = {'talk.religion.misc':'Religion','rec.autos''Autos',
   'rec.sport.hockey':'Hockey','sci.electronics':'Electronics', 'sci.space': 'Space'}

Créer l'ensemble d'entraînement -

training_data = fetch_20newsgroups(subset = 'train',
   categories = category_map.keys(), shuffle = True, random_state = 5)

Construisez un vectoriseur de comptage et extrayez le terme comptage -

vectorizer_count = CountVectorizer()
train_tc = vectorizer_count.fit_transform(training_data.data)
print("\nDimensions of training data:", train_tc.shape)

Le transformateur tf-idf est créé comme suit -

tfidf = TfidfTransformer()
train_tfidf = tfidf.fit_transform(train_tc)

Maintenant, définissez les données de test -

input_data = [
   'Discovery was a space shuttle',
   'Hindu, Christian, Sikh all are religions',
   'We must have to drive safely',
   'Puck is a disk made of rubber',
   'Television, Microwave, Refrigrated all uses electricity'
]

Les données ci-dessus nous aideront à former un classificateur multinomial Naive Bayes -

classifier = MultinomialNB().fit(train_tfidf, training_data.target)

Transformez les données d'entrée à l'aide du vectoriseur de comptage -

input_tc = vectorizer_count.transform(input_data)

Maintenant, nous allons transformer les données vectorisées en utilisant le transformateur tfidf -

input_tfidf = tfidf.transform(input_tc)

Nous allons prédire les catégories de sortie -

predictions = classifier.predict(input_tfidf)

La sortie est générée comme suit -

for sent, category in zip(input_data, predictions):
   print('\nInput Data:', sent, '\n Category:', \
      category_map[training_data.target_names[category]])

Le prédicteur de catégorie génère la sortie suivante -

Dimensions of training data: (2755, 39297)

Input Data: Discovery was a space shuttle
Category: Space

Input Data: Hindu, Christian, Sikh all are religions
Category: Religion

Input Data: We must have to drive safely
Category: Autos

Input Data: Puck is a disk made of rubber
Category: Hockey

Input Data: Television, Microwave, Refrigrated all uses electricity
Category: Electronics

Recherche de genre

Dans cet énoncé de problème, un classificateur serait formé pour trouver le sexe (masculin ou féminin) en fournissant les noms. Nous devons utiliser une heuristique pour construire un vecteur de caractéristiques et entraîner le classificateur. Nous utiliserons les données étiquetées du package scikit-learn. Voici le code Python pour créer un chercheur de genre -

Importons les packages nécessaires -

import random

from nltk import NaiveBayesClassifier
from nltk.classify import accuracy as nltk_accuracy
from nltk.corpus import names

Nous devons maintenant extraire les N dernières lettres du mot d'entrée. Ces lettres agiront comme des caractéristiques -

def extract_features(word, N = 2):
   last_n_letters = word[-N:]
   return {'feature': last_n_letters.lower()}
	
if __name__=='__main__':

Créez les données d'entraînement en utilisant les noms étiquetés (hommes et femmes) disponibles dans NLTK -

male_list = [(name, 'male') for name in names.words('male.txt')]
female_list = [(name, 'female') for name in names.words('female.txt')]
data = (male_list + female_list)

random.seed(5)
random.shuffle(data)

Maintenant, les données de test seront créées comme suit -

namesInput = ['Rajesh', 'Gaurav', 'Swati', 'Shubha']

Définissez le nombre d'échantillons utilisés pour le train et le test avec le code suivant

train_sample = int(0.8 * len(data))

Maintenant, nous devons parcourir différentes longueurs afin que la précision puisse être comparée -

for i in range(1, 6):
   print('\nNumber of end letters:', i)
   features = [(extract_features(n, i), gender) for (n, gender) in data]
   train_data, test_data = features[:train_sample],
features[train_sample:]
   classifier = NaiveBayesClassifier.train(train_data)

La précision du classificateur peut être calculée comme suit -

accuracy_classifier = round(100 * nltk_accuracy(classifier, test_data), 2)
   print('Accuracy = ' + str(accuracy_classifier) + '%')

Maintenant, nous pouvons prédire la sortie -

for name in namesInput:
   print(name, '==>', classifier.classify(extract_features(name, i)))

Le programme ci-dessus générera la sortie suivante -

Number of end letters: 1
Accuracy = 74.7%
Rajesh -> female
Gaurav -> male
Swati -> female
Shubha -> female

Number of end letters: 2
Accuracy = 78.79%
Rajesh -> male
Gaurav -> male
Swati -> female
Shubha -> female

Number of end letters: 3
Accuracy = 77.22%
Rajesh -> male
Gaurav -> female
Swati -> female
Shubha -> female

Number of end letters: 4
Accuracy = 69.98%
Rajesh -> female
Gaurav -> female
Swati -> female
Shubha -> female

Number of end letters: 5
Accuracy = 64.63%
Rajesh -> female
Gaurav -> female
Swati -> female
Shubha -> female

Dans la sortie ci-dessus, nous pouvons voir que la précision du nombre maximum de lettres de fin est de deux et qu'elle diminue à mesure que le nombre de lettres de fin augmente.

Modélisation de sujets: identification des modèles dans les données texte

Nous savons que les documents sont généralement regroupés en thèmes. Parfois, nous devons identifier les modèles dans un texte qui correspondent à un sujet particulier. La technique pour ce faire est appelée modélisation de sujets. En d'autres termes, nous pouvons dire que la modélisation de sujets est une technique pour découvrir des thèmes abstraits ou une structure cachée dans un ensemble de documents donné.

Nous pouvons utiliser la technique de modélisation de sujet dans les scénarios suivants -

Classification du texte

À l'aide de la modélisation de sujets, la classification peut être améliorée car elle regroupe des mots similaires plutôt que d'utiliser chaque mot séparément comme une caractéristique.

Systèmes de recommandation

À l'aide de la modélisation de sujets, nous pouvons créer les systèmes de recommandation en utilisant des mesures de similarité.

Algorithmes pour la modélisation de sujets

La modélisation de sujet peut être implémentée à l'aide d'algorithmes. Les algorithmes sont les suivants -

Allocation de dirichlet latente (LDA)

Cet algorithme est le plus populaire pour la modélisation de sujets. Il utilise les modèles graphiques probabilistes pour la mise en œuvre de la modélisation thématique. Nous devons importer le package gensim en Python pour utiliser le slgorithme LDA.

Analyse sémantique latente (LDA) ou indexation sémantique latente (LSI)

Cet algorithme est basé sur l'algèbre linéaire. Fondamentalement, il utilise le concept de SVD (Singular Value Decomposition) sur la matrice des termes du document.

Factorisation matricielle non négative (NMF)

Il est également basé sur l'algèbre linéaire.

Tous les algorithmes mentionnés ci-dessus pour la modélisation de sujets auraient le number of topics en paramètre, Document-Word Matrix comme entrée et WTM (Word Topic Matrix) & TDM (Topic Document Matrix) comme sortie.