Il contenuto seguente rappresenta il prosieguo di quanto esposto in Fondamenti: selezione attributi e rappresentazione dei documenti.

In sintesi: i documenti nel corpus sono rappresentati come vettori in uno spazio M-dimensionale, con M pari al numero di attributi selezionati e indicizzati nel vocabolario V. Ad ogni attributo è associato un peso. Numerose sono le metriche di pesatura utilizzabili per calcolare il valore dei pesi degli attributi.

Per esempio, nello schema di rappresentazione BOW (bag of words), il peso wij è un numero intero che esprime la frequenza statistica (cioè il numero di occorrenze) dell’attributo i-esimo nel documento j-esimo.

In questo post tratteremo in modo specifico di altre metriche di pesatura che realizzano delle trasformazioni pari-dimensionali ossia delle variazione delle rappresentazioni vettoriali con mantenimento nel numero di attributi M.

Un’altra famiglia storica di schemi di rappresentazione, chiamata TF-IDF, ricorre a metriche di pesatura che relazionano due variabili: la frequenza dell’attributo TF (term frequency) e la frequenza inversa del documento IDF (inverse document-frequency). Il peso è qui un numero reale.

La TF di un attributo è una proprietà locale ad ogni documento ed è pari al rapporto tra il numero di occorrenze dell’attributo nel documento diviso il numero totale di attributi nel documento stesso.

La IDF di un attributo è una proprietà globale del corpus ed è espressa come funzione (solitamente il log10) del rapporto tra il numero totale di documenti del corpus e il numero di documenti simili rispetto all’attributo in esame.

Con riferimento ad uno specifico attributo, due o più documenti si definiscono simili se contengono lo stesso attributo.

Una metrica di pesatura per TF-IDF può essere definita con la seguente formula:

\left ( TF \cdot IDF \right )

Questa metrica è implemetata nella libreria gensim. Secondo questa metrica, un valore alto di un peso wij può essere ottenuto con un’alta frequenza dell’attributo i-esimo (nel documento j-esimo) ed una bassa frequenza in tutti gli altri documenti simili. Maggiore è l’occorrenza dell’attributo in altri documenti simili e più  il suo peso associato tenderà a zero.

Il concetto alla base delle rappresentazioni TF-IDF  è che gli attributi che meglio discriminano il contenuto di un documento sono quelli in grado di far risaltare quel documento rispetto a tutta la collezione (il corpus) in quanto sono molto frequenti o solo nel documento in esame o in pochi altri documenti simili.

Con gensim è possibile ottenere una rappresentazione vettoriale del tipo TF-IDF mediante una singola istruzione:

from gensim import models
schema_tfidf=models.TfidfModel(corpus_bow)

for idx in schema_tfidf.dfs:
	print 'index:%i, simdocs:%i, idf:%f' % (idx,schema_tfidf.dfs[idx],schema_tfidf.idfs[idx])

index:0, simdocs:1, idf:2.321928
index:1, simdocs:4, idf:0.321928
index:2, simdocs:5, idf:0.000000
index:3, simdocs:1, idf:2.321928
index:4, simdocs:1, idf:2.321928
index:5, simdocs:1, idf:2.321928
index:6, simdocs:1, idf:2.321928
index:7, simdocs:1, idf:2.321928
index:8, simdocs:1, idf:2.321928
index:9, simdocs:1, idf:2.321928
index:10, simdocs:1, idf:2.321928
index:11, simdocs:1, idf:2.321928
index:12, simdocs:1, idf:2.321928
index:13, simdocs:1, idf:2.321928
index:14, simdocs:1, idf:2.321928

La prima istruzione costruisce la rappresentazione TF-IDF a partire dal corpus BOW precedentemente generato. Con la seconda istruzione abbiamo visualizzato, per ogni attributo del vocabolario, una terna di informazioni: 1. l’indice numerico (come associato nel vocabolario), 2. il numero di documenti simili e 3. il fattore di frequenza inversa (idf).

