¿Cómo calcular la precisión, el recuerdo, la precisión y la puntuación f1 para el caso multiclase con scikit learn?

Estoy trabajando en un problema de análisis de sentimientos, los datos se ven así:

label instances 5 1190 4 838 3 239 1 204 2 127 

Así que mis datos están desequilibrados ya que 1190 instances están etiquetadas con 5 . Para la clasificación estoy usando el SVC de scikit. El problema es que no sé cómo equilibrar mis datos de la manera correcta para calcular con precisión la precisión, el recuerdo, la precisión y la puntuación f1 para el caso multiclase. Así que probé los siguientes enfoques:

Primero:

  wclf = SVC(kernel='linear', C= 1, class_weight={1: 10}) wclf.fit(X, y) weighted_prediction = wclf.predict(X_test) print 'Accuracy:', accuracy_score(y_test, weighted_prediction) print 'F1 score:', f1_score(y_test, weighted_prediction,average='weighted') print 'Recall:', recall_score(y_test, weighted_prediction, average='weighted') print 'Precision:', precision_score(y_test, weighted_prediction, average='weighted') print '\n clasification report:\n', classification_report(y_test, weighted_prediction) print '\n confussion matrix:\n',confusion_matrix(y_test, weighted_prediction) 

Segundo:

 auto_wclf = SVC(kernel='linear', C= 1, class_weight='auto') auto_wclf.fit(X, y) auto_weighted_prediction = auto_wclf.predict(X_test) print 'Accuracy:', accuracy_score(y_test, auto_weighted_prediction) print 'F1 score:', f1_score(y_test, auto_weighted_prediction, average='weighted') print 'Recall:', recall_score(y_test, auto_weighted_prediction, average='weighted') print 'Precision:', precision_score(y_test, auto_weighted_prediction, average='weighted') print '\n clasification report:\n', classification_report(y_test,auto_weighted_prediction) print '\n confussion matrix:\n',confusion_matrix(y_test, auto_weighted_prediction) 

Tercero:

 clf = SVC(kernel='linear', C= 1) clf.fit(X, y) prediction = clf.predict(X_test) from sklearn.metrics import precision_score, \ recall_score, confusion_matrix, classification_report, \ accuracy_score, f1_score print 'Accuracy:', accuracy_score(y_test, prediction) print 'F1 score:', f1_score(y_test, prediction) print 'Recall:', recall_score(y_test, prediction) print 'Precision:', precision_score(y_test, prediction) print '\n clasification report:\n', classification_report(y_test,prediction) print '\n confussion matrix:\n',confusion_matrix(y_test, prediction) F1 score:/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:676: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1". sample_weight=sample_weight) /usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1172: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1". sample_weight=sample_weight) /usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1082: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1". sample_weight=sample_weight) 0.930416613529 

Sin embargo, estoy recibiendo advertencias como esta:

 /usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1172: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1" 

¿Cómo puedo manejar correctamente mis datos desbalanceados para calcular de forma correcta las métricas del clasificador?

Related of "¿Cómo calcular la precisión, el recuerdo, la precisión y la puntuación f1 para el caso multiclase con scikit learn?"

Creo que hay mucha confusión sobre qué pesos se usan para qué. No estoy seguro de saber exactamente lo que te molesta, así que voy a cubrir diferentes temas, ten paciencia;).

Pesos de clase

Los pesos del parámetro class_weight se utilizan para entrenar al clasificador . No se utilizan en el cálculo de ninguna de las métricas que está utilizando : con diferentes ponderaciones de clase, los números serán diferentes simplemente porque el clasificador es diferente.

Básicamente, en cada clasificador de scikit-learn, los pesos de clase se usan para decirle a su modelo lo importante que es una clase. Eso significa que durante el entrenamiento, el clasificador hará esfuerzos adicionales para clasificar correctamente las clases con alto peso.
Cómo lo hacen es específico del algoritmo. Si desea detalles sobre cómo funciona para SVC y el documento no tiene sentido para usted, no dude en mencionarlo.

Las métricas

