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
Entonces mis datos no están balanceados ya que 1190 instances
están etiquetados 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, la recuperación, la exactitud y la puntuación f1 para el caso multiclase. Entonces 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 tratar correctamente mis datos desequilibrados para calcular correctamente las métricas del clasificador?
python
machine-learning
nlp
artificial-intelligence
scikit-learn
new_with_python
fuente
fuente
average
parámetro en el tercer caso?Respuestas:
Creo que hay mucha confusión sobre qué pesos se utilizan para qué. No estoy seguro de saber con precisión qué es lo que te molesta, así que voy a cubrir diferentes temas, ten paciencia;).
Pesos de clase
Los pesos del
class_weight
parámetro se utilizan 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 todos los clasificadores de scikit-learn, los pesos de las clases se utilizan para indicarle a su modelo qué tan importante es una clase. Eso significa que durante el entrenamiento, el clasificador hará un esfuerzo adicional 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, querrá saber qué tan bien está funcionando. Aquí se pueden utilizar las métricas que usted ha mencionado:
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 puntuaciones altas a los modelos que solo predicen la clase más frecuente.
No detallaré todas estas métricas, pero tenga en cuenta que, a excepción de
accuracy
, se aplican naturalmente a nivel de clase: como puede ver en esteprint
informe de clasificación, están definidas para cada clase. Se basan en conceptos comotrue positives
ofalse negative
que requieren definir qué clase es la positiva .La advertencia
Recibe esta advertencia porque está utilizando la puntuación f1, la recuperación y la precisión sin definir cómo se deben calcular. 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:
avg / total
resultado anterior. También se llama promediado macro .'weighted'
de scikit-learn pesará el puntaje f1 con 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 decirle que debe elegir una . Por lo tanto, debe especificar un
average
argumento para el método de puntuación.El que elija depende de cómo desee medir el rendimiento del clasificador: por ejemplo, el macropromedio 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. Sin embargo, si usa el promedio ponderado, obtendrá más importancia para la clase 5.
Toda la especificación del argumento en estas métricas no es 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.
Calcular puntuaciones
Lo último que quiero mencionar (no dude en omitirlo si es consciente de ello) 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 usando
StratifiedShuffleSplit
, que le brinda divisiones aleatorias de sus datos (después de barajar) que preservan la distribución de la etiqueta.Espero que esto ayude.
fuente
class_weight={1:10}
dato que tiene 3 clases?ValueError: The least populated class in y has only 1 member, which is too few. The minimum number of labels for any class cannot be less than 2.
. Está funcionando bien con la división de prueba de tren, pero ¿alguien puede ayudarme por qué recibo este error con SSS? Gracias.Muchas respuestas muy detalladas aquí, pero no creo que esté respondiendo las preguntas correctas. Según entiendo la pregunta, hay dos preocupaciones:
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.:
De esta manera terminas con números tangibles e interpretables para cada una de las clases.
Luego...
2.
... puede saber si los datos desbalanceados son 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 de hecho un problema y puede actuar en consecuencia, ya que 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.
fuente
precision_recall_fscore_support
? ¿Las etiquetas se imprimen por encargo?average=None
y defina las etiquetas, luego obtendrá la métrica que está buscando, para cada una de sus etiquetas especificadas.Pregunta planteada
Respondiendo a la pregunta '¿Qué métrica debería usarse para la clasificación de clases múltiples 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 incorporadas en la medida F, y el exceso de métricas complica la comparación de métodos, ajuste de parámetros, etc.
El micropromedio es sensible al desequilibrio de clases: si su método, por ejemplo, funciona bien para las etiquetas más comunes y estropea totalmente otras, las métricas micropromediadas muestran buenos resultados.
El promedio de ponderación no es adecuado para datos desequilibrados, porque pondera por conteos de etiquetas. Además, es muy poco interpretable e impopular: por ejemplo, no se menciona un promedio de este tipo en la siguiente encuesta muy detallada que recomiendo encarecidamente revisar:
Pregunta específica de la aplicación
Sin embargo, volviendo a su tarea, investigaría 2 temas:
Métricas de uso común. Como puedo inferir después de revisar la literatura, hay 2 métricas de evaluación principales:
( enlace ): tenga en cuenta que los autores trabajan con casi la misma distribución de calificaciones, consulte la Figura 5.
( enlace )
( enlace ): exploran tanto la precisión como el MSE, considerando que este último es mejor
( enlace ): 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 importa más evitar errores graves, por ejemplo, asignar una reseña de 1 estrella a 5 estrellas o algo así, mire MSE; si la diferencia importa, pero no tanto, pruebe MAE, ya que no cuadra la diferencia; de lo contrario, manténgase con precisión.
Acerca de los enfoques, no de las métricas
Pruebe los enfoques de regresión, por ejemplo, SVR , ya que generalmente superan a los clasificadores multiclase como SVC u OVA SVM.
fuente
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 todo su conocimiento disponible y elegir su estado con prudencia.
Bien, ¿y si está realmente desequilibrado?
Una vez más, mire sus datos. A veces puedes encontrar una o dos observaciones multiplicadas por cien veces. A veces es útil crear estas observaciones falsas 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, no se suele utilizar ninguna de sus métricas. Hay dos razones principales.
Primero: siempre es mejor trabajar con probabilidades que con predicciones sólidas (porque ¿de qué otra manera podrías separar modelos con predicción 0.9 y 0.6 si ambos te dan la misma clase?)
Y segundo: es mucho más fácil comparar tus modelos de predicción y construir nuevos los que dependen de una sola buena métrica.
Desde mi experiencia, podría recomendar logloss o MSE (o simplemente significar error al cuadrado).
¿Cómo corregir las advertencias de sklearn?
Simplemente (como observó Yangjie) sobrescriba el
average
parámetro con uno de estos valores:'micro'
(calcular métricas globalmente),'macro'
(calcular métricas para cada etiqueta) o'weighted'
(igual que la macro pero con pesos automáticos).Todas sus advertencias vinieron después de llamar a funciones de métricas con un
average
valor predeterminado'binary'
que es inapropiado para la predicción multiclase.¡Buena suerte y diviértete con el aprendizaje automático!
Editar:
encontré otra recomendación del respondedor para cambiar a enfoques de regresión (por ejemplo, SVR) con la que no estoy de acuerdo. Por lo que recuerdo, ni siquiera existe una regresión multiclase. Sí, hay regresión de etiquetas múltiples que es muy diferente y sí, en algunos casos es posible cambiar entre regresión y clasificación (si las clases se ordenaron 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 muchas 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.
fuente