AI con Python - Pacchetto NLTK

In questo capitolo impareremo come iniziare con il pacchetto Natural Language Toolkit.

Prerequisito

Se vogliamo creare applicazioni con l'elaborazione del linguaggio naturale, il cambiamento di contesto lo rende molto difficile. Il fattore contesto influenza il modo in cui la macchina comprende una frase particolare. Quindi, dobbiamo sviluppare applicazioni in linguaggio naturale utilizzando approcci di apprendimento automatico in modo che anche la macchina possa comprendere il modo in cui un essere umano può comprendere il contesto.

Per costruire tali applicazioni useremo il pacchetto Python chiamato NLTK (Natural Language Toolkit Package).

Importazione di NLTK

Dobbiamo installare NLTK prima di usarlo. Può essere installato con l'aiuto del seguente comando:

pip install nltk

Per creare un pacchetto conda per NLTK, usa il seguente comando:

conda install -c anaconda nltk

Ora dopo aver installato il pacchetto NLTK, dobbiamo importarlo tramite il prompt dei comandi di python. Possiamo importarlo scrivendo il seguente comando sul prompt dei comandi di Python:

>>> import nltk

Download dei dati di NLTK

Ora dopo aver importato NLTK, dobbiamo scaricare i dati richiesti. Può essere fatto con l'aiuto del seguente comando sul prompt dei comandi di Python:

>>> nltk.download()

Installazione di altri pacchetti necessari

Per creare applicazioni di elaborazione del linguaggio naturale utilizzando NLTK, è necessario installare i pacchetti necessari. I pacchetti sono i seguenti:

gensim

È una robusta libreria di modelli semantici utile per molte applicazioni. Possiamo installarlo eseguendo il seguente comando:

pip install gensim

modello

È usato per fare gensimpacchetto funziona correttamente. Possiamo installarlo eseguendo il seguente comando

pip install pattern

Concetto di tokenizzazione, stemming e lemmatizzazione

In questa sezione capiremo cosa sono tokenizzazione, stemming e lemmatizzazione.

Tokenizzazione

Può essere definito come il processo di rottura del testo dato, cioè la sequenza di caratteri in unità più piccole chiamate token. I gettoni possono essere parole, numeri o segni di punteggiatura. Viene anche chiamata segmentazione delle parole. Di seguito è riportato un semplice esempio di tokenizzazione:

Input - Mango, banana, ananas e mela sono tutti frutti.

Output -

Il processo di rottura del testo dato può essere fatto con l'aiuto di individuare i confini delle parole. La fine di una parola e l'inizio di una nuova parola sono chiamati confini di parola. Il sistema di scrittura e la struttura tipografica delle parole influenzano i confini.

Nel modulo Python NLTK, abbiamo diversi pacchetti relativi alla tokenizzazione che possiamo utilizzare per dividere il testo in token secondo i nostri requisiti. Alcuni dei pacchetti sono i seguenti:

pacchetto sent_tokenize

Come suggerisce il nome, questo pacchetto dividerà il testo di input in frasi. Possiamo importare questo pacchetto con l'aiuto del seguente codice Python -

from nltk.tokenize import sent_tokenize

pacchetto word_tokenize

Questo pacchetto divide il testo di input in parole. Possiamo importare questo pacchetto con l'aiuto del seguente codice Python -

from nltk.tokenize import word_tokenize

Pacchetto WordPunctTokenizer

Questo pacchetto divide il testo di input in parole così come i segni di punteggiatura. Possiamo importare questo pacchetto con l'aiuto del seguente codice Python -

from nltk.tokenize import WordPuncttokenizer

Stemming

Lavorando con le parole, incontriamo molte variazioni dovute a motivi grammaticali. Il concetto di variazioni qui significa che dobbiamo trattare con diverse forme delle stesse parole comedemocracy, democratic, e democratization. È molto necessario che le macchine comprendano che queste diverse parole hanno la stessa forma di base. In questo modo, sarebbe utile estrarre le forme base delle parole mentre stiamo analizzando il testo.

Possiamo raggiungere questo obiettivo arginando. In questo modo, possiamo dire che lo stemming è il processo euristico di estrarre le forme base delle parole tagliando le estremità delle parole.

Nel modulo Python NLTK, abbiamo diversi pacchetti relativi allo stemming. Questi pacchetti possono essere usati per ottenere le forme base della parola. Questi pacchetti utilizzano algoritmi. Alcuni dei pacchetti sono i seguenti:

Pacchetto PorterStemmer

Questo pacchetto Python utilizza l'algoritmo di Porter per estrarre il modulo di base. Possiamo importare questo pacchetto con l'aiuto del seguente codice Python -

