Pytanie Inny wynik z roc_auc_score () i auc ()


Mam problem ze zrozumieniem różnicy (jeśli taka istnieje) pomiędzy roc_auc_score() i auc() w nauce scikit.

Im wiąże się przewidywanie wyjścia binarnego z klasami niezrównoważonymi (około 1,5% dla Y = 1).

Klasyfikator

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

Krzywa 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

i

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

Ktoś może wyjaśnić tę różnicę? Myślałem, że obaj właśnie obliczają obszar pod krzywą ROC. Być może z powodu niezbilansowanego zbioru danych, ale nie mogłem zrozumieć, dlaczego.

Dzięki!


21
2017-07-01 10:48


pochodzenie




Odpowiedzi:


AUC nie zawsze jest obszarem pod krzywą ROC. Obszar pod krzywą to (abstrakcyjny) obszar pod trochę krzywa, więc jest bardziej ogólna niż AUROC. W przypadku klas niezrównoważonych, może być lepiej znaleźć AUC dla krzywej precyzyjnego przywoływania.

Zobacz źródło sklearn dla 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) 

Jak widać, najpierw otrzymuje krzywą rocową, a następnie wywołuje auc() aby uzyskać obszar.

Domyślam się, że twoim problemem jest predict_proba() połączenie. Dla normalności predict() wyjścia są zawsze takie same:

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

Jeśli zmienisz powyższe, otrzymasz różne wyniki:

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

15
2017-07-01 12:20



Dziękuję za wskazanie wagi krzywej przypominania o precyzji, ale w tym przypadku krzywa to ROC. Pytanie brzmiało: dlaczego uzyskuję dwa różne wyniki od obu metod powinien obliczyć ten sam obszar? - gowithefloww
Dlaczego oni mieliby to robić? Wszystko zależy od tego, w jaki sposób otrzymałeś dane wejściowe auc() funkcjonować. Powiedz, sklearn sugeruje fpr, tpr, thresholds = metrics.roc_curve(y, pred, pos_label=2); metrics.auc(fpr, tpr), a potem to naturalne auc() i roc_auc_score() zwróć ten sam wynik. Ale nie jest jasne, jak się masz false_positive_rate, true_positive_rate ze swojego wpisu. - oopcode
Przy okazji, podoba mi się krzywa ROC właśnie dlatego, że jest niewrażliwa na stopnie wchłonięte (zobacz (fastml.com/what-you-wanted-to-know-about-cu) - gowithefloww
Mój zły, skopiowałem niewłaściwą linię kodu. Teraz jest naprawiony, dziękuję za wskazanie! - gowithefloww
Masz rację. od est.predict(X) wyprowadza jakiś plik binarny, nie ma sensu go używać roc_auc_score(y, est.predict(X)) . Pisanie roc_auc_score(y, est.predict_proba(X)[:,1]) rozwiązuje problem. Dziękuję Ci! - gowithefloww


predict zwraca tylko jedną klasę lub drugą. Następnie obliczasz ROC z wynikami predict na klasyfikatorze są tylko trzy progi (próba cała jedna klasa, trywialna wszystkie inne klasy i pomiędzy). Twoja krzywa ROC wygląda następująco:

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

W międzyczasie, predict_proba() zwraca cały zakres prawdopodobieństw, więc teraz możesz umieścić więcej niż trzy progi na danych.

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

Stąd różne obszary.


9
2017-07-01 18:56





Kiedy używasz y_pred (etykiety klas), już zdecydowałeś próg. Kiedy używasz y_prob (dodatnie prawdopodobieństwo klasy) jesteś otwarty na próg, a ROC Curve powinna pomóc Ty decydujesz o progu.

W pierwszym przypadku używasz prawdopodobieństw:

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

Kiedy to zrobisz, rozważasz wykonanie AUC "przed" decyzja o progu, z którego będziesz korzystać.

W drugim przypadku używasz prognozy (nie prawdopodobieństwa), w takim przypadku użyj "predict" zamiast "predict_proba" zarówno dla ciebie, jak i dla ciebie powinien otrzymać taki sam wynik.

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

4
2018-03-16 20:14



W przypadku użycia predict zamiast predict_proba i, jak powiedziałeś, kończąc na wyborze określonego progu .. w jaki sposób obliczenia roc_auc_score byłoby ? dowolny pomysł ? - Ophilia
@Ophilia, tylko z dokumentów scikit-learn.org/stable/modules/generated/...  roc_auc_score(y_true, y_score...), gdzie y_score - "Wyniki docelowe, mogą być szacunkami prawdopodobieństwa klasy pozytywnej, wartościami ufności, lub bez progów miara decyzji ". Tak samo będzie z obliczeniem AUC predict_proba() - Arnold Klein