Nell’esempio precedente, l’attributo con indice 2 (corrispondente alla parola volpe, come verificabile nel vocabolario) compare in tutti i documenti del corpus e la frequenza inversa è di conseguenza pari a 0. Ciò implica l’annullamento dei pesi associati all’attributo nelle rappresentazioni vettoriali di tutti i documenti (cioè quell’attributo è globalmente ignorato). Questo annullamento, talvolta, potrebbero far perdere informazioni utili. Per esempio, anche per il nostro corpus esemplificativo, potrebbe risultare non  conveniente ignorare la parola volpe perchè, come evidente, essa ha un preciso peso concettuale nel corpus (essendo il soggetto principale dei documenti).

Un’altra metrica di pesatura, più conservativa, introduce una piccola variazione alla precedente metrica ed è così definita:

\left ( 1 + TF \cdot IDF \right )

La libreria sklearn implementa questa variante della metrica. Tale metrica funziona come la precendente ma con la differenza che gli attributi non sono mai completamente ignorati (sempre ponderati in relazione alla loro diffusione nel corpus).

Infatti, usando la libreria sklearn:

from sklearn.feature_extraction.text import TfidfVectorizer
tfidf_vect = TfidfVectorizer(stop_words=set(my_stop_words))
corpus_tfidf=tfidf_vect.fit_transform(corpus)

### oppure usando il corpus bow già generato (come fatto con gensim) ###
#from sklearn.feature_extraction.text import TfidfTransformer
#tfidf_vect = TfidfTransformer()
#corpus_tfidf = transformer.fit_transform(corpus_bow)

idf = tfidf_vect.idf_
print dict(zip(tfidf_vect.get_feature_names(), idf))

{u'alto': 2.09861228866811, u'furba': 2.09861228866811,
u'rinuncixf2': 2.09861228866811, u'raggiungere': 2.09861228866811,
u'voleva': 2.09861228866811, u'sostenendo': 2.09861228866811,
u'mangiare': 2.09861228866811, u'furbizia': 2.09861228866811,
u'matura': 2.09861228866811, u'volpe': 1.0, u'troppo': 2.09861228866811,
u'uva': 1.1823215567939547, u'riusciva': 2.09861228866811,
u'paga': 2.09861228866811, u'volte': 2.09861228866811}

Si noti come la frequenza inversa della parola volpe è ora pari a 1.0 e non nulla, di conseguenza il peso dell’attributo nei documenti è ridotto ma non annullato.

A seconda delle implementazioni, potrebbe essere consigliabile contemplare anche nell’implementazione gensim la variante conservativa; nell’esempio seguente è mostrato un possibile approccio implementativo:

for idx in schema_tfidf.idfs: schema_tfidf.idfs[idx]+=1.0

Trasformazioni pari-dimensionali

Una volta generato uno schema di rappresentazione TF-IDF è possibile utilizzarlo per trasformare qualsiasi vettore BOW nella nuova rappresentazione TF-IDF. Ovviamente il vettore che si vuole trasformare deve essere stato generato usando lo stesso corpus BOW da cui si è paritti  per la generazione dello schema TF-IDF.

Per esempio, è possibile generare una versione TF-IDF anche di tutto il corpus rappresentato con i vettori BOW. In gensim:

corpus_tfidf=schema_tfidf[corpus_bow]

In sklearn corpus_tfidf[/corpus] è stato generato al momento all'invocazione del metodo [python]fit_transform del vettorizzatore TfidfVectorizer.

La trasformazione di un vettore, dalla rappresentazione BOW alla rappresentazione TF-IDF, è di tipo pari-dimensionale nel senso che non riduce la dimensionalità dei vettori documenti. Usando sklearn, possiamo facilmente verificare che:

corpus_bow.shape

corpus_tfidf.shape

(5,15)

(5,15)

Trasformazioni con riduzione della dimensionalità
Un’altra tipologia importante di trasformazioni è quella che prevede la riduzione della dimensionalità dei dati. L’alta dimensionalità infatti, non influisce solo sulla stima e sull’identificazione degli attributi rilevanti, ma aumenta il costo temporale e può peggiorare le prestazioni computazionali.

Nota. Per evitare di appesantire la presente trattazione, le trasformazioni con riduzione della dimensionalità saranno trattate in un successivo post.

Pubblicato da lorenzo

Full-time engineer. I like to write about data science and artificial intelligence.

Vuoi commentare?