from nltk.stem.porter import PorterStemmer

Ad esempio, se daremo la parola ‘writing’ come input a questo stemmer li otterremo la parola ‘write’ dopo lo stemma.

Pacchetto LancasterStemmer

Questo pacchetto Python utilizzerà l'algoritmo di Lancaster per estrarre il modulo di base. Possiamo importare questo pacchetto con l'aiuto del seguente codice Python -

from nltk.stem.lancaster import LancasterStemmer

Ad esempio, se daremo la parola ‘writing’ come input a questo stemmer li otterremo la parola ‘write’ dopo lo stemma.

Pacchetto SnowballStemmer

Questo pacchetto Python utilizzerà l'algoritmo della palla di neve per estrarre il modulo di base. Possiamo importare questo pacchetto con l'aiuto del seguente codice Python -

from nltk.stem.snowball import SnowballStemmer

Ad esempio, se daremo la parola ‘writing’ come input a questo stemmer li otterremo la parola ‘write’ dopo lo stemma.

Tutti questi algoritmi hanno diversi livelli di rigore. Se confrontiamo questi tre stemmers, allora lo stemmers Porter è il meno rigoroso e Lancaster è il più rigoroso. Lo stemmer Snowball è buono da usare in termini di velocità e rigore.

Lemmatizzazione

Possiamo anche estrarre la forma base delle parole mediante lemmatizzazione. Fondamentalmente svolge questo compito con l'uso di un vocabolario e l'analisi morfologica delle parole, normalmente mirando a rimuovere solo le desinenze flessive. Questo tipo di forma base di qualsiasi parola si chiama lemma.

La principale differenza tra stemming e lemmatization è l'uso del vocabolario e l'analisi morfologica delle parole. Un'altra differenza è che lo stemma più comunemente fa collassare parole correlate in modo derivativo mentre la lemmatizzazione comunemente collassa solo le diverse forme flessive di un lemma. Ad esempio, se forniamo la parola saw come parola di input, lo stemming potrebbe restituire la parola "s", ma la lemmatizzazione tenterebbe di restituire la parola see o saw a seconda che l'uso del token fosse un verbo o un sostantivo.

Nel modulo Python NLTK, abbiamo il seguente pacchetto relativo al processo di lemmatizzazione che possiamo usare per ottenere le forme base della parola:

Pacchetto WordNetLemmatizer

Questo pacchetto Python estrarrà la forma base della parola a seconda che sia usata come nome o come verbo. Possiamo importare questo pacchetto con l'aiuto del seguente codice Python -

from nltk.stem import WordNetLemmatizer

Chunking: divisione dei dati in blocchi

È uno dei processi importanti nell'elaborazione del linguaggio naturale. Il compito principale del chunking è identificare le parti del discorso e le frasi brevi come le frasi nominali. Abbiamo già studiato il processo di tokenizzazione, la creazione di token. Il chunking è fondamentalmente l'etichettatura di quei token. In altre parole, il chunking ci mostrerà la struttura della frase.

Nella sezione seguente, impareremo i diversi tipi di Chunking.

Tipi di chunking

Esistono due tipi di chunking. I tipi sono i seguenti:

Divorare

In questo processo di frammentazione, l'oggetto, le cose, ecc. Si muovono verso l'essere più generali e il linguaggio diventa più astratto. Ci sono più possibilità di accordo. In questo processo, riduciamo lo zoom. Ad esempio, se raggruppiamo la domanda che "a che scopo sono le auto"? Potremmo ottenere la risposta "trasporto".

Chunking down

In questo processo di frammentazione, l'oggetto, le cose, ecc. Si muovono verso l'essere più specifici e il linguaggio diventa più penetrato. La struttura più profonda dovrebbe essere esaminata nel chunking. In questo processo, ingrandiamo. Ad esempio, se abbattiamo la domanda "Racconta specificamente di un'auto"? Otterremo informazioni più piccole sull'auto.

Example

In questo esempio, eseguiremo il chunking della frase dei nomi, una categoria di blocchi che troverà i pezzi delle frasi nominali nella frase, utilizzando il modulo NLTK in Python -

Follow these steps in python for implementing noun phrase chunking −

Step 1- In questo passaggio, dobbiamo definire la grammatica per il chunking. Consisterà nelle regole che dobbiamo seguire.

Step 2- In questo passaggio, dobbiamo creare un parser di blocchi. Analizzerebbe la grammatica e darebbe l'output.

Step 3 - In questo ultimo passaggio, l'output viene prodotto in un formato ad albero.

Importiamo il pacchetto NLTK necessario come segue:

import nltk

