true sklearn score scikit recall positive medida macro learn accuracy python machine-learning nlp artificial-intelligence scikit-learn

python - sklearn - ¿Cómo calcular la precisión, el recuerdo, la precisión y la puntuación f1 para el caso de múltiples clases con scikit learn?



scikit learn precision score (4)

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

Pesas de clase

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

Básicamente, en cada clasificador scikit-learn, los pesos de clase se utilizan para decirle a su modelo lo importante que es una clase. Eso significa que durante el entrenamiento, el clasificador hará esfuerzos adicionales para clasificar adecuadamente las clases con pesos altos.
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, desea saber qué tan bien está funcionando. Aquí puede usar las métricas que mencionó: accuracy , recall_score , f1_score ...

Por lo general, cuando la distribución de la clase no está equilibrada, la precisión se considera una mala elección, ya que otorga puntajes altos 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 a nivel de clase: como puede ver en esta print de un informe de clasificación, están definidas para cada clase. Se basan en conceptos como true positives o 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 la puntuación f1, la recuperación y la precisión sin definir cómo deben calcularse! La pregunta podría reformularse: del informe de clasificación anterior, ¿cómo se genera un número global para la puntuación 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 macro promedio.
  2. Calcule la puntuación f1 utilizando el recuento global de positivos verdaderos / falsos negativos, etc. (suma el número de positivos verdaderos / falsos negativos para cada clase). Aka micro promedio.
  3. Calcule un promedio ponderado de la puntuación f1. El uso de ''weighted'' en scikit-learn pesará el puntaje f1 por el apoyo de la clase: cuantos más elementos tenga una clase, más importante será el puntaje f1 para esta clase en el cálculo.

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

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

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

Puntajes 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 en los datos que se usaron para ajustar el clasificador es completamente irrelevante.

Aquí hay una manera de hacerlo usando StratifiedShuffleSplit , que le brinda divisiones aleatorias de sus datos (después de barajar) que preservan la distribución de la etiqueta.

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.

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

Por lo tanto, mis datos no están equilibrados, ya que 1190 instances están etiquetadas con 5 . Para la clasificación estoy usando scikit''s SVC . 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 de varias clases. 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, recibo 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 desequilibrados para calcular de manera correcta las métricas del clasificador?


En primer lugar, es un poco más difícil usar solo el análisis de conteo para saber si sus datos están desequilibrados o no. Por ejemplo: ¿1 de cada 1000 observaciones positivas es solo un ruido, un error o un avance en la ciencia? Nunca sabes.
Por lo tanto, siempre es mejor utilizar todos sus conocimientos disponibles y elegir su estado con toda sabiduría.

De acuerdo, ¿y si está realmente desequilibrado?
Una vez más, mire sus datos. A veces puedes encontrar una o dos observaciones multiplicadas por cien. A veces es útil crear estas falsas observaciones de una clase.
Si todos los datos están limpios, el siguiente paso es usar ponderaciones de clase en el modelo de predicción.

Entonces, ¿qué pasa con las métricas multiclase?
En mi experiencia, generalmente no se usa ninguna de sus métricas. 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 error cuadrático medio).

¿Cómo arreglar las advertencias de sklearn?
Simplemente (como notó yangjie) sobrescribe 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 el valor average predeterminado ''binary'' cual no es apropiado para la predicción de varias clases.
¡Buena suerte y diviértete con el aprendizaje automático!

Editar:
Encontré otra recomendación de respuesta para cambiar a enfoques de regresión (por ejemplo, SVR) con los que no puedo estar de acuerdo. Por lo que recuerdo, ni siquiera existe una regresión multiclase. Sí, hay una regresión de múltiples capas que es muy diferente y sí, en algunos casos es posible 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 potentes: 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 las predicciones y la mayoría de las veces obtendrá un resultado aún mejor.

final_prediction = (KNNprediction * RFprediction) ** 0.5


Muchas respuestas muy detalladas aquí, pero no creo que estés respondiendo las preguntas correctas. Según tengo entendido la pregunta, hay dos preocupaciones:

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

1)

Puede utilizar la mayoría de las funciones de puntuación en scikit-learn tanto con problemas multiclase como 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)

... puede saber si los datos desequilibrados son incluso un problema. Si la puntuación para las clases menos representadas (clase 1 y 2) es menor que para las clases con más muestras de entrenamiento (clase 4 y 5), entonces sabrá que los datos desequilibrados son en realidad 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 clases 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 utilizar para la clasificación de varias clases con datos desequilibrados": Medida Macro-F1. También se pueden utilizar Macro Precision y Macro Recall, pero no son tan fáciles de interpretar como para la clasificación binaria, ya están incorporados en la medida F, 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 etiquetas más comunes y desordena totalmente a los demás, las métricas micro promediadas muestran buenos resultados.

El promedio de ponderación no es adecuado para datos desequilibrados, ya que pesa por recuentos de etiquetas. Además, es muy difícil de interpretar e impopular: por ejemplo, no se menciona tal promedio en la siguiente survey muy detallada que recomiendo revisar:

Sokolova, Marina y Guy Lapalme. "Un análisis sistemático de las medidas de rendimiento para las tareas de clasificación". Procesamiento y gestión de la información 45.4 (2009): 427-437.

Pregunta específica de la aplicación

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

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

Métricas de uso común. Como puedo deducir después de mirar a través de la literatura, hay 2 métricas de evaluación principales:

  1. Accuracy , que se utiliza, por ejemplo, en

Yu, April y Daryl Chang. "Predicción de sentimientos multiclase con Yelp Business".

( link ) - tenga en cuenta que los autores trabajan con casi la misma distribución de calificaciones, ver 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 sobre la Asociación de Lingüística Computacional. Asociación de Lingüística Computacional, 2005.

( link )

  1. MSE (o, con menos frecuencia, Error absoluto medio - MAE ) - vea, por ejemplo,

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

( link ): exploran tanto la precisión como el MSE, considerando que este último es mejor

Pappas, Nikolaos, Rue Marconi y Andrei Popescu-Belis. "Explicando las estrellas: Aprendizaje ponderado de instancias múltiples para el análisis de sentimientos 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.

( link ): utilizan scikit-learn para la evaluación y los enfoques de referencia y afirman 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.

Costo de diferentes errores . Si le interesa más evitar errores graves, por ejemplo, evaluar una reseña de 1 a 5 estrellas o algo así, mire MSE; si la diferencia es importante, pero no tanto, intente con MAE, ya que no cuadra diff; de lo contrario, quédese con precisión.

Acerca de enfoques, no métricas

Pruebe los enfoques de regresión, por ejemplo, SVR , ya que generalmente superan a los clasificadores Multiclass como SVC u OVA SVM.