La cybersecurity è condivisione. Riconosci il rischio, combattilo, condividi le tue esperienze ed incentiva gli altri a fare meglio di te.
Introduzione all’NLP: tutto quello che serve per cominciare!
Marcello Politi : 15 Settembre 2023 22:22
I dati di tipo testuale stanno aumentando in modo esorbitante, e la maggior parte di questi dati non sono strutturati, quindi è difficile ricavarne informazioni utili. Degli esempi di questa enorme quantità di dati che vengono diffusi ogni giorno sono i tweet, i post sui social media o i forum online. Le persone scrivono i loro commenti utilizzando un linguaggio non sempre corretto, spesso ricorrendo al dialetto o alle emoji per far capire le loro emozioni, e quindi generando dati di bassa qualità.
L’obiettivo principale dei diversi approcci di Natural Language Processing (NLP) è quello di ottenere una comprensione del testo simile a quella umana. L’NLP ci aiuta a esaminare una grande quantità di testo non strutturato e ad estrarne caratteristiche (o feature) e pattern.
In genere, in un task di NLP come il sentiment analysis o named entity recognition, ci sono dei passaggi standard da seguire. Il problema principale è che gli algoritmi di apprendimento automatico non sanno come gestire le parole, quindi dobbiamo trovare una rappresentazione numerica appropriata dei nostri testi. Per generare questa rappresentazione dobbiamo ripulire i dati da qualsiasi rumore e poi eseguire l’estrazione delle feature, cioè trasformare i dati grezzi in dati numerici comprensibili alle macchine.
Sei un Esperto di Formazione? Entra anche tu nel Partner program! Accedi alla sezione riservata ai Creator sulla nostra Academy e scopri i vantaggi riservati ai membri del Partner program. Per ulteriori informazioni, scrivici ad [email protected] oppure su Whatsapp al 379 163 8765
Ti piacciono gli articoli di Red Hot Cyber? Non aspettare oltre, iscriviti alla newsletter settimanale per non perdere nessun articolo
Esaminiamo gli step più comuni del preprocessing del testo. Di seguito descriverò un elenco di step di preprocessing, ma non è necessario eseguirli tutti per risolvere un determinato task. Al contrario, spesso utilizzando reti neurali basati suu transformers si tende a lasciare il testo invariato (quindi non si applica preprocessing) al fine di non alterare il contesto delle frasi. Sta quindi a voi, come professionisti dell’NLP, capire di cosa avete bisogno.
Text Preprocessing
Tokenization: la tokenizzazione è il processo che trasforma un testo in unità atomiche. Ad esempio, le unità atomiche possono essere parole, sottoparole o anche i singoli caratteri.
Rimozione del rumore come URL e hashtag: spesso, quando esaminiamo un dataset, questo è molto sporco, ad esempio perché è stato prelevato da Internet. In molti casi, simboli o parole inutili nel testo, come i tag HTML, non aggiungono informazioni ma creano solo rumore.
Segmentazione degli hashtag: nel testo troviamo frequentemente parole precedute da un hashtag (# è molto usato nei social media). Queste parole possono essere molto importanti per capire il topic del testo, quindi dobbiamo essere in grado di identificarle e rimuovere il simbolo #.
Sostituzione di emoticon ed emoji: Le emoticon e le emoji possono essere visualizzate in modo errato, spero di non essere l’unico ad aver avuto problemi di codifica con le emoji. A volte è opportuno rimuoverle, ma in un’attività di sentiment analysis, ad esempio, possono essere molto utili per capire il sentimento della frase. Quindi dipende molto dalla vostra discrezione.
Sostituzione di caratteri allungati: ciaooooooooo → ciao
Correzione degli errori ortografici: qui un ottimo articolo al riguardo.
Espansione delle contrazioni: I’ll → I will. (Un esempio di come farlo)
Rimozione delle punteggiature
Rimozione dei numeri
Trasformare il testo in minuscolo
Rimozione delle stop-words: si tratta di parole che compaiono molte volte e quindi non aggiungono molte informazioni al testo, ad esempio parole come “il, ah, ok”.
Stemming: è la tecnica per sostituire e rimuovere i suffissi e gli affissi per ottenere la radice, la parola base o stem. Es: “eats”→ “eat”.
Lemmatizzazione: lo scopo della lemmatizzazione è lo stesso dello stemming, cioè ridurre le parole alla loro base o radice. Tuttavia, nella lemmatizzazione, l’inflessione delle parole non viene semplicemente eliminata, ma si utilizza la conoscenza lessicale per trasformare le parole nella loro forma base. Es: “wolves”→ “wolf”.
Part of Speech (POS) Tagging: è il processo di identificazione di una parola in un testo (corpus) come corrispondente a una particolare parte del discorso, in base alla sua definizione e al suo contesto.
Gestione delle negazioni : Le negazioni possono cambiare completamente il significato della frase. Trovarle esplicitamente può quindi aiutare molto il vostro algoritmo.
Feature Extraction
Categorical word representation:
One hot encoding: Questo è il primo metodo e anche il più semplice da applicare per rappresentare il testo in uno spazio vettoriale. Ogni parola è associata ad un vettore di lunghezza pari alla cardinalità del dizionario che contiente tutte le parole possibili. Tutte le entries di ogni vettore sono 0, tranne una posizione in cui troviamo un 1. Quindi ogni vettore è diverso e i vettori hanno tutti la stessa distanza tra loro, perciò non ci sono parole più simili di altre.
Bag-of-Words (BoW): è semplicemente un’estensione del one-hot encoding. Si sommano le rappresentazioni one-hot delle parole della frase.
Weighted Word representation
Le rappresentazioni precedenti non tengono conto della frequenza delle parole nel testo, che tuttavia può essere un dato importante per comprenderne l’importanza.
Term Frequency (TF): invece di utilizzare solo 0 e 1, calcola la frequenza di una parola. La TF di una parola viene calcolata andando a contare quante volte una parola compare nel testo diviso il numero totale di parole (in modo da non penalizzare i documenti brevi a scapito di quelli più lunghi).
Term Frequency-Inverse Document Frequency (TF-IDF) : parole come “il” appaiono molte volte in un documento ma non sono molto informative. Quindi, una parola deve avere un peso elevato se appare molte volte in un documento e se compare in pochi documenti diversi nel vostro corpus. La forma per il calcolo di questo peso è la seguente.
Representation Learning : rappresentazione non contestuale delle parole
Le rappresentazioni numeriche del testo appena viste sono molto intuitive e facili da usare, ma presentano diversi problemi. In primo luogo, non riescono a catturare il significato sintattico e semantico delle parole e soffrono anche della cosiddetta maledizione della dimensionalità. Un vettore che rappresenta una parola avrà una lunghezza pari alla dimensione del vocabolario di parole di una lingua. Se lavorassimo su testi in più lingue contemporaneamente, la dimensionalità crescerebbe di molto!
Per questo motivo, ora vediamo modelli che riescono ad apprendere una rappresentazione delle parole utilizzando vettori con una dimensionalità fissa e limitata. Il vantaggio più significativo di questi vettori o word embeddings è che forniscono una rappresentazione più efficiente ed espressiva, mantenendo la somiglianza delle parole con il contesto e utilizzano una bassa dimensionalità. Questi vettori tendono quindi a catturare il significato delle parole. Questo tipo di rappresentazione è detta anche rappresentazione continua delle parole.
Word2Vec : La grande innovazione introdotta è che gli embedding delle parole sono i pesi di una rete neurale! Questo modello utilizza due strati nascosti che vengono utilizzati in una rete neurale per creare un vettore per ogni parola. I vettori di parole catturati dai modelli Continuous Bag of words (CBOW) e Skip-gram di word2vec contengono informazioni semantiche e sintattiche sulle parole.
Global Vectors (GloVe): L’algoritmo Global Vectors for Word Representation o GloVe è abbastanza simile a Word2Vec. Tuttavia, il metodo è leggermente diverso. GloVe prende in considerazione solo le informazioni contestuali su base 1-1. Ciò significa che GloVe crea solo una matrice relativa parola per parola, che include la probabilità di visualizzare la parola k vicino alla parola i. I risultati sono ottimi e permettono di mettere in relazione le parole in all’interno del contesto tra loro.
FastText : questo algoritmo suddivide una parola in n-grammi, anziché in parole intere, per darli in pasto a una rete neurale, che può cogliere le relazioni tra i caratteri o sillabe delle parole.
Representation Learning : rappresentazione contestuale delle parol
Perché ci interessa il contesto? Per spiegarlo meglio, a mio avviso, è più facile mostrare un esempio. Una parola può assumere significati diversi a seconda del contesto in cui è inserita. Nella frase: “Dove sei? Sono gia le sei, facciamo tardi!”. la parola “sei” assume due significati diversi e quindi dovrà avere due rappresentazioni diverse. Creare l’embedding di una parola a seconda del contesto potrebbe essere un boost per il vostro modello ML. Attenzione, però, alle fasi di preprocessing che potrebbero alterare il contesto. Vediamo i metodi principali per creare rappresentazioni contestuali di dati testuali.
Generic Context word representation (Context2Vec) : questo metodo utilizza una rete neurale di tipo LSTM per apprendere in modo efficiente una funzione generica di embedding. L’obiettivo principale di questo modello è quello di generare un embedding generico, indipendente dal task che vogliamo risolvere.
Contextualized word representations Vectors (CoVe): utilizza architetture neurali, spesso transformers, per modellare le relazioni tra le parole all’interno di una frase. Ciò consente a CoVe di creare rappresentazioni dinamiche delle parole che si adattano al loro contesto, catturando varie sfumature. Di conseguenza, le rappresentazioni CoVe codificano informazioni semantiche più ricche, dimostrandosi utili per compiti come l’analisi del sentimento, il riconoscimento delle entità e l’analisi sintattica, in quanto intrinsecamente comprendono le sfumature contestuali del linguaggio.
Embedding from language Models (ELMo) : I vettori di parole sono appresi da un modello linguistico bidirezionale. ELMo utilizza la concatenazione lineare delle rappresentazioni apprese dal modello linguistico bidirezionale, invece di limitarsi alle rappresentazioni dello strato finale del modello, come avviene per altre rappresentazioni contestuali delle parole. In frasi diverse, ELMo fornisce rappresentazioni diverse per la stessa parola. Qui trovate un bel tutorial su questo algoritmo.
Universal Language Model Fine-Tuning (ULMFiT) : Questo algoritmo, si basa molto sul concetto di apprendimento per trasferimento ( o transfer learning), in particolare consentendo l’addestramento del modello linguistico su un corpus (un insieme di documenti) e la possibilità di perfezionare poi il modello su corpora diversi, ma basandosi su quanto appreso nella fase precedente. Si tratta di un metodo di apprendimento basato sul transfer learning che può essere applicato a compiti di NLP. Per le sue rappresentazioni utilizza un’architettura AWD-LSTM a 3 strati. L’addestramento consiste in tre fasi: 1) pre-addestramento del modello linguistico generale su un testo basato su Wikipedia, 2) messa a punto del modello linguistico su un compito target e 3) messa a punto del classificatore sul compito target.
Modelli pre-addestrati basati su transformers
Prima di capire come funzionano i seguenti modelli vi cosniglio di dare una letta ai seguenti documenti:
Generative Pre-Training –GPT (OpenAI Transformer) : è il primo Language Model pre-addestrato basato sull’ architettura transformer e può gestire efficacemente la semantica delle parole considerando il contesto del testo. Si basa sulla parte decoder del transformer per modellare il linguaggio. È un modello autoregressivo che cioè fa predizione della parola successiva in base al contesto precedente per questo ottimo per la generazione di testo. Essendo addestrato su un insieme massiccio di dati testuali, GPT rientra nel campi dell’addestramento non supervisionato. Uno svantaggio di GPT è che è unidirezionale, cioè il modello è addestrato solo per prevedere il contesto futuro da sinistra a destra.
GPT 2 (OpenAI Transformer) : Il team OpenAI ha rilasciato una variante piu grande di GPT nel 2019. Essa incorpora alcuni leggeri miglioramenti rispetto alla precedente Complessivamente, esistono quattro varianti distinte di GPT2: la più piccola è identica in dimensioni a GPT, quella media è di dimensioni simili a BERT_LARGE e quella xlarge è stata rilasciata con un numero di parametri di 1,5B.
BERT : Questo modello è addestrato sul task chiamato masked language modelling (MLM), in cui alcuni token di una sequenza di input sono mascherati in modo casuale, e l’obiettivo è quello di prevedere queste posizioni mascherate prendendo come input la sequenza corrotta. BERT implementa un encoder transformer per tenere conto dei contesti bidirezionali durante il pre-training. Inoltre, BERT fa uso anche del task di “predizione della frase successiva” (NSP). Date due frasi in ingresso, NSP predice se la seconda frase è l’effettiva frase successiva alla prima. Utilizzando questi due task per l’addestramento, si riesce a generare un modello con buone capacità linguistiche.
Se volete imparare ad usare BERT potete leggere alcuni dei miei articoli online:
RoBERTa : apporta alcune modifiche al modello BERT e ottiene miglioramenti sostanziali. Le modifiche includono: (1) addestramento più lungo del modello con batch più grandi e più dati (2) eliminazione del task NSP (3) addestramento su sequenze più lunghe (4) modifica dinamica delle posizioni mascherate durante il preaddestramento.
ALBERT: presenta tecniche di riduzione dei parametri per ridurre il consumo di memoria e aumentare la velocità di addestramento del BERT.
XLNet : XLNet, un metodo di pretraining autoregressivo generalizzato che (1) consente l’apprendimento di contesti bidirezionali (2) supera i limiti di BERT grazie alla sua impostazione autoregressiva..
ELECTRA : Invece di alterare alcune posizioni degli input con il tag [MASK], ELECTRA sostituisce alcuni token degli input con le loro alternative plausibili. ELECTRA quindi addestra un discriminatore per prevedere se ogni token dell’input corrotto è stato sostituito o meno dal generatore. Il discriminatore preaddestrato può essere fine-tunato (addestrato ulteriormente) in compiti piu specifici.
T5 : è un modello di rete neurale estremamente grande, addestrato su una combinazione di testo non etichettato e di dati etichettati provenienti da task comunii di NLP, poi fine-tunato (addestrato ulteriorlmente su task specifici) individualmente per ciascuno dei task che gli autori intendono risolvere [3].
BART : BART viene addestrato (1) corrompendo il testo con una funzione di rumore arbitraria e (2) addestrando un modello per ricostruire il testo originale[4].
Downstream Learning
Una volta che gli embedding (vettori) di un testo sono stati appressi, possono essere utilizzati per risolvere vari compiti di NLP, chiamati downstream tasks. Gli embeddings contestuali hanno dimostrato prestazioni impressionanti rispetto agli embeddings non contestuali. Ma la domanda che ci si pone ora è: “Come possiamo utilizzare i modelli pretrainati a riconoscere il contesto per downstream tasks?”.
Feature-based Con questo metodo si congela il modello, in modo che quando si deve risolvere il task, il modello non venga addestrato sul dataset custom. Si utilizzerà solo il modello preaddestrato per generare le feature (gli embeddings) che verranno utilizzati, ad esempio, come input per un classificatore.
Fine-tuning A differenza del metodo precedente, il modello pre-addestrato sarà addestrato per qualche epoca in più sul dataset del downstream task, per adattarsi al caso specifico.
Adapters Gli adapters sono piccoli moduli che si inseriscono tra gli strati dei modelli pre-addestrati per per ottenere modelli in grado di essere addestrati in stile multitasking. I parametri del modello pre-addestrato vengono congelati mentre gli adattatori vengono addestrati.
Contrastare l’oblio catastrofico Ogni volta che andiamo ad addestrare reti pre-trainate per adattarle a un particolare task, lo facciamo per migliorare le prestazioni di quei modelli al nostro caso specifico. Ma la modifica dei parametri pre-addestrati può portare il modello a dimenticare completamente le cose che ha imparato. Ad esempio, se utilizzo un modello linguistico che comprende bene la lingua italiana e voglio perfezionarlo per il dialetto siciliano, il modello potrebbe dimenticare del tutto l’italiano. Gli studi sull’oblio catastrofico sono ancora molti, ma vediamo i metodi per attenuare questo effetto:
Congelare i layer: : è possibile congelare tutti gli strati per impedire l’update dei pesi della rete tranne gli ultimi k strati. Un altro metodo è quello di scongelare e addestrare solo uno strato alla volta (metodo chain town).
Adaptive Learning rates dinamici : in NLP come in computer vision, si ritiene che gli strati inferiori catturino le caratteristiche più importanti. Pertanto, per i primi strati si può utilizzare un learning rate più basso.
Regolarizzazione :la regolarizzazione (penalizzazione dei pesi) limita la capacità di apprendimento del modello.
Compressione del modello
Ad oggi, i modelli di deep learning sono diventati enormi, contenenti milioni e milioni di parametri. Oltre a richiedere gigantesche risorse computazionali, questi modelli sono anche dannosi per l’ambiente. È stato stimato che l’addestramento di un modello può emettere una quantità di CO2 pari alla vita media di 5 automobili in America. Fortunatamente, si stanno studiando metodi per ridurre le dimensioni di queste reti, vediamone alcuni.
Pruning: ho affrontato questo problema durante la stesura della mia tesi di laurea e potete leggere l’articolo che ho scritto sull’implementazione del pruning in Julia. Il pruning cerca di rimuovere dalla rete i pesi meno importanti, andando così a diminuire le dimensioni della rete e mantenendo comunque costanti le prestazioni. Knowledge Distillation: è il processo di trasferimento della conoscenza da un modello di grandi dimensioni a uno più piccolo. Un esempio di modello e della sua versione distillata sono Bert e DistilBert. Quantization: è il processo di riduzione della precisione dei pesi usando meno cifre decimali in modo da consumare meno memoria.
Librerie da conoscere: CoreNLP, NLTK, Gensim, spaCY, PyTorch, Tensorflow
Conclusioni
In questo articolo non ho parlato di tematiche all’avanguardia di NLP come i modelli generativi e librerie come Langchain, perchè scriverò degli articoli più dettagliati su questi argomenti in futuro. Spero che utilizzando questa breve guida non perderete come me troppo tempo a cercare su Google quali sono le cose fondamentali da sapere in NLP, ma potrete concentrarvi sull’apprendimento di questa fantastica materia!
Marcello Politi Esperto di intelligenza artificiale con una grande passione per l'esplorazione spaziale. Ho avuto la fortuna di lavorare presso l'Agenzia Spaziale Europea, contribuendo a progetti di ottimizzazione del flusso di dati e di architettura del software. Attualmente, sono AI Scientist & Coach presso la PiSchool, dove mi dedico alla prototipazione rapida di prodotti basati sull'intelligenza artificiale. Mi piace scrivere articoli riguardo la data science e recentemente sono stato riconosciuto come uno dei blogger più prolifici su Towards Data Science.