Estoy recibiendo este extraño error:
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 también imprime la puntuación f la primera vez que lo ejecuto:
metrics.f1_score(y_test, y_pred, average='weighted')
La segunda vez que lo ejecuto, proporciona la puntuación sin error. ¿A qué se debe?
>>> 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 final 'precisión', 'predijo', promedio, warn_for)
mensaje de error? No hay paréntesis abierto así que ¿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 he mirado aquí y no sé si es el mismo error. Este SO post tampoco tiene solución.
Como se menciona en los comentarios, algunas etiquetas de y_true no aparecen en y_pred. Concretamente en este caso, la etiqueta '2' nunca se predice:
>>> set(y_test) - set(y_pred)
{2}
Esto significa que no hay puntuación F que calcular para esta etiqueta y, por tanto, la puntuación F para este caso se considera 0,0. Dado que usted solicitó un promedio de la puntuación, debe tener en cuenta que una puntuación de 0 se incluyó 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 he mencionado, se trata de una advertencia, que se trata de manera diferente a un error en python. El comportamiento por defecto en la mayoría de los entornos es mostrar una advertencia específica sólo una vez. Este comportamiento se puede cambiar:
import warnings
warnings.filterwarnings('always') # "error", "ignore", "always", "default", "module" or "once"
Si establece esto antes de importar los otros módulos, verá la advertencia cada vez que ejecute el código.
No hay manera de evitar ver esta advertencia la primera vez, aparte de establecer warnings.filterwarnings('ignore')
. Lo que puede hacer es decidir que no le interesan las puntuaciones de las etiquetas que no se predijeron y, a continuación, especificar explícitamente las etiquetas que le interesan (que son las etiquetas 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é se produce la advertencia. Si simplemente quiere controlar los avisos, puede utilizar precision_recall_fscore_support
. Ofrece un argumento (semioficial) warn_for
que puede utilizarse para silenciar las advertencias.
(_, _, f1, _) = metrics.precision_recall_fscore_support(y_test, y_pred,
average='weighted',
warn_for=tuple())
Como ya se ha mencionado en algunos comentarios, úsalo con cuidado.
Como el mensaje de error indica, el método utilizado para obtener la puntuación F es de la "Clasificación" parte de sklearn - por lo que el hablar de "etiquetas".
¿Tiene un problema de regresión? Sklearn proporciona un "F score" método para la regresión en el "feature selection" grupo: http://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.f_regression.html
En caso de que tengas un problema de clasificación, la respuesta de @Shovalt'me parece correcta.