web-dev-qa-db-fra.com

Résultat différent avec roc_auc_score () et auc ()

J'ai du mal à comprendre la différence (s'il y en a une) entre roc_auc_score() et auc() dans scikit-learn.

Im liant pour prédire une sortie binaire avec des classes déséquilibrées (environ 1,5% pour Y = 1).

Classificateur

model_logit = LogisticRegression(class_weight='auto')
model_logit.fit(X_train_ridge, Y_train)

Courbe Roc

false_positive_rate, true_positive_rate, thresholds = roc_curve(Y_test, clf.predict_proba(xtest)[:,1])

AUC

auc(false_positive_rate, true_positive_rate)
Out[490]: 0.82338034042531527

et

roc_auc_score(Y_test, clf.predict(xtest))
Out[493]: 0.75944737191205602

Quelqu'un peut expliquer cette différence? Je pensais que les deux calculaient simplement l'aire sous la courbe ROC. Peut-être à cause de l'ensemble de données déséquilibré mais je n'ai pas pu comprendre pourquoi.

Merci!

34
gowithefloww

L'ASC n'est pas toujours l'aire sous la courbe d'une courbe ROC. Area Under the Curve est une zone (abstraite) sous certains courbe, c'est donc une chose plus générale que AUROC. Avec des classes déséquilibrées, il peut être préférable de trouver AUC pour une courbe de rappel de précision.

Voir la source sklearn pour roc_auc_score:

def roc_auc_score(y_true, y_score, average="macro", sample_weight=None):
    # <...> docstring <...>
    def _binary_roc_auc_score(y_true, y_score, sample_weight=None):
            # <...> bla-bla <...>

            fpr, tpr, tresholds = roc_curve(y_true, y_score,
                                            sample_weight=sample_weight)
            return auc(fpr, tpr, reorder=True)

    return _average_binary_score(
        _binary_roc_auc_score, y_true, y_score, average,
        sample_weight=sample_weight) 

Comme vous pouvez le voir, cela obtient d'abord une courbe roc, puis appelle auc() pour obtenir l'aire.

Je suppose que votre problème est l'appel à predict_proba(). Pour une predict() normale, les sorties sont toujours les mêmes:

import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve, auc, roc_auc_score

est = LogisticRegression(class_weight='auto')
X = np.random.Rand(10, 2)
y = np.random.randint(2, size=10)
est.fit(X, y)

false_positive_rate, true_positive_rate, thresholds = roc_curve(y, est.predict(X))
print auc(false_positive_rate, true_positive_rate)
# 0.857142857143
print roc_auc_score(y, est.predict(X))
# 0.857142857143

Si vous modifiez ce qui précède pour cela, vous obtiendrez parfois des sorties différentes:

false_positive_rate, true_positive_rate, thresholds = roc_curve(y, est.predict_proba(X)[:,1])
# may differ
print auc(false_positive_rate, true_positive_rate)
print roc_auc_score(y, est.predict(X))
29
oopcode

predict ne renvoie qu'une classe ou l'autre. Ensuite, vous calculez un ROC avec les résultats de predict sur un classificateur, il n'y a que trois seuils (tester toutes les classes, trivial toutes les autres classes, et entre les deux). Votre courbe ROC ressemble à ceci:

      ..............................
      |
      |
      |
......|
|
|
|
|
|
|
|
|
|
|
|

Pendant ce temps, predict_proba() renvoie une gamme complète de probabilités, vous pouvez donc maintenant mettre plus de trois seuils sur vos données.

             .......................
             |
             |
             |
          ...|
          |
          |
     .....|
     |
     |
 ....|
.|
|
|
|
|

D'où différents domaines.

15
Andreus

Lorsque vous utilisez le y_pred (étiquettes de classe), vous avez déjà décidé du seuil. Lorsque vous utilisez y_prob (probabilité de classe positive), vous êtes ouvert au seuil, et la courbe ROC devrait vous aider à décider du seuil.

Pour le premier cas, vous utilisez les probabilités:

y_probs = clf.predict_proba(xtest)[:,1]
fp_rate, tp_rate, thresholds = roc_curve(y_true, y_probs)
auc(fp_rate, tp_rate)

Lorsque vous faites cela, vous envisagez l'AUC "avant" de prendre une décision sur le seuil que vous utiliserez.

Dans le deuxième cas, vous utilisez la prédiction (et non les probabilités), dans ce cas, utilisez "prédire" au lieu de "prédire_proba" pour les deux et vous devriez obtenir le même résultat.

y_pred = clf.predict(xtest)
fp_rate, tp_rate, thresholds = roc_curve(y_true, y_pred)
print auc(fp_rate, tp_rate)
# 0.857142857143

print roc_auc_score(y, y_pred)
# 0.857142857143
8
Dayvid Oliveira