1.5 Porównywanie klasyfikatorów

Realizując badania rozpoznawania wzorców niedostatecznym jest prezentowanie jedynie naszych, autorskich rozwiązań, a konieczne jest również umieszczenie ich w kontekście istniejących już metod. W tym celu posługujemy się testowaniem statystycznym, a konkretnie, testami parowymi, pozwalającymi nam określić (nie)zależność statystyczną wyników osiąganych przez różne algorytmy.

Aby zaprezentować sposób poprawnego porównywania klasyfikatorów, stwórzmy listę clfs zawierające dwa różne klasyfikatory k-NN. Pierwszy z nich będzie operować na jednym, a drugi na pięciu najbliższych sąsiadach.

Atrybuty algorytmów klasyfikacji nazywamy ich hiperparametrami. W związku z tym, poniższe badanie moglibyśmy zatytułować: "Wpływ hiperparametru k na jakość klasyfikacji z wykorzystaniem algorytmu k najbliższych sąsiadów".

from sklearn import neighbors
clfs = [
    neighbors.KNeighborsClassifier(n_neighbors = 1),
    neighbors.KNeighborsClassifier(n_neighbors = 5)
]

W następnym kroku, dla przypomnienia, wczytamy zbiór danych iris, dzieląc go na przestrzeń cech X i zbiór etykiet y.

url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
df = pd.read_csv(url, header=None)
data = df.values
X = data[:,:-1]
y = data[:,-1]

Dalej, dokonamy podziału zbioru z użyciem k-foldowej walidacji krzyżowej, dla k równego 10. Tym razem jednak dodamy pętlę iterującą klasyfikatory z naszej listy algorytmów (for clf in clfs) i zamiast składować tylko jeden wynik dla każdego podziału, będziemy zapisywać wektor dokładności dla każdego z klasyfikatorów.

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

results = []
for train, test in cv.split(X,y):
    X_train, y_train = X[train], y[train]
    X_test, y_test = X[test], y[test]
    result = []
    for clf in clfs:
        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),
        result.append(accuracy[0])
    results.append(result)
results = np.array(results)

print(results)
[[1.         1.        ]
 [0.93333333 0.93333333]
 [1.         1.        ]
 ...
 [1.         1.        ]
 [1.         1.        ]
 [1.         1.        ]]

Stosując powyższe podejście uzyskaliśmy dwuwymiarową tablicę results, której każdy wiersz opisuje dokładności dla zadanego folda, a kolumna, dla zadanego algorytmu klasyfikacji. Co ważne, każdy z algorytmów został przetestowany k razy na tym samym podziale zbioru.

Matematyczną wiedzę o testach statystycznych powinni Państwo wynieść z kursów poświęconych statystyce, więc nie będziemy zagłębiać się w ich matematyczne niuanse. Nauczymy się jedynie, na koniec modułu, w jaki sposób wyliczyć z tablicy results prawdopodobieństwo zależności wyników dla testów:

  • T-studenta,

  • Wilcoxona.

Implementację powyższych testów możemy odnaleźć w module stats pakietu scipy. Zaimportujmy go do skryptu.

from scipy import stats

Testy możemy przeprowadzić, kolejno, funkcjami ttest_ind i wilcoxon, przekazując im w argumentach kolumny tablicy wyników odpowiadające porównywanym przez nas klasyfikatorom.

test_t = stats.ttest_ind(results[:,0],results[:,1])
test_w = stats.wilcoxon(results[:,0],results[:,1])

Wyświetlmy na ekranie średnie dokładności uzyskane przez oba klasyfikatory.

print np.mean(results,axis=0)
[0.96       0.96666667]

Z uzyskanych uśrednień wynikałoby, że k-NN dla k=5 jest odrobinę (ale naprawdę odrobinę) lepszy od k-NN dla k=1. Aby zweryfikować, czy jest to prawda, sprawdźmy p-wartości uzyskanych testów. Przed odczytaniem wyników należy ustalić próg pewności, który z reguły wynosi 95% lub 99%. Bądźmy łaskawi i uznajmy, że 95% wystarczy.

print test_t
print test_w
Ttest_indResult(statistic=-0.2873478855663521, pvalue=0.7771278487505224)
WilcoxonResult(statistic=2.0, pvalue=0.5637028616507731)

Aby wynik dwóch metod był statystycznie niezależny od siebie, przy progu 95%, p-wartość testu powinna być mniejsza lub równa 0.05 (1 - próg). Tak w przypadku testu T-Studenta, jak Wilcoxona, wartość ta jest znacznie wyższa, nie możemy więc uznać któregokolwiek z nich za lepszy od drugiego.

Gratulacje! Właśnie przeprowadziliśmy poprawnie zupełnie nieistotne badania!

Testy parowe, jak sama nazwa wskazuje, służą do porównywania ze sobą jedynie dwóch klasyfikatorów. Zastanów się, proszę, w jaki sposób porównać ze sobą jakość trzech i więcej metod.

Last updated