Un Modello linguistico o Language Model, costruito a partire da un corpus di training in una determinata lingua, permette di associare una probabilità ad una determinata sequenza di parole.
Le applicazioni sono molteplici e spaziano dal confronto sulla verosimiglianza di frasi, al calcolo della probabilità della parola successiva in una frase, all'autocompletamento, alla correzione di parole fuori contesto in una frase, all'individuazione dell'output più probabile nella speech recognition, al supporto predittivo alla comunicazione aumentata e accessibile.
Attraverso un approccio "tradizionale" statistico-probabilistico basato sugli N-Grammi, sequenze di N parole nel corpus, esaminiamo come è possibile costruire un modello di linguaggio in modo relativamente semplice.
La probabilità degli Unigrammi all'interno del corpus, ovvero delle singole parole, è banalmente P(w)=C(w)m ovvero il rapporto tra il numero di occorrenze della parola nel corpus e la dimensione del corpus.
Dato invece un generico N-Gramma wn1=w1w2⋯wn definiamo la probabilità dell'N-Gramma come probabilità condizionata P(wn|w1⋯wn−1)=P(wn|wn−11)=C(wn1)∑C(wn−11w) , rapporto tra le occorrenze dell'N-Gramma e quelle di tutti gli N-Grammi nel Corpus le cui n-1 prime parole sono wn−11.
Con determinati accorgimenti sulla conclusione della frase che vedremo a seguire, è possibile semplificare l'espressione come P(wn|w1⋯wn−1)=P(wn|wn−11)=C(wn1)C(wn−11) , rapporto tra le occorrenze dell'N-Gramma e quelle dell' (N-1)-Gramma composto dalle prime N-1 parole
Data una frase w1w2…wn possiamo calcolare la probabilità P(w1w2…wn) della sequenza utilizzando la semplice relazione relativa alla probabilità condizionata per cui P(A∩B)=P(A)P(B|A) . Avremo pertanto che la probabilità di una frase è riconducibile al prodotto delle probabilità di N-Grammi secondo la relazione:
P(wn1)=P(wn−11)P(wn|wn−11)=P(wn−21)P(wn−1|wn−21)P(wn|wn−11)=P(w1)P(w2|w1)P(w3|w21)⋯P(wn|wn−11)=P(w1)∏ni=2P(wi|wi−11)
Ciò è intuitivamente verificabile con un esempio, ipotizzando ad esempio di voler calcolare la probabilità della frase "oggi vado al mare" avremo P(oggi vado al mare)=P(oggi)P(vado|oggi)P(al|oggi vado)P(mare|oggi vado al)
La probabilità di una frase come calcolata sopra si scontra con un primo limite obiettivo, ovvero che è calcolabile e non nulla solo se nel corpus sono presenti tutti gli N-Grammi coinvolti nel calcolo. Ciò implicherebbe un corpus enorme dove compaiono tutte le possibili frasi da valutare, ipotesi assolutamente irrealistica e che non consentirebbe al nostro modello di generalizzare.
Si formula quindi l'assunzione che la probabilità di un generico N-Gramma di un qualunque ordine m>n sia ragionevolmente approssimabile come quella del N-Gramma di ordine n P(wk|wk−1k−m+1)≈P(wk|wk−1k−n+1) , ovvero che la probabilità di una parola sia condizionata solo dalle n parole precedenti.
Assumiamo ad esempio n=2 e che quindi il nostro modello sia basato su digrammi, avremo quindi che la probabilità della frase sopra vista diventa: P(oggi vado al mare)=P(oggi)P(vado|oggi)P(al|vado)P(mare|al)
Come vediamo il modello è già in grado di effettuare una prima generalizzazione, risultando sufficiente la sola presenza nel Corpus dei digrammi coinvolti.
Più in generale l'approssimazione di Markov per N-Grammi di grado N ci consente di modifcare la probabilità della frase vista sopra come prodotto di N-Grammi al più di grado N:
P(wn1)=P(w1)n∏i=2P(wi|wi−1max{1;i−N+1})
L'esempio sopra ci mostra che, a prescindere dalla scelta di n, vengono utilizzati nel calcolo anche n-1 N-Grammi di grado inferiore ad n all'inizio della frase.
Questo non è desiderabile per almeno due motivi: oltre al fatto che vengono utilizzati N-Grammi eterogenei con un diverso grado di sensibilità al contesto, andiamo a perdere un'informazione di contesto molto rilevante che è quella relativa all'inizio della frase.
La probabilità dell'unigramma P(oggi) difatti è relativa alla mera frequenza relativa dell'unigramma nel corpus, senza nessuna informazione riguardo alla posizione nella frase.
A questo fine si prependono n-1 token speciali di delimitazione <d> per rappresentare correttamente il contesto di inizio.
Nel caso esaminato, dove si utilizzano Digrammi, andremo ad inserire un solo <d> in avvio e avremo quindi:
P(<d>oggi vado al mare)=P(oggi|<d>)P(vado|oggi)P(al|vado)P(mare|al)
Utilizzando invece Trigrammi, si inseriranno due <d> in avvio di frase e avremo:
P(<d><d>oggi vado al mare)=P(oggi|<d> <d>)P(vado|<d> oggi)P(al|oggi vado)P(mare|vado al)
Anche alla fine della frase abbiamo una esigenza analoga di corretta rappresentazione del contesto di chiusura, inserendo un solo delimitatore <d> e un corrispondente N-Gramma a valorizzare la probabilità che le ultime N-1 parole rilevino realmente la fine della frase.
Come accennato sopra, questo accorgimento ci permetterà di utilizzare in modo coerente la relazione P(wn|wn−11)=C(wn1)C(wn−11) che altrimenti potrebbe risultare inesatta per gli N-Grammi in chiusura di frase.
Riprendendo l'esempio con l'utilizzo di Digrammi avremo:
P(<d>oggi vado al mare<d>)=P(oggi|<d>)P(vado|oggi)P(al|vado)P(mare|al)P(<d>|mare)
Mentre utilizzando Trigrammi:
P(<d><d>oggi vado al mare<d>)=P(oggi|<d> <d>)P(vado|<d> oggi)P(al|oggi vado)P(mare|vado al)P(<d>|mare)
Con l'inserimento dei delimitatori tra le n parole possiamo quindi definire in modo più compatto la probabilità della frase:
P(wn1)=n∏i=NP(wi|wi−1i−N+1)
Definiti i criteri per il modello linguistico, si procede quidi al calcolo della probabilità degli N-Grammi organizzando i dati del Corpus di training in Matrici.
Il primo passo è la realizzazione di una matrice delle occorrenze degli N-Grammi, dove le righe riportano gli (N-1)-Grammi ai quali sono condizionate la parole w indicate nelle colonne.
Consideriamo ad esempio il seguente corpus di 3 frasi sul quale costruire un modello con Digrammi:
Oggi vado al mare
Al mare oggi piove
Se piove vado al parco
C(wi|wi−1)<d>oggivadoalmarepioveseparco<d>01010010oggi00100100vado00020000al00002001mare11000000piove10100000se00000100parco10000000
P(wi|wi−1)<d>oggivadoalmarepioveseparco<d>00,3300,33000,330oggi000,50000,5000vado00010000al00000,67000,33mare0,500,50000000piove0,5000,5000000se00000100parco10000000
Per calcolare la probabilità di una qualunque frase wn1 , inseriti gli opportuni delimitatori, effettueremo quindi una produttoria delle probabilità dei Digrammi P(wn1)=n−1∏i=1P(wi+1|wi) . Nella pratica, con corpus estesi e probabilità che tendono rapidamente a zero, è opportuno per evitare problemi di underflow utilizzare la relazione in forma logaritmica logP(wn1)=n−1∑i=1logP(wi+1|wi)
Proviamo ad esempio a calcolare la probabilità di <d>Oggi piove<d> : P(<d>oggi piove<d>)=P(oggi|<d>)P(piove|oggi)P(<d>|piove)=0,33⋅0,50⋅0,50=0,0825
Un primo limite che si rileva immediatamente è quello relativo all'utilizzo di parole sconosciute. Il modello come impostato non appare applicabile a frasi con parole non presenti nel corpus.
Per gestire il caso di parole sconosciute viene costruito un dizionario a partire dal corpus, composto generalemente dalle parole con frequenza uguale o maggiore di un parametro k o in accordo ad altro criterio, sostituendo poi nel corpus tutte le parole non presenti nel dizionario con il token <unk> a rappresentare una parola sconosciuta.
Riprendendo l'esempio sopra, con un dizionario costruito con k=2 , vediamo che le parole se e parco vengono sostituite da <unk> e la nostra matrice delle probabilità viene ricalcolata come:
P(wi|wi−1)<d>oggivadoalmarepiove<unk><d>00,3300,33000,33oggi000,50000,500vado0001000al00000,6700,33mare0,500,5000000piove0,5000,500000<unk>0,5000000,500
Proviamo ora a calcolare la probabilità di una frase con parole non presenti nel dizionario:
P(<d>Quando piove vado al museo<d>)=P(<d><unk> piove vado al <unk><d>)==P(<unk>|<d>)P(piove|<unk>)P(vado|piove)P(al|vado)P(<unk>|al)P(<d>|<unk>)==0,33⋅0,50⋅0,50⋅1⋅0,33⋅0,50=0,0136125
E' quindi possibile calcolare la probabilità della frase secondo pur in presenza di parole estranee al corpus.
Un altro limite che rileviamo dall'osservazione matrice di probabilità è relativo all'alto numero di valori pari a zero nella matrice - circostanza tanto più vera quanto meno esteso è il corpus e quanto più alto è il grado N degli N-Grammi utilizzato.
La presenza di un N-Gramma con probabilità zero nel modello, rende automaticamente a probabilità nulla ogni frase che lo contenga a prescindere dall'apporto di probabilità degli altri N-Grammi.
Nell'esempio sopra la frase Oggi piove al mare avrebbe probabilità zero in quanto P(al|piove)=0 , nonostante non appaia come frase del tutto implausibile per il modello.
Questo non è un comportamento generalmente desiderabile e limita la generalizzazione del modello in presenza di N-Grammi non presenti nel Corpus, anche dopo l'adozione di un dizionario.
Indichiamo tre approcci utilizzati per ovviare a questo problema:
Questo approccio consiste in un ricalcolo della matrice di probabilità applicando uno smoothing di valore k , dipendente sia dalla numerosità/sparsità della tabella e dal grado di smoothing desiderato, secondo la formula
P(wn|wn−11)=C(wn1)+kC(wn−11)+k|V| , dove |V| è la dimensione del dizionario, pari al numero di colonne della matrice.
In questo caso, ipotizzando uno smoothing con k=0,1 la nostra matrice sarà ricalcolata a partire dalle occorrenze come:
Vediamo ora che non esistono più probabilità nulle nella matrice (sebbene alcuni casi specifici dovrebbero essere trattati separatamente, come l'ipotesi di un Digramma (<d>|<d>) da porre a zero, in quanto corrispondente ad una frase vuota), ed il modello è in grado di generalizzare su qualunque frase con qualunque parola.
L'approccio di backoff prevede, nel caso la probabilità in tabella del N-Gramma P(wnn−N+1) sia nulla, di utilizzare la probabilità del corrispondente (N-1)-Gramma moltiplicato per un coefficiente di riduzione d , ovvero d⋅P(wnn−(N−1)+1) . Generalmente si utilizza un coefficiente d≈0,40.
Il criterio viene applicato ricorsivamente sino a quando non abbiamo una probabilità non nulla.
Ipotizziamo di avere un modello su Trigrammi e di voler calcolare la probabilità di una frase nella quale occorre P(libro|leggo un) con valore in matrice pari a zero: al suo posto calcoleremo d⋅P(libro|un) , e se anche tale valore fosse nullo, si utilizzerà d2⋅P(libro).
Ovviamente questo approccio prevede di calcolare non solo la matrice delle probabilità degli N-Grammi di ordine N, ma anche quelle di ordine inferiore.
Simile all'approccio precedente, prevede di prendere comunque in considerazione tutte le probabilità degli N-Grammi di ordine inferiore, da ponderare con opportuni coefficienti decrescenti. Avremo quindi ˆP(wnn−N+1)=N∑i=1λiP(wnn−N+i) , dove N∑i=1λi=1.
Nel caso del punto precedente avremo che ˆP(libro|leggo un)=λ1P(libro|leggo un)+λ2P(libro|un)+λ3P(libro)
Una volta costruito il modello sul corpus di training e definiti criteri e correttivi per il calcolo della probabilità di una frase, possiamo ottenere una misura della "bontà" del modello, sia in termini della capacità di generalizzare correttamente, sia in termini di aderenza al contesto linguistico/tematico al quale dovrà essere applicato, valutando le sue performance in termini di capacità di predizione rispetto ad un corpus di test, composto da frasi che il modello non ha utilizzato in fase di training.
La misura generalmente utilizzatà è la Perplessità definita come PP(W)=m√m∏i=11P(Wi) dove W è il corpus di test suddiviso in m N-Grammi indicati con Wi
La perplessità varia a partire da un minimo teorico di 1, ad indicare un modello in grado di predirre esattamente il corpus di test, crescendo man mano che si incontrano N-Grammi con probabilità inferiore ad 1.
Valori tipici della perplessità per modelli di linguaggio addestrati su corpus dimensionalmente rilevanti oscillano nell'ordine tra 100 e 1000, con valori inferiori per modelli ad N-Grammi di ordine superiore, in grado di cogliere in modo più articolato relazioni tra parole più distanti.
Uno dei task più classici dell'NLP è il Part of Speech Tagging, ovvero l'analisi grammaticale di un testo con attribuzione ad ogni parola della relativa caratteristica lessicale (Nome, Verbo, Aggettivo, Pronome, etc...).
Tale caratteristica lessicale dipende, oltre che dalla parola, dalla sua collocazione nel contesto della frase: un rilevante numero di parole può assumere una caratteristica diversa a seconda dell'utilizzo; ad esempio "la" può essere articolo, pronome, o nome.
L'approccio con il modello di Markov a stati nascosti è una soluzione classica che permette di ottenere risultati di accuratezza apprezzabili senza utilizzare word embedding.
Nel modello di Markov a Stati Nascosti andiamo a rappresentare attraverso un grafo orientato ai cui rami sono associate delle probabilità, poi tradotto poi in 2 matrici, la conoscenza desunta da un corpus di training testuale al quale sono già state associate le caratteristiche lessicali.
Gli Stati nel nostro problema corrispondono alle caratteristiche lessicali - nell'esempio a seguire per semplicità consideriamo solo "Nome", "Verbo", "Articolo".
Parliamo di stati nascosti perchè, quando analizziamo una frase, non conosciamo a priori la sequenza dei corrispondenti Stati - che anzi, è nostro obiettivo determinare nella configurazione più probabile per la frase in esame - ma stiamo osservando gli "Eventi", ovvero le parole della frase che costituiscono l'emissione degli stati corrispondenti.
Nel modello aggiungiamo anche uno stato π che corrisponde al delimitatore della frase, quindi rappresentando sia l'inizio che la fine - è pertanto l'unico stato noto a priori.
Alle possibili Transizioni tra i vari stati vengono associate le probabilità calcolate sul corpus di training: partendo da un qualsiasi stato Si la parola successiva quindi sarà riconducibile ad un determinato stato Sjcon una certa probabilità P(Sj|Si)=C(Si,Sj)+εC(Si)+ε⋅N , dove C(Si,Sj) è il conteggio nel corpus delle occorrenze della sequenza Si Sj , C(Si) è il conteggio nel corpus delle occorrenze di Si , una piccola costante di smoothing ε evita che vi siano transizioni a probabilità nulla ed N è il numero degli stati;
Tutte le probabilità P(Sj|Si) saranno collocate in una matrice A(N×N) detta Matrice di transizione.
Alle possibili Emissioni dei vari stati, nel nostro caso le parole che possono essere manifestazione di un particolare Stato, vengono associale le rispettive probabilità calcolate sul corpus di training: per un determinato stato Si e per ogni parola wjnel dizionario ricavato dal corpus, avremo che P(wj|Si)=C(Si,wj)+εC(Si)+ε⋅|V|, dove C(Si,wj) è il conteggio nel corpus delle occorrenze della parola wj quando compare con stato Si , C(Si) è il conteggio nel corpus delle occorrenze di Si , una piccola costante di smoothing ε evita che vi siano emissioni a probabilità nulla e |V| è il numero di parole nel nostro dizionario.
Il dizionario V , specie per corpus rilevanti, è costruito utilizzando non tutte le parole del corpus, ma solo quelle che presentano un frequenza maggiore di un certo valore k (tipicamente 1 o 2) , e aggiungendovi una parola speciale unk a rappresentare una generica corrispondenza non presente nel vocabolario (eventualmente possono essere aggiunte delle parole specializzate unk_nom , unk_ver , etc. dove siano implementate regole o un'analisi euristica del suffisso per determinare la possibile appartenenza di una parola sconosciuta a uno specifico Stato).
In fase di training e applicazione del modello, quando viene incontrata una parola non presente nel dizionario viene considerata come unk (oppure, applicando alla parola le opportune analisi euristiche per la possibile associazione a uno Dtato, verrà considerata come unk_Stato ).
Ciò permetterà di addestrare e utilizzare il modello con buoni risultati anche per parole non presenti nel set di training.
Tutte le probabilità P(Sj|Si) saranno collocate in una matrice B(N×|V|) detta Matrice di emissione.
Ipotizziamo uno scenario semplificato con un corpus di training composto da sole 3 frasi e con i 3 stati N (nome), V(verbo), A(articolo):
ilA gattoN cercaV laA mammaNMarioN suonaV unA laNlaA mammaN guardaV ilA gattoN
e procediamo al conteggio delle transizioni e degli stati
C(Si,Sj)πANVC(Si)π02103A00505N30036V03003
e al conteggio delle emissioni, ipotizzando di adottare un dizionario con tutte le parole del corpus.
C(Si,wj)ilgattocercalamammaMariosuonaunguarda−unk−−del−π00000000004A20020001000N02012100000V00100010100
Procediamo ora al calcolo della matrice di transizione A, utilizzando un coefficiente di smoothing ε=0,01 (che non applichiamo alla transizione P(π|π) considerata di fatto impossibile, corrispondendo ad una frase nulla)
P(Sj|Si)πANVπ00,6630,3330,003A0,0020,0020,9940,002N0,4980,0020,0020,498V0,0030,9900,0030,003
e al calcolo della matrice di emissione B, utilizzando un coefficiente di smoothing ε=0,01 (per lo stato π le emissioni sono sempre certe e verso il delimitatore −del−, senza necessità di considerare nello smoothing la ripettiva riga e la rispettiva colonna)
P(wj|Si)ilgattocercalamammaMariosuonaunguarda−unk−−del−π00000000001A0,3940,0020,0020,3940,0020,0020,0020,1980,0020,0020N0,0020,3300,0020,1660,3300,1660,0020,0020,0020,0020V0,0030,0030,3260,0030,0030,0030,3260,0030,3260,0030
Rileviamo facilmente che il prodotto delle matrici AB conterrà le probabilità P(w(t+1)j|S(t)i) che la parola successiva allo stato S(t)i sia w(t+1)j
Data una frase arbitraria da analizzare, dobbiamo trovare la sequenza di stati da associare ad ogni parola, tale da massimizzare la probabilità risultante della frase, calcolata sulla base delle matrici di transizione ed emissione.
Ci viene in aiuto in ciò l'algoritmo di Viterbi , che con un approccio di programmazione dinamica, permette di analizzare i percorsi tra stati sul grafo a partire dallo stato iniziale attraversando gli stati successivi individuando il miglior percorso in relazione alle emissioni date (le k parole della frase w).
L'algoritmo prevede la costruzione iterativa per colonne di due matrici C(N×k) , contenente le probabilità dei migliori percorsi attraversati, e D(N×k) con la traccia degli stati attraversati.
La prima colonna della matrice C(N×k) viene inizializzata ponendo ci,1=a1,i⋅bi,indice(w1) , ovvero le probabilità di emettere la prima parola w1 attraverso la transizione dallo stato iniziale verso un primo stato Si.
La prima colonna della La prima colonna della matrice D(N×k) viene inizializzata ponendo di,1=0 in quanto non abbiamo ancora parti precedenti del percorso da tracciare.
Le successive colonne della matrice C(N×k) vengono iterativamente calcolate come ci,j=maxkck,j−1⋅ak,i⋅bi,indice(wj) , scegliendo in pratica di raggiungere lo stato Si dallo stato precedente Sk che massimizza la probabilità del percorso parziale.
Di conseguenza nella matrice D(N×k) andremo ad inserire proprio tale k calcolato come di,j=argmaxk ck,j−1⋅ak,i⋅bi,indice(wj)
Una volta calcolate le due matrici, avremo che il massimo valore presente nella colonna k della matrice C rappresenta la probabilità della sequenza di stati più probabile. In particolare il suo indice sk=argmaxi ci,k ci indicherà lo stato della sequenza più probabile associato all'ultima parola wk .
Per trovare gli Stati associati alle parole precedenti, itereremo nella matrice D popolata con gli indici delgli stati di provenienza dei vari percorsi, ponendo sj−1=dsj,j , ottenendo infine l'intera sequenza desiderata degli stati Ss1Ss2⋯Ssk
Supponiamo, a partire dalle matrici di transizione ed emissione già calcolate, di voler analizzare la frase Il gatto mangia un topo
Rileviamo subito che abbiamo 2 parole sconosciute per il nostro dizionario che quindi sostituiremo con -unk- al fine dell'analisi.
Inizializziamo le matrici secondo le formule indicate, partendo dallo stato di inizio frase:
CungattomangiailtopoA1,313⋅10−1N6,660⋅10−4V9,000⋅10−6 DungattomangiailtopoA0N0V0
e proseguiamo iterativamente a riempire le successive colonne secondo le formule sopra indicate:
CungattomangiailtopoA1,313⋅10−15,251⋅10−71,722⋅10−71,261⋅10−55,044⋅10−11N6,660⋅10−44,306⋅10−21,722⋅10−73,860⋅10−102,507⋅10−8V9,000⋅10−69,950⋅10−76,433⋅10−55,790⋅10−107,566⋅10−11 DungattomangiailtopoA01231N01231V02231
e ripercorrendo a ritroso, colonna per colonna, gli indici degli stati nella tabella D a partire dall'indice indicato in rosso, otteniamo
s5=2→Stopo=Ns4=1→Sil=As3=3→Smangia=Vs2=2→Sgatto=Ns1=1→Sun=A
che costituisce la sequenza di stati attribuiti alle frase con massima la probabilità secondo il modello di Markov presentato - ed è effettivamente la corretta analisi grammaticale della frase, nonostante presenza di due parole estranee al dizionario.