notebook, update
This commit is contained in:
parent
be3b063764
commit
78ec703590
@ -6,14 +6,14 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"# Datenaufbereitung und Variablen Auslese\n",
|
"# Datenaufbereitung und Variablen Auslese\n",
|
||||||
"## Imputation\n",
|
"## Imputation\n",
|
||||||
"Author: Dr. Yves Staudt"
|
"Author: Prof. Dr. Yves Staudt"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"In diesem Notebook bereiten wir die Daten speziell für Clustering-Verfahren vor. Es enthält alle notwendigen Verarbeitungsschritte, die für die Anwendung von Clustering-Methoden erforderlich sind."
|
"In diesem Notebook bereiten wir die Spalten mit fehlenden Werten des Hotel-Bookings-Datensatzes auf. Wir untersuchen zunächst Ausmass und Muster der fehlenden Werte und füllen sie anschliessend mit geeigneten Verfahren (**Imputation**): numerische Variablen z. B. über Mittelwert/Median, kategoriale über die häufigste oder eine eigene Kategorie. Bei Bedarf ergänzen wir einen **Fehlend-Indikator**, der festhält, wo ein Wert ursprünglich gefehlt hat."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -25,7 +25,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 6,
|
"execution_count": 1,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
@ -59,7 +59,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 7,
|
"execution_count": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@ -71,13 +71,13 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"df = pd.read_csv(\"../../../Data/hotel_bookings/hotel_bookings.csv\")\n",
|
"df = pd.read_csv(\"../Data/hotel_bookings.csv\")\n",
|
||||||
"print(f\"Grösse des Datensatzes: {df.shape}\")"
|
"print(f\"Grösse des Datensatzes: {df.shape}\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 8,
|
"execution_count": 3,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@ -97,7 +97,7 @@
|
|||||||
" dtype='object')"
|
" dtype='object')"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 8,
|
"execution_count": 3,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
@ -110,13 +110,13 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Manuelle Daten löschen \n",
|
"## Variablen manuell entfernen\n",
|
||||||
"Bestimmte Variablen wie das genaue Jahr, spezifische Tage oder Kalenderwochen bieten in einer Analyse nur begrenzten Mehrwert. Daher entfernen wir die Variablen *`arrival_date_year`*, *`arrival_date_week_number`* und *`arrival_date_day_of_month`*."
|
"Einige Variablen tragen für unsere Analyse nur wenig bei: Das genaue Ankunftsjahr (*`arrival_date_year`*) erschwert die Generalisierung auf andere Zeiträume, während sehr granulare Zeitangaben wie der Kalendertag (*`arrival_date_day_of_month`*) und die Kalenderwoche (*`arrival_date_week_number`*) kaum zusätzlichen Mehrwert gegenüber dem bereits vorhandenen Ankunftsmonat bieten. Wir entfernen aus subjektiver Sicht diese drei Variablen daher aus dem Datensatz."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 9,
|
"execution_count": 4,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@ -136,13 +136,13 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Missing Variables\n",
|
"## Fehlende Werte\n",
|
||||||
"Zuerst schauen wir die Variablen und deren fehlende Werte an. "
|
"Als Nächstes verschaffen wir uns einen Überblick über die fehlenden Werte: Für jede Variable berechnen wir den **Anteil fehlender Einträge** (in %) und betrachten nur die Variablen, die tatsächlich Lücken aufweisen."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 10,
|
"execution_count": 5,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@ -172,35 +172,103 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"Wir haben vier Variablen mit fehlenden Werten identifiziert. Eine dieser Variablen weist einen hohen Anteil fehlender Werte auf (94%), während die Variablen `country` und `children` nur einen geringen Anteil an fehlenden Werten haben. Für `country` und `children` könnte es sinnvoll sein, die betroffenen Zeilen einfach zu löschen. In diesem Bericht füllen wir jedoch die fehlenden Werte auf, um die Daten vollständig zu machen."
|
"Wir identifizieren **vier Variablen** mit fehlenden Werten: `company` (≈94 %), `agent` (≈14 %), `country` (<1 %) und `children` (nur 4 Einträge).\n",
|
||||||
|
"\n",
|
||||||
|
"Die Variablen unterscheiden sich deutlich:\n",
|
||||||
|
"- Bei `company` und `agent` bedeutet ein fehlender Wert vermutlich, dass die Buchung **nicht** über eine Firma bzw. einen Reisevermittler lief — das Fehlen trägt hier also selbst Information.\n",
|
||||||
|
"- Bei `country` und `children` sind nur sehr wenige Einträge betroffen; hier könnte man die betroffenen Zeilen auch einfach entfernen.\n",
|
||||||
|
"\n",
|
||||||
|
"In diesem Notebook füllen wir die fehlenden Werte stattdessen auf (**Imputation**), um den Datensatz vollständig zu machen."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Train Test Split \n",
|
"## Train-Test-Split\n",
|
||||||
"Beim Clustering liegt der Fokus darauf, Gemeinsamkeiten in den Daten zu identifizieren, ohne dass eine Zielvariable vorgegeben ist. Daher wird in diesem Fall kein Train-Test-Split durchgeführt."
|
"Bevor wir die Daten weiter aufbereiten, teilen wir sie in einen **Trainings-** und einen **Testdatensatz** auf. Dieser Schritt muss zwingend **vor** dem Auffüllen erfolgen: Würden wir den gesamten Datensatz gemeinsam auffüllen, flössen Informationen aus dem Testteil unbeabsichtigt in den Trainingsteil ein (**Data Leakage**) — der Testdatensatz wäre dann nicht mehr „ungesehen\".\n",
|
||||||
]
|
"\n",
|
||||||
},
|
"Deshalb **erlernen** wir alle Aufbereitungsschritte (z. B. das Auffüllen fehlender Werte) ausschliesslich auf dem Trainingsdatensatz und **übertragen** sie anschliessend auf den Testdatensatz. Das entspricht auch dem realen Anwendungsfall: Neue Daten müssen mit derselben, bereits bekannten Methodik vorverarbeitet werden.\n",
|
||||||
{
|
"\n",
|
||||||
"cell_type": "markdown",
|
"Wir bereiten den Datensatz mit allgemeinen Schritten auf; Zielvariable ist der durchschnittliche Tagespreis (`adr`)."
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"## Daten Formate\n",
|
|
||||||
"Wir haben gelernt, dass die Datenformate eine wichtige Rolle spielen, daher schauen wir uns die zuerst an. "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"### Kategorielle Variablen"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 11,
|
"execution_count": 6,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"The shape of the data set with training varialbes is: (119390, 28)\n",
|
||||||
|
"The shape of the target variable is: (119390,)\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"x = df.drop(columns = ['adr'])\n",
|
||||||
|
"y = df['adr']\n",
|
||||||
|
"print(f\"The shape of the data set with training varialbes is: {x.shape}\")\n",
|
||||||
|
"print(f\"The shape of the target variable is: {y.shape}\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Nachdem die erklärenden Variablen (`x`) von der Zielvariable (`y`) getrennt sind, teilen wir den Datensatz in Trainings- und Testdaten auf. Wir verwenden 70 % für das Training und 30 % für den Test; ein fester `random_state` macht die Aufteilung reproduzierbar."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 7,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"The shape of the training sample is: (83573, 28)\n",
|
||||||
|
"The shape of the test sample is: (35817, 28)\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"X_train, X_test, y_train, y_test = train_test_split(\n",
|
||||||
|
" x,\n",
|
||||||
|
" y,\n",
|
||||||
|
" test_size=0.3,\n",
|
||||||
|
" random_state=0)\n",
|
||||||
|
"\n",
|
||||||
|
"print(f\"The shape of the training sample is: {X_train.shape}\")\n",
|
||||||
|
"print(f\"The shape of the test sample is: {X_test.shape}\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Datenformate\n",
|
||||||
|
"Datenformate spielen eine zentrale Rolle: Welche Aufbereitungs- und Modellierungsschritte sinnvoll sind, hängt vom **Typ** jeder Variable ab. Grundsätzlich unterscheiden wir:\n",
|
||||||
|
"- **Numerische Variablen** — *diskret* (abzählbar, z. B. Anzahl) oder *kontinuierlich* (beliebig fein, z. B. ein Preis).\n",
|
||||||
|
"- **Kategoriale Variablen** — *nominal* (ohne Reihenfolge, z. B. Land) oder *ordinal* (mit Reihenfolge, z. B. Bewertungsstufen).\n",
|
||||||
|
"\n",
|
||||||
|
"Wir verschaffen uns daher zuerst einen Überblick über die Datentypen im Trainingsdatensatz."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### Kategoriale Variablen\n",
|
||||||
|
"In pandas liegen kategoriale Variablen typischerweise als Datentyp `object` (Text) vor. Wir filtern daher alle `object`-Spalten heraus, um die kategorialen Variablen zu identifizieren, und zählen, wie viele es sind. Anschliessend betrachten wir ihre **Kardinalität** (Anzahl verschiedener Ausprägungen) — ein wichtiges Kriterium für das spätere Encoding."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 8,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@ -230,7 +298,6 @@
|
|||||||
"company float64\n",
|
"company float64\n",
|
||||||
"days_in_waiting_list int64\n",
|
"days_in_waiting_list int64\n",
|
||||||
"customer_type object\n",
|
"customer_type object\n",
|
||||||
"adr float64\n",
|
|
||||||
"required_car_parking_spaces int64\n",
|
"required_car_parking_spaces int64\n",
|
||||||
"total_of_special_requests int64\n",
|
"total_of_special_requests int64\n",
|
||||||
"reservation_status object\n",
|
"reservation_status object\n",
|
||||||
@ -238,18 +305,18 @@
|
|||||||
"dtype: object"
|
"dtype: object"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 11,
|
"execution_count": 8,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"df.dtypes"
|
"X_train.dtypes"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 12,
|
"execution_count": 9,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@ -268,7 +335,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"# Extract column names with data type 'object'\n",
|
"# Extract column names with data type 'object'\n",
|
||||||
"# Dies inkludiert alle Spalten, welche mehrheitlich nicht durch numerische Werte besetzt werden. \n",
|
"# Dies inkludiert alle Spalten, welche mehrheitlich nicht durch numerische Werte besetzt werden. \n",
|
||||||
"object_columns = df.select_dtypes(include=['object']).columns\n",
|
"object_columns = X_train.select_dtypes(include=['object']).columns\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Print the column names with 'object' data type\n",
|
"# Print the column names with 'object' data type\n",
|
||||||
"print(f\"Liste von kategorischen Variablen: {object_columns}\")\n",
|
"print(f\"Liste von kategorischen Variablen: {object_columns}\")\n",
|
||||||
@ -286,7 +353,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 13,
|
"execution_count": 10,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@ -296,34 +363,34 @@
|
|||||||
"hotel: 2\n",
|
"hotel: 2\n",
|
||||||
"arrival_date_month: 12\n",
|
"arrival_date_month: 12\n",
|
||||||
"meal: 5\n",
|
"meal: 5\n",
|
||||||
"country: 177\n",
|
"country: 162\n",
|
||||||
"market_segment: 8\n",
|
"market_segment: 8\n",
|
||||||
"distribution_channel: 5\n",
|
"distribution_channel: 5\n",
|
||||||
"reserved_room_type: 10\n",
|
"reserved_room_type: 10\n",
|
||||||
"assigned_room_type: 12\n",
|
"assigned_room_type: 11\n",
|
||||||
"deposit_type: 3\n",
|
"deposit_type: 3\n",
|
||||||
"customer_type: 4\n",
|
"customer_type: 4\n",
|
||||||
"reservation_status: 3\n",
|
"reservation_status: 3\n",
|
||||||
"reservation_status_date: 926\n"
|
"reservation_status_date: 916\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"for col in df.select_dtypes(include=['object']):\n",
|
"for col in X_train.select_dtypes(include=['object']):\n",
|
||||||
" cardinality = len(pd.Index(df[col].value_counts()))\n",
|
" cardinality = len(pd.Index(X_train[col].value_counts()))\n",
|
||||||
" print(df[col].name + \": \" + str(cardinality))"
|
" print(X_train[col].name + \": \" + str(cardinality))"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"Die Variable `hotel` ist binär und sollte immer mithilfe des k−1-One-Hot-Encoding umgewandelt werden. Die Variablen `country` und `reservation_status_date` weisen im Vergleich zu den anderen Variablen eine hohe Kardinalität auf. `reservation_status_date` ist eine Datumsvariable, die in ihrer ursprünglichen Form nicht direkt genutzt werden kann. Da Transformationen dieser Variable bereits umgesetzt wurden, wird sie in diesem Schritt entfernt."
|
"Die Variable `hotel` ist **binär** und wird daher per k−1-One-Hot-Encoding kodiert (eine Dummy-Spalte genügt). Die Variablen `country` und `reservation_status_date` weisen dagegen eine **hohe Kardinalität** auf. `reservation_status_date` ist zudem eine **Datumsvariable**, die in ihrer Rohform nicht direkt nutzbar ist und für die weitere Analyse keinen Mehrwert bietet. Wir entfernen sie daher aus dem Trainings- und dem Testdatensatz."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 14,
|
"execution_count": 11,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@ -331,39 +398,46 @@
|
|||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"\n",
|
"\n",
|
||||||
"Shape of the data set after remove of unnecessary variables: (119390, 28)\n"
|
"Shape of the data set after remove of unnecessary variables: (83573, 27)\n",
|
||||||
|
"\n",
|
||||||
|
"Shape of the data set after remove of unnecessary variables: (35817, 27)\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"df = df.drop(columns=['reservation_status_date'])\n",
|
"X_train = X_train.drop(columns=['reservation_status_date']) \n",
|
||||||
"print(f\"\\nShape of the data set after remove of unnecessary variables: {df.shape}\")\n"
|
"print(f\"\\nShape of the data set after remove of unnecessary variables: {X_train.shape}\")\n",
|
||||||
|
"X_test = X_test.drop(columns=['reservation_status_date']) \n",
|
||||||
|
"print(f\"\\nShape of the data set after remove of unnecessary variables: {X_test.shape}\")\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Numerische Variablen"
|
"### Numerische Variablen\n",
|
||||||
|
"Numerische Variablen enthalten Zahlenwerte und sind entweder *diskret* (abzählbar, z. B. Anzahl Personen) oder *kontinuierlich* (beliebig fein, z. B. der Tagespreis). Im Gegensatz zu kategorialen Variablen können Modelle direkt mit ihnen rechnen; je nach Verfahren ist aber noch eine **Skalierung** sinnvoll.\n",
|
||||||
|
"\n",
|
||||||
|
"Wir filtern hier die Spalten mit Datentyp `float` heraus, um die numerischen Variablen zu identifizieren und zu zählen."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 15,
|
"execution_count": 12,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Liste von numerischen Variablen: Index(['children', 'agent', 'company', 'adr'], dtype='object')\n",
|
"Liste von numerischen Variablen: Index(['children', 'agent', 'company'], dtype='object')\n",
|
||||||
"Lange der Liste von numerischen Variablen: 4\n"
|
"Lange der Liste von numerischen Variablen: 3\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"# Extract column names with data type 'float'\n",
|
"# Extract column names with data type 'float'\n",
|
||||||
"numeric_columns = df.select_dtypes(include= ['float']).columns\n",
|
"numeric_columns = X_train.select_dtypes(include= ['float']).columns\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Print the column names with 'float' data type\n",
|
"# Print the column names with 'float' data type\n",
|
||||||
"print(f\"Liste von numerischen Variablen: {numeric_columns}\")\n",
|
"print(f\"Liste von numerischen Variablen: {numeric_columns}\")\n",
|
||||||
@ -376,7 +450,9 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"Es gibt lediglich drei numerische Variablen in unserem Datensatz. Dabei handelt es sich unter anderem um die Variablen `agent` und `company`, die ursprünglich kategorisch waren, aber durch die Anonymisierung in numerische Werte umgewandelt wurden."
|
"In unserem Datensatz sind nur **drei** Variablen als numerisch (`float`) gespeichert: `children`, `agent` und `company`. Während `children` tatsächlich eine Zählgrösse ist, sind `agent` und `company` eigentlich **kategorial** — es handelt sich um (anonymisierte) ID-Nummern, die nur zufällig als Zahl vorliegen.\n",
|
||||||
|
"\n",
|
||||||
|
"Der Datentyp allein sagt also noch nichts über die inhaltliche Bedeutung einer Variable aus: `agent` und `company` sollten als Kategorien behandelt werden, nicht als Messgrössen."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -384,11 +460,11 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Imputation\n",
|
"## Imputation\n",
|
||||||
"Bevor mit den weiteren Umformungen begonnen werden kann, müssen die fehlenden Werte aufgefüllt werden. Zunächst ist jedoch zu prüfen, ob die Daten systematisch nach einer bestimmten Struktur fehlen oder ob es sich um zufällige fehlende Werte handelt. Eine detaillierte Analyse hierzu finden Sie im Notebook Analyse_Fehlend_Nach_Struktur_oder_Nicht.ipynb.\n",
|
"Bevor wir die Daten weiter umformen, müssen die fehlenden Werte aufgefüllt werden. Zunächst prüfen wir aber, ob Werte **systematisch** (nach einem Muster) oder rein **zufällig** fehlen. Die detaillierte Analyse dazu finden Sie im Notebook `Analyse_Fehlend_Nach_Struktur_oder_Nicht.ipynb`.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Die Analyse ergab, dass die Daten für die Variablen 'Land' und 'Kinder' systematisch fehlen. Ebenso fehlt bei den Variablen agent und company strukturiert eine Datengrundlage. Laut Dokumentation weisen fehlende Werte in der Variable `agent` und `company` darauf hin, dass es sich nicht um eine Buchung über einen Agenten oder eine Firma handelt.\n",
|
"Ergebnis der Analyse: Die Variablen `country`, `children`, `agent` und `company` fehlen **systematisch**. Laut Dokumentation bedeutet ein fehlender Wert bei `agent` bzw. `company`, dass die Buchung *nicht* über einen Agenten bzw. eine Firma lief — das Fehlen trägt hier also selbst Information.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Für systematisch fehlende Daten empfiehlt es sich, eine Indikatorvariable zu erstellen, die angibt, ob ein Wert fehlt (Ja/Nein). Für die Variablen 'Land', 'Kinder', agent und company kann dies mit Hilfe der Funktion AddMissingIndicator umgesetzt werden."
|
"Bei systematisch fehlenden Werten empfiehlt es sich, eine **Indikatorvariable** zu ergänzen, die festhält, ob ein Wert gefehlt hat (1/0). Für `country`, `children`, `agent` und `company` setzen wir das mit `AddMissingIndicator` um."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -400,7 +476,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 16,
|
"execution_count": 13,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@ -827,7 +903,7 @@
|
|||||||
"AddMissingIndicator(variables=['company', 'agent', 'country', 'children'])"
|
"AddMissingIndicator(variables=['company', 'agent', 'country', 'children'])"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 16,
|
"execution_count": 13,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
@ -839,84 +915,90 @@
|
|||||||
")\n",
|
")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# fit the imputer\n",
|
"# fit the imputer\n",
|
||||||
"addBinary_imputer.fit(df)"
|
"addBinary_imputer.fit(X_train)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"In dem wir die Add Missing Indicator Umformung durchführen verändern wir die Form unseres Datensatzes. Dies können wir mit folgendem Befehl sehen. "
|
"Da die Werte **systematisch** fehlen, markieren wir mit `AddMissingIndicator` für jede betroffene Variable, ob ein Wert gefehlt hat (1/0). Dadurch kommt pro Variable eine neue Indikatorspalte hinzu — der Datensatz wird also **breiter**. Den Effekt auf die Form (Anzahl Spalten) sehen wir am folgenden Vorher-/Nachher-Vergleich."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 17,
|
"execution_count": 14,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Form of the dataset before transformation: (119390, 28)\n",
|
"Form of the dataset before transformation: ((83573, 27), (35817, 27))\n",
|
||||||
"Form of the dataset after transformation: (119390, 32)\n"
|
"Form of the dataset after transformation: ((83573, 31), (35817, 31))\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"print(f\"Form of the dataset before transformation: {df.shape}\")\n",
|
"print(f\"Form of the dataset before transformation: {X_train.shape, X_test.shape}\")\n",
|
||||||
"# transform \n",
|
"# transform \n",
|
||||||
"df = addBinary_imputer.transform(df)\n",
|
"X_train = addBinary_imputer.transform(X_train)\n",
|
||||||
"print(f\"Form of the dataset after transformation: {df.shape}\")"
|
"X_test = addBinary_imputer.transform(X_test)\n",
|
||||||
|
"print(f\"Form of the dataset after transformation: {X_train.shape, X_test.shape}\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"Um zu verdeutlichen, dass die Variablen `agent` und `company` eine andere Bedeutung haben, werden wir diese umbenennen."
|
"`AddMissingIndicator` hat die Indikatorspalten standardmässig `agent_na` und `company_na` genannt. Da ein fehlender Wert hier bedeutet, dass die Buchung *nicht* über einen Agenten bzw. eine Firma lief, benennen wir die beiden Spalten aussagekräftiger in `Not_agent_booking` und `Not_company_booking` um."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 18,
|
"execution_count": 15,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# Rename columns using rename()\n",
|
"# Rename columns using rename()\n",
|
||||||
"df = df.rename(columns={'agent_na': 'Not_agent_booking', 'company_na': 'Not_company_booking'})"
|
"X_train = X_train.rename(columns={'agent_na': 'Not_agent_booking', 'company_na': 'Not_company_booking'})\n",
|
||||||
|
"X_test = X_test.rename(columns={'agent_na': 'Not_agent_booking', 'company_na': 'Not_company_booking'})"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"Da wir mit den Variablen `agent` und `company` nicht weiterarbeiten werden, löschen wir sie nun."
|
"Die ursprünglichen Spalten `agent` und `company` enthalten nur (anonymisierte) ID-Nummern ohne direkt nutzbare Information. Die für uns relevante Information — ob die Buchung über einen Agenten bzw. eine Firma lief — steckt nun in den Indikatorspalten `Not_agent_booking` und `Not_company_booking`. Wir entfernen daher `agent` und `company`."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 19,
|
"execution_count": 16,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Shape of data frame after remove of variables: (119390, 30)\n"
|
"Shape of data frame after remove of variables: (83573, 29)\n",
|
||||||
|
"Shape of data frame after remove of variables: (35817, 29)\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"df = df.drop(columns=['agent','company'])\n",
|
"X_train = X_train.drop(columns=['agent','company'])\n",
|
||||||
"print(f\"Shape of data frame after remove of variables: {df.shape}\")"
|
"print(f\"Shape of data frame after remove of variables: {X_train.shape}\")\n",
|
||||||
|
"X_test = X_test.drop(columns=['agent','company'])\n",
|
||||||
|
"print(f\"Shape of data frame after remove of variables: {X_test.shape}\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Numerische Variablen Imputation"
|
"### Numerische Variablen — Imputation\n",
|
||||||
|
"Numerische Variablen sind *diskret* (abzählbar, z. B. Anzahl Personen) oder *kontinuierlich* (beliebig fein, z. B. der Tagespreis). Fehlende Werte füllen wir mit einer **Lagekennzahl** auf — meist dem **Median** (robust gegenüber Ausreissern) oder dem Mittelwert. Wichtig: Die Kennzahl wird nur auf den Trainingsdaten gelernt und dann auf Trainings- und Testdaten angewendet."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -930,7 +1012,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 20,
|
"execution_count": 17,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
@ -945,13 +1027,12 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"\n",
|
"Mit `.fit` ermittelt der Imputer die Werte, mit denen später aufgefüllt wird (hier den **Median** von `children`). Das ist nur ein **Lernschritt** — die Daten selbst werden dabei noch **nicht** verändert; das geschieht erst mit `.transform`."
|
||||||
"Der Befehl `.fit` ermöglicht es dem Imputer, die Werte zu ermitteln, die für das Auffüllen der fehlenden Daten verwendet werden sollen. Dabei handelt es sich lediglich um einen Lernprozess; tatsächliche Änderungen an den Daten werden durch diesen Befehl noch nicht vorgenommen."
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 21,
|
"execution_count": 18,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@ -1378,26 +1459,26 @@
|
|||||||
"MeanMedianImputer(variables=['children'])"
|
"MeanMedianImputer(variables=['children'])"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 21,
|
"execution_count": 18,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"# we fit the imputer\n",
|
"# we fit the imputer\n",
|
||||||
"imputer.fit(df)"
|
"imputer.fit(X_train)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"Mit dem folgenden Befehl bekomme ich die Variablen aufgelistet für welche fehlende Werte ersetzt worden sind. "
|
"Das Attribut `imputer.variables_` listet die Variablen auf, für die der Imputer einen Auffüllwert gelernt hat."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 22,
|
"execution_count": 19,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@ -1406,7 +1487,7 @@
|
|||||||
"['children']"
|
"['children']"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 22,
|
"execution_count": 19,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
@ -1421,19 +1502,19 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"Wir beobachten, dass nur die Variable `children` aufgefüllt worden ist. "
|
"Wie erwartet hat der Imputer nur die Variable `children` aufgefüllt — genau diese hatten wir im `MeanMedianImputer` angegeben."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"Mit dem folgenden Befehl können wir nachvollziehen, mit welchem Wert die fehlenden Daten in der Variable `children` aufgefüllt wurden."
|
"Das Attribut `imputer.imputer_dict_` zeigt, mit welchem Wert je Variable aufgefüllt wurde — hier der **Median** von `children`."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 23,
|
"execution_count": 20,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@ -1442,7 +1523,7 @@
|
|||||||
"{'children': 0.0}"
|
"{'children': 0.0}"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 23,
|
"execution_count": 20,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
@ -1455,37 +1536,38 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"Nun führen wir die Transformation durch. "
|
"Mit `.transform` füllen wir die fehlenden Werte nun tatsächlich auf — der zuvor gelernte Median wird in `children` eingesetzt. Das Ergebnis ist wieder ein DataFrame."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 24,
|
"execution_count": 21,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# feature-engine returns a dataframe\n",
|
"# feature-engine returns a dataframe\n",
|
||||||
"\n",
|
"\n",
|
||||||
"df = imputer.transform(df)"
|
"X_train = imputer.transform(X_train)\n",
|
||||||
|
"X_test = imputer.transform(X_test)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Kategorisch Variablen Imputation"
|
"### Kategoriale Variablen — Imputation"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"Nun müssen die fehlenden Werte der kategorialen Variable `country` aufgefüllt werden. Dabei nehmen wir an, dass die häufigste Ausprägung in den vorhandenen Daten eine repräsentative Grundlage bildet. Daher werden die fehlenden Werte durch die häufigste Kategorie ersetzt. Dieser Schritt wird im Folgenden umgesetzt."
|
"Nun füllen wir die fehlenden Werte der kategorialen Variable `country` auf. Wir nehmen an, dass die **häufigste Kategorie** (Modus) eine repräsentative Ersetzung ist, und verwenden dafür den `CategoricalImputer` mit `imputation_method=\"frequent\"`. (Alternativ liesse sich auch eine eigene Kategorie wie „Missing`` einsetzen.)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 25,
|
"execution_count": 22,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@ -1912,7 +1994,7 @@
|
|||||||
"CategoricalImputer(imputation_method='frequent', variables=['country'])"
|
"CategoricalImputer(imputation_method='frequent', variables=['country'])"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 25,
|
"execution_count": 22,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
@ -1923,7 +2005,7 @@
|
|||||||
"imputer = CategoricalImputer(imputation_method=\"frequent\", \n",
|
"imputer = CategoricalImputer(imputation_method=\"frequent\", \n",
|
||||||
" variables = ['country'])\n",
|
" variables = ['country'])\n",
|
||||||
"\n",
|
"\n",
|
||||||
"imputer.fit(df)"
|
"imputer.fit(X_train)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1936,7 +2018,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 26,
|
"execution_count": 23,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@ -1945,7 +2027,7 @@
|
|||||||
"{'country': 'PRT'}"
|
"{'country': 'PRT'}"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 26,
|
"execution_count": 23,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
@ -1963,25 +2045,26 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 27,
|
"execution_count": 24,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# transformation\n",
|
"# transformation\n",
|
||||||
"df = imputer.transform(df)"
|
"X_train = imputer.transform(X_train)\n",
|
||||||
|
"X_test = imputer.transform(X_test)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Kontrolle fehlende Werte\n",
|
"## Kontrolle der fehlenden Werte\n",
|
||||||
"In diesem Schritt kontrollieren wir ob wir alle fehlende Werte gelöscht haben. "
|
"Zum Abschluss prüfen wir, ob nach der Imputation noch fehlende Werte vorhanden sind. Dazu berechnen wir je Spalte den Anteil fehlender Einträge und behalten nur Spalten mit Lücken — die Liste sollte nun leer sein."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 28,
|
"execution_count": 25,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@ -1989,23 +2072,31 @@
|
|||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Liste fehlende Werte Series([], dtype: float64)\n",
|
"Liste fehlende Werte Series([], dtype: float64)\n",
|
||||||
"Anzahl fehlende Werte in df: 0\n"
|
"Anzahl fehlende Werte in X_train: 0\n",
|
||||||
|
"Liste fehlende Werte Series([], dtype: float64)\n",
|
||||||
|
"Anzahl fehlende Werte in X_test: 0\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"## Kontrolle ob es noch fehlende Werte hat\n",
|
"## Kontrolle ob es noch fehlende Werte auf X_train hat\n",
|
||||||
"missing_values = df.isnull().mean() * 100 \n",
|
"missing_values = X_train.isnull().mean() * 100 \n",
|
||||||
"missing_values = missing_values[missing_values > 0] #\n",
|
"missing_values = missing_values[missing_values > 0] #\n",
|
||||||
"print(f\"Liste fehlende Werte {missing_values}\")\n",
|
"print(f\"Liste fehlende Werte {missing_values}\")\n",
|
||||||
"print(f\"Anzahl fehlende Werte in df: {len(missing_values)}\")"
|
"print(f\"Anzahl fehlende Werte in X_train: {len(missing_values)}\")\n",
|
||||||
|
"\n",
|
||||||
|
"## Kontrolle ob es noch fehlende Werte auf X_train hat\n",
|
||||||
|
"missing_values = X_test.isnull().mean() * 100 \n",
|
||||||
|
"missing_values = missing_values[missing_values > 0] #\n",
|
||||||
|
"print(f\"Liste fehlende Werte {missing_values}\")\n",
|
||||||
|
"print(f\"Anzahl fehlende Werte in X_test: {len(missing_values)}\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"Keine fehlende Werte sind mehr da, daher können wir nun weiterarbeiten. "
|
"Die Kontrolle bestätigt: Es sind keine fehlenden Werte mehr vorhanden. Der Datensatz ist nun vollständig und wir können mit den nächsten Aufbereitungsschritten fortfahren."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2017,17 +2108,18 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 30,
|
"execution_count": 26,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"df.to_csv(\"../../../Data/hotel_bookings/hotel_imputedcsv\",index=False)\n"
|
"X_train.to_csv(\"../../../Data/hotel_bookings/X_train_imputed.csv\",index=False)\n",
|
||||||
|
"X_test.to_csv(\"../../../Data/hotel_bookings/X_test_imputed.csv\",index=False)\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"kernelspec": {
|
"kernelspec": {
|
||||||
"display_name": ".venv (3.12.11)",
|
"display_name": "ml2",
|
||||||
"language": "python",
|
"language": "python",
|
||||||
"name": "python3"
|
"name": "python3"
|
||||||
},
|
},
|
||||||
@ -2041,7 +2133,7 @@
|
|||||||
"name": "python",
|
"name": "python",
|
||||||
"nbconvert_exporter": "python",
|
"nbconvert_exporter": "python",
|
||||||
"pygments_lexer": "ipython3",
|
"pygments_lexer": "ipython3",
|
||||||
"version": "3.12.11"
|
"version": "3.12.9"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nbformat": 4,
|
"nbformat": 4,
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
unterlagen/M06_Argue_with_Data 1.pdf
Normal file
BIN
unterlagen/M06_Argue_with_Data 1.pdf
Normal file
Binary file not shown.
BIN
unterlagen/M08_Missing_Data.pdf
Normal file
BIN
unterlagen/M08_Missing_Data.pdf
Normal file
Binary file not shown.
BIN
unterlagen/M09_Reproducible_Preprocessing_Git_DVC.pdf
Normal file
BIN
unterlagen/M09_Reproducible_Preprocessing_Git_DVC.pdf
Normal file
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user