web-dev-qa-db-fra.com

Comment pénaliser davantage les faux négatifs que les faux positifs

Du point de vue commercial, les faux négatifs entraînent des coûts environ dix fois plus élevés (en argent réel) que les faux positifs. Compte tenu de mes modèles de classification binaire standard (logit, forêt aléatoire, etc.), comment puis-je l'intégrer dans mon modèle?

Dois-je modifier (pondérer) la fonction de perte en faveur de l'erreur "préférée" (FP)? Si oui, comment faire?

10
ivegotaquestion

Il y a plusieurs options pour vous:

  • Comme suggéré dans les commentaires, class_weight Devrait augmenter la fonction de perte vers la classe préférée. Cette option est prise en charge par divers estimateurs, notamment sklearn.linear_model.LogisticRegression , sklearn.svm.SVC , sklearn.ensemble.RandomForestClassifier , et d'autres. Notez qu'il n'y a pas de limite théorique au rapport de poids, donc même si 1 à 100 n'est pas assez fort pour vous, vous pouvez continuer avec 1 à 500, etc.

  • Vous pouvez également sélectionner le seuil de décision très bas lors de la validation croisée pour choisir le modèle qui donne le rappel le plus élevé (bien que probablement de faible précision). Le rappel proche de 1.0 Signifie effectivement false_negatives Proche de 0.0, Ce qui est ce qu'il faut. Pour cela, utilisez les fonctions sklearn.model_selection.cross_val_predict et sklearn.metrics.precision_recall_curve :

    y_scores = cross_val_predict(classifier, x_train, y_train, cv=3,
                                 method="decision_function")
    
    precisions, recalls, thresholds = precision_recall_curve(y_train, y_scores)
    

    Si vous tracez les precisions et recalls contre les thresholds, vous devriez voir l'image comme ceci:

    precision-recall-tradeoff

    Après avoir choisi le meilleur seuil, vous pouvez utiliser les scores bruts de la méthode classifier.decision_function() pour votre classement final.

Enfin, essayez de ne pas sur-optimiser votre classificateur, car vous pouvez facilement vous retrouver avec un classificateur const trivial (ce qui n'est évidemment jamais faux, mais inutile).

12
Maxim

Comme @Maxim l'a mentionné, il y a 2 étapes pour effectuer ce type de réglage: dans l'étape d'apprentissage du modèle (comme les poids personnalisés) et l'étape de prédiction (comme l'abaissement du seuil de décision).

Un autre réglage pour l'étape de formation du modèle est en utilisant un marqueur de rappel . vous pouvez l'utiliser dans votre validation croisée de recherche de grille ( GridSearchCV ) pour régler votre classificateur avec le meilleur hyper-param vers un rappel élevé.

Le paramètre de notation GridSearchCV peut accepter la chaîne 'rappel' ou la fonction rappel_score .

Puisque vous utilisez une classification binaire, les deux options devraient fonctionner dès le départ et appeler rappel_score avec ses valeurs par défaut qui conviennent à une classification binaire:

  • moyenne: `` binaire '' (c'est-à-dire une valeur de rappel simple)
  • pos_label: 1 (comme la valeur vraie de numpy)

Si vous avez besoin de le personnaliser, vous pouvez envelopper un marqueur existant, ou un personnalisé, avec make_scorer , et le transmettre au paramètre de notation .

Par exemple:

from sklearn.metrics import recall_score, make_scorer

recall_custom_scorer = make_scorer(
    lambda y, y_pred, **kwargs: recall_score(y, y_pred, pos_label='yes')[1]
)

GridSearchCV(estimator=est, param_grid=param_grid, scoring=recall_custom_scorer, ...)
1
mork