2016-05-01 27 views
8

Eseguo il seguente codice per convertire la matrice di testo in matrice TF-IDF.Come vengono calcolati TF-IDF dallo scikit-learn TfidfVectorizer

text = ['This is a string','This is another string','TFIDF computation calculation','TfIDF is the product of TF and IDF'] 

from sklearn.feature_extraction.text import TfidfVectorizer 
vectorizer = TfidfVectorizer(max_df=1.0, min_df=1, stop_words='english',norm = None) 

X = vectorizer.fit_transform(text) 
X_vovab = vectorizer.get_feature_names() 
X_mat = X.todense() 
X_idf = vectorizer.idf_ 

ottengo il seguente output

X_vovab =

[u'calculation', 
u'computation', 
u'idf', 
u'product', 
u'string', 
u'tf', 
u'tfidf'] 

e X_mat =

([[ 0.  , 0.  , 0.  , 0.  , 1.51082562, 
     0.  , 0.  ], 
    [ 0.  , 0.  , 0.  , 0.  , 1.51082562, 
     0.  , 0.  ], 
    [ 1.91629073, 1.91629073, 0.  , 0.  , 0.  , 
     0.  , 1.51082562], 
    [ 0.  , 0.  , 1.91629073, 1.91629073, 0.  , 
     1.91629073, 1.51082562]]) 

Ora Non capisco come questi punteggi vengono calcolati. La mia idea è che per il testo [0], il punteggio per solo 'stringa' sia calcolato e che ci sia un punteggio nella quinta colonna. Ma come TF_IDF è il prodotto della frequenza di termine che è 2 e IDF che è log (4/2) è 1,39 e non 1,51 come mostrato nella matrice. Come viene calcolato il punteggio TF-IDF in scikit-learn.

risposta

9

TF-IDF è fatto in più fasi da Scikit di Scopri TfidfVectorizer, che di fatto utilizza TfidfTransformer ed eredita CountVectorizer.

Permettetemi di riassumere i passi lo fa per renderlo più semplice:

  1. tfs è calcolato fit_transform di CountVectorizer()
  2. IDF sono calcolati in forma di TfidfTransformer()
  3. tfidfs sono calcolati TfidfTransformer di transform()

È possibile controllare il codice sorgente here.

Torna al tuo esempio.Ecco il calcolo che viene fatto per il peso TFIDF per la 5a legislatura del vocabolario, primo documento (X_mat [0,4]):

In primo luogo, il TF per 'stringa', nel 1 ° documento:

tf = 1 

in secondo luogo, l'IDF per 'stringa', con lisciatura abilitato (comportamento di default):

df = 2 
N = 4 
idf = ln(N + 1/df + 1) + 1 = log (5/3) + 1 = 1.5108256238 

E, infine, il peso TFIDF per (documento 0, caratteristica 4):

tfidf(0,4) = tf * idf = 1 * 1.5108256238 = 1.5108256238 

Ho notato che hai scelto di non normalizzare la matrice tfidf. Tieni presente che la normalizzazione della matrice tfidf è un approccio comune e solitamente consigliato, poiché la maggior parte dei modelli richiede la normalizzazione della matrice di caratteristiche (o della matrice di progettazione).

TfidfVectorizer L-2 normalizzerà la matrice di output per impostazione predefinita, come fase finale del calcolo. Avere normalizzato significa che avrà solo pesi compresi tra 0 e 1.

+0

Questa è davvero una buona risposta !! Ho passato un'intera giornata a capirlo. @Rabbit puoi mostrare in questo esempio come viene applicata la normalizzazione? – Himadri

3

La formula precisa calcolo è dato nel docs:

La formula effettivo utilizzato per TF-IDF è tf * (IDF + 1) = tf + tf * idf, invece di tf * idf

e

Smooth pesi IDF con l'aggiunta di uno a documentare le frequenze, come se un documento in più è stato visto contenente ogni termine della collezione esattamente una volta.

Ciò significa 1.51082562 è ottenuto come 1.51082562=1+ln((4+1)/(2+1))

+0

quindi 1,51 rappresentano solo il punteggio IDF e non il punteggio TF-IDF. Il punteggio TF-IDF suppongo sia 2 * 1,51 = 3,02. – prashanth

+1

Il termine frequenza è solo 1, non è vero? Ecco perché abbiamo 1 * 1.51 –

+0

Ora ci vado. Grazie. – prashanth