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