Una vez que tenga un clasificador, querrá saber qué tan bien está funcionando. Aquí puede utilizar las métricas que mencionó: accuracy , recall_score , f1_score

Por lo general, cuando la distribución de clases no está equilibrada, la precisión se considera una mala elección, ya que otorga altas calificaciones a los modelos que solo predicen la clase más frecuente.

No detallaré todas estas métricas, pero tenga en cuenta que, con la excepción de la accuracy , se aplican naturalmente en el nivel de clase: como se puede ver en esta print de un informe de clasificación, se definen para cada clase. Se basan en conceptos como los true positives o los false negative que requieren definir qué clase es la positiva .

  precision recall f1-score support 0 0.65 1.00 0.79 17 1 0.57 0.75 0.65 16 2 0.33 0.06 0.10 17 avg / total 0.52 0.60 0.51 50 

La advertencia

 F1 score:/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:676: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1". 

¡Recibe esta advertencia porque está utilizando el puntaje, recordatorio y precisión de f1 sin definir cómo deben computarse! La pregunta podría reformularse: en el informe de clasificación anterior, ¿cómo se genera un número global para el puntaje f1? Tú podrías:

  1. Tome el promedio de la puntuación f1 para cada clase: ese es el resultado avg / total anterior. También se llama promedio de macro .
  2. Calcule la puntuación f1 utilizando el recuento global de verdaderos positivos / falsos negativos, etc. (sume el número de verdaderos positivos / falsos negativos para cada clase). Aka micro promediado.
  3. Calcular un promedio ponderado de la puntuación f1. El uso de 'weighted' en scikit-learn pesará la puntuación f1 con el apoyo de la clase: cuantos más elementos tenga una clase, más importante será la puntuación f1 para esta clase en el cálculo.

Estas son 3 de las opciones en scikit-learn, la advertencia está ahí para decir que debes elegir una . Así que tienes que especificar un argumento average para el método de puntuación.

La opción que elija depende de cómo desea medir el rendimiento del clasificador: por ejemplo, el promedio de macro no tiene en cuenta el desequilibrio de clase y la puntuación f1 de la clase 1 será tan importante como la puntuación f1 de la clase 5. Si usa un promedio ponderado, sin embargo, tendrá más importancia para la clase 5.

La especificación del argumento completo en estas métricas no está muy clara en scikit-learn en este momento, mejorará en la versión 0.18 de acuerdo con los documentos. Están eliminando algunos comportamientos estándar no obvios y están emitiendo advertencias para que los desarrolladores lo noten.

Puntuaciones de computación

Lo último que quiero mencionar (siéntase libre de omitirlo si lo sabe) es que las puntuaciones solo son significativas si se calculan sobre datos que el clasificador nunca ha visto . Esto es extremadamente importante ya que cualquier puntaje que obtenga sobre los datos que se usaron para ajustar el clasificador es completamente irrelevante.

Esta es una forma de hacerlo utilizando StratifiedShuffleSplit , que le brinda una división aleatoria de sus datos (después de la mezcla aleatoria) que preserva la distribución de tags.

 from sklearn.datasets import make_classification from sklearn.cross_validation import StratifiedShuffleSplit from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score, classification_report, confusion_matrix # We use a utility to generate artificial classification data. X, y = make_classification(n_samples=100, n_informative=10, n_classes=3) sss = StratifiedShuffleSplit(y, n_iter=1, test_size=0.5, random_state=0) for train_idx, test_idx in sss: X_train, X_test, y_train, y_test = X[train_idx], X[test_idx], y[train_idx], y[test_idx] svc.fit(X_train, y_train) y_pred = svc.predict(X_test) print(f1_score(y_test, y_pred, average="macro")) print(precision_score(y_test, y_pred, average="macro")) print(recall_score(y_test, y_pred, average="macro")) 

Espero que esto ayude.

Muchas respuestas muy detalladas aquí, pero no creo que esté respondiendo las preguntas correctas. Como entiendo la pregunta, hay dos preocupaciones:

  1. ¿Cómo puntúo un problema multiclase?
  2. ¿Cómo trato con los datos desequilibrados?

