2016-08-18 20 views
8

Szukałem google i widzę post kroczący o tym błędzie. To nie są moje przypadki.sklearn auc ValueError: Tylko jedna klasa obecna w y_true

Używam kerasów do trenowania prostej sieci neuronowej i przygotowania predykcji do podzielonego zestawu danych testowych. Ale kiedy używam roc_auc_score do obliczenia auc, otrzymałem "ValueError: Tylko jedna klasa obecna w y_true. Wynik ROC AUC nie jest zdefiniowany w tym przypadku.".

Sprawdzam dystrybucję etykiet docelowych i są one wysoce niezrównoważone. Niektóre etykiety (w sumie 29 etykiet) mają tylko 1 instancję. Jest więc prawdopodobne, że nie będą mieć żadnej pozytywnej instancji etykiety na etykiecie testowej. Tak więc funkcja roc_auc_score sklearn zgłosiła jedyny problem z jedną klasą. To uzasadnione.

Ale jestem ciekawy, jak gdy używam funkcji sklearn cross_val_score, może obsłużyć obliczenia AUC bez błędu.

my_metric = 'roc_auc' 
scores = cross_validation.cross_val_score(myestimator, data, 
            labels, cv=5,scoring=my_metric) 

Zastanawiam się, co wydarzyło się w cross_val_score, czy to dlatego, że cross_val_score użyć warstwowy podział poprzeczny sprawdzania poprawności danych?

== == AKTUALIZACJA
I nadal zarobić trochę kopania, ale wciąż nie może znaleźć różnicę behind.I zobaczyć, że wezwanie cross_val_score check_scoring(estimator, scoring=None, allow_none=False) zwrócić strzelców, a check_scoring wezwie get_scorer(scoring) który powróci scorer=SCORERS[scoring]

A SCORERS['roc_auc'] jest roc_auc_scorer;
roc_auc_scorer dokonuje

roc_auc_scorer = make_scorer(roc_auc_score, greater_is_better=True, 
           needs_threshold=True) 

So, nadal używa funkcji roc_auc_score. Nie rozumiem dlaczego cross_val_score zachowuje się inaczej przy bezpośrednim wywoływaniu roc_auc_score.

+0

co jest 'my_metric'? – maxymoo

+0

@maxymoo Używam łańcucha 'roc_auc', jest to poprawna wartość. –

+0

Jeśli wykonujesz krzyżową walidację i masz za mało jednego rodzaju etykiety, niektóre fałdy mogą być pozbawione takich etykiet. Spróbuj zmniejszyć liczbę zagięć i upewnij się, że używasz warstwowego próbkowania. – Kris

Odpowiedz

3

Myślę, że twoje przeczucie jest prawidłowe. AUC (obszar pod krzywą ROC) potrzebuje wystarczającej liczby obu klas, aby mieć sens.

Domyślnie cross_val_score oblicza metrykę wydajności po każdym zagięciu osobno. Inną opcją może być wykonanie cross_val_predict i obliczenie AUC dla wszystkich złożonych kombinacji.

Można zrobić coś takiego:

from sklearn.metrics import roc_auc_score 
from sklearn.cross_validation import cross_val_predict 
from sklearn.linear_model import LogisticRegression 
from sklearn.datasets import make_classification 


class ProbaEstimator(LogisticRegression): 
    """ 
    This little hack needed, because `cross_val_predict` 
    uses `estimator.predict(X)` internally. 

    Replace `LogisticRegression` with whatever classifier you like. 

    """ 
    def predict(self, X): 
     return super(self.__class__, self).predict_proba(X)[:, 1] 


# some example data 
X, y = make_classification() 

# define your estimator 
estimator = ProbaEstimator() 

# get predictions 
pred = cross_val_predict(estimator, X, y, cv=5) 

# compute AUC score 
roc_auc_score(y, pred) 
Powiązane problemy