106 votes

UndefinedMetricWarning: le score F est mal défini et défini sur 0.0 dans les étiquettes sans échantillon prédit

J'obtiens cette erreur bizarre:

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)`

mais alors, il imprime également le f-score de la première fois que je lance:

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

La deuxième fois que je lance, il fournit le score sans erreur. Pourquoi est-ce?

>>> 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

Aussi, pourquoi est-il une fuite en 'precision', 'predicted', average, warn_for) message d'erreur? Il n'y a pas de parenthèse ouverte alors pourquoi prend-elle fin à une parenthèse fermante? Je suis en cours d'exécution sklearn 0.18.1 à l'aide de Python 3.6.0 dans une conda de l'environnement sur Windows 10.

J'ai également regardé ici et je ne sais pas si c'est le même bug. Cette SORTE de post n'a pas de solution.

142voto

Shovalt Points 1657

Comme mentionné dans les commentaires, certaines étiquettes en y_true n'apparaissent pas dans y_pred. Plus précisément dans ce cas, le label " 2 " n'est jamais prédit:

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

Cela signifie qu'il n'y a pas de F-score à calculer pour cette étiquette, et donc le F-score pour ce cas est considéré comme 0.0. Depuis que vous avez demandé une moyenne de la partition, vous devez prendre en compte qu'un score de 0 a été inclus dans le calcul, et c'est pourquoi scikit-learn est de vous montrer que d'avertissement.

Ce qui m'amène à vous de ne pas voir l'erreur une deuxième fois. Comme je l'ai mentionné, c'est un avertissement, qui est traitée différemment d'une erreur dans python. Le comportement par défaut dans la plupart des environnements est de montrer un avertissement spécifique qu'une seule fois. Ce comportement peut être changé:

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

Si vous définissez cette avant d'importer les autres modules, vous verrez l'avertissement à chaque fois que vous exécutez le code.

Il n'y a aucun moyen d'éviter de voir cet avertissement la première fois, à part pour le paramètre warnings.filterwarnings('ignore'). Ce que vous pouvez faire, c'est décider que vous n'êtes pas intéressé dans les scores des étiquettes que l'on n'avait pas prévu, puis de spécifier explicitement les étiquettes que vous êtes intéressé (qui sont des étiquettes qui ont été prédits au moins une fois):

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

L'avertissement n'est pas indiqué dans ce cas.

3voto

normanius Points 118

La réponse acceptée explique déjà bien pourquoi l'avertissement se produit. Si vous souhaitez simplement contrôler les avertissements, vous pouvez utiliser precision_recall_fscore_support . Il offre un argument (semi-officiel) warn_for qui pourrait être utilisé pour couper les avertissements.

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

Comme mentionné dans certains commentaires, utilisez-le avec précaution.

-1voto

Tw UxTLi51Nus Points 852

Comme le message d'erreur indique, la méthode utilisée pour obtenir la F score est de la "Classification" de sklearn - ainsi, le parler des "étiquettes".

Avez-vous un problème de régression? Sklearn fournit un "F score de la méthode de régression en vertu de la fonction "sélection de groupe": http://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.f_regression.html

Dans le cas où vous avez un problème de classement, @Shovalt la réponse semble correct pour moi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X