Um einen Klassifikator zu bewerten, muss man ihn in einer Reihe von Fällen anwenden, bei denen man zumindest im Nachhinein Kenntnis über die „wahre“ Klasse der jeweiligen Objekte hat.
Ein Beispiel für so einen Fall ist ein medizinischer Labortest, mit dem festgestellt werden soll, ob eine Person eine bestimmte Krankheit hat. Später wird durch aufwändigere Untersuchungen festgestellt, ob die Person tatsächlich an dieser Krankheit leidet. Der Test stellt einen Klassifikator dar, der die Personen in die Kategorien „krank“ und „gesund“ einordnet. Da es sich um eine Ja/Nein-Frage handelt, sagt man auch, der Test fällt positiv (Einordnung „krank“) oder negativ (Einordnung „gesund“) aus. Um zu beurteilen, wie gut geeignet der Labortest für die Diagnose der Krankheit ist, wird nun bei jedem Patienten dessen tatsächlicher Gesundheitszustand mit dem Ergebnis des Tests verglichen. Dabei können vier mögliche Fälle auftreten:
Richtig positiv: Der Patient ist krank, und der Test hat dies richtig angezeigt.
Falsch negativ: Der Patient ist krank, aber der Test hat ihn fälschlicherweise als gesund eingestuft.
Falsch positiv: Der Patient ist gesund, aber der Test hat ihn fälschlicherweise als krank eingestuft.
Richtig negativ: Der Patient ist gesund, und der Test hat dies richtig angezeigt.
Im ersten und letzten Fall war die Diagnose also richtig, in den anderen beiden Fällen liegt ein Fehler vor. Die vier Fälle werden in verschiedenen Kontexten auch anders benannt. So sind auch die englischen Begriffe true positive, false positive, false negative und true negative gebräuchlich.
Es wird nun gezählt, wie häufig jede der vier möglichen Kombinationen von Testergebnis (ermittelte Klasse) und Gesundheitszustand (tatsächliche Klasse) vorgekommen ist. Diese Häufigkeiten werden in eine sogenannte Wahrheitsmatrix (auch Konfusionsmatrix genannt) eingetragen:
Wir können auch noch die Confusion Matrix (Wahrheitsmatrix) bestimmen. Mithilfe dieser, sehen wir, wie häufig unser Classifier einen Fehler gemacht hat.
cm = confusion_matrix(y_test, y_pred)
cm
Überprüfe bei Deiner Implementation, wie viele Fehler dein Classifier gemacht hat für k = 5.
Gibt es Unterschiede zwischen deiner Implementation und der von scratch?
Was bedeutet die Confusion Matrix?
By definition a confusion matrix C is such that Ci,j is equal to the number of observations known to be in group i and predicted to be in group j
confusion matrix scratch for k = 5
[[12 0 0]
[ 0 6 2]
[ 0 0 10]]
confusion matrix sklearn for k = 5
[[12 0 0]
[ 0 6 2]
[ 0 0 10]]
Confusion Matrix ist dieselbe.
d.h. 12 Observationen sind Gruppe 1 und wurden auch als Gruppe 1 predicted oder 6 Observationen sind Gruppe 2 und wurden auch korrekt predicted (als Gruppe 2). Jedoch haben wir 2 misclassifications - dort haben wir eine prediction für Gruppe 3, aber tatsächlich waren sie in Gruppe 2.
Cross Validation (Kreuzvalidierung) ist ein Verfahren, um zu prüfen, wie gut die Vorhersagekraft eines statistischen Modells ist. Dabei wird der erwartete Vorhersage-Fehler geschätzt und untereinander verglichen.
D.h. Um mit Sicherheit sagen zu können, dass wir eine Genauigkeit von xy% bei zukünftigen ungesehenen Daten erreichen können, muss man dieses Modell mit ungesehenen Daten testen.
Dabei teilen wir unsere Daten in Trainings- und Testdaten auf. Die Trainingsdaten bilden das Fundament unseres Algorithmus. Die Testdaten dienen dazu, zu überprüfen, wie viele Fehler der Algorithmus macht, um damit die Genauigkeit zu überprüfen.
Das Besondere bei diesen Methoden ist, dass keine weiteren Informationen neben den Trainingsdaten des Modells notwendig sind. Das ist häufig von großem Vorteil, wenn z. B. wenig Daten vorhanden sind und deswegen einen Großteil für das Training des Modells aufgewendet wird.
Obwohl es verschiedenste Arten der Kreuzvalidierung gibt, bleibt das Prinzip das Gleiche: die Modelldaten werden in zwei sich gegenseitig ausschließende Mengen aufgeteilt, in eine größere (die Trainingsmenge) und eine kleinere (die Testmenge).
Die größere Datenmenge wird dazu verwendet, ein Modell aufzustellen, während die kleinere Datenmenge dazu dient, das Modell zu bestätigen, indem man das Modell auf die kleinere Datenmenge anwendet und die Ergebnisse mit den tatsächlichen Werten vergleicht.
Dieser Prozess wird mit verschiedenen Untermengen so lange wiederholt, bis jedes Objekt der Datenmenge einmal für die Testmenge verwendet wurde.
Wichtig, man macht die Cross-Validation auf dem train_dataset.
Um unser Modell mittels Kreuzvalidierung zu trainieren und zu testen, verwenden wir die Funktion cross_val_score mit einem Kreuzvalidierungswert von 10. cross_val_score nimmt unser k-NN-Modell und unsere Daten als Parameter auf. Dann werden die Daten in 10 Gruppen aufgeteilt und 10 Mal angepasst und bewertet, wobei die Genauigkeit jedes Mal einem array angefügt wird. Wir speichern die Genauigkeitswerte in der Variablen scores.
Ergänze den Code-Ausschnitt (und implementiere diesen). Was sagen uns jetzt die printed values aus?
import pandas as pd
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
import numpy as np
iris = pd.read_csv('IRIS.csv')
X = iris[["sepal_length", "sepal_width", "petal_length", "petal_width"]].values
y = iris["species"].values
le = LabelEncoder()
y = le.fit_transform(y)
X = StandardScaler().fit_transform(X)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# Instantiate learning model (k = 3)
knn = KNeighborsClassifier(n_neighbors= ❓)
cv_scores = cross_val_score(❓, ❓, ❓, cv=❓) #finde heraus, was Du dieser function alles mitgeben musst
# print each cv score (accuracy) and average them
print(cv_scores)
print('cv_scores mean:{}'.format(np.mean(cv_scores)))
import pandas as pd
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import confusion_matrix, accuracy_score
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
import numpy as np
iris = pd.read_csv('IRIS.csv')
X = iris[["sepal_length", "sepal_width", "petal_length", "petal_width"]].values
y = iris["species"].values
le = LabelEncoder()
y = le.fit_transform(y)
X = StandardScaler().fit_transform(X)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# Instantiate learning model (k = 3)
knn = KNeighborsClassifier(n_neighbors=3)
cv_scores = cross_val_score(knn, X_train, y_train, cv=10)
#print each cv score (accuracy) and average them
print(cv_scores)
print('cv_scores mean:{}'.format(np.mean(cv_scores)))
print(cv_scores)
Das gibt uns die accuracy der verschiedenen folds aus.
print('cv_scores mean:{}'.format(np.mean(cv_scores)))
Bei der Kreuzvalidierung liegt unser Durchschnittswert bei 95.83 %. Das sagt uns aus, dass bei einem ungesehenen Datensatz die Accuracy ca. bei 95% liegt.
Wir wollen nun wiederum graphisch darstellen, wie der mean average für den cross validation score für verschiedene k's aussieht.
Kannst Du das auf Grund des gegebenen Codes implementieren?
#creating list of K for KNN
k_list = list(range(1,50,2))
# creating list of cv scores
accuracies = []
# perform 10-fold cross validation
for k in k_list:
knn = KNeighborsClassifier(n_neighbors=k)
scores = cross_val_score(knn, X_train, y_train, cv=10, scoring='accuracy')
accuracies_crossval.append(scores.mean())
fig, ax = plt.subplots()
ax.plot(k_list, accuracies_crossval)
ax.set(xlabel="Value of k for KNN",
ylabel="Cross-Validated Accuracy (Mean)")
plt.show()
In der Abbildung sieht man dass unser K zwischen 10 und 15 sein muss, bevor die Accuracy sinkt wegen Underfitting. Die beste Accuracy kannst Du auch aus accuracies_crossval auslesen.