1.4 Miary oceny jakości klasyfikacji

Narzędzia do oceny jakości (czy też ewaluacji) klasyfikacji znajdują się w module metrics pakietu sklearn. Zaimportujmy go do skryptu.

from sklearn import metrics

Po poprawnym przeprowadzeniu klasyfikacji na zbiorze testowym uzyskaliśmy wektor predykcji (prediction). Na etapie podziału, od tego samego zbioru, oddzieliliśmy również wektor oryginalnych etykiet (y_test).

Dla oryginalnego zbioru etykiet czasami stosuje się również nazwę ground truth. Nie w każdym przypadku jest to poprawne określenie, ale jego stosowanie nie jest naganne. A zawsze brzmi niemal jak byśmy wiedzieli o czym mówimy.

Ocena jakości klasyfikacji polega na odpowiednim porównaniu ze sobą tych dwóch wektorów. Podstatowym narzędziem takiej oceny jest tak zwana macierz pomyłek (confussion matrics). Wyliczmy ją dla naszej pary porównawczej.

confusion_matrix = metrics.confusion_matrix(y_test, prediction)
print(confusion_matrix)
[[16  0  0]
 [ 0 18  1]
 [ 0  0 15]]

Dane zapisane po przekątnej macierzy pomyłek (tej, w której indeks wiersza i kolumny jest równy) informują o wzorcach poprawnie przypisanych do swoich klas. Pozostałe komórki macierzy oznaczają poszczególne błędy przypisania.

Najprostszą i jednocześnie najbardziej powszechnie stosowaną miarą jakości klasyfikacji (do której na tę chwilę się ograniczymy) jest jej dokładność, czyli stosunek sumy wartości znajdujących się na przekątnej macierzy pomyłek do sumy wszystkich wartości macierzy. Możemy uzyskać ją używając funkcji accuracy_score().

accuracy = metrics.accuracy_score(y_test, prediction)
print accuracy
0.98

Zgodnie z literaturą, miarą bardziej poprawną od jakości klasyfikacji, jest jej błąd. Wynosi on dokładnie 1 - dokładność.

W większości eksperymentów nie będziemy stosować prostego podziału zbioru, a k-foldowej walidacji krzyżowej. W takim wypadku uzyskamy k wartości wybranej przez nas miary jakości. Dokonując pomiarów, na poczet późniejszych testów statystycznych powinniśmy zapisywać wszystkie k wyliczonych miar.

Deklarujemy parametr k, przyjmując dla niego wartość 10 podziałów. Inicjalizujemy obiekt podziału w zmiennej cv. Inicjalizujemy pustą listę accuracies, w której będziemy składować kolejne wyliczone dokładności. Następnie iterujemy obiekt podziału, przy każdej pętli uzyskując krotkę (train,test). Musimy pamiętać, że zwraca ona nie podzielone obiekty, a jedynie ich indeksy. W związku z tym do kolejnych zmiennych przypisujemy już odpowiednie podzbiory tablic X i y. Po podziale uczymy klasyfikator (fit), wyliczamy wektory wsparć (predict_proba), wyliczamy i tłumaczymy predykcję i wyliczamy dokładność (accuracy). Na koniec, na koniec listy accuracies dodajemy wyliczoną dokładność. Serwować podgrzane.

k = 10
cv = model_selection.StratifiedKFold(n_splits=k)

accuracies = []
for train, test in cv.split(X, y):
    X_train, y_train = X[train], y[train]
    X_test, y_test = X[test], y[test]

    clf.fit(X_train, y_train)
    probas = clf.predict_proba(X_test)
    prediction = np.argmax(probas,axis = 1)
    prediction = clf.classes_[prediction]
    accuracy = metrics.accuracy_score(y_test, prediction)
    accuracies.append(accuracy)

print accuracies
[1.0, 0.9333333333333333, 1.0, 1.0, 0.8666666666666667, 0.9333333333333333, 0.9333333333333333, 1.0, 1.0, 1.0]

Podając wynik klasyfikacji, nie chwalimy się całym wektorem dokładności, a prezentujemy jego uśrednioną dokładność i jej odchylenie standardowe.

mean_accuracy = np.mean(accuracies)
std_accuracy = np.std(accuracies)
print "Średnia dokładność %.3f (+- %.2f)" % (mean_accuracy, std_accuracy)
Średnia dokładność 0.967 (+- 0.04)

Last updated