2015-12-11 19 views
5

Sto lavorando al problema dell'estrazione di parole chiave. Si consideri il caso molto generaleScikit Learn TfidfVectorizer: Come ottenere i primi n termini con il punteggio tf-idf più alto

tfidf = TfidfVectorizer(tokenizer=tokenize, stop_words='english') 
    t="""Two Travellers, walking in the noonday sun, sought the shade of a widespreading tree to rest. As they lay looking up among the pleasant leaves, they saw that it was a Plane Tree. 

"How useless is the Plane!" said one of them. "It bears no fruit whatever, and only serves to litter the ground with leaves." 

"Ungrateful creatures!" said a voice from the Plane Tree. "You lie here in my cooling shade, and yet you say I am useless! Thus ungratefully, O Jupiter, do men receive their blessings!" 

Our best blessings are often the least appreciated.""" 

tfs = tfidf.fit_transform(t.split(" ")) 
str = 'tree cat travellers fruit jupiter' 
response = tfidf.transform([str]) 
feature_names = tfidf.get_feature_names() 
for col in response.nonzero()[1]: 
    print feature_names[col], ' - ', response[0, col] 

e questo mi dà

(0, 28) 0.443509712811 
    (0, 27) 0.517461475101 
    (0, 8) 0.517461475101 
    (0, 6) 0.517461475101 
tree - 0.443509712811 
travellers - 0.517461475101 
jupiter - 0.517461475101 
fruit - 0.517461475101 

che è buono. Per ogni nuovo documento che arriva, c'è un modo per ottenere i primi n termini con il punteggio tfidf più alto?

+2

Probabilmente non si dovrebbe sovrascrivere il tipo di dati Python str. – scottlittle

risposta

14

Devi fare un po 'di canto e danza per ottenere le matrici come array NumPy invece, ma questo dovrebbe fare quello che stai cercando:

feature_array = np.array(tfidf.get_feature_names()) 
tfidf_sorting = np.argsort(response.toarray()).flatten()[::-1] 

n = 3 
top_n = feature_array[tfidf_sorting][:n] 

Questo mi dà:

array([u'fruit', u'travellers', u'jupiter'], 
    dtype='<U13') 

La chiamata argsort è davvero utile, here are the docs for it. Dobbiamo fare [::-1] perché argsort supporta solo l'ordinamento da piccolo a grande. Chiamiamo flatten per ridurre le dimensioni a 1d in modo che gli indici ordinati possano essere utilizzati per indicizzare l'array di funzioni 1d. Nota che includere la chiamata a flatten funzionerà solo se stai testando un documento alla volta.

Inoltre, in un'altra nota, intendevi qualcosa come tfs = tfidf.fit_transform(t.split("\n\n"))? Altrimenti, ogni termine nella stringa multilinea viene trattato come un "documento". Usare \n\n significa invece che stiamo effettivamente guardando 4 documenti (uno per ogni riga), il che ha più senso quando si pensa a tfidf.

+0

grazie mille uomo :) – AbtPst

+1

Come ottenerlo utilizzando DictVectorizer + TfidfTransformer? – diugalde

+1

Cosa fare se si desidera elencare i primi n termini per ogni classe e non per ciascun documento? Ho fatto una domanda [qui] (https://stackoverflow.com/questions/44833987/listing-top-n-features-in-each-class-using-sklearn-and-tf-idf-values) ma ancora nessuna risposta ! – Pedram