Praxiseinstieg Machine Learning mit Scikit-Learn, Keras und TensorFlow. Aurélien Géron. Читать онлайн. Newlib. NEWLIB.NET

Автор: Aurélien Géron
Издательство: Bookwire
Серия:
Жанр произведения: Математика
Год издания: 0
isbn: 9783960103400
Скачать книгу
image Statt einen Transformer zu verwenden, können Sie den String "drop" angeben, wenn Spalten zu verwerfen sind, oder "pass through", wenn die Spalten unverändert belassen werden sollen. Standardmäßig werden die verbleibenden Spalten (also die nicht aufgeführten) verworfen, aber Sie können den Hyperparameter remainder auf einen beliebigen Transformer setzen (oder auf "passthrough"), wenn sie anders behandelt werden sollen.

      Setzen Sie Scikit-Learn 0.19 oder älter ein, können Sie eine Third-Party-Bibliothek wie sklearn-pandas verwenden oder Ihren eigenen Transformer bauen, um die gleiche Funktionalität zu erhalten, wie sie der ColumnTransformer bietet. Alternativ nutzen Sie die Klasse FeatureUnion, die unterschiedliche Transformer anwenden und deren Ergebnisse verbinden kann. Aber Sie können nicht für jeden Transformer verschiedene Spalten angeben – sie werden alle auf die gesamten Daten angewendet. Es ist möglich, diese Beschränkung zu umgehen, indem Sie einen eigenen Transformer für die Spaltenauswahl nutzen (siehe dazu das Jupyter-Notebook).

       Wähle ein Modell aus und trainiere es

      Endlich! Sie haben Ihre Aufgabe abgesteckt, die Daten erhalten und untersucht, Sie haben einen Trainings- und einen Testdatensatz erstellt, und Sie haben Pipelines zur Transformation geschrieben, um Ihre Daten automatisiert aufzuräumen und auf Machinbe-Learning-Algorithmen vorzubereiten. Nun sind Sie bereit, ein Machine-Learning-Modell auszuwählen und zu trainieren.

       Trainieren und Auswerten auf dem Trainingsdatensatz

      Die gute Nachricht ist, dass es dank der vorherigen Schritte nun wesentlich einfacher wird, als Sie vielleicht denken. Wir trainieren zuerst ein lineares Regressionsmodell wie im vorigen Kapitel:

      from sklearn.linear_model import LinearRegression

      lin_reg = LinearRegression()

      lin_reg.fit(housing_prepared, housing_labels)

      Fertig! Sie haben nun ein funktionsfähiges lineares Regressionsmodell. Probieren wir es mit einigen Datenpunkten aus dem Trainingsdatensatz aus:

      >>> some_data = housing.iloc[:5]

      >>> some_labels = housing_labels.iloc[:5]

      >>> some_data_prepared = full_pipeline.transform(some_data)

      >>> print("Vorhersagen:", lin_reg.predict(some_data_prepared))

      Vorhersagen: [ 210644.6045 317768.8069 210956.4333 59218.9888 189747.5584]

      >>> print("Labels:", list(some_labels))

      Labels: [286600.0, 340600.0, 196900.0, 46300.0, 254500.0]

      Es funktioniert, auch wenn die Vorhersagen nicht unbedingt sehr genau sind (z.B. liegt die erste Vorhersage um etwa 40% daneben!). Bestimmen wir den RMSE dieses Regressionsmodells für den gesamten Trainingsdatensatz mithilfe der Funktion mean_squared_error aus Scikit-Learn:

      >>> from sklearn.metrics import mean_squared_error

      >>> housing_predictions = lin_reg.predict(housing_prepared)

      >>> lin_mse = mean_squared_error(housing_labels, housing_predictions)

      >>> lin_rmse = np.sqrt(lin_mse)

      >>> lin_rmse

      68628.19819848922

      In Ordnung, dieser RMSE ist besser als gar nichts, aber bestimmt nicht großartig: Der Wert median_housing_values liegt in den meisten Bezirken zwischen 120.000 und 265.000 USD. Damit ist eine typische Abweichung von 68628 bei der Vorhersage nicht sehr zufriedenstellend. Dies ist ein Beispiel für ein Modell, das die Trainingsdaten underfittet. Das kann bedeuten, dass die Merkmale nicht genügend Information für eine gute Vorhersage liefern oder dass das Modell nicht mächtig genug ist. Wie wir im vorigen Kapitel gesehen haben, sind die wichtigsten Gegenmaßnahmen bei Underfitting die Auswahl eines mächtigeren Modells, das Bereitstellen besserer Merkmale für den Trainingsalgorithmus und das Verringern von Restriktionen im Modell. Dieses Modell ist allerdings nicht regularisiert, und damit fällt die dritte Möglichkeit aus. Sie könnten versuchen, weitere Merkmale hinzuzufügen (beispielsweise den Logarithmus der Bevölkerung). Wir probieren aber erst einmal ein komplexeres Modell aus.

      Wir trainieren nun einen DecisionTreeRegressor. Dies ist ein mächtiges Modell, das komplexe nichtlineare Zusammenhänge in den Daten erfassen kann (Entscheidungsbäume werden im Detail in Kapitel 6 vorgestellt). Der Code dazu sollte Ihnen mittlerweile bekannt vorkommen:

      from sklearn.tree import DecisionTreeRegressor

      tree_reg = DecisionTreeRegressor()

      tree_reg.fit(housing_prepared, housing_labels)

      Das trainierte Modell können wir wieder auf dem Trainingsdatensatz auswerten:

      >>> housing_predictions = tree_reg.predict(housing_prepared)

      >>> tree_mse = mean_squared_error(housing_labels, housing_predictions)

      >>> tree_rmse = np.sqrt(tree_mse)

      >>> tree_rmse

      0.0

      Was bitte!? Überhaupt kein Fehler? Kann dieses Modell wirklich perfekt sein? Natürlich ist es wesentlich wahrscheinlicher, dass das Modell einem immensen Overfitting der Daten zum Opfer gefallen ist. Wie können wir uns dessen sicher sein? Wie wir weiter oben gesehen haben, sollten wir den Testdatensatz nicht anfassen, bis wir ein betriebsbereites Modell haben, dessen Qualität wir zuversichtlich einschätzen. Wir müssen daher einen Teil des Trainingsdatensatzes zum Trainieren verwenden und einen anderen Teil zur Validierung des Modells.

       Bessere Auswertung mittels Kreuzvalidierung

      Wir könnten den Entscheidungsbaum evaluieren, indem wir den Trainingsdatensatz mit der Funktion train_test_split() in einen kleineren Trainingsdatensatz und einen Validierungsdatensatz aufteilen, dann das Modell mit dem kleineren Trainingsdatensatz trainieren und schließlich mit dem Validierungsdatensatz auswerten. Dies macht ein wenig Arbeit, ist aber nicht schwer und funktioniert recht gut.

      Eine hervorragende Alternative dazu ist die in Scikit-Learn eingebaute k-fache Kreuzvalidierung. Der folgende Code spaltet den Trainingsdatensatz zufällig in zehn unterschiedliche Teilmengen, genannt Folds, auf. Anschließend trainiert und evaluiert er den Entscheidungsbaum zehnmal hintereinander, wobei jedes Mal ein anderer Fold zur Evaluierung genutzt wird, während auf den übrigen neun Folds trainiert wird. Das Ergebnis ist ein Array mit zehn Scores aus der Evaluierung:

      from sklearn.model_selection import cross_val_score

      scores = cross_val_score(tree_reg, housing_prepared, housing_labels,

      scoring="neg_mean_squared_error", cv=10)

      tree_rmse_scores = np.sqrt(-scores)

image Die Kreuzvalidierung in Scikit-Learn erwartet eine Nutzenfunktion (größer ist besser) anstelle einer Kostenfunktion (kleiner ist besser). Daher ist die Scoring-Funktion das Gegenteil des MSE (also ein negativer Wert). Deshalb steht im Code der Ausdruck -scores vor dem Berechnen der Quadratwurzel.

      Betrachten wir das Ergebnis:

      >>> def display_scores(scores):

      ...