Algoritmi di disambiguazione (Word Sense Disambiguation)
La polisemia, ovvero la capacità di una parola di assumere significati diversi a seconda del contesto, è un fenomeno linguistico comune a tutte le lingue del mondo. Questa caratteristica, se da un lato arricchisce il linguaggio, dall’altro può generare ambiguità significative, soprattutto in fase di traduzione. La Word Sense Disambiguation (WSD), o disambiguazione del significato delle parole, rappresenta un’area cruciale della linguistica computazionale che mira a risolvere tali ambiguità, consentendo una comprensione più precisa e accurata del testo.
In inglese, ad esempio, la parola “bank” può riferirsi sia a un’istituzione finanziaria che alla riva di un fiume. In italiano, invece, abbiamo due termini distinti: “banca” per l’istituzione finanziaria e “riva” o “sponda” per il lato di un fiume. Allo stesso modo, “bat” può indicare sia un pipistrello, un mammifero volante, sia una mazza utilizzata in sport come il baseball o il cricket, mentre in italiano questi significati sono resi rispettivamente con “pipistrello” e “mazza”. Un ulteriore esempio è dato dalla parola “light”, che in inglese può significare sia “leggero” (opposto di pesante) che “luce”, mentre in italiano esistono due parole distinte per questi concetti.

Queste differenze lessicali tra le lingue possono creare notevoli sfide per i traduttori e i sistemi di traduzione automatica. Senza una corretta disambiguazione, il rischio di fraintendimenti è elevato, con conseguenti errori nella traduzione che possono alterare il significato originale del testo. La WSD si propone proprio di affrontare e risolvere queste problematiche, analizzando il contesto in cui una parola è utilizzata per determinarne il significato preciso e selezionare la traduzione appropriata.

La Word Sense Disambiguation presuppone l’esistenza di una relazione tra una parola, il suo contesto e il senso che tale parole assume:

La disambiguazione può essere affrontata con una varietà di approcci, ognuno con i propri punti di forza e debolezze. La scelta dell’algoritmo dipende spesso dal tipo di dati disponibili, dalle risorse computazionali e dalle esigenze specifiche dell’applicazione. Utilizzare una combinazione di metodi spesso porta ai migliori risultati.
Tra gli algoritmi Supervisionati c’è il Naive Bayes, basato sul teorema di Bayes con l’assunzione di indipendenza tra caratteristiche e il Support Vector Machines (SVM) che è un classificatore discriminativo che cerca di massimizzare il margine tra le classi.
In questo articolo ci focalizzaremo sul Naive Bayes e sul Support Vector Machines (SVM), ma vi sono altre tecniche che meritano di essere citate:
Gli algoritmi di Decision Trees (alberi decisionali) che costruiscono un albero decisionale basato sulle caratteristiche del contesto per classificare i sensi.
Il Random Forest: Una collezione di alberi decisionali che combinano i risultati per migliorare la precisione e ridurre l’overfitting.
Il k-Nearest Neighbors (k-NN) che classifica un senso basandosi sui k contesti più vicini nel dataset di addestramento.
Le reti neurali artificiali per apprendere rappresentazioni complesse dei contesti e predire i sensi.
Tra gli algoritmi non supervisionati ci sono quelli di clustering che raggruppano contesti simili e associano ciascun cluster a un senso specifico.
Se vuoi capire il funzionamento degli algoritmi di clustering leggi l’articolo
Il clustering: come l’AI apprende senza troppi “preconcetti”
Ci sono gli algoritmi di Word Embeddings (e.g., Word2Vec, GloVe) che utilizzano vettori di parole per rappresentare semanticamente le parole e i loro contesti. Le parole nel contesto vengono disambiguate in base alla vicinanza nel vettore spaziale.
Ne abbiamo parlato ampiamente nell’articolo
Word embedding e il modello Skip-gram
Ora, concentriamoci sull’approccio bayesiano applicato al Word Sense Disambiguation. Un articolo che può chiarire i concetti implicati nei modelli che applicano il teorema di Bayes è il seguente:
L’inferenza baysiana: un modo razionale di cambiare idea






Support Vector Machines (SVM)
Prima di esaminare il funzionamento di questo algoritmo, vediamo come si può rappresentare il contesto di una parola che intendiamo disambiguare.



Si costruisce una matrice documento-termine simile a questa:

dove t1, t2, t3,… (caratteristiche) sono tutte le parole di tutti i documenti prese una sola volta. Le righe sono i singoli documenti (contesti). Questa matrice la si può trovare anche trasposta: termine-documento.
Per approfondire il metodo TF-IDF (Term Frequency-Inverse Document Frequency) leggi l’articolo
Il significato delle parole con i modelli NLP