Ora dobbiamo definire la frase. Qui, DT significa il determinante, VBP significa il verbo, JJ significa l'aggettivo, IN significa la preposizione e NN significa il sostantivo.

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

Ora, dobbiamo dare la grammatica. Qui daremo la grammatica sotto forma di espressione regolare.

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

Dobbiamo definire un parser che analizzerà la grammatica.

parser_chunking = nltk.RegexpParser(grammar)

Il parser analizza la frase come segue:

parser_chunking.parse(sentence)

Successivamente, dobbiamo ottenere l'output. L'output viene generato nella semplice variabile chiamataoutput_chunk.

Output_chunk = parser_chunking.parse(sentence)

Dopo l'esecuzione del seguente codice, possiamo disegnare il nostro output sotto forma di albero.

output.draw()

Modello Bag of Word (BoW)

Bag of Word (BoW), un modello nell'elaborazione del linguaggio naturale, viene fondamentalmente utilizzato per estrarre le caratteristiche dal testo in modo che il testo possa essere utilizzato nella modellazione come negli algoritmi di apprendimento automatico.

Ora sorge la domanda sul perché abbiamo bisogno di estrarre le caratteristiche dal testo. È perché gli algoritmi di apprendimento automatico non possono funzionare con dati grezzi e hanno bisogno di dati numerici in modo da poter estrarre informazioni significative da essi. La conversione dei dati di testo in dati numerici è chiamata estrazione delle caratteristiche o codifica delle caratteristiche.

Come funziona

Questo è un approccio molto semplice per estrarre le caratteristiche dal testo. Supponiamo di avere un documento di testo e di voler convertirlo in dati numerici o di voler estrarre le caratteristiche da esso, quindi prima di tutto questo modello estrae un vocabolario da tutte le parole nel documento. Quindi, utilizzando una matrice dei termini del documento, costruirà un modello. In questo modo, BoW rappresenta il documento solo come un sacco di parole. Qualsiasi informazione sull'ordine o sulla struttura delle parole nel documento viene eliminata.

Concetto di matrice dei termini del documento

L'algoritmo BoW costruisce un modello utilizzando la matrice dei termini del documento. Come suggerisce il nome, la matrice dei termini del documento è la matrice di vari conteggi di parole che si verificano nel documento. Con l'aiuto di questa matrice, il documento di testo può essere rappresentato come una combinazione ponderata di varie parole. Impostando la soglia e scegliendo le parole più significative, possiamo costruire un istogramma di tutte le parole nei documenti che può essere utilizzato come vettore di caratteristiche. Di seguito è riportato un esempio per comprendere il concetto di matrice dei termini del documento:

Example

Supponiamo di avere le seguenti due frasi:

  • Sentence 1 - Stiamo usando il modello Bag of Words.

  • Sentence 2 - Il modello Bag of Words viene utilizzato per estrarre le caratteristiche.

Ora, considerando queste due frasi, abbiamo le seguenti 13 parole distinte:

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

Ora, dobbiamo costruire un istogramma per ogni frase usando il conteggio delle parole in ogni frase -

  • 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,1]

In questo modo, abbiamo i vettori delle caratteristiche che sono stati estratti. Ogni vettore di caratteristiche è tridimensionale perché abbiamo 13 parole distinte.

Concetto di statistica

Il concetto di statistica è chiamato TermFrequency-Inverse Document Frequency (tf-idf). Ogni parola è importante nel documento. Le statistiche ci aiutano a capire l'importanza di ogni parola.

Frequenza del termine (tf)

È la misura della frequenza con cui ogni parola appare in un documento. Può essere ottenuto dividendo il conteggio di ogni parola per il numero totale di parole in un dato documento.

Frequenza documento inversa (idf)

È la misura di quanto sia unica una parola per questo documento in un dato insieme di documenti. Per calcolare idf e formulare un vettore di caratteristiche distintive, dobbiamo ridurre i pesi delle parole che ricorrono comunemente come e soppesare le parole rare.

Costruire un modello di borsa di parole in NLTK

In questa sezione, definiremo una raccolta di stringhe utilizzando CountVectorizer per creare vettori da queste frasi.

Importiamo il pacchetto necessario -

from sklearn.feature_extraction.text import CountVectorizer

Ora definisci l'insieme di frasi.

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_)

Il programma di cui sopra genera l'output come mostrato di seguito. Mostra che abbiamo 13 parole distinte nelle due frasi precedenti:

{'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}

Questi sono i vettori di funzionalità (dal testo alla forma numerica) che possono essere utilizzati per l'apprendimento automatico.

Risolvere problemi

In questa sezione, risolveremo alcuni problemi correlati.

Previsione di categoria

In una serie di documenti, non solo le parole ma anche la categoria delle parole è importante; in quale categoria di testo rientra una parola particolare. Ad esempio, vogliamo prevedere se una determinata frase appartiene alla categoria e-mail, notizie, sport, computer, ecc. Nell'esempio seguente, utilizzeremo tf-idf per formulare un vettore di caratteristiche per trovare la categoria di documenti. Useremo i dati da 20 dataset di newsgroup di sklearn.

Dobbiamo importare i pacchetti necessari -

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

Definisci la mappa delle categorie. Stiamo utilizzando cinque diverse categorie denominate Religione, Auto, Sport, Elettronica e Spazio.

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

Crea il set di allenamento -

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

Crea un vettorizzatore di conteggio ed estrai i termini conteggi

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

Il trasformatore tf-idf viene creato come segue:

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

Ora, definisci i dati del 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'
]

I dati di cui sopra ci aiuteranno a formare un classificatore multinomiale Naive Bayes -

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

Trasforma i dati di input utilizzando il vettorizzatore di conteggio -

input_tc = vectorizer_count.transform(input_data)

Ora, trasformeremo i dati vettorizzati usando il trasformatore tfidf -

input_tfidf = tfidf.transform(input_tc)

Prevederemo le categorie di output -

predictions = classifier.predict(input_tfidf)

L'output viene generato come segue:

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

Il predittore di categoria genera il seguente output:

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

Gender Finder

In questa affermazione del problema, un classificatore sarebbe addestrato a trovare il sesso (maschio o femmina) fornendo i nomi. Dobbiamo usare un'euristica per costruire un vettore di caratteristiche e addestrare il classificatore. Useremo i dati etichettati dal pacchetto scikit-learn. Di seguito è riportato il codice Python per creare un rilevatore di genere -

Importiamo i pacchetti necessari -

import random

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

Ora dobbiamo estrarre le ultime N lettere dalla parola in ingresso. Queste lettere fungeranno da caratteristiche:

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

Crea i dati di allenamento utilizzando nomi etichettati (maschili e femminili) disponibili in 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)

Ora, i dati del test verranno creati come segue:

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

Definisci il numero di campioni utilizzati per l'addestramento e il test con il codice seguente

train_sample = int(0.8 * len(data))

Ora, dobbiamo iterare su lunghezze diverse in modo che la precisione possa essere confrontata -

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 precisione del classificatore può essere calcolata come segue:

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

Ora possiamo prevedere l'output -

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

Il programma sopra genererà il seguente output:

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

Nell'output sopra, possiamo vedere che la precisione nel numero massimo di lettere finali è due e diminuisce all'aumentare del numero di lettere finali.

Topic Modeling: identificazione di modelli nei dati di testo

Sappiamo che generalmente i documenti sono raggruppati in argomenti. A volte abbiamo bisogno di identificare i modelli in un testo che corrispondono a un particolare argomento. La tecnica per eseguire questa operazione si chiama modellazione dell'argomento. In altre parole, possiamo dire che la modellazione di argomenti è una tecnica per scoprire temi astratti o strutture nascoste in un dato insieme di documenti.

Possiamo utilizzare la tecnica di modellazione degli argomenti nei seguenti scenari:

Classificazione del testo

Con l'aiuto della modellazione degli argomenti, la classificazione può essere migliorata perché raggruppa parole simili insieme anziché utilizzare ciascuna parola separatamente come caratteristica.

Sistemi di raccomandazione

Con l'aiuto della modellazione degli argomenti, possiamo costruire i sistemi di raccomandazione utilizzando misure di similarità.

Algoritmi per la modellazione di argomenti

La modellazione degli argomenti può essere implementata utilizzando algoritmi. Gli algoritmi sono i seguenti:

Latent Dirichlet Allocation (LDA)

Questo algoritmo è il più popolare per la modellazione di argomenti. Utilizza i modelli grafici probabilistici per implementare la modellazione degli argomenti. Dobbiamo importare il pacchetto gensim in Python per usare lo slgorithm LDA.

Latent Semantic Analysis (LDA) o Latent Semantic Indexing (LSI)

Questo algoritmo è basato sull'algebra lineare. Fondamentalmente utilizza il concetto di SVD (Singular Value Decomposition) sulla matrice dei termini del documento.

Fattorizzazione di matrice non negativa (NMF)

Si basa anche sull'algebra lineare.

Tutti gli algoritmi sopra menzionati per la modellazione di argomenti avrebbero l'estensione number of topics come parametro, Document-Word Matrix come input e WTM (Word Topic Matrix) & TDM (Topic Document Matrix) come output.