2012-06-20 14 views
54

Los clasificadores de paquetes de aprendizaje automático como LIBLINEAR y NLTK ofrecer un método show_most_informative_features(), que es realmente útil para depurar características:¿Cómo obtener la mayoría de las características informativas para los clasificadores scikit-learn?

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 

Mi pregunta es si algo similar se aplica para los clasificadores en scikit-learn. Busqué en la documentación, pero no pude encontrar nada igual.

Si aún no existe esa función, ¿alguien sabe una solución alternativa para llegar a esos valores?

Gracias mucho!

+0

¿Te refieres al parámetro más discriminatorio? – Simon

+0

No estoy seguro de lo que quiere decir con los parámetros. me refiero a las características más discriminatorias, como en un modelo de bolsa de palabras para la clasificación de correo no deseado, cuyas palabras brindan más evidencia para cada clase.no los parámetros que entiendo como "configuraciones" para el clasificador, como la velocidad de aprendizaje, etc. – tobigue

+7

@eowl: en lenguaje de aprendizaje automático, * parámetros * son los ajustes generados por el procedimiento de aprendizaje en función de las * características * de su conjunto de entrenamiento. La tasa de aprendizaje, etc. son * hiperparámetros *. –

Respuesta

40

Con la ayuda de código larsmans me ocurrió con este código para el 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

¡gracias, justo lo que necesitaba! – WeaselFox

+0

¿Cómo se llama a la función desde el método principal? ¿Qué significa f1 y f2? Intento llamar a la función del clasificador Árbol de decisiones con scikit-learn. –

+0

Este código solo funcionará con un clasificador lineal que tenga una matriz 'coef_', por lo que desafortunadamente no creo que sea posible usarlo con los clasificadores de árbol de decisión de sklearn. 'fn_1' y' fn_2' representan los nombres de las características. – tobigue

49

Los clasificadores no registran los nombres de las funciones, solo ven las matrices numéricas. Sin embargo, si extrajo sus características usando una Vectorizer/CountVectorizer/TfidfVectorizer/DictVectorizer, y está utilizando un modelo lineal (por ejemplo LinearSVC o Naive Bayes), entonces se puede aplicar el mismo truco que los document classification example usos. Ejemplo (no probado, puede contener un error o dos):

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))) 

Esto es para la clasificación multiclase; para el caso binario, creo que debería usar clf.coef_[0] solamente. Puede que tenga que ordenar el class_labels.

+0

sí, en mi caso tengo solo dos clases, pero con su código pude encontrar lo que quería. ¡muchas gracias! – tobigue

+0

@eowl: de nada. ¿Tomaste el 'np.abs' de' coef_'? Porque obtener los coeficientes más altos solo devolverá las características que son indicativas de la clase positiva. –

+0

sth. así ... ordené la lista y tomé la cabeza y la cola, lo que te permite ver aún qué función vota para qué clase. Publiqué mi solución [a continuación] (http://stackoverflow.com/a/11140887/979377). – tobigue

0

También puede hacer algo como esto para crear un gráfico de características de importancia por orden:

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

Para añadir una actualización, RandomForestClassifier ahora es compatible con el atributo .feature_importances_. Este attribute le dice cuánto de la varianza observada se explica con esa característica. Obviamente, la suma de todos estos valores debe ser < = 1.

Me parece que este atributo es muy útil cuando se realiza ingeniería de características.

¡Gracias al equipo de scikit-learn y a los colaboradores por implementar esto!

editar: Esto funciona tanto para RandomForest como para GradientBoosting. Así que RandomForestClassifier, RandomForestRegressor, GradientBoostingClassifier y GradientBoostingRegressor son compatibles con esto.

5

hemos lanzado recientemente una biblioteca (https://github.com/TeamHG-Memex/eli5) que permite hacer eso: se encarga de clasificadores variuos de scikit-learn, casos binarios/multiclase, permite resaltar el texto de acuerdo con valores de características, se integra con IPython, etc.

Cuestiones relacionadas