1.

Puede usar la mayoría de las funciones de puntuación en scikit-learn con problemas de varias clases y con problemas de una sola clase. Ex.:

 from sklearn.metrics import precision_recall_fscore_support as score predicted = [1,2,3,4,5,1,2,1,1,4,5] y_test = [1,2,3,4,5,1,2,1,1,4,1] precision, recall, fscore, support = score(y_test, predicted) print('precision: {}'.format(precision)) print('recall: {}'.format(recall)) print('fscore: {}'.format(fscore)) print('support: {}'.format(support)) 

De esta manera terminas con números tangibles e interpretables para cada una de las clases.

 | Label | Precision | Recall | FScore | Support | |-------|-----------|--------|--------|---------| | 1 | 94% | 83% | 0.88 | 204 | | 2 | 71% | 50% | 0.54 | 127 | | ... | ... | ... | ... | ... | | 4 | 80% | 98% | 0.89 | 838 | | 5 | 93% | 81% | 0.91 | 1190 | 

Entonces…

2.

… puedes saber si los datos no balanceados son un problema. Si el puntaje para las clases menos representadas (clase 1 y 2) es más bajo que para las clases con más muestras de entrenamiento (clase 4 y 5), entonces sabe que los datos no balanceados son de hecho un problema, y ​​puede actuar en consecuencia, como descrito en algunas de las otras respuestas en este hilo. Sin embargo, si la misma distribución de clase está presente en los datos que desea predecir, sus datos de entrenamiento desequilibrados son un buen representante de los datos, y por lo tanto, el desequilibrio es algo bueno.

Pregunta planteada

Respondiendo a la pregunta ‘qué métrica se debe usar para la clasificación de múltiples clases con datos desequilibrados’: Macro-F1-measure. También se pueden usar Macro Precision y Macro Recall, pero no son tan fáciles de interpretar como para la clasificación binaria, ya están incorporados en F-measure, y el exceso de métricas complica la comparación de métodos, el ajuste de parámetros, etc.

Los micro promedios son sensibles al desequilibrio de clase: si su método, por ejemplo, funciona bien para las tags más comunes y desordena totalmente a los demás, las métricas de micro promedios muestran buenos resultados.

El promedio de ponderación no es adecuado para datos desequilibrados, ya que ponderan por conteos de tags. Además, es muy difícil de interpretar e impopular: por ejemplo, no se menciona un promedio de este tipo en la siguiente encuesta muy detallada que recomiendo encarecidamente:

Sokolova, Marina y Guy Lapalme. “Un análisis sistemático de las medidas de desempeño para tareas de clasificación”. Tratamiento y gestión de la información 45.4 (2009): 427-437.

Pregunta específica de la aplicación

Sin embargo, volviendo a tu tarea, investigaría 2 temas:

  1. métricas comúnmente utilizadas para su tarea específica: le permite (a) comparar su método con otros y entender si hace algo mal, y (b) no explorar esto por sí mismo y reutilizar los hallazgos de otra persona;
  2. El costo de diferentes errores de sus métodos, por ejemplo, el caso de uso de su aplicación puede depender solo de las revisiones de 4 y 5 estrellas, en este caso, una buena métrica debe contar solo con estas 2 tags.

Métricas de uso común. Como puedo inferir después de leer la literatura, hay dos métricas de evaluación principales:

  1. La precisión , que se utiliza, por ejemplo, en

Yu, April y Daryl Chang. “Predicción de sentimiento multiclase usando el negocio de Yelp”.

( enlace ): tenga en cuenta que los autores trabajan con casi la misma distribución de calificaciones, consulte la Figura 5.

Pang, Bo y Lillian Lee. “Ver estrellas: explotar las relaciones de clase para la categorización de sentimientos con respecto a las escalas de calificación”. Actas de la 43ª Reunión Anual de la Asociación de Lingüística Computacional. Asociación para la lingüística computacional, 2005.

( enlace )

  1. MSE (o, con menor frecuencia, Error absoluto absoluto – MAE ) – vea, por ejemplo,

Lee, Moontae y R. Grafe. “Análisis de sentimiento multiclase con reseñas de restaurantes”. Proyectos finales de CS N 224 (2010).

( enlace ) – exploran tanto la precisión como la MSE, considerando que esta última es mejor

Pappas, Nikolaos, Rue Marconi y Andrei Popescu-Belis. “Explicación de las estrellas: Aprendizaje ponderado de instancias múltiples para el análisis de sentimiento basado en aspectos”. Actas de la conferencia de 2014 sobre métodos empíricos en el procesamiento del lenguaje natural. No. EPFL-CONF-200899. 2014.

( enlace ): utilizan scikit-learn para la evaluación y los enfoques de referencia y establecen que su código está disponible; sin embargo, no puedo encontrarlo, así que si lo necesita, escriba una carta a los autores, el trabajo es bastante nuevo y parece estar escrito en Python.

Coste de los diferentes errores . Si le interesa más evitar los errores graves, por ejemplo, evaluar una crítica de 1 a 5 estrellas o algo así, mire MSE; si la diferencia es importante, pero no tanto, pruebe el MAE, ya que no encaja en la diferencia; De lo contrario quédate con la precisión.

Sobre enfoques, no métricas

Pruebe los métodos de regresión, por ejemplo, SVR , ya que generalmente superan a los clasificadores multiclase como SVC u OVA SVM.

En primer lugar, es un poco más difícil usar solo el análisis de conteo para determinar si sus datos están desequilibrados o no. Por ejemplo: ¿1 en 1000 la observación positiva es solo un ruido, un error o un gran avance en la ciencia? Nunca sabes.
Por lo tanto, siempre es mejor utilizar todo su conocimiento disponible y elegir su estado con todo el criterio.

Bien, ¿y si es realmente desequilibrado?
Una vez más – mira tus datos. A veces puedes encontrar una o dos observaciones multiplicadas por cientos de veces. A veces es útil crear estas falsas observaciones de una clase.
Si todos los datos están limpios, el siguiente paso es usar los pesos de clase en el modelo de predicción.

Entonces, ¿qué pasa con las métricas multiclase?
En mi experiencia, ninguna de tus métricas se usa habitualmente. Hay dos razones principales.
Primero: siempre es mejor trabajar con probabilidades que con predicción sólida (porque, ¿de qué otra manera podría separar los modelos con predicción 0.9 y 0.6 si ambos le dan la misma clase?)
Y segundo: es mucho más fácil comparar sus modelos de predicción y construir nuevos dependiendo de solo una buena métrica.
Desde mi experiencia, podría recomendar logloss o MSE (o simplemente significar error al cuadrado).

¿Cómo arreglar las advertencias de sklearn?
Simplemente (como advirtió Yangjie) sobrescriba el parámetro average con uno de estos valores: 'micro' (calcular métricas globalmente), 'macro' (calcular métricas para cada etiqueta) o 'weighted' (igual que macro pero con pesos automáticos).

 f1_score(y_test, prediction, average='weighted') 

Todas sus advertencias se produjeron después de llamar a las funciones de métricas con un valor average predeterminado 'binary' que no es apropiado para la predicción multiclase
¡Buena suerte y diviértete con el aprendizaje automático!

Editar:
Encontré otra recomendación de respuesta para cambiar a los enfoques de regresión (por ejemplo, SVR) con los que no estoy de acuerdo. Por lo que recuerdo, no existe una regresión multiclase. Sí, hay una regresión multilabel que es muy diferente y sí, es posible en algunos casos cambiar entre regresión y clasificación (si las clases están ordenadas de alguna manera) pero es bastante raro.

Lo que recomendaría (en el ámbito de scikit-learn) es probar otras herramientas de clasificación muy poderosas: aumento de gradiente , bosque aleatorio (mi favorito), KNeighbors y muchos más.

Después de eso, puede calcular la media aritmética o geométrica entre predicciones y la mayoría de las veces obtendrá un resultado aún mejor.

 final_prediction = (KNNprediction * RFprediction) ** 0.5