Woher die Daten stammen

Der Datensatz wurde im Februar 2019 von Nuno Antonio, Ana de Almeida und Luis Nunes in der Zeitschrift Data in Brief (Band 22) unter dem Titel Hotel booking demand datasets veröffentlicht. Die Autoren haben die Buchungsdaten zweier portugiesischer Hotels aus deren Property-Management-Systemen gezogen, personenbezogene Angaben entfernt und die Daten unter der Lizenz CC BY 4.0 freigegeben – jeder darf sie nutzen, solange die Quelle genannt wird. Genau deshalb steht sie in der Fußzeile des Dashboards.

2015–2017Buchungssysteme zweier Hotels
2019Antonio, de Almeida, Nunes: zwei Dateien, anonymisiert
2020TidyTuesday und Kaggle: eine Datei, 119.390 Zeilen
ProjektNotebook liest die TidyTuesday-Fassung per URL

Das Projekt verwendet die Fassung, die 2020 im TidyTuesday-Projekt der R-Community erschienen ist und wortgleich auf Kaggle als Hotel Booking Demand liegt: Die beiden Originaldateien sind zu einer zusammengefügt, die Spalte hotel unterscheidet die Häuser. Das Notebook lädt diese Datei direkt von GitHub, ohne Anmeldung – das ist der reproduzierbare Weg aus Lab 02.

Der Datensatz ist echt, aber ohne Personenbezug: Namen, Adressen, Kontaktdaten fehlen; Agenturen und Firmen tragen nur Kennnummern. Deshalb darf er in Colab, in einer Datenbank auf einem Hochschulserver und in einem öffentlichen Repository liegen. Für Daten aus einem eigenen Praxisprojekt gilt das nicht automatisch – siehe Lab 02, Abschnitt Datenschutz.

Die 32 Spalten

Jede Zeile ist eine Buchung. Die Spalten lassen sich in fünf Gruppen lesen; die Reihenfolge in der Datei ist die der Autoren, nicht die der Logik.

GruppeSpalteBedeutungWerte
Haus und Statushotelwelches HausCity Hotel (79.330), Resort Hotel (40.060)
is_canceledstorniert?1 = ja (44.224), 0 = nein
reservation_status, reservation_status_dateletzter Status und sein DatumCheck-Out, Canceled, No-Show
Zeitlead_timeTage zwischen Buchung und Anreise0 bis 737, Median 69
arrival_date_year, _month, _week_number, _day_of_monthAnreisedatum, in vier Spalten zerlegt2015–2017; Monat als englisches Wort
stays_in_weekend_nights, stays_in_week_nightsNächte am Wochenende und unter der WocheSumme = Aufenthaltsdauer
Gästeadults, children, babiesPersonen je Buchungchildren fehlt in 4 Zeilen
countryHerkunftslandISO-3-Code, 177 Länder, 488-mal leer
is_repeated_guest, previous_cancellations, previous_bookings_not_canceledVorgeschichte des GastsZahlen
Vertrieb und Vertragmarket_segmentüber welchen Markt die Buchung kamOnline TA, Offline TA/TO, Groups, Direct, Corporate, Complementary, Aviation, Undefined
distribution_channelVertriebskanalTA/TO, Direct, Corporate, GDS, Undefined
customer_type, deposit_typeKundentyp und KautionsartTransient, Transient-Party, Contract, Group · No Deposit, Non Refund, Refundable
agent, companyKennnummer der Agentur bzw. Firma„NULL“ als Text, wenn keine
Zimmer und PreismealVerpflegungBB, HB, FB, SC, Undefined
reserved_room_type, assigned_room_typegebuchter und zugeteilter ZimmertypBuchstabencodes A–L
adrAverage Daily Rate: Zimmerpreis je Nacht−6,38 bis 5.400; 1.959-mal 0
booking_changes, days_in_waiting_list, required_car_parking_spaces, total_of_special_requestsÄnderungen, Warteliste, Parkplätze, SonderwünscheZahlen

Was der Datensatz nicht enthält, ist ebenso wichtig: keine Zimmerzahl je Haus, keinen Nebenumsatz, keinen Buchungspreis für Frühstück oder Parkplatz, keinen Namen. Lab 00 hat daraus die Grenzen des Projekts abgeleitet.

Datentypen und Rollen

Beim Einlesen ordnet pandas jeder Spalte einen Typ zu: 16 Spalten sind ganze Zahlen, 4 sind Dezimalzahlen, 12 sind Text. Für die Auswertung zählt die Rolle einer Spalte; sie entscheidet später, ob die Spalte in die Faktentabelle oder in eine Dimension wandert.

Vier Rollen

  • Kennzahl (measure) – wird summiert oder gemittelt: adr, lead_time, die Nächte, adults. Aus adr mal Nächte entsteht später revenue.
  • Merkmal (dimension) – wird gefiltert und gruppiert: hotel, market_segment, country, deposit_type. Wenige verschiedene Werte, oft Text.
  • Flag – ein Ja/Nein, gespeichert als 0 und 1: is_canceled, is_repeated_guest. Der Mittelwert eines Flags ist ein Anteil – der Mittelwert von is_canceled ist die Stornoquote.
  • Zeitangabe – das Anreisedatum in vier Spalten und das Statusdatum. Beide werden im Sternschema zu Schlüsseln auf eine Datumsdimension.

Eine Zahl ist nicht automatisch eine Kennzahl. agent ist eine Nummer, aber summieren wäre Unsinn – sie ist ein Merkmal. Die Probe: Ergibt die Summe über alle Buchungen einen Sinn? Bei adr nein (je Nacht), bei revenue ja, bei agent nie.

Eigenheiten, die man kennen muss

Diese sechs sind dokumentiert – im Notebook, in den Aussagen des Dashboards und in der Literatur zum Datensatz. Wer sie kennt, erkennt sie später in jeder Auswertung wieder.

„NULL“ ist ein Wort

In agent und company steht bei fehlender Angabe der Text NULL – 16.340- bzw. 112.593-mal. Für pandas ist das je nach Version eine Zeichenkette, nicht ein fehlender Wert. Das Notebook ersetzt den Text durch echtes NaN, sonst zählt „NULL“ als Agentur.

Kein Land: UNK

488 Buchungen haben kein Herkunftsland. Das Notebook setzt UNK ein, damit die Zeilen nicht aus Joins fallen. Der Code CN steht im Datensatz für China – kein gültiger ISO-3-Code, aber so geliefert; das Dashboard übersetzt ihn.

adr: 0, negativ, 5.400

1.959 Buchungen haben einen Zimmerpreis von 0 (Freiplätze, Reklamationen), eine ist negativ (−6,38, eine Gutschrift) und eine liegt bei 5.400 € – ein Tippfehler. Ein Mittelwert reagiert auf solche Ausreißer; der Median nicht. Das Projekt lässt die Werte stehen und benennt sie.

Non Refund: 99 % storniert

14.587 Buchungen sind „nicht erstattbar“ – und 99,4 % davon storniert. Fachlich unplausibel; die Erklärung liegt in Sammelbuchungen, die nach Nichterscheinen als storniert verbucht wurden. Ein bekanntes Artefakt dieses Datensatzes, das jede Stornoanalyse erwähnen muss.

Null Nächte

715 Buchungen haben null Nächte – Tagesnutzung oder Stornierung am Anreisetag. Ihr revenue ist 0, obwohl adr gesetzt sein kann. Für die Aufenthaltsdauer zählen sie mit.

Undefined

meal hat 1.169-mal „Undefined“, was laut Autoren dasselbe bedeutet wie SC (keine Verpflegung). market_segment und distribution_channel haben je eine Handvoll „Undefined“. Das Dashboard zeigt sie als „Nicht angegeben“.

Storniert ist nicht dasselbe wie nicht erschienen. is_canceled = 1 fasst zwei Status zusammen: Canceled (43.017) und No-Show (1.207). Für die Stornoquote zählen beide, für eine Analyse der Stornofristen nur der erste. Wer das eine meint, muss das andere ausschließen.

Eine Buchung als Datensatz

Ein Buchungssystem liefert eine Buchung über eine Schnittstelle als JSON; pandas zeigt dieselbe erste Zeile als Tabelle. Beide Formen tragen dieselbe Information, nur die JSON-Form macht die Typen sichtbar: Zahlen ohne Anführungszeichen, Text mit, Wahrheitswerte als true/false.

BI_Hotel_Booking_Demand.ipynb – ColabPython 3
[2]
df = pd.read_csv(URL)
print("Zeilen, Spalten:", df.shape)
df.head(1).T
Zeilen, Spalten: (119390, 32)
hotelResort Hotel
is_canceled0
lead_time342
arrival_date_year2015
arrival_date_monthJuly
adults2
countryPRT
market_segmentDirect
deposit_typeNo Deposit
adr0.0 1
reservation_statusCheck-Out

Nachbildung der Oberfläche, Stand 09/2026 – Beschriftungen wie im Original; Ausgabe auf elf Spalten gekürzt.

  1. 1Die allererste Buchung des Datensatzes hat null Nächte und einen Zimmerpreis von 0 – ein Beispiel dafür, dass „erste Zeile“ nicht „typische Zeile“ heißt.

Übungen

Fünf Übungen: Herkunft und Lizenz, die Rollen der Spalten, die Eigenheiten, eine Buchung als JSON und die Bedeutung einzelner Werte.

Zusammenfassung