Implementare Word2Vec con la libreria Gensim in Python

Introduzione

Gli esseri umani hanno una capacità naturale di capire cosa dicono gli altri e cosa dire in risposta. Questa capacità si sviluppa interagendo costantemente con altre persone e con la società per molti anni. Il linguaggio gioca un ruolo molto importante nel modo in cui gli esseri umani interagiscono. Le lingue che gli umani usano per interagire sono chiamate lingue naturali.

Le regole delle varie lingue naturali sono diverse. Tuttavia, c’è una cosa in comune nei linguaggi naturali: flessibilità ed evoluzione.

I linguaggi naturali sono altamente molto flessibili. Supponiamo che stiate guidando una macchina e che il vostro amico dica uno di questi tre enunciati: “Accosta”, “Ferma la macchina”, “Alt”. Capite immediatamente che vi sta chiedendo di fermare la macchina. Questo perché le lingue naturali sono estremamente flessibili. Ci sono più modi per dire una cosa.

Un altro aspetto importante dei linguaggi naturali è il fatto che sono in continua evoluzione. Per esempio, qualche anno fa non esisteva un termine come “Google it”, che si riferisce alla ricerca di qualcosa sul motore di ricerca Google. I linguaggi naturali sono sempre in evoluzione.

Al contrario, i linguaggi informatici seguono una sintassi rigida. Se si vuole dire a un computer di stampare qualcosa sullo schermo, c’è un comando speciale per questo. Il compito del Natural Language Processing è quello di fare in modo che i computer comprendano e generino il linguaggio umano in un modo simile a quello umano.

Questo è un compito enorme e ci sono molti ostacoli coinvolti. Questa lezione video dell’Università del Michigan contiene un’ottima spiegazione del perché NLP è così difficile.

In questo articolo implementeremo la tecnica Word2Vec word embedding usata per creare vettori di parole con la libreria Gensim di Python. Tuttavia, prima di saltare direttamente alla sezione di codifica, passeremo brevemente in rassegna alcune delle tecniche di word embedding più comunemente usate, insieme ai loro pro e contro.

Approcci di word embedding

Una delle ragioni per cui il Natural Language Processing è un problema difficile da risolvere è il fatto che, a differenza degli esseri umani, i computer possono capire solo numeri. Dobbiamo rappresentare le parole in un formato numerico che sia comprensibile per i computer. Il word embedding si riferisce alle rappresentazioni numeriche delle parole.

Esistono attualmente diversi approcci di word embedding e tutti hanno i loro pro e contro. Qui ne discuteremo tre:

  1. Bag of Words
  2. TF-IDF Scheme
  3. Word2Vec

Bag of Words

L’approccio bag of words è uno dei più semplici approcci di word embedding. I seguenti sono i passi per generare le incorporazioni di parole usando l’approccio del sacco di parole.

Vedremo le incorporazioni di parole generate dall’approccio del sacco di parole con l’aiuto di un esempio. Supponiamo di avere un corpus con tre frasi.

  • S1 = Amo la pioggia
  • S2 = pioggia pioggia andare via
  • S3 = Sono via

Per convertire le frasi di cui sopra nelle loro corrispondenti rappresentazioni di incorporazione di parole usando l’approccio del sacco di parole, dobbiamo eseguire i seguenti passi:

Nota che per S2 abbiamo aggiunto 2 al posto di “rain” nel dizionario; questo perché S2 contiene “rain” due volte.

Pro e contro del sacco di parole

L’approccio del sacco di parole ha sia pro che contro. Il vantaggio principale dell’approccio bag of words è che non è necessario un corpus di parole molto grande per ottenere buoni risultati. Potete vedere che costruiamo un modello di bag of words molto semplice con tre frasi. Computazionalmente, un modello a sacco di parole non è molto complesso.

Un grande svantaggio dell’approccio a sacco di parole è il fatto che abbiamo bisogno di creare enormi vettori con spazi vuoti per rappresentare un numero (matrice sparsa) che consuma memoria e spazio. Nell’esempio precedente, avevamo solo 3 frasi. Eppure si possono vedere tre zeri in ogni vettore.

