2012-06-20 7 views
54

I classificatori in pacchetti di machine learning come liblinear e NLTK offrire un metodo show_most_informative_features(), che è davvero utile per il debug caratteristiche:Come ottenere la maggior parte delle funzioni informative per i classificatori di apprendimento di scikit?

viagra = None   ok : spam  =  4.5 : 1.0 
hello = True   ok : spam  =  4.5 : 1.0 
hello = None   spam : ok  =  3.3 : 1.0 
viagra = True   spam : ok  =  3.3 : 1.0 
casino = True   spam : ok  =  2.0 : 1.0 
casino = None   ok : spam  =  1.5 : 1.0 

mia domanda è se è implementato qualcosa di simile per i classificatori a scikit-learn. Ho cercato la documentazione, ma non ho trovato nulla di simile.

Se questa funzione non esiste ancora, qualcuno conosce una soluzione alternativa per ottenere tali valori?

Grazie mille!

+0

Intendi il parametro più discriminante? – Simon

+0

Non sono sicuro di cosa intendi con i parametri. Intendo le caratteristiche più discriminanti, come in un modello di tipo "bag of word" per la classificazione dello spam, che le parole danno la maggior prova per ogni classe.non i parametri che ho capito come "impostazioni" per il classificatore - come il tasso di apprendimento ecc. – tobigue

+7

@eowl: in linguaggio di apprendimento automatico, * parametri * sono le impostazioni generate dalla procedura di apprendimento basata sulle * caratteristiche * del set di allenamento. Il tasso di apprendimento ecc. Sono * iperparametri *. –

risposta

40

Con l'aiuto del codice di larsmans sono arrivato fino a questo codice per il caso binario:

def show_most_informative_features(vectorizer, clf, n=20): 
    feature_names = vectorizer.get_feature_names() 
    coefs_with_fns = sorted(zip(clf.coef_[0], feature_names)) 
    top = zip(coefs_with_fns[:n], coefs_with_fns[:-(n + 1):-1]) 
    for (coef_1, fn_1), (coef_2, fn_2) in top: 
     print "\t%.4f\t%-15s\t\t%.4f\t%-15s" % (coef_1, fn_1, coef_2, fn_2) 
+0

grazie, proprio quello di cui avevo bisogno! – WeaselFox

+0

Come si chiama la funzione dal metodo principale? cosa significa f1 e f2? Sto provando a chiamare la funzione dal classificatore di Decision Decision con scikit-learn. –

+0

Questo codice funziona solo con un classificatore lineare che ha una matrice 'coef_', quindi sfortunatamente non penso sia possibile utilizzarlo con le classificazioni dell'albero delle decisioni di sklearn. 'fn_1' e' fn_2' rappresentano i nomi delle funzionalità. – tobigue

49

Gli stessi classificatori non registrano i nomi delle funzioni, visualizzano solo array numerici. Tuttavia, se è stato estratto le funzionalità utilizzando un Vectorizer/CountVectorizer/TfidfVectorizer/DictVectorizer, e si utilizza un modello lineare (per esempio LinearSVC o Naive Bayes) allora si può applicare lo stesso trucco che le document classification example usi. Esempio (testata, può contenere un errore o due):

def print_top10(vectorizer, clf, class_labels): 
    """Prints features with the highest coefficient values, per class""" 
    feature_names = vectorizer.get_feature_names() 
    for i, class_label in enumerate(class_labels): 
     top10 = np.argsort(clf.coef_[i])[-10:] 
     print("%s: %s" % (class_label, 
       " ".join(feature_names[j] for j in top10))) 

Questo è per la classificazione multiclasse; per il caso binario, penso che dovresti usare solo clf.coef_[0]. Potrebbe essere necessario ordinare lo class_labels.

+0

sì, nei miei casi ho solo due classi, ma con il tuo codice sono riuscito a trovare la cosa che volevo. molte grazie! – tobigue

+0

@ eowl: prego. Hai preso il 'np.abs' di' coef_'? Perché ottenere i coefficienti con il valore più alto restituirà solo le caratteristiche che sono indicative della classe positiva. –

+0

sth. così ... ho risolto la lista e ho preso la testa e la coda, cosa che ti permette di vedere ancora quali caratteristiche votano per quale classe. ho pubblicato la mia soluzione [in basso] (http://stackoverflow.com/a/11140887/979377). – tobigue

0

Si può anche fare qualcosa di simile per creare un grafico delle caratteristiche importanza per ordine:

importances = clf.feature_importances_ 
std = np.std([tree.feature_importances_ for tree in clf.estimators_], 
     axis=0) 
indices = np.argsort(importances)[::-1] 

# Print the feature ranking 
#print("Feature ranking:") 


# Plot the feature importances of the forest 
plt.figure() 
plt.title("Feature importances") 
plt.bar(range(train[features].shape[1]), importances[indices], 
    color="r", yerr=std[indices], align="center") 
plt.xticks(range(train[features].shape[1]), indices) 
plt.xlim([-1, train[features].shape[1]]) 
plt.show() 
10

Per aggiungere un aggiornamento, RandomForestClassifier ora supporta l'attributo .feature_importances_. Questo attribute indica quanto della varianza osservata è spiegata da quella funzione. Ovviamente, la somma di tutti questi valori deve essere < = 1.

Trovo che questo attributo sia molto utile quando si esegue l'ingegneria delle funzioni.

Grazie al team di scikit-learn e ai collaboratori per l'implementazione di questo!

modifica: funziona sia per RandomForest che GradientBoosting. Quindi RandomForestClassifier, RandomForestRegressor, GradientBoostingClassifier e GradientBoostingRegressor supportano tutto questo.

5

Abbiamo recentemente rilasciato una libreria (https://github.com/TeamHG-Memex/eli5), che permette di farlo: gestisce classificatori Variuos da scikit-learn, casi binari/multiclasse, permette di evidenziare il testo in base ai valori di funzionalità, si integra con IPython, ecc