L’algoritmo SVM è un esempio di modello discriminativo. Leggi l’articolo Modelli generativi e discriminativi a confronto per capire meglio questa tipologia di algoritmi.
Esempio con Python
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.svm import SVC
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
# Dati di esempio (contesti annotati con i sensi delle parole)
contexts = [
"He went to the bank to deposit money",
"The river bank was full of flowers",
"She withdrew cash from the bank",
"They sat on the bank and enjoyed the view"
]
labels = [1, 0, 1, 0] # 1: financial institution, 0: river side
# Vectorizzazione del contesto usando TF-IDF
vectorizer = TfidfVectorizer()
# Creazione e addestramento del modello SVM
svm_model = make_pipeline(StandardScaler(with_mean=False), SVC(kernel='linear', C=1))
# Addestramento del modello
X = vectorizer.fit_transform(contexts)
svm_model.fit(X, labels)
# Nuovo contesto da disambiguare
new_context = ["He walked along the bank"]
X_new = vectorizer.transform(new_context)
# Predizione del senso
predicted_label = svm_model.predict(X_new)
print("Predicted label:", predicted_label[0]) # Output: 0 (river side)
Spiegazione del codice
import numpy as np
Viene importata la libreria numpy, che è una libreria molto nota e utilizzata in Python per lavorare con array multidimensionali e per fare calcoli numerici avanzati. È comunemente abbreviata come np per convenzione.
from sklearn.feature_extraction.text import TfidfVectorizer
TfidfVectorizer è importato dal modulo sklearn.feature_extraction.text. Questo calcola il TF-IDF score per i nostri dati di testo, che è una statistica numerica che riflette l’importanza di una parola in un documento di una collezione o di un corpus.
from sklearn.svm import SVC
Viene importato SVC (Support Vector Classifier) dal modulo sklearn.svm. È un tipo di SVM (Support Vector Machine), che può essere utilizzato per problemi di classificazione.
from sklearn.pipeline import make_pipeline
make_pipeline è una funzione che viene importata da sklearn.pipeline. Viene utilizzata per assemblare più trasformazioni e un estimatore finale in una singola entità, facilitando l’applicazione sequenziale di una lista di trasformazioni e estimatori.
from sklearn.preprocessing import StandardScaler
StandardScaler è importato da skinglesklearn.preprocessing. Questo trasformatore standardizza le caratteristiche rimuovendo la media e scalando a varianza unitaria.
# Dati di esempio (contesti annotati con i sensi delle parole)
contexts = [
"He went to the bank to deposit money",
"The river bank was full of flowers",
"She withdrew cash from the bank",
"They sat on the bank and enjoyed the view"
]
Definiamo una lista di stringhe, ognuna rappresentante un contesto in cui la parola “bank” è stata usata, ma con due possibili significati (istituzione finanziaria o lato del fiume).
labels = [1, 0, 1, 0] # 1: financial institution, 0: river side
Il significato di ogni contesto è stato annotato con un’etichetta, 1 o 0, per rappresentare l’istituzione finanziaria e il lato del fiume, rispettivamente.
# Vectorizzazione del contesto usando TF-IDF
vectorizer = TfidfVectorizer()
Viene creato un oggetto TfidfVectorizer che sarà usato per trasformare il testo in un vettore di frequenze termine-inverso frequenze documento (TF-IDF) che possono essere utilizzati come input per modelli di machine learning.
# Creazione e addestramento del modello SVM
svm_model = make_pipeline(StandardScaler(with_mean=False), SVC(kernel='linear', C=1))
Qui abbiamo creato un modello pipeline che combina StandardScaler con SVC. StandardScaler è utilizzato per standardizzare i dati prima di fornirli al classificatore SVM. Si noti che with_mean=False è necessario quando si lavora con matrici sparse (come quelle che si ottengono generalmente dopo il TF-IDF).
# Addestramento del modello
X = vectorizer.fit_transform(contexts)
La funzione fit_transform prende il testo dal nostro dataset e lo trasforma in una matrice TF-IDF che il nostro modello SVM può utilizzare per l’addestramento.
Esempio di matrice

Ogni riga corrisponde a un documento/context, e ogni valore rappresenta il punteggio TF-IDF per quel termine in quel documento. Le caratteristiche (colonne) sono tutte le parole (o termini) uniche presenti in tutti i documenti del corpus. Questa rappresentazione viene spesso chiamata matrice documento-termine.
svm_model.fit(X, labels)
Il classificatore SVM è addestrato su questa matrice TF-IDF (X) e su altre etichette (labels).
# Nuovo contesto da disambiguare
new_context = ["He walked along the bank"]
Abbiamo un nuovo contesto in cui la parola “bank” è presente e vogliamo predire se si riferisce ad un istituzione finanziaria o a un lato del fiume.
X_new = vectorizer.transform(new_context)
Il nuovo contesto è trasformato in un vettore TF-IDF senza essere adattato ai dati precedenti perché abbiamo già impartito al nostro vettorizzatore le conoscenze del vocabolario durante l’addestramento.
# Predizione del senso
predicted_label = svm_model.predict(X_new)
Il classificatore svm_model predice l’etichetta per il nuovo contesto.
print("Predicted label:", predicted_label[0]) # Output: 1 (financial institution)
Stampa la predizione del modello, che in questo caso è 0, il che indica che il modello ha predetto il contesto river side per la parola “bank” nel nuovo contesto. (La tua descrizione della previsione nel commento, però, è errata. L’output corretto basato sul codice e i dati di esempio sarebbe 1, indicante l’istituzione finanziaria, invece di 0).