{ "cells": [ { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "# Data Science 2 (Klassifikation)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "from matplotlib.lines import Line2D\n", "import numpy as np\n", "import pandas as pd\n", "import seaborn as sns\n", "import sklearn\n", "\n", "from sklearn.linear_model import LogisticRegression\n", "from sklearn.model_selection import train_test_split\n", "\n", "# Matplotlib parameters\n", "plt.rcParams[\"figure.dpi\"] = 150\n", "plt.rcParams[\"figure.figsize\"] = [5, 4]\n", "sns.set_style(\"whitegrid\")" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "## Aufgabe 1: Evaluation von Klassifizierungen\n", "Im Folgenden wollen wir uns mit verschiedenen Metriken zur Evaluation von Klassifikatoren vertraut machen. " ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "### Aufgabe 1.1: Precision, Recall und F1-Score\n", "Gegeben ist ein Vektor an richtigen Labels und verschiedene Klassifizierungen. Berechnen Sie Precision, Recall und F1-Score für die Klassifizierungen A, B, C und D. \"1\" steht für positiv, \"0\" für negativ." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "true_labels = [0, 1, 0, 0, 1, 0, 1]\n", "classification_A = [0, 1, 1, 1, 1, 0, 1]\n", "classification_B = [1, 0, 1, 0, 1, 1, 1]\n", "classification_C = [0, 0, 0, 0, 0, 1, 0]\n", "classification_D = [0, 1, 0, 0, 0, 1, 0]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# your code goes here" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "### Aufgabe 1.2: Recall an einem Beispiel\n", "![Recall Aufgabe](../resources/10_data_science/klassifikation.png)" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "## Aufgabe 2: k-Nearest-Neighbor\n", "\n", "### Aufgabe 2.1: kNN Zuordnungen bestimmen\n", "\n", "Das untenstehende Diagramm zeigt die Verteilung der Attributswerte eines zweidimensionalen Trainingsdatensatzes inklusive der zugehörigen Labels als Farben.\n", "\n", "Bestimmen Sie den jeweils kleinsten (ganzzahligen) Wert für k, mit dem der k-Nearest-Neighbor (kNN) Algorithmus die zusätzlichen Datenpunkte in das gewünschte Cluster einordnert. Bei gleichem k Ordnert der Algorithmus den Punkt in das Cluster mit der niedrigeren Ziffer ein. Als Abstandsmaß wird die Manhatten-Distanz verwendet." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# ==== Parameters ====\n", "variant = 1\n", "points_to_classify = [\"7,3\", \"5,5\", \"-4,3\"]\n", "num_points = 50\n", "num_points_tiny_cluster = 5\n", "num_clusters = 4\n", "grid_size = 7\n", "grid_offset = [0, 0]\n", "seed = 42\n", "\n", "# ==== Data Generation ====\n", "generator = np.random.default_rng(seed)\n", "points = np.concatenate(\n", " (\n", " generator.integers(low=-grid_size, high=grid_size, size=(2, num_points), endpoint=True),\n", " generator.integers(\n", " low=-grid_size, high=grid_size, size=(2, num_points_tiny_cluster), endpoint=True\n", " ),\n", " ),\n", " axis=1,\n", ")\n", "\n", "assignments = np.concatenate(\n", " (\n", " generator.integers(low=1, high=num_clusters - 1, size=num_points, endpoint=True),\n", " np.ones(shape=num_points_tiny_cluster, dtype=int) * num_clusters,\n", " )\n", ")\n", "\n", "data = pd.DataFrame({\"x\": points[0], \"y\": points[1], \"cluster\": assignments})\n", "data = data.drop_duplicates([\"x\", \"y\"], keep=\"last\")\n", "groups = data.groupby(\"cluster\")\n", "\n", "default_markers = [\"o\", \"v\", \"P\", \"s\", \"^\", \"*\", \"D\"]\n", "default_colors = [plt.cm.viridis(i) for i in np.linspace(0, 1, num_clusters)]\n", "\n", "fig, ax = plt.subplots(figsize=(5, 5))\n", "legend_elements = []\n", "\n", "for idx, (group_name, group_data) in enumerate(groups):\n", " color = default_colors[idx % len(default_colors)]\n", " marker = default_markers[idx % len(default_markers)]\n", " ax.scatter(\n", " x=group_data.x,\n", " y=group_data.y,\n", " color=color,\n", " marker=marker,\n", " s=80.0,\n", " linewidths=1.0,\n", " )\n", " legend_elements.append(\n", " Line2D([0], [0], marker=marker, color=color, label=group_name, linewidth=0)\n", " )\n", "\n", "if points_to_classify:\n", " for point in points_to_classify:\n", " x, y = map(int, point.split(\",\"))\n", " ax.scatter(x, y, color=\"red\", marker=\"x\", s=120.0, linewidths=4)\n", "\n", "plt.figlegend(\n", " handles=legend_elements,\n", " title=\"Cluster-Zuweisungen\",\n", " ncols=num_clusters,\n", " framealpha=1.0,\n", ")\n", "\n", "ax.set_xlabel(\"x\")\n", "ax.set_ylabel(\"y\")\n", "\n", "# Fix: Set linear scaling for both axes\n", "ax.set_xlim(-grid_size - 0.5, grid_size + 0.5)\n", "ax.set_ylim(-grid_size - 0.5, grid_size + 0.5)\n", "\n", "# Set ticks at integer positions for linear scaling\n", "ax.set_xticks(np.arange(-grid_size, grid_size + 1, 1))\n", "ax.set_yticks(np.arange(-grid_size, grid_size + 1, 1))\n", "\n", "# Minor ticks for finer grid\n", "ax.set_xticks(np.arange(-grid_size, grid_size + 1, 1), minor=True)\n", "ax.set_yticks(np.arange(-grid_size, grid_size + 1, 1), minor=True)\n", "\n", "ax.grid(True, which=\"both\", alpha=0.4)\n", "ax.set_aspect(\"equal\", adjustable=\"box\")\n", "ax.set_axisbelow(True)\n", "\n", "plt.tight_layout()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "| Punkt (x,y)| gewolltes Cluster | notwendiges k |\n", "|------------|-------------------|---------------|\n", "| (7,3) | 4 | |\n", "| (5,5) | 3 | |\n", "| (-4,5) | 1 | |" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "## 2.2 k-Nearest Neighbors (kNN) am Beispiel Dokumentenzuordnung*\n", "\n", "Die kNN-Suche (k-Nearest Neighbors) ist ein essenzieller Bestandteil moderner KI-Systeme. Sie ermöglicht es beispielsweise, aus einer großen Menge indizierter Dokumente die relevantesten Nachbarn für eine Anfrage zu finden. Dies wird häufig mit Vektorrepräsentationen von Texten umgesetzt, wobei die Ähnlichkeit meist über die euklidische Distanz oder Kosinus-Ähnlichkeit berechnet wird.\n", "\n", "In der folgenden Aufgabe sollt ihr nun selbst den kNN-Algorithmus implementieren. Aus einer Auswahl mehrerer \"Dokumente\" (hier sind es der Einfachheit halber kurze Strings) wollen wir eine einfache Anfrage, wie z.B. \"Was ist maschinelles Lernen?\" senden können und das Dokument auswählen, dass am ehesten zur Anfrage passt.\n", "Das bedeutet, es wird das Dokument ausgewählt, dessen Wörter eine besonders hohe Ähnlichkeit zu den Wörtern in der Anfrage haben.\n", "\n", "Zuerst initialisieren wir dazu die \"Dokumente\":" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# Dokumente sind kurze Strings\n", "documents = [\n", " \"Künstliche Intelligenz ist ein Teilgebiet der Informatik.\",\n", " \"Maschinelles Lernen ist eine Methode der KI.\",\n", " \"Neuronale Netze sind Modelle für maschinelles Lernen.\",\n", " \"Retrieval Augmented Generation nutzt kNN-Suche.\",\n", " \"Die euklidische Distanz misst die Ähnlichkeit von Vektoren.\",\n", "]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# Speichere alle verschiedenen Wörter aus den Dokumenten\n", "vocab = sorted(\n", " list(set(word.lower() for doc in documents for word in doc.replace(\".\", \"\").split()))\n", ")\n", "print(\"Vokabular:\", vocab)" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "Mit Strings können wir nicht gut rechnen. Daher suchen wir einen Weg, die Dokumente als Zahlen darzustellen.\n", "Wir entscheiden uns dazu, ein Dokument zu einen Vektor umzuwandeln, der aus Zahlen besteht.\n", "Der 1. Eintrag des Vektors steht dabei für die Anzahl, wie oft die erste Vokabel aus der Vokabelliste im Dokument vorkommt, usw.\n", "\n", "In der Praxis werden deutlich komplexere Vektorisierungen verwendet, wie z.B. TF-IDF oder Word Embeddings, aber für diese Aufgabe reicht es, die Häufigkeit der Wörter zu zählen." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# Bekommt einen Text (text) und Vokabelliste (vocab).\n", "# Gibt eine Liste zurück, die für jede Vokabel angibt, wie oft es im text vorkommt\n", "# (i-tes Element ist die Anzahl der i-ten Vokabel im Text)\n", "def count_vocab_in_text(text: str, vocab: list[str]) -> list[int]:\n", " words = text.lower().replace(\".\", \"\").split()\n", " return [words.count(word) for word in vocab]\n", "\n", "\n", "# Jedes Dokument wird zu einen Vektor umgewandelt. Wir speichern sie uns in eine Liste:\n", "vectorized_docs = [count_vocab_in_text(doc, vocab) for doc in documents]" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "Nachdem wir die Dokumente zu Vektoren umgewandelt haben, die aus Zahlen (Anzahl der Vokabeln im Dokument) besteht, können wir nun die eigentliche Anfrage stellen:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# Anfrage als String\n", "query = \"Was ist maschinelles Lernen?\"\n", "\n", "# Anfrage als Vektor\n", "query_vector = count_vocab_in_text(query, vocab)" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "Hier kommt nun kNN ins Spiel. Wir haben eine Liste an Dokumenten, die zu Vektoren umgewandelt wurden (`vectorized_docs`), und wir haben die Anfrage, die auch zu einem Vektor umgewandelt wurde (`query_vector`).\n", "Implementiert nun den kNN-Algorithmus anhand der euklidischen Distanz:\n", " \n", "Hinweis:\n", "- Berechnet erst die Distanzen von der Anfrage zu allen Dokumenten\n", "- Sortiert die Distanzen aufsteigend\n", "- Wähle die ersten k Dokumente mit geringsten Abstand" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "def euclidean_distance(a: list[int], b: list[int]) -> float:\n", " return float(np.linalg.norm(np.array(a) - np.array(b)))\n", "\n", "\n", "def knn_search(\n", " query_vec: list[int], doc_vecs: list[list[int]], k: int = 2\n", ") -> tuple[list[int], list[float]]:\n", " \"\"\"Rückgabewert: Indizes der k Dokumente, Distanzen\"\"\"\n", " # Hier kNN implementieren\n", " # TODO: Berechnet erst die Distanzen von der Anfrage zu allen Dokumenten\n", " # TODO: Sortiert die Distanzen aufsteigend\n", " # TODO: Wähle die ersten k Dokumente mit geringsten Abstand\n", " return NotImplemented\n", "\n", "\n", "# Führe kNN aus und gebe das Ergebnis aus\n", "indices, dists = knn_search(query_vector, vectorized_docs, k=2)\n", "print(\"Die nächsten Nachbarn sind:\")\n", "for idx, dist in zip(indices, dists):\n", " print(f\"Dokument {idx}: '{documents[idx]}' mit Distanz {dist:.2f}\")" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "**Hinweis:**\n", "- Anders, als beim klassischen kNN-Algorithmus klassifizieren wir hier die Dokumente nicht, sondern ranken sie lediglich nach kürzester Distanz. Beim klassischen kNN würde der Datenpunkt die Klasse der Mehrheit der k Datenpunkte mit kürzester Distanz annehmen.\n", "- In diesem Kurs betrachten wir lediglich eine sehr einfache Implementierung des kNN-Algorithmus. In der Praxis werden deutlich komplexere Algorithmen verwendet, die z.B. auf Baumstrukturen basieren, um die Suche zu beschleunigen." ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "## Aufgabe 3: Klassifikation in der Praxis\n", "\n", "Im Folgenden werden wir einen Datensatz klassifizieren. Wir werden Sie in den einzelnen Teilaufgaben durch die nötigen Schritte führen. \n", "\n", "Wir werden für die meisten Teilaufgaben Funktionalitäten von scikit-learn nutzen. \n", "\n", "Im Folgenden geht es um einen Datensatz mit Titanic-Passagieren. Sie werden ein Modell bauen, das anhand verschiedener Attribute vorhersagt, ob Passagiere den Schiffsuntergang überlebt haben oder nicht. \n", "\n", "\n", "### Aufgabe 3.1: Datensatz einlesen" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# Datasatz einlesen und Spalten benennen\n", "titanic = pd.read_csv(\"../resources/10_data_science/titanic-train.csv\")\n", "titanic.columns = [\n", " \"PassengerId\",\n", " \"Survived\",\n", " \"Pclass\",\n", " \"Name\",\n", " \"Sex\",\n", " \"Age\",\n", " \"SibSp\",\n", " \"Parch\",\n", " \"Ticket\",\n", " \"Fare\",\n", " \"Cabin\",\n", " \"Embarked\",\n", "]\n", "\n", "# Erste Zeilen des Datensets ausgeben\n", "titanic.head()" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "Der Datensatz enthält folgende \"Attribute\" (= \"Variablen\" = \"Features\")\n", "* Survived - Hat überlebt? (0 = No; 1 = Yes)\n", "* Pclass - Passagierklasse (1 = erste; 2 = zweite; 3 = dritte)\n", "* Name - Name\n", "* Sex - Geschlecht\n", "* Age - Alter\n", "* SibSp - Zahl der Geschwister/Partner an Bord\n", "* Parch - Zahl der Eltern/Kinder an Bord\n", "* Ticket - Ticketnummer\n", "* Fare - Ticketkosten (in britischen Pfund)\n", "* Cabin - Kabinennummer\n", "* Embarked - Zustiegshafen (C = Cherbourg; Q = Queenstown; S = Southampton) \n", "\n", "Unser Modell soll die Spalte `Survived` vorhersagen, also ob Passagiere überlebt haben.\n", "\n", "Da wir ein Modell zur Vorhersage des Überlebens von Passagieren der Titanic aufbauen, wird unser Ziel die Variable \"Survived\" sein. Um sicherzustellen, dass es sich um eine binäre Variable handelt, verwenden wir die Funktion countplot() von Seaborn.\n", "\n", "### Aufgabe 3.2: Die Daten kennen lernen\n", "Ein wichtiger erster Schritt ist es, den Datensatz, mit dem man arbeitet, kennen zu lernen. `scikit-learn`, `pandas`, und `seaborn` bieten dazu zum Beispiel folgende nützliche Funktionen:\n", "\n", "- `dataframe.info()`: zeigt die Datentypen eines DataFrames. Dies sind im Moment noch automatisch erkannte Datentypen.\n", "- `dataframe.describe()`: zeigt Informationen über Verteilungen numerischer Attribute\n", "- `dataframe.plot(kind=\"scatter\", x=\"ATTRIBUT1\", y=\"ATTRIBUT2\")`: plottet zwei Attribute eines Datensatzes gegeneinander\n", "- `dataframe[[\"ATTRIBUT1\", \"ATTRIBUT2\"]].head()`: Zeigt einen Teil der Attribute\n", "- `sns.countplot(x=\"ATTRIBUT\", data=dataframe)`: Visualisiert die Werteverteilung eines Attributs\n", "- `dataframe.isnull()`: Zeigt fehlende Werte an\n", "- `dataframe.isnull().sum()` zeigt die Zahl der fehlenden Werte pro Spalte\n", "\n", "Wenden Sie verschiedene dieser Funktionen auf den Titanic-Datensatz an. Fragen:\n", "- Welche Informationen lernen Sie über den Datensatz? \n", "- Welche der Attribute werden aktuell als numerisch gesehen, welche als kategorisch? Sind die Datentypen sinnvoll?\n", "- Wie viele Werte nimmt das Attribut `Survived` an?\n", "- In welchen Spalten gibt es fehlende Werte?\n", "- Welche der Attribute halten Sie für relevant, um das Überleben vorherzusagen?" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# your code goes here" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "### Aufgabe 3.3: Mit fehlenden Werten umgehen\n", "Fehlende Werte können großen Einfluss auf Datenanalysen haben. Manche Modelle können mit fehlenden Werten nicht umgehen. Es gibt verschiedene Wege, mit fehlenden Werten umzugehen (Stichworte: imputation, omission, analysis). \n", "\n", "Aufgabe: Entfernen Sie alle Attribute, die fehlende Werte enthalten (außer \"Embarked\", dies werden wir später separat behandeln) . Entfernen Sie außerdem PassengerID, Name, und Ticket, da diese vermutlich keinen Einfluss auf das Überleben haben. \n", "\n", "Hierzu ist die Funktion `drop()` hilfreich: \n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# your code goes here" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "Falls Sie die Attribute korrekt entfernt haben, haben Sie nun noch 7 Attribute und nur die Variable 'Embarked' enthält noch 2 Nullwerte. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "titanic_data.isnull().sum()" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "Hier entfernen wir die entsprechenden Datenpunkte (da das Attribut generell nützlich ist):" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# Verbliebene Datenpunkte mit fehlenden Werten entfernen\n", "titanic_data.dropna(inplace=True)\n", "\n", "# Check: keine fehlenden Werte mehr\n", "titanic_data.isnull().sum()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "titanic_data.head()" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "### Aufgabe 3.4: Mit kategorischen Attributen umgehen\n", "\n", "Logistische Regression kann nicht mit kategorischen Attributen umgehen (mehr dazu später). Daher müssen kategorische Attribute in numerische umgewandelt werden. Hierzu wird üblicherweise \"dummy coding\" eingesetzt. Dabei wird ein kategorisches Attribut von mehreren \"dummy\" Attributen repräsentiert.\n", "\n", "Beispiel einer kategorischen Variable \"Farbe\":" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "bsp = pd.DataFrame({\"Farbe\": [\"rot\", \"blau\", \"schwarz\"]})\n", "bsp" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "Dummy Coding würde für dieses kategorische Attribut drei Dummy-Attribute erstellen:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "pd.get_dummies(bsp.Farbe)" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "Aufgabe: Wandeln Sie alle kategorischen Attribute des Datensets in numerische um. Verwenden Sie hierzu die [get_dummies()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.get_dummies.html) Funktion:\n", "\n", "```python\n", "# dummies erzeugen\n", "dummies_ATTRIBUT1 = pd.get_dummies(titanic_data['ATTRIBUT'], drop_first=True)\n", "# ...\n", "\n", "# dummies zum Datenset hinzufügen\n", "titanic_dmy = pd.concat([titanic_data, dummies_ATTRIBUT1, dummies_ATTRIBUT2,...], axis=1)\n", "\n", "# kategorische Attribute aus dem Datenset entfernen\n", "titanic_dmy.drop(['ATTRIBUT1', 'ATTRIBUT2', ...], axis=1, inplace=True)\n", "```\n", "\n", "Hinweis: Der Parameter `drop_first=True` sorgt dafür, dass eines der Dummy-Attribute ausgelassen wird, um redundante Informationen zu entfernen." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# your code goes here" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "### Aufgabe 3.5: Mit korrelierten Attributen umgehen\n", "\n", "Korrelierte Attribute können bei logistischer Regression Probleme verursachen. Wir werden anhand einer Korrelations-Matrix korrelierte Attribute identifizeren und aus dem Datensatz entfernen. \n", "\n", "Eine Korrelations-Matrix zeigt für jedes Attribut-Attribut-Paar die Korrelation an: von 1 für stark positive Korrelation, über 0 für keine Korrelation, zu -1 für stark negative Korrelation.\n", "\n", "Eine Ausgabe der Matrix als Heatmap kann nützlich sein." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# Korrelationsmatrix\n", "round(titanic_dmy.corr(), 2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# Ausgabe als Heatmap\n", "\n", "# Farbpalette mit zwei Extremen (für negative und positive Korrelationen)\n", "cmap = sns.diverging_palette(10, 220, as_cmap=True)\n", "\n", "# Heatmap zeichnen\n", "sns.heatmap(\n", " titanic_dmy.corr(),\n", " cmap=cmap,\n", " vmax=1.0,\n", " vmin=-1.0,\n", " center=0,\n", " square=True,\n", " linewidths=0.5,\n", " cbar_kws={\"shrink\": 0.5},\n", ")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "**Frage:** Welche Attributpaare sind am stärksten korreliert?" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "Es wäre denkbar, die Attribute, die korreliert sind, zu entfernen. Dies werden wir der Einfachheit halber nicht tun." ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "### Aufgabe 3.6: Vorbereiten der Daten für Modell-Training" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# Zerlegen in Trainingsattribute (alles außer 'Survived') und Labels ('Survived')\n", "X = titanic_dmy.drop(\"Survived\", axis=1).values\n", "y = titanic_dmy.loc[:, \"Survived\"].values\n", "\n", "# Aufteilung in Trainingsset und Testset\n", "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=25)" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "### Aufgabe 3.7: Modell fitten und analysieren\n", "\n", "Wir fitten nun ein logistisches Regressionsmodell anhand der Trainingsdaten:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "lr_model = LogisticRegression(solver=\"liblinear\")\n", "lr_model = lr_model.fit(X_train, y_train)" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "Analysieren Sie nun die Qualtiät diese Modells. Hilfreiche Funktionen daüfr sind:\n", "- `y_train_pred = model.predict(X_train)` und `y_train_pred = model.predict(X_test)`: generiert Modell-Vorhersagen für die gegebenen Datenpunkte\n", "- `sklearn.metrics.confusion_matrix(y_test, y_test_pred)`: erstellt die Konfusionsmatrix für Modell-Vorhersagen\n", "\n", "Vergleichen Sie die Qualität zu zwei Modellen, die gar nicht oder nicht bis zum Ende trainiert wurden." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# Untrainiertes Modell:\n", "lr_model_unfitted = LogisticRegression(solver=\"liblinear\", max_iter=0)\n", "lr_model_unfitted = lr_model_unfitted.fit(X_train, y_train)\n", "\n", "# Nicht fertig trainiertes Modell:\n", "lr_model_partially_fitted = LogisticRegression(solver=\"liblinear\", max_iter=3)\n", "lr_model_partially_fitted = lr_model_partially_fitted.fit(X_train, y_train)\n", "\n", "# Die Warnungen können Sie ignorieren, da wir bewusst schlechte Modelle trainieren" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# your code goes here" ] } ], "metadata": {}, "nbformat": 4, "nbformat_minor": 4 }