Immaginate un corpus con migliaia di articoli. In tal caso, il numero di parole uniche in un dizionario può essere migliaia. Se un documento contiene il 10% delle parole uniche, il vettore di incorporazione corrispondente conterrà ancora il 90% di zeri.

Un altro grande problema con l’approccio del sacco di parole è il fatto che non mantiene alcuna informazione sul contesto. Non si preoccupa dell’ordine in cui le parole appaiono in una frase. Per esempio, tratta allo stesso modo le frasi “La bottiglia è nella macchina” e “La macchina è nella bottiglia”, che sono frasi completamente diverse.

Un tipo di approccio a bag of words, conosciuto come n-gram, può aiutare a mantenere la relazione tra le parole. Gli n-grammi si riferiscono a una sequenza contigua di n parole. Per esempio, 2 grammi per la frase “Tu non sei felice”, sono “Tu sei”, “non sono” e “non felice”. Anche se l’approccio degli n-grammi è capace di catturare le relazioni tra le parole, la dimensione del set di caratteristiche cresce esponenzialmente con troppi n-grammi.

Schema TF-IDF

Lo schema TF-IDF è un tipo di approccio di bag words dove invece di aggiungere zeri e uno nel vettore di incorporazione, si aggiungono numeri fluttuanti che contengono più informazioni utili rispetto a zeri e uno. L’idea dietro lo schema TF-IDF è il fatto che le parole che hanno un’alta frequenza di occorrenza in un documento, e meno frequenza di occorrenza in tutti gli altri documenti, sono più cruciali per la classificazione.

TF-IDF è un prodotto di due valori: La frequenza del termine (TF) e la frequenza inversa del documento (IDF).

La frequenza del termine si riferisce al numero di volte in cui una parola appare nel documento e può essere calcolata come:

Term frequence = (Number of Occurences of a word)/(Total words in the document)

Per esempio, se guardiamo la frase S1 della sezione precedente, cioè “Amo la pioggia”, ogni parola nella frase ricorre una volta e quindi ha una frequenza di 1. Al contrario, per S2, cioè “pioggia, pioggia, vai via”, la frequenza del termine è 1. “rain rain go away”, la frequenza di “rain” è due mentre per il resto delle parole è 1.

IDF si riferisce al log del numero totale di documenti diviso per il numero di documenti in cui la parola esiste, e può essere calcolato come:

IDF(word) = Log((Total number of documents)/(Number of documents containing the word))

Per esempio, il valore IDF per la parola “rain” è 0.1760, poiché il numero totale di documenti è 3 e rain appare in 2 di essi, quindi log(3/2) è 0.1760. D’altra parte, se si guarda la parola “amore” nella prima frase, essa appare in uno dei tre documenti e quindi il suo valore IDF è log(3), che è 0,4771.

Pro e contro di TF-IDF

Anche se TF-IDF è un miglioramento rispetto al semplice approccio bag of words e produce risultati migliori per i comuni compiti NLP, i pro e i contro generali rimangono gli stessi. Abbiamo ancora bisogno di creare un’enorme matrice sparsa, che richiede anche molti più calcoli rispetto al semplice approccio del bag of words.

Word2Vec

L’approccio <a target=”_blank rel=”nofollow”” href=”https://en.wikipedia.org/wiki/Word2vec”>Word2Vec embedding, sviluppato da Tomas Mikolov, è considerato lo stato dell’arte. L’approccio Word2Vec utilizza tecniche di deep learning e basate su reti neurali per convertire le parole in vettori corrispondenti in modo tale che i vettori semanticamente simili siano vicini l’uno all’altro nello spazio N-dimensionale, dove N si riferisce alle dimensioni del vettore.

Word2Vec restituisce alcuni risultati sorprendenti. La capacità di Word2Vec di mantenere la relazione semantica si riflette in un classico esempio in cui se si ha un vettore per la parola “Re” e si rimuove il vettore rappresentato dalla parola “Uomo” dal “Re” e gli si aggiunge “Donne”, si ottiene un vettore che è vicino al vettore “Regina”. Questa relazione è comunemente rappresentata come:

King - Man + Women = Queen

Il modello Word2Vec esiste in due versioni: Skip Gram Model e Continuous Bag of Words Model (CBOW).

Nel modello Skip Gram, le parole del contesto sono predette usando la parola base. Per esempio, data una frase “Amo ballare sotto la pioggia”, il modello Skip Gram predirà “amore” e “ballo” data la parola “a” come input.

Al contrario, il modello CBOW predirà “a”, se le parole di contesto “amore” e “ballo” sono fornite come input al modello. Il modello impara queste relazioni usando reti neurali profonde.

Pro e contro di Word2Vec

Word2Vec ha diversi vantaggi rispetto al bag of words e allo schema IF-IDF. Word2Vec mantiene il significato semantico delle diverse parole in un documento. Le informazioni sul contesto non vengono perse. Un altro grande vantaggio dell’approccio Word2Vec è che la dimensione del vettore di incorporazione è molto piccola. Ogni dimensione nel vettore di incorporazione contiene informazioni su un aspetto della parola. Non abbiamo bisogno di enormi vettori sparsi, a differenza degli approcci bag of words e TF-IDF.

Nota: I dettagli matematici di come funziona Word2Vec implicano una spiegazione delle reti neurali e della probabilità softmax, che va oltre lo scopo di questo articolo. Se volete capire le basi matematiche di Word2Vec, leggete questo articolo: https://arxiv.org/abs/1301.3781

Word2Vec in Python con la libreria Gensim

In questa sezione, implementeremo il modello Word2Vec con l’aiuto della libreria Gensim di Python. Segui questi passi:

Creazione del corpus

Abbiamo discusso in precedenza che per creare un modello Word2Vec, abbiamo bisogno di un corpus. Nelle applicazioni reali, i modelli Word2Vec sono creati utilizzando miliardi di documenti. Per esempio, il modello Word2Vec di Google è addestrato utilizzando 3 milioni di parole e frasi. Tuttavia, per il bene della semplicità, creeremo un modello Word2Vec utilizzando un singolo articolo di Wikipedia. Il nostro modello non sarà buono come quello di Google. Tuttavia, è abbastanza buono per spiegare come il modello Word2Vec può essere implementato utilizzando la libreria Gensim.

Prima di poter riassumere gli articoli di Wikipedia, abbiamo bisogno di recuperarli. Per farlo useremo un paio di librerie. La prima libreria che dobbiamo scaricare è la libreria Beautiful Soup, che è una utility Python molto utile per il web scraping. Esegui il seguente comando al prompt dei comandi per scaricare l’utility Beautiful Soup.

$ pip install beautifulsoup4

Un’altra importante libreria di cui abbiamo bisogno per analizzare XML e HTML è la libreria lxml. Esegui il seguente comando al prompt dei comandi per scaricare lxml:

$ pip install lxml

L’articolo che stiamo per raschiare è l’articolo di Wikipedia sull’intelligenza artificiale. Scriviamo uno script Python per raschiare l’articolo da Wikipedia:

Nello script sopra, prima scarichiamo l’articolo di Wikipedia usando il metodo urlopen della classe request della libreria urllib. Poi leggiamo il contenuto dell’articolo e lo analizziamo usando un oggetto della classe BeautifulSoup. Wikipedia memorizza il contenuto testuale dell’articolo all’interno dei tag p. Usiamo la funzione find_all dell’oggetto BeautifulSoup per recuperare tutti i contenuti dai tag paragrafo dell’articolo.

Finalmente, uniamo tutti i paragrafi insieme e memorizziamo l’articolo raschiato nella variabile article_text per un uso successivo.

Preprocessing

A questo punto abbiamo importato l’articolo. Il prossimo passo è quello di preprocessare il contenuto per il modello Word2Vec. Il seguente script pre-elabora il testo:

Nello script sopra, convertiamo tutto il testo in minuscolo e poi rimuoviamo tutte le cifre, i caratteri speciali e gli spazi extra dal testo. Dopo la pre-elaborazione, ci rimangono solo le parole.

Il modello Word2Vec è addestrato su un insieme di parole. Per prima cosa, abbiamo bisogno di convertire il nostro articolo in frasi. Usiamo l’utilità nltk.sent_tokenize per convertire il nostro articolo in frasi. Per convertire le frasi in parole, usiamo l’utilità nltk.word_tokenize. Come ultimo passo di pre-elaborazione, rimuoviamo tutte le parole di stop dal testo.

Dopo che lo script completa la sua esecuzione, l’oggetto all_words contiene la lista di tutte le parole nell’articolo. Useremo questa lista per creare il nostro modello Word2Vec con la libreria Gensim.

Creazione del modello Word2Vec

Con Gensim, è estremamente semplice creare il modello Word2Vec. La lista di parole viene passata alla classe Word2Vec del pacchetto gensim.models. Dobbiamo specificare il valore del parametro min_count. Un valore di 2 per min_count specifica di includere nel modello Word2Vec solo le parole che appaiono almeno due volte nel corpus. Il seguente script crea il modello Word2Vec usando l’articolo di Wikipedia che abbiamo raschiato.

from gensim.models import Word2Vecword2vec = Word2Vec(all_words, min_count=2)

Per vedere il dizionario delle parole uniche che esistono almeno due volte nel corpus, esegui il seguente script:

vocabulary = word2vec.wv.vocabprint(vocabulary)

Quando lo script di cui sopra viene eseguito, vedrai una lista di tutte le parole uniche che appaiono almeno due volte.

Analisi del modello

Abbiamo creato con successo il nostro modello Word2Vec nella sezione precedente. Ora è il momento di esplorare ciò che abbiamo creato.

Trovare i vettori per una parola

Sappiamo che il modello Word2Vec converte le parole nei loro vettori corrispondenti. Vediamo come possiamo visualizzare la rappresentazione vettoriale di qualsiasi parola particolare.

v1 = word2vec.wv

Il vettore v1 contiene la rappresentazione vettoriale per la parola “artificiale”. Per default, un vettore di cento dimensioni è creato da Gensim Word2Vec. Questo è un vettore molto, molto più piccolo rispetto a quello che sarebbe stato prodotto da bag of words. Se usiamo l’approccio bag of words per incorporare l’articolo, la lunghezza del vettore per ciascuno sarà 1206 poiché ci sono 1206 parole uniche con una frequenza minima di 2. Se la frequenza minima di occorrenza è impostata a 1, la dimensione del vettore bag of words aumenterà ulteriormente. D’altra parte, i vettori generati attraverso Word2Vec non sono influenzati dalla dimensione del vocabolario.

Trovare parole simili

Prima abbiamo detto che l’informazione contestuale delle parole non si perde usando l’approccio Word2Vec. Possiamo verificarlo trovando tutte le parole simili alla parola “intelligence”.

Date un’occhiata al seguente script:

sim_words = word2vec.wv.most_similar('intelligence')

Se stampate la variabile sim_words nella console, vedrete le parole più simili a “intelligence” come mostrato di seguito:

Dall’output, potete vedere le parole simili a “intelligence” insieme al loro indice di similarità. La parola “ai” è la parola più simile a “intelligenza” secondo il modello, il che ha effettivamente senso. Allo stesso modo, parole come “umano” e “artificiale” spesso coesistono con la parola “intelligenza”. Il nostro modello ha catturato con successo queste relazioni usando solo un singolo articolo di Wikipedia.

Conclusione

In questo articolo, abbiamo implementato un modello di Word2Vec word embedding con la libreria Gensim di Python. Abbiamo fatto questo raschiando un articolo di Wikipedia e costruito il nostro modello Word2Vec usando l’articolo come corpus. Abbiamo anche esaminato brevemente gli approcci di word embedding più comunemente usati insieme ai loro pro e contro in confronto a Word2Vec.

Vorrei suggerirvi di creare un vostro modello Word2Vec con l’aiuto di qualsiasi corpus di testo e vedere se potete ottenere risultati migliori rispetto all’approccio bag of words.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.