Praxiseinstieg Machine Learning mit Scikit-Learn, Keras und TensorFlow. Aurélien Géron

Praxiseinstieg Machine Learning mit Scikit-Learn, Keras und TensorFlow - Aurélien Géron


Скачать книгу
Klassifikator hat eine ROC AUC von genau 1, ein völlig zufälliger dagegen hat eine ROC AUC von 0,5. In Scikit-Learn gibt es eine Funktion zum Berechnen der ROC AUC:

      >>> from sklearn.metrics import roc_auc_score

      >>> roc_auc_score(y_train_5, y_scores)

      0.9611778893101814

image Da die ROC-Kurve der Relevanz-Sensitivitäts-Kurve (oder auch PR-Kurve, engl. Precision/Recall) recht ähnlich ist, fragen Sie sich vielleicht, welche Sie denn nun benutzen sollen. Als Faustregel sollten Sie die PR-Kurve immer dann bevorzugen, wenn die positive Kategorie selten ist oder wenn die falsch Positiven wichtiger als die falsch Negativen sind. Andernfalls verwenden Sie die ROC-Kurve. Beim Betrachten der obigen ROC-Kurve (und des ROC-AUC-Scores) könnten Sie denken, dass der Klassifikator wirklich gut ist. Aber das liegt vor allem daran, dass es nur wenige Positive (5en) im Vergleich zu den Negativen (Nicht-5en) gibt. Die PR-Kurve dagegen macht deutlich, dass unser Klassifikator noch Luft nach oben hat (die Kurve sollte näher an der oberen linken Ecke liegen).

      Trainieren wir nun einen RandomForestClassifier und vergleichen wir dessen ROC-Kurve und ROC-AUC-Score mit dem SGDClassifier. Zunächst benötigen wir die Scores für jeden Datenpunkt im Trainingsdatensatz. Allerdings besitzt der RandomForestClassifier aufgrund seiner Funktionsweise (siehe Kapitel 7) keine Methode decision_function(). Stattdessen besitzt er die Methode predict_proba(). Klassifikatoren in Scikit-Learn haben im Allgemeinen die eine oder die andere – oder beide. Die Methode predict_proba() liefert ein Array mit einer Zeile pro Datenpunkt und einer Spalte pro Kategorie. Es enthält die Wahrscheinlichkeit, dass ein bestimmter Datenpunkt einer bestimmten Kategorie angehört (z.B. eine 70%ige Chance, dass das Bild eine 5 darstellt):

      from sklearn.ensemble import RandomForestClassifier

      forest_clf = RandomForestClassifier(random_state=42)

      y_probas_forest = cross_val_predict(forest_clf, X_train, y_train_5, cv=3,

      method="predict_proba")

      Die Funktion roc_curve() erwartet Labels und Scores, aber statt Scores können Sie ihr auch Wahrscheinlichkeiten von Kategorien mitgeben. Nutzen wir die Wahrscheinlichkeit der positiven Kategorie als Score:

      y_scores_forest = y_probas_forest[:, 1] # score = Wahrscheinlichkeit

      # der positiven Kategorie

      fpr_forest, tpr_forest, thresholds_forest = roc_curve(y_train_5,y_scores_forest)

      Nun sind Sie so weit, die ROC-Kurve zu plotten. Dabei ist es hilfreich, zum Vergleich auch die erste ROC-Kurve zu plotten (siehe Abbildung 3-7):

      plt.plot(fpr, tpr, "b:", label="SGD")

      plot_roc_curve(fpr_forest, tpr_forest, "Random Forest")

      plt.legend(loc="lower right")

      plt.show()

      Wie in Abbildung 3-7 gezeigt, sieht die Kurve für den RandomForestClassifier viel besser aus als die für den SGDClassifier: Sie kommt deutlich näher an die linke obere Ecke heran. Dementsprechend ist auch der ROC-AUC-Score deutlich besser:

      >>> roc_auc_score(y_train_5, y_scores_forest)

      0.9983436731328145

      Versuchen Sie, Relevanz und Sensitivität zu berechnen: Sie sollten eine Relevanz von 99,0% und eine Sensitivität von 86,6% erhalten. Gar nicht schlecht!

      Sie wissen nun hoffentlich, wie Sie binäre Klassifikatoren trainieren, ein für Ihre Aufgabe geeignetes Qualitätsmaß auswählen, Ihre Klassifikatoren mithilfe einer Kreuzvalidierung auswerten, einen Ihren Anforderungen entsprechenden Kompromiss zwischen Relevanz und Sensitivität finden und unterschiedliche Modelle über ROC-Kurven und ROC-AUC-Scores vergleichen können. Versuchen wir als Nächstes, mehr als nur die 5en zu erkennen.

      Abbildung 3-7: Vergleich zweier ROC-Kurven: Der Random-Forest-Klassifikator ist besser als der SGD-Klassifikator, weil dessen ROC-Kurve viel näher an der oberen linken Ecke ist und eine größere AUC besitzt.

       Klassifikatoren mit mehreren Kategorien

      Während binäre Klassifikatoren zwischen zwei Kategorien unterscheiden, können Klassifikatoren mit mehreren Kategorien (auch multinomiale Klassifikatoren genannt) mehr als zwei Kategorien unterscheiden.

      Einige Algorithmen (wie SGD-Klassifikatoren, Random-Forest-Klassifikatoren oder naive Bayes-Klassifikatoren) sind in der Lage, direkt mehrere Kategorien zu berücksichtigen. Andere (wie logistische Regression oder Support-Vector-Machine-Klassifikatoren) sind stets binäre Klassifikatoren. Es gibt jedoch einige Strategien, mit denen sich mit mehreren binären Klassifikatoren mehrere Kategorien zuordnen lassen.

      Sie könnten beispielsweise ein System zum Einteilen der Bilder von Ziffern in zehn Kategorien (von 0 bis 9) entwickeln, indem Sie zehn binäre Klassifikatoren trainieren, einen für jede Ziffer (also einen 0-Detektor, einen 1-Detektor, einen 2-Detektor und so weiter). Wenn Sie anschließend ein Bild klassifizieren möchten, ermitteln Sie für jeden dieser Klassifikatoren den Entscheidungsscore und wählen die Kategorie aus, deren Klassifikator den höchsten Score lieferte. Dies bezeichnet man als One-versus-the-Rest-(OvR-)Strategie (oder One-versus-All).

      Eine weitere Strategie ist, einen binären Klassifikator pro Zahlenpaar zu trainieren: einen zum Unterscheiden von 0 und 1, einen weiteren zum Unterscheiden von 0 und 2, einen für 1 und 2 und so weiter. Dies bezeichnet man als One-versus-One-(OvO-)Strategie. Wenn es N Kategorien gibt, müssen Sie N × (N – 1) / 2 Klassifikatoren trainieren. Bei der MNIST-Aufgabe müsste man also 45 binäre Klassifikatoren trainieren! Wenn Sie ein Bild klassifizieren möchten, müssten Sie das Bild alle 45 Klassifikatoren durchlaufen lassen und prüfen, welche Kategorie am häufigsten vorkommt. Der Hauptvorteil von OvO ist, dass jeder Klassifikator nur auf dem Teil der Trainingsdaten mit den beiden zu unterscheidenden Kategorien trainiert werden muss.

      Einige Algorithmen (wie Support-Vector-Machine-Klassifikatoren) skalieren schlecht mit der Größe des Trainingsdatensatzes. Bei diesen ist also OvO zu bevorzugen, weil sich viele Klassifikatoren mit kleinen Trainingsdatensätzen schneller trainieren lassen als wenige Klassifikatoren auf großen Trainingsdatensätzen. Bei den meisten binären Klassifikationsalgorithmen ist jedoch OvR vorzuziehen.

      Scikit-Learn erkennt, wenn Sie einen binären Klassifikationsalgorithmus für eine Aufgabe mit mehreren Kategorien einsetzen, und verwendet abhängig vom Algorithmus automatisch OvR oder OvO. Probieren wir das mit einem SVM-Klassifikator (siehe Kapitel 5) und der Klasse sklearn.svm.SVC:

      >>> from sklearn.svm import SVC

      >>> svm_clf = SVC()

      >>> svm_clf.fit(X_train, y_train) # y_train, nicht y_train_5

      >>> svm_clf.predict([some_digit])

      array([5], dtype=uint8)

      Das war leicht! Der Code trainiert den SVC auf den Trainingsdaten mit den ursprünglichen Zielkategorien von 0 bis 9 (y_train) anstatt mit den Zielkategorien 5-gegen-den-Rest (y_train_5). Anschließend wird eine Vorhersage getroffen (in diesem Fall eine richtige). Im Hintergrund nutzt Scikit-Learn die OvO-Strategie: Es trainiert 45 binäre Klassifikatoren, ermittelt deren Entscheidungswerte für das Bild und wählt die Kategorie aus, die die


Скачать книгу