UndefinedMetricWarning: F-score está mal definido y se establece en 0.0 en tags sin muestras predichas

Estoy recibiendo este error extraño:

classification.py:1113: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples. 'precision', 'predicted', average, warn_for)` 

pero luego también imprime el puntaje f la primera vez que corro:

 metrics.f1_score(y_test, y_pred, average='weighted') 

La segunda vez que corro, proporciona la puntuación sin error. ¿Porqué es eso?

 >>> y_pred = test.predict(X_test) >>> y_test array([ 1, 10, 35, 9, 7, 29, 26, 3, 8, 23, 39, 11, 20, 2, 5, 23, 28, 30, 32, 18, 5, 34, 4, 25, 12, 24, 13, 21, 38, 19, 33, 33, 16, 20, 18, 27, 39, 20, 37, 17, 31, 29, 36, 7, 6, 24, 37, 22, 30, 0, 22, 11, 35, 30, 31, 14, 32, 21, 34, 38, 5, 11, 10, 6, 1, 14, 12, 36, 25, 8, 30, 3, 12, 7, 4, 10, 15, 12, 34, 25, 26, 29, 14, 37, 23, 12, 19, 19, 3, 2, 31, 30, 11, 2, 24, 19, 27, 22, 13, 6, 18, 20, 6, 34, 33, 2, 37, 17, 30, 24, 2, 36, 9, 36, 19, 33, 35, 0, 4, 1]) >>> y_pred array([ 1, 10, 35, 7, 7, 29, 26, 3, 8, 23, 39, 11, 20, 4, 5, 23, 28, 30, 32, 18, 5, 39, 4, 25, 0, 24, 13, 21, 38, 19, 33, 33, 16, 20, 18, 27, 39, 20, 37, 17, 31, 29, 36, 7, 6, 24, 37, 22, 30, 0, 22, 11, 35, 30, 31, 14, 32, 21, 34, 38, 5, 11, 10, 6, 1, 14, 30, 36, 25, 8, 30, 3, 12, 7, 4, 10, 15, 12, 4, 22, 26, 29, 14, 37, 23, 12, 19, 19, 3, 25, 31, 30, 11, 25, 24, 19, 27, 22, 13, 6, 18, 20, 6, 39, 33, 9, 37, 17, 30, 24, 9, 36, 39, 36, 19, 33, 35, 0, 4, 1]) >>> metrics.f1_score(y_test, y_pred, average='weighted') C:\Users\Michael\Miniconda3\envs\snowflakes\lib\site-packages\sklearn\metrics\classification.py:1113: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples. 'precision', 'predicted', average, warn_for) 0.87282051282051276 >>> metrics.f1_score(y_test, y_pred, average='weighted') 0.87282051282051276 >>> metrics.f1_score(y_test, y_pred, average='weighted') 0.87282051282051276 

Además, ¿por qué hay un mensaje de error final de 'precision', 'predicted', average, warn_for) ? No hay paréntesis abiertos, ¿por qué termina con un paréntesis de cierre? Estoy ejecutando sklearn 0.18.1 utilizando Python 3.6.0 en un entorno conda en Windows 10.

También miré aquí y no sé si es el mismo error. Esta publicación SO no tiene solución tampoco.

Como se mencionó en los comentarios, algunas tags en y_true no aparecen en y_pred. Específicamente en este caso, la etiqueta ‘2’ nunca se predice:

 >>> set(y_test) - set(y_pred) {2} 

Esto significa que no hay un puntaje F para calcular para esta etiqueta y, por lo tanto, el puntaje F para este caso se considera 0.0. Dado que solicitó un promedio de la puntuación, debe tener en cuenta que se incluyó una puntuación de 0 en el cálculo, y es por eso que scikit-learn le muestra esa advertencia.

Esto me lleva a que no veas el error por segunda vez. Como mencioné, esta es una advertencia , que se trata de manera diferente a un error en Python. El comportamiento predeterminado en la mayoría de los entornos es mostrar una advertencia específica solo una vez. Este comportamiento puede ser cambiado:

 import warnings warnings.filterwarnings('always') # "error", "ignore", "always", "default", "module" or "once" 

Si configura esto antes de importar los otros módulos, verá la advertencia cada vez que ejecute el código.

No hay forma de evitar ver esta advertencia la primera vez, aparte de configurar warnings.filterwarnings('ignore') . Lo que puede hacer es decidir que no está interesado en los puntajes de las tags que no se predijeron, y luego especifique explícitamente las tags que le interesan (que son tags que se predijeron al menos una vez):

 >>> metrics.f1_score(y_test, y_pred, average='weighted', labels=np.unique(y_pred)) 0.91076923076923078 

La advertencia no se muestra en este caso.

La respuesta aceptada ya explica bien por qué ocurre la advertencia. Si simplemente desea controlar las advertencias, puede usar precision_recall_fscore_support . Ofrece un argumento (semioficial) de warn_for que podría usarse para silenciar las advertencias.

 (_, _, f1, _) = metrics.precision_recall_fscore_support(y_test, y_pred, average='weighted', warn_for=tuple()) 

Como ya se mencionó en algunos comentarios, use esto con cuidado.

Como indica el mensaje de error, el método utilizado para obtener la puntuación F es de la parte de “Clasificación” de sklearn, por lo que se habla de “tags”.

¿Tienes un problema de regresión? Sklearn proporciona un método de “puntuación F” para la regresión en el grupo “selección de características”: http://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.f_regression.html

En caso de que tenga un problema de clasificación, la respuesta de @Shovalt me ​​parece correcta.