Der Fahrplan
Das Notebook folgt den sechs Schritten aus Lab 00 – nur dass es die Schritte 2 bis 5 selbst ausführt und Schritt 6 vorbereitet. Es läuft ohne Installation in Colab, weil alle Pakete (pandas, numpy, matplotlib) dort vorhanden sind; nur für die Datenbankzelle installiert es zwei Pakete nach.
Die Reihenfolge ist zwingend: Abschnitt 4 rechnet mit revenue, das Abschnitt 3 erzeugt; Abschnitt
6 braucht arrival_date, ebenfalls aus Abschnitt 3. Wer eine Zelle überspringt, bekommt einen
KeyError – die Meldung sagt, welche Spalte fehlt, und damit, welche Zelle nicht gelaufen ist.
Deshalb der Rat aus Lab 02: nach dem Öffnen immer Laufzeit → Alle ausführen.
Abschnitte 1 und 2: Laden und sichten
Die erste Codezelle lädt die Datei per URL (Lab 01) und zeigt df.head(). Die zweite und dritte
Zelle sichten: df.info() nennt je Spalte Typ und Zahl der gefüllten Werte,
df.describe() Minimum, Maximum, Mittelwert und Quartile. Hier fallen die Eigenheiten aus Lab 01
zum ersten Mal auf – adr mit Maximum 5.400, children mit 119.386 statt 119.390
Werten.
RangeIndex: 119390 entries, 0 to 119389 1
Data columns (total 32 columns):
# Column Non-Null Count Dtype
0 hotel 119390 non-null str
1 is_canceled 119390 non-null int64 2
…
10 children 119386 non-null float64 3
…
27 adr 119390 non-null float64
dtypes: float64(4), int64(16), str(12)
Nachbildung der Oberfläche, Stand 09/2026 – Beschriftungen wie im Original; Ausgabe gekürzt.
- 1119.390 Zeilen – die Kontrollzahl, die in jedem späteren Artefakt wiederkehrt.
- 2
is_canceledist eine ganze Zahl (0/1). Ihr Mittelwert ist die Stornoquote – deshalb bleibt sie eine Zahl und wird nicht zu Text. - 3Vier fehlende Werte in
children: 119.386 statt 119.390. Die Spalte ist deshalbfloat64, obwohl Kinder ganze Zahlen sind – pandas kann fehlende Werte nur in Dezimalspalten halten.
Abschnitt 3: Bereinigen und ableiten
Zwei Zellen. Die erste füllt Lücken, die zweite erzeugt die Spalten, die für Kennzahlen gebraucht werden. Beide treffen Annahmen, und beide schreiben sie hin. Eine Bereinigung, die nur im Code steht, ist nach drei Monaten eine Zahl, die niemand mehr erklären kann.
Drei Annahmen der Bereinigung
childrenfehlt → 0. Annahme: keine Angabe heißt kein Kind. Betrifft vier Zeilen.countryfehlt →UNK. Annahme: lieber ein sichtbares „unbekannt“ als eine Zeile, die später aus jedem Join fällt. Betrifft 488 Zeilen.agent,company: der Text „NULL“ → echtesNaN. Neuere pandas-Versionen erkennen den Text schon beim Laden; die Zeilen sichern das für andere Quellen ab.
Vier abgeleitete Spalten
arrival_date– aus Jahr, Monatsname und Tag ein echtes Datum; der englische Monatsname wird über ein Wörterbuch zur Zahl.total_nights– Wochenend- plus Wochentagsnächte.total_guests– Erwachsene plus Kinder plus Babys.revenue–adr × total_nights: der Zimmerumsatz einer Buchung, nur Übernachtung. Das ist die Spalte, aus der alle drei Umsatzbegriffe des Projekts entstehen.
Abschnitt 4: Kennzahlen
Eine Zelle rechnet den ganzen Katalog: zehn Kennzahlen über alle Buchungen, gesammelt in einer
pd.Series. Die Definitionen sind dieselben wie später in der Datenbank, in Power BI und im
Dashboard – Lab 06 rechnet sie in SQL nach. Zwei Zeilen unterscheiden sich nur im Filter auf is_canceled: Die Summe von revenue ohne Filter ist der gebuchte Umsatz, mit Filter der stornobereinigte.
| Kennzahl | Zeile im Notebook | Wert |
|---|---|---|
| Anzahl Buchungen | len(df) | 119.390 |
| Stornoquote | df["is_canceled"].mean() * 100 | 37,0 % |
| Ø Vorlaufzeit | df["lead_time"].mean() | 104,0 Tage |
| Ø Aufenthaltsdauer | df["total_nights"].mean() | 3,43 Nächte |
| Gebuchte Zimmernächte | df["total_nights"].sum() | 409.257 |
| Ø Zimmerpreis (ADR) | df["adr"].mean() | 101,83 € |
| Umsatz (stornobereinigt) | df.loc[df["is_canceled"] == 0, "revenue"].sum() | 25.996.260 € |
| Gebuchter Umsatz | df["revenue"].sum() | 42.723.498 € |
| Wiederholungsgast-Anteil | df["is_repeated_guest"].mean() * 100 | 3,2 % |
| Anteil mit Sonderwünschen | (df["total_of_special_requests"] > 0).mean() * 100 | 41,1 % |
Der Hinweis im Notebook gilt für jede Auswertung danach: Der Datensatz kennt keine Zimmerkapazität, deshalb gibt es keine Auslastung und keinen RevPAR. Gebuchte Zimmernächte sind der Ersatz – und das steht so dabei.
Abschnitt 5: Vier Auswertungen
Jede Auswertung ist ein groupby plus ein Diagramm mit matplotlib. Die vier Zellen entsprechen den
vier Fragestellungen aus Lab 00 – und den vier Seiten des späteren Power-BI-Berichts.
| Abschnitt | Gruppierung | Diagramm | Frage |
|---|---|---|---|
| 5.1 | df.groupby("hotel"): Buchungen, Stornoquote, ADR, Nächte | zwei Säulendiagramme | Hotels im Vergleich |
| 5.2 | df.groupby("arrival_date_month").size(), Monate in Kalenderreihenfolge | Linie | Saisonalität |
| 5.3 | value_counts() je Vertriebskanal und Marktsegment | zwei Balkendiagramme | Vertrieb |
| 5.4 | pd.cut(lead_time) in sechs Klassen, dann Stornoquote je Klasse | Säulen | Stornorisiko |
Die Zelle 5.2 hat einen Fallstrick, den man kennen sollte: groupby("arrival_date_month")
sortiert alphabetisch – April, August, December. Die Zeile .reindex(month_order) bringt die
Monate in Kalenderreihenfolge. Ohne sie zeigt die Linie eine Saison, die es nicht gibt.
Abschnitte 6 und 7: Sternschema und Export
Eine kleine Funktion make_dim erzeugt
aus jeder Merkmalsspalte eine Dimensionstabelle mit laufender Nummer; eine Datumsdimension entsteht aus allen
Tagen zwischen dem frühesten und dem spätesten Datum; die Faktentabelle bekommt statt der Texte die Nummern.
Das Modell selbst erklärt Lab 04.
Woran man erkennt, dass es geklappt hat
dim_hotelhat zwei Zeilen,dim_country178 (177 Länder plus UNK),dim_date1.064 Tage.fact_bookingshat weiterhin 119.390 Zeilen – ein Join, der Zeilen verliert oder verdoppelt, wäre hier sichtbar.- Keine Nummer in der Faktentabelle ist
NaN; sonst gäbe es einen Wert, der in keiner Dimension steht.
Abschnitt 7 schreibt die neun Tabellen als CSV-Dateien ins Colab-Dateisystem. Für die Vorlesung ist dieser
Schritt schon getan: Dieselben Dateien liegen im Repository unter data/ und sind mit
sql/02_load_data.py in die Datenbank geladen worden – genau die Dateien, die auch diese
Lernumgebung in Ihren Browser lädt.
Abschnitt 7.1: Live aus der Datenbank
Die letzte Codezelle verbindet sich mit der fertigen Datenbank und liest die Stornoquote je Hotel per SQL. Das Ergebnis muss mit Abschnitt 5.1 übereinstimmen – 41,7 % und 27,8 %. Tut es das, ist bewiesen, dass Notebook und Datenbank dieselben Daten tragen.
Auch hier steht kein Kennwort im Code: Die Verbindungs-URL kommt aus dem Secrets-Panel von Colab (Lab 02), Name
HOTEL_DB_URL; Benutzer und Kennwort der Leserolle stehen im README des Repos. Lab 05 erklärt, was die
Rolle darf und was nicht.
Abschnitt 8: Wo KI hilft
Der letzte Abschnitt ist Text: eine Tabelle, an welchen Stellen des Projekts ein KI-Assistent hilft – Spalten
erklären, Auffälligkeiten finden, ein Sternschema vorschlagen, Diagrammcode erzeugen, eine Zusammenfassung
schreiben. Die Regel dazu steht im Notebook selbst: KI schlägt vor, der Mensch prüft. Ein vorgeschlagenes
Sternschema, das agent als Kennzahl führt, ist schnell erzeugt und langsam bemerkt.
Probieren Sie es aus: Lassen Sie sich von einem Assistenten den Code für Abschnitt 5.4 erklären und vergleichen Sie die Erklärung mit der Zelle. Wo die Erklärung eine Zeile auslässt oder erfindet, haben Sie gelernt, warum man prüft.
Übungen
Fünf Übungen: die Reihenfolge der Abschnitte, die Annahmen der Bereinigung, eine Zuordnung von Codezeilen zu Abschnitten, eine Checkliste durch das echte Notebook in Colab und Verständnisfragen zu Sternschema und Datenbankzelle.
Zusammenfassung
- Acht Abschnitte in fester Reihenfolge; ein KeyError nennt die Zelle, die nicht gelaufen ist.
- Sichten heißt
info()unddescribe()lesen – dort zeigen sich die Eigenheiten zuerst. - Jede Bereinigung ist eine Annahme und steht im Text: children → 0, country → UNK, „NULL“ → NaN.
revenue = adr × total_nightsist die Spalte, aus der alle drei Umsatzbegriffe entstehen.- Vier Auswertungen, vier Fragen; die Monatsreihenfolge braucht
reindex. - Das Sternschema entsteht aus Merkmalsspalten und einer Datumsdimension; die Faktentabelle behält 119.390 Zeilen.
- Abschnitt 7.1 beweist, dass Notebook und Datenbank dieselben Zahlen liefern.