Abbildung 2-3: Ihre Arbeitsumgebung in Jupyter
Ein Notebook besteht aus einer Abfolge von Zellen. Jede Zelle kann ausführbaren Code oder formatierten Text enthalten. Im Moment enthält das Notebook nur eine leere Codezelle mit dem Label In [1]:. Schreiben Sie in die Zelle print("Hello world!")
Abbildung 2-4: Python-Notebook mit Hello-World-Befehl
Die Daten herunterladen
In einer typischen Arbeitsumgebung wären Ihre Daten in einer relationalen Datenbank (oder einem anderen Datenspeicher) und über viele Tabellen, Dokumente oder Dateien verteilt. Um auf sie zuzugreifen, müssten Sie zuerst Zugriffsrechte und Passwörter erhalten10 und sich mit dem Datenmodell vertraut machen. In diesem Projekt sind die Dinge jedoch deutlich einfacher: Sie laden housing.tgz herunter, eine einzelne komprimierte Datei, in der sämtliche Daten als kommaseparierte Datei (CSV) namens housing.csv vorliegen.
Sie könnten Ihren Browser zum Herunterladen nutzen und anschließend tar xzf housing.tgz zum Entpacken und Extrahieren der CSV-Datei eingeben, es ist aber besser, dazu eine kleine Funktion zu schreiben. Eine solche Funktion ist besonders dann nützlich, wenn sich die Daten regelmäßig ändern, weil Sie so die jeweils neuesten Daten mit einem selbst geschriebenen Skript herunterladen können (Sie könnten dieses automatisch in regelmäßigen Abständen ausführen lassen). Den Prozess der Datenbeschaffung zu automatisieren, hilft außerdem, wenn Sie den Datensatz auf mehreren Maschinen installieren möchten.
Mit der folgenden Funktion können Sie die Daten herunterladen:11
import os
import tarfile
import urllib
DOWNLOAD_ROOT = "https://raw.githubusercontent.com/ageron/handson-ml2/master/"
HOUSING_PATH = os.path.join("datasets", "housing")
HOUSING_URL = DOWNLOAD_ROOT + "datasets/housing/housing.tgz"
def fetch_housing_data(housing_url=HOUSING_URL, housing_path=HOUSING_PATH):
os.makedirs(housing_path, exist_ok=True)
tgz_path = os.path.join(housing_path, "housing.tgz")
urllib.request.urlretrieve(housing_url, tgz_path)
housing_tgz = tarfile.open(tgz_path)
housing_tgz.extractall(path=housing_path)
housing_tgz.close()
Wenn Sie nun fetch_housing_data() aufrufen, wird das Verzeichnis datasets/housing in Ihrer Arbeitsumgebung erstellt, die Datei housing.tgz wird heruntergeladen, und die Datei housing.csv wird in dieses Verzeichnis entpackt.
Nun laden Sie die Daten mit pandas. Auch diesmal sollten Sie eine kleine Funktion zum Laden der Daten schreiben:
import pandas as pd
def load_housing_data(housing_path=HOUSING_PATH):
csv_path = os.path.join(housing_path, "housing.csv")
return pd.read_csv(csv_path)
Diese Funktion liefert ein pandas-DataFrame-Objekt mit sämtlichen Daten.
Wirf einen kurzen Blick auf die Datenstruktur
Schauen wir uns die ersten fünf Zeilen des DataFrames mit der Methode head() an (siehe Abbildung 2-5).
Abbildung 2-5: Die ersten fünf Zeilen im Datensatz
Jede Zeile steht für einen Bezirk. Es gibt zehn Merkmale (Sie können die ersten sechs im Screenshot sehen): longitude, latitude, housing_median_age, total_rooms, total_bedrooms, population, households, median_income, median_house_value und ocean_proximity.
Die Methode info() hilft, schnell eine Beschreibung der Daten zu erhalten. Dies sind insbesondere die Anzahl der Zeilen, der Typ jedes Attributs und die Anzahl der Werte ungleich null (siehe Abbildung 2-6).
Abbildung 2-6: Informationen zu Immobilien
Im Datensatz gibt es 20.640 Datenpunkte. Damit ist er für Machine-Learning-Verhältnisse eher klein, für den Anfang ist das aber ausgezeichnet! Beachten Sie, dass das Merkmal total_bedrooms nur 20.433 Werte ungleich null hat, es gibt also 207 Bezirke ohne diese Angabe. Darum werden wir uns später kümmern müssen.
Bis auf das Feld ocean_proximity sind sämtliche Merkmale numerisch. Dessen Typ ist object, und es könnte beliebige Python-Objekte enthalten. Da Sie aber diese Daten aus einer CSV-Datei geladen haben, muss es sich dabei natürlich um Text handeln. Beim Betrachten der ersten fünf Zeilen haben Sie möglicherweise bemerkt, dass sich die Werte in der Spalte ocean_proximity wiederholen. Es handelt sich dabei also um ein kategorisches Merkmal. Sie können mit der Methode value_counts() herausfinden, welche Kategorien es gibt und wie viele Bezirke zu jeder Kategorie gehören:
>>> housing["ocean_proximity"].value_counts()
<1H OCEAN 9136
INLAND 6551
NEAR OCEAN 2658
NEAR BAY 2290
ISLAND 5
Name: ocean_proximity, dtype: int64
Betrachten wir auch die anderen Spalten. Die Methode describe() fasst die numerischen Merkmale zusammen (siehe Abbildung 2-7).
Abbildung 2-7: Zusammenfassung aller numerischen Merkmalen
Die Zeilen count, mean, min und max sind selbsterklärend. Beachten Sie, dass die leeren Werte ignoriert werden (z.B. beträgt count bei total_bedrooms 20433, nicht 20640). Die Zeile std enthält die Standardabweichung, die die Streuung der Werte angibt.12 Die Zeilen mit 25%, 50% und 75% zeigen die entsprechenden Perzentile: Ein Perzentil besagt, dass ein bestimmter prozentualer Anteil der Beobachtungen unterhalb eines Werts liegt. Beispielsweise haben 25% der Bezirke ein housing_median_age unter 18, 50% liegen