You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ML-For-Beginners/translations/de/2-Regression/4-Logistic/solution/R/lesson_4-R.ipynb

686 lines
32 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Erstellen Sie ein logistisches Regressionsmodell - Lektion 4\n",
"\n",
"![Infografik: Logistische vs. lineare Regression](../../../../../../translated_images/linear-vs-logistic.ba180bf95e7ee66721ba10ebf2dac2666acbd64a88b003c83928712433a13c7d.de.png)\n",
"\n",
"#### **[Quiz vor der Vorlesung](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/15/)**\n",
"\n",
"#### Einführung\n",
"\n",
"In dieser letzten Lektion zur Regression, einer der grundlegenden *klassischen* ML-Techniken, werfen wir einen Blick auf die logistische Regression. Diese Technik wird verwendet, um Muster zu erkennen und binäre Kategorien vorherzusagen. Ist diese Süßigkeit Schokolade oder nicht? Ist diese Krankheit ansteckend oder nicht? Wird dieser Kunde dieses Produkt wählen oder nicht?\n",
"\n",
"In dieser Lektion lernen Sie:\n",
"\n",
"- Techniken der logistischen Regression\n",
"\n",
"✅ Vertiefen Sie Ihr Verständnis für die Arbeit mit dieser Art von Regression in diesem [Learn-Modul](https://learn.microsoft.com/training/modules/introduction-classification-models/?WT.mc_id=academic-77952-leestott)\n",
"\n",
"## Voraussetzung\n",
"\n",
"Nachdem wir mit den Kürbisdaten gearbeitet haben, sind wir nun vertraut genug, um zu erkennen, dass es eine binäre Kategorie gibt, mit der wir arbeiten können: `Color`.\n",
"\n",
"Lassen Sie uns ein logistisches Regressionsmodell erstellen, um vorherzusagen, *welche Farbe ein gegebener Kürbis wahrscheinlich hat* (orange 🎃 oder weiß 👻), basierend auf einigen Variablen.\n",
"\n",
"> Warum sprechen wir über binäre Klassifikation in einer Lektion über Regression? Nur aus sprachlicher Bequemlichkeit, da die logistische Regression [eigentlich eine Klassifikationsmethode](https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression) ist, wenn auch eine lineare. Lernen Sie in der nächsten Lektion weitere Methoden zur Klassifikation von Daten kennen.\n",
"\n",
"Für diese Lektion benötigen wir die folgenden Pakete:\n",
"\n",
"- `tidyverse`: Das [tidyverse](https://www.tidyverse.org/) ist eine [Sammlung von R-Paketen](https://www.tidyverse.org/packages), die Datenwissenschaft schneller, einfacher und unterhaltsamer macht!\n",
"\n",
"- `tidymodels`: Das [tidymodels](https://www.tidymodels.org/) Framework ist eine [Sammlung von Paketen](https://www.tidymodels.org/packages/) für Modellierung und maschinelles Lernen.\n",
"\n",
"- `janitor`: Das [janitor-Paket](https://github.com/sfirke/janitor) bietet einfache Werkzeuge zur Untersuchung und Bereinigung von unordentlichen Daten.\n",
"\n",
"- `ggbeeswarm`: Das [ggbeeswarm-Paket](https://github.com/eclarke/ggbeeswarm) bietet Methoden zur Erstellung von Beeswarm-Diagrammen mit ggplot2.\n",
"\n",
"Sie können diese Pakete wie folgt installieren:\n",
"\n",
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"janitor\", \"ggbeeswarm\"))`\n",
"\n",
"Alternativ überprüft das untenstehende Skript, ob Sie die für dieses Modul erforderlichen Pakete installiert haben, und installiert sie bei Bedarf.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"suppressWarnings(if (!require(\"pacman\"))install.packages(\"pacman\"))\n",
"\n",
"pacman::p_load(tidyverse, tidymodels, janitor, ggbeeswarm)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## **Definiere die Frage**\n",
"\n",
"Für unsere Zwecke werden wir dies als binär ausdrücken: 'Weiß' oder 'Nicht Weiß'. Es gibt auch eine Kategorie 'gestreift' in unserem Datensatz, aber es gibt nur wenige Instanzen davon, daher werden wir sie nicht verwenden. Sie verschwindet ohnehin, sobald wir Nullwerte aus dem Datensatz entfernen.\n",
"\n",
"> 🎃 Fun Fact: Wir nennen weiße Kürbisse manchmal 'Geister'-Kürbisse. Sie sind nicht sehr leicht zu schnitzen, daher sind sie nicht so beliebt wie die orangenen, aber sie sehen cool aus! Wir könnten unsere Frage also auch so formulieren: 'Geist' oder 'Nicht Geist'. 👻\n",
"\n",
"## **Über logistische Regression**\n",
"\n",
"Die logistische Regression unterscheidet sich in einigen wichtigen Punkten von der linearen Regression, die du zuvor gelernt hast.\n",
"\n",
"#### **Binäre Klassifikation**\n",
"\n",
"Die logistische Regression bietet nicht die gleichen Funktionen wie die lineare Regression. Erstere liefert eine Vorhersage über eine `binäre Kategorie` (\"orange oder nicht orange\"), während letztere in der Lage ist, `kontinuierliche Werte` vorherzusagen, zum Beispiel basierend auf der Herkunft eines Kürbisses und der Erntezeit, *wie stark sein Preis steigen wird*.\n",
"\n",
"![Infografik von Dasani Madipalli](../../../../../../translated_images/pumpkin-classifier.562771f104ad5436b87d1c67bca02a42a17841133556559325c0a0e348e5b774.de.png)\n",
"\n",
"### Andere Klassifikationen\n",
"\n",
"Es gibt andere Arten der logistischen Regression, einschließlich multinomialer und ordinaler:\n",
"\n",
"- **Multinomial**, bei der es mehr als eine Kategorie gibt - \"Orange, Weiß und Gestreift\".\n",
"\n",
"- **Ordinal**, bei der geordnete Kategorien verwendet werden, nützlich, wenn wir unsere Ergebnisse logisch ordnen möchten, wie unsere Kürbisse, die nach einer begrenzten Anzahl von Größen geordnet sind (mini, sm, med, lg, xl, xxl).\n",
"\n",
"![Multinomiale vs ordinale Regression](../../../../../../translated_images/multinomial-vs-ordinal.36701b4850e37d86c9dd49f7bef93a2f94dbdb8fe03443eb68f0542f97f28f29.de.png)\n",
"\n",
"#### **Variablen MÜSSEN NICHT korrelieren**\n",
"\n",
"Erinnerst du dich, wie die lineare Regression besser mit stärker korrelierten Variablen funktionierte? Die logistische Regression ist das Gegenteil - die Variablen müssen nicht übereinstimmen. Das funktioniert für diese Daten, die nur schwache Korrelationen aufweisen.\n",
"\n",
"#### **Du brauchst viele saubere Daten**\n",
"\n",
"Die logistische Regression liefert genauere Ergebnisse, wenn du mehr Daten verwendest; unser kleiner Datensatz ist für diese Aufgabe nicht optimal, also behalte das im Hinterkopf.\n",
"\n",
"✅ Überlege, welche Arten von Daten sich gut für die logistische Regression eignen würden.\n",
"\n",
"## Übung - Daten bereinigen\n",
"\n",
"Bereinige zunächst die Daten ein wenig, indem du Nullwerte entfernst und nur einige der Spalten auswählst:\n",
"\n",
"1. Füge den folgenden Code hinzu:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Load the core tidyverse packages\n",
"library(tidyverse)\n",
"\n",
"# Import the data and clean column names\n",
"pumpkins <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/2-Regression/data/US-pumpkins.csv\") %>% \n",
" clean_names()\n",
"\n",
"# Select desired columns\n",
"pumpkins_select <- pumpkins %>% \n",
" select(c(city_name, package, variety, origin, item_size, color)) \n",
"\n",
"# Drop rows containing missing values and encode color as factor (category)\n",
"pumpkins_select <- pumpkins_select %>% \n",
" drop_na() %>% \n",
" mutate(color = factor(color))\n",
"\n",
"# View the first few rows\n",
"pumpkins_select %>% \n",
" slice_head(n = 5)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Sie können jederzeit einen Blick auf Ihren neuen Dataframe werfen, indem Sie die Funktion [*glimpse()*](https://pillar.r-lib.org/reference/glimpse.html) wie unten gezeigt verwenden:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"pumpkins_select %>% \n",
" glimpse()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Lassen Sie uns bestätigen, dass wir tatsächlich ein binäres Klassifikationsproblem bearbeiten:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Subset distinct observations in outcome column\n",
"pumpkins_select %>% \n",
" distinct(color)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Visualisierung - kategorisches Diagramm\n",
"Bis jetzt haben Sie die Kürbisdaten erneut geladen und bereinigt, sodass ein Datensatz mit einigen Variablen, einschließlich Farbe, erhalten bleibt. Lassen Sie uns das Dataframe im Notebook mithilfe der ggplot-Bibliothek visualisieren.\n",
"\n",
"Die ggplot-Bibliothek bietet einige praktische Möglichkeiten, Ihre Daten zu visualisieren. Zum Beispiel können Sie die Verteilungen der Daten für jede Sorte und Farbe in einem kategorischen Diagramm vergleichen.\n",
"\n",
"1. Erstellen Sie ein solches Diagramm, indem Sie die Funktion geombar verwenden, unsere Kürbisdaten nutzen und eine Farbzuordnung für jede Kürbiskategorie (orange oder weiß) festlegen:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "python"
}
},
"outputs": [],
"source": [
"# Specify colors for each value of the hue variable\n",
"palette <- c(ORANGE = \"orange\", WHITE = \"wheat\")\n",
"\n",
"# Create the bar plot\n",
"ggplot(pumpkins_select, aes(y = variety, fill = color)) +\n",
" geom_bar(position = \"dodge\") +\n",
" scale_fill_manual(values = palette) +\n",
" labs(y = \"Variety\", fill = \"Color\") +\n",
" theme_minimal()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Durch die Beobachtung der Daten können Sie erkennen, wie die Farbdaten mit der Sorte zusammenhängen.\n",
"\n",
"✅ Angesichts dieses kategorialen Diagramms, welche interessanten Untersuchungen können Sie sich vorstellen?\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Datenvorverarbeitung: Feature-Encoding\n",
"\n",
"Unser Kürbis-Datensatz enthält Zeichenkettenwerte in allen seinen Spalten. Mit kategorischen Daten zu arbeiten ist für Menschen intuitiv, aber nicht für Maschinen. Maschinelle Lernalgorithmen funktionieren besser mit Zahlen. Deshalb ist Encoding ein sehr wichtiger Schritt in der Datenvorverarbeitungsphase, da es uns ermöglicht, kategorische Daten in numerische Daten umzuwandeln, ohne Informationen zu verlieren. Ein gutes Encoding führt zu einem guten Modell.\n",
"\n",
"Für das Feature-Encoding gibt es zwei Haupttypen von Encodern:\n",
"\n",
"1. Ordinaler Encoder: Er eignet sich gut für ordinale Variablen, das sind kategorische Variablen, bei denen die Daten einer logischen Reihenfolge folgen, wie die Spalte `item_size` in unserem Datensatz. Er erstellt eine Zuordnung, bei der jede Kategorie durch eine Zahl repräsentiert wird, die der Reihenfolge der Kategorie in der Spalte entspricht.\n",
"\n",
"2. Kategorischer Encoder: Er eignet sich gut für nominale Variablen, das sind kategorische Variablen, bei denen die Daten keiner logischen Reihenfolge folgen, wie alle Merkmale außer `item_size` in unserem Datensatz. Es handelt sich um ein One-Hot-Encoding, was bedeutet, dass jede Kategorie durch eine binäre Spalte repräsentiert wird: Die kodierte Variable ist gleich 1, wenn der Kürbis zu dieser Sorte gehört, und 0, wenn nicht.\n",
"\n",
"Tidymodels bietet ein weiteres praktisches Paket: [recipes](https://recipes.tidymodels.org/) ein Paket zur Datenvorverarbeitung. Wir definieren ein `recipe`, das angibt, dass alle Prädiktorspalten in eine Menge von Ganzzahlen kodiert werden sollen, `prep` es, um die erforderlichen Mengen und Statistiken für die Operationen zu schätzen, und schließlich `bake`, um die Berechnungen auf neue Daten anzuwenden.\n",
"\n",
"> Normalerweise wird recipes üblicherweise als Vorverarbeitungswerkzeug für die Modellierung verwendet, wobei es definiert, welche Schritte auf einen Datensatz angewendet werden müssen, um ihn für die Modellierung vorzubereiten. In diesem Fall wird **dringend empfohlen**, ein `workflow()` zu verwenden, anstatt ein Rezept manuell mit prep und bake zu schätzen. Das werden wir gleich sehen.\n",
">\n",
"> Für den Moment verwenden wir jedoch recipes + prep + bake, um festzulegen, welche Schritte auf einen Datensatz angewendet werden sollen, um ihn für die Datenanalyse vorzubereiten, und anschließend die vorverarbeiteten Daten mit den angewendeten Schritten zu extrahieren.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Preprocess and extract data to allow some data analysis\n",
"baked_pumpkins <- recipe(color ~ ., data = pumpkins_select) %>%\n",
" # Define ordering for item_size column\n",
" step_mutate(item_size = ordered(item_size, levels = c('sml', 'med', 'med-lge', 'lge', 'xlge', 'jbo', 'exjbo'))) %>%\n",
" # Convert factors to numbers using the order defined above (Ordinal encoding)\n",
" step_integer(item_size, zero_based = F) %>%\n",
" # Encode all other predictors using one hot encoding\n",
" step_dummy(all_nominal(), -all_outcomes(), one_hot = TRUE) %>%\n",
" prep(data = pumpkin_select) %>%\n",
" bake(new_data = NULL)\n",
"\n",
"# Display the first few rows of preprocessed data\n",
"baked_pumpkins %>% \n",
" slice_head(n = 5)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"✅ Was sind die Vorteile der Verwendung eines Ordinal Encoders für die Spalte Item Size?\n",
"\n",
"### Beziehungen zwischen Variablen analysieren\n",
"\n",
"Nachdem wir unsere Daten vorverarbeitet haben, können wir die Beziehungen zwischen den Merkmalen und dem Label analysieren, um eine Vorstellung davon zu bekommen, wie gut das Modell in der Lage sein wird, das Label anhand der Merkmale vorherzusagen. Der beste Weg, diese Art von Analyse durchzuführen, ist das Plotten der Daten. \n",
"Wir werden erneut die ggplot-Funktion geom_boxplot_ verwenden, um die Beziehungen zwischen Item Size, Variety und Color in einem kategorischen Plot zu visualisieren. Um die Daten besser darzustellen, verwenden wir die kodierte Spalte Item Size und die nicht kodierte Spalte Variety.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Define the color palette\n",
"palette <- c(ORANGE = \"orange\", WHITE = \"wheat\")\n",
"\n",
"# We need the encoded Item Size column to use it as the x-axis values in the plot\n",
"pumpkins_select_plot<-pumpkins_select\n",
"pumpkins_select_plot$item_size <- baked_pumpkins$item_size\n",
"\n",
"# Create the grouped box plot\n",
"ggplot(pumpkins_select_plot, aes(x = `item_size`, y = color, fill = color)) +\n",
" geom_boxplot() +\n",
" facet_grid(variety ~ ., scales = \"free_x\") +\n",
" scale_fill_manual(values = palette) +\n",
" labs(x = \"Item Size\", y = \"\") +\n",
" theme_minimal() +\n",
" theme(strip.text = element_text(size = 12)) +\n",
" theme(axis.text.x = element_text(size = 10)) +\n",
" theme(axis.title.x = element_text(size = 12)) +\n",
" theme(axis.title.y = element_blank()) +\n",
" theme(legend.position = \"bottom\") +\n",
" guides(fill = guide_legend(title = \"Color\")) +\n",
" theme(panel.spacing = unit(0.5, \"lines\"))+\n",
" theme(strip.text.y = element_text(size = 4, hjust = 0)) \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Verwenden Sie ein Swarm-Plot\n",
"\n",
"Da Farbe eine binäre Kategorie ist (Weiß oder Nicht), benötigt sie 'einen [spezialisierten Ansatz](https://github.com/rstudio/cheatsheets/blob/main/data-visualization.pdf) für die Visualisierung'.\n",
"\n",
"Versuchen Sie, ein `Swarm-Plot` zu verwenden, um die Verteilung der Farbe in Bezug auf die item_size darzustellen.\n",
"\n",
"Wir verwenden das [ggbeeswarm-Paket](https://github.com/eclarke/ggbeeswarm), das Methoden bereitstellt, um Bienenstock-ähnliche Plots mit ggplot2 zu erstellen. Bienenstock-Plots sind eine Möglichkeit, Punkte darzustellen, die sich normalerweise überlappen würden, sodass sie stattdessen nebeneinander angeordnet werden.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Create beeswarm plots of color and item_size\n",
"baked_pumpkins %>% \n",
" mutate(color = factor(color)) %>% \n",
" ggplot(mapping = aes(x = color, y = item_size, color = color)) +\n",
" geom_quasirandom() +\n",
" scale_color_brewer(palette = \"Dark2\", direction = -1) +\n",
" theme(legend.position = \"none\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Jetzt, da wir eine Vorstellung von der Beziehung zwischen den binären Kategorien der Farbe und der größeren Gruppe der Größen haben, wollen wir die logistische Regression untersuchen, um die wahrscheinliche Farbe eines bestimmten Kürbisses zu bestimmen.\n",
"\n",
"## Erstellen Sie Ihr Modell\n",
"\n",
"Wählen Sie die Variablen aus, die Sie in Ihrem Klassifikationsmodell verwenden möchten, und teilen Sie die Daten in Trainings- und Testdatensätze auf. [rsample](https://rsample.tidymodels.org/), ein Paket in Tidymodels, bietet eine Infrastruktur für effizientes Datensplitting und Resampling:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Split data into 80% for training and 20% for testing\n",
"set.seed(2056)\n",
"pumpkins_split <- pumpkins_select %>% \n",
" initial_split(prop = 0.8)\n",
"\n",
"# Extract the data in each split\n",
"pumpkins_train <- training(pumpkins_split)\n",
"pumpkins_test <- testing(pumpkins_split)\n",
"\n",
"# Print out the first 5 rows of the training set\n",
"pumpkins_train %>% \n",
" slice_head(n = 5)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"🙌 Wir sind jetzt bereit, ein Modell zu trainieren, indem wir die Trainingsmerkmale mit dem Trainingslabel (Farbe) verknüpfen.\n",
"\n",
"Wir beginnen damit, ein Rezept zu erstellen, das die Vorverarbeitungsschritte festlegt, die an unseren Daten durchgeführt werden müssen, um sie für die Modellierung vorzubereiten, z. B.: Kategorische Variablen in eine Reihe von Ganzzahlen zu kodieren. Genau wie `baked_pumpkins` erstellen wir ein `pumpkins_recipe`, aber wir führen kein `prep` und `bake` aus, da dies in einen Workflow eingebunden wird, den Sie in nur wenigen Schritten sehen werden.\n",
"\n",
"Es gibt eine ganze Reihe von Möglichkeiten, ein logistisches Regressionsmodell in Tidymodels zu spezifizieren. Siehe `?logistic_reg()`. Für den Moment werden wir ein logistisches Regressionsmodell über die Standard-Engine `stats::glm()` spezifizieren.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Create a recipe that specifies preprocessing steps for modelling\n",
"pumpkins_recipe <- recipe(color ~ ., data = pumpkins_train) %>% \n",
" step_mutate(item_size = ordered(item_size, levels = c('sml', 'med', 'med-lge', 'lge', 'xlge', 'jbo', 'exjbo'))) %>%\n",
" step_integer(item_size, zero_based = F) %>% \n",
" step_dummy(all_nominal(), -all_outcomes(), one_hot = TRUE)\n",
"\n",
"# Create a logistic model specification\n",
"log_reg <- logistic_reg() %>% \n",
" set_engine(\"glm\") %>% \n",
" set_mode(\"classification\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Jetzt, da wir ein Rezept und eine Modellspezifikation haben, müssen wir eine Möglichkeit finden, diese zusammen in einem Objekt zu bündeln, das zunächst die Daten vorverarbeitet (prep+bake im Hintergrund), das Modell auf den vorverarbeiteten Daten anpasst und auch potenzielle Nachbearbeitungsaktivitäten ermöglicht.\n",
"\n",
"In Tidymodels wird dieses praktische Objekt als [`workflow`](https://workflows.tidymodels.org/) bezeichnet und fasst bequem Ihre Modellierungskomponenten zusammen.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Bundle modelling components in a workflow\n",
"log_reg_wf <- workflow() %>% \n",
" add_recipe(pumpkins_recipe) %>% \n",
" add_model(log_reg)\n",
"\n",
"# Print out the workflow\n",
"log_reg_wf\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Nachdem ein Workflow *festgelegt* wurde, kann ein Modell mit der [`fit()`](https://tidymodels.github.io/parsnip/reference/fit.html)-Funktion `trainiert` werden. Der Workflow wird ein Rezept schätzen und die Daten vor dem Training vorverarbeiten, sodass wir dies nicht manuell mit prep und bake durchführen müssen.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Train the model\n",
"wf_fit <- log_reg_wf %>% \n",
" fit(data = pumpkins_train)\n",
"\n",
"# Print the trained workflow\n",
"wf_fit\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Das Modell gibt die während des Trainings gelernten Koeffizienten aus.\n",
"\n",
"Nachdem wir das Modell mit den Trainingsdaten trainiert haben, können wir Vorhersagen für die Testdaten mithilfe von [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html) treffen. Beginnen wir damit, das Modell zu verwenden, um Labels für unseren Testdatensatz sowie die Wahrscheinlichkeiten für jedes Label vorherzusagen. Wenn die Wahrscheinlichkeit größer als 0,5 ist, wird die vorhergesagte Klasse `WHITE` sein, andernfalls `ORANGE`.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Make predictions for color and corresponding probabilities\n",
"results <- pumpkins_test %>% select(color) %>% \n",
" bind_cols(wf_fit %>% \n",
" predict(new_data = pumpkins_test)) %>%\n",
" bind_cols(wf_fit %>%\n",
" predict(new_data = pumpkins_test, type = \"prob\"))\n",
"\n",
"# Compare predictions\n",
"results %>% \n",
" slice_head(n = 10)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Sehr schön! Das bietet einige zusätzliche Einblicke in die Funktionsweise der logistischen Regression.\n",
"\n",
"### Bessere Verständlichkeit durch eine Konfusionsmatrix\n",
"\n",
"Jeden einzelnen Vorhersagewert mit seinem entsprechenden \"Ground Truth\"-Wert zu vergleichen, ist keine besonders effiziente Methode, um zu beurteilen, wie gut das Modell vorhersagt. Glücklicherweise hat Tidymodels noch ein paar weitere Tricks parat: [`yardstick`](https://yardstick.tidymodels.org/) - ein Paket, das verwendet wird, um die Effektivität von Modellen anhand von Leistungskennzahlen zu messen.\n",
"\n",
"Eine Leistungskennzahl, die mit Klassifikationsproblemen verbunden ist, ist die [`Konfusionsmatrix`](https://wikipedia.org/wiki/Confusion_matrix). Eine Konfusionsmatrix beschreibt, wie gut ein Klassifikationsmodell funktioniert. Sie zeigt tabellarisch, wie viele Beispiele in jeder Klasse von einem Modell korrekt klassifiziert wurden. In unserem Fall wird sie zeigen, wie viele orangefarbene Kürbisse als orange klassifiziert wurden und wie viele weiße Kürbisse als weiß; die Konfusionsmatrix zeigt auch, wie viele in die **falschen** Kategorien eingeordnet wurden.\n",
"\n",
"Die Funktion [**`conf_mat()`**](https://tidymodels.github.io/yardstick/reference/conf_mat.html) aus yardstick berechnet diese Kreuztabellierung der beobachteten und vorhergesagten Klassen.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Confusion matrix for prediction results\n",
"conf_mat(data = results, truth = color, estimate = .pred_class)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Lassen Sie uns die Verwirrungsmatrix interpretieren. Unser Modell soll Kürbisse zwischen zwei binären Kategorien klassifizieren: Kategorie `weiß` und Kategorie `nicht-weiß`.\n",
"\n",
"- Wenn Ihr Modell einen Kürbis als weiß vorhersagt und er tatsächlich zur Kategorie 'weiß' gehört, nennen wir das ein `true positive`, dargestellt durch die Zahl oben links.\n",
"\n",
"- Wenn Ihr Modell einen Kürbis als nicht weiß vorhersagt und er tatsächlich zur Kategorie 'weiß' gehört, nennen wir das ein `false negative`, dargestellt durch die Zahl unten links.\n",
"\n",
"- Wenn Ihr Modell einen Kürbis als weiß vorhersagt und er tatsächlich zur Kategorie 'nicht-weiß' gehört, nennen wir das ein `false positive`, dargestellt durch die Zahl oben rechts.\n",
"\n",
"- Wenn Ihr Modell einen Kürbis als nicht weiß vorhersagt und er tatsächlich zur Kategorie 'nicht-weiß' gehört, nennen wir das ein `true negative`, dargestellt durch die Zahl unten rechts.\n",
"\n",
"| Wahrheit |\n",
"|:--------:|\n",
"\n",
"\n",
"| | | |\n",
"|---------------|--------|-------|\n",
"| **Vorhersage** | WEISS | ORANGE |\n",
"| WEISS | TP | FP |\n",
"| ORANGE | FN | TN |\n",
"\n",
"Wie Sie sich vielleicht denken können, ist es wünschenswert, eine größere Anzahl von true positives und true negatives sowie eine geringere Anzahl von false positives und false negatives zu haben, da dies darauf hinweist, dass das Modell besser funktioniert.\n",
"\n",
"Die Verwirrungsmatrix ist hilfreich, da sie zu anderen Metriken führt, die uns helfen können, die Leistung eines Klassifikationsmodells besser zu bewerten. Gehen wir einige davon durch:\n",
"\n",
"🎓 Präzision: `TP/(TP + FP)` definiert als der Anteil der vorhergesagten positiven Ergebnisse, die tatsächlich positiv sind. Auch bekannt als [positiver Vorhersagewert](https://en.wikipedia.org/wiki/Positive_predictive_value \"Positive predictive value\").\n",
"\n",
"🎓 Recall: `TP/(TP + FN)` definiert als der Anteil der positiven Ergebnisse aus der Anzahl der Proben, die tatsächlich positiv waren. Auch bekannt als `Sensitivität`.\n",
"\n",
"🎓 Spezifität: `TN/(TN + FP)` definiert als der Anteil der negativen Ergebnisse aus der Anzahl der Proben, die tatsächlich negativ waren.\n",
"\n",
"🎓 Genauigkeit: `TP + TN/(TP + TN + FP + FN)` Der Prozentsatz der Labels, die für eine Probe korrekt vorhergesagt wurden.\n",
"\n",
"🎓 F-Maß: Ein gewichteter Durchschnitt von Präzision und Recall, wobei der beste Wert 1 und der schlechteste Wert 0 ist.\n",
"\n",
"Lassen Sie uns diese Metriken berechnen!\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Combine metric functions and calculate them all at once\n",
"eval_metrics <- metric_set(ppv, recall, spec, f_meas, accuracy)\n",
"eval_metrics(data = results, truth = color, estimate = .pred_class)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Visualisiere die ROC-Kurve dieses Modells\n",
"\n",
"Lass uns eine weitere Visualisierung durchführen, um die sogenannte [`ROC-Kurve`](https://en.wikipedia.org/wiki/Receiver_operating_characteristic) anzusehen:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Make a roc_curve\n",
"results %>% \n",
" roc_curve(color, .pred_ORANGE) %>% \n",
" autoplot()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"ROC-Kurven werden häufig verwendet, um die Leistung eines Klassifikators in Bezug auf wahre vs. falsche Positive zu visualisieren. ROC-Kurven zeigen typischerweise die `True Positive Rate`/Sensitivität auf der Y-Achse und die `False Positive Rate`/1-Spezifität auf der X-Achse. Daher sind die Steilheit der Kurve und der Abstand zwischen der Mittellinie und der Kurve entscheidend: Man möchte eine Kurve, die schnell nach oben und über die Linie verläuft. In unserem Fall gibt es zunächst falsche Positive, bevor die Linie korrekt nach oben und darüber verläuft.\n",
"\n",
"Abschließend verwenden wir `yardstick::roc_auc()`, um die tatsächliche Fläche unter der Kurve (Area Under the Curve, AUC) zu berechnen. Eine Möglichkeit, die AUC zu interpretieren, ist die Wahrscheinlichkeit, dass das Modell ein zufällig ausgewähltes positives Beispiel höher einstuft als ein zufällig ausgewähltes negatives Beispiel.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Calculate area under curve\n",
"results %>% \n",
" roc_auc(color, .pred_ORANGE)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Das Ergebnis liegt bei etwa `0,975`. Da der AUC-Wert zwischen 0 und 1 liegt, strebt man einen hohen Wert an, da ein Modell, das zu 100 % korrekte Vorhersagen trifft, einen AUC-Wert von 1 erreicht. In diesem Fall ist das Modell *ziemlich gut*.\n",
"\n",
"In zukünftigen Lektionen über Klassifikationen wirst du lernen, wie du die Werte deines Modells verbessern kannst (zum Beispiel, indem du mit unausgeglichenen Daten umgehst, wie in diesem Fall).\n",
"\n",
"## 🚀Herausforderung\n",
"\n",
"Es gibt noch viel mehr über logistische Regression zu entdecken! Aber der beste Weg, etwas zu lernen, ist, zu experimentieren. Finde einen Datensatz, der sich für diese Art von Analyse eignet, und erstelle ein Modell damit. Was lernst du dabei? Tipp: Schau dir [Kaggle](https://www.kaggle.com/search?q=logistic+regression+datasets) für interessante Datensätze an.\n",
"\n",
"## Rückblick & Selbststudium\n",
"\n",
"Lies die ersten Seiten von [diesem Paper von Stanford](https://web.stanford.edu/~jurafsky/slp3/5.pdf), das einige praktische Anwendungen der logistischen Regression beschreibt. Überlege, welche Aufgaben besser für die eine oder andere Art von Regressionsaufgaben geeignet sind, die wir bisher behandelt haben. Was würde am besten funktionieren?\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Haftungsausschluss**: \nDieses Dokument wurde mit dem KI-Übersetzungsdienst [Co-op Translator](https://github.com/Azure/co-op-translator) übersetzt. Obwohl wir uns um Genauigkeit bemühen, weisen wir darauf hin, dass automatisierte Übersetzungen Fehler oder Ungenauigkeiten enthalten können. Das Originaldokument in seiner ursprünglichen Sprache sollte als maßgebliche Quelle betrachtet werden. Für kritische Informationen wird eine professionelle menschliche Übersetzung empfohlen. Wir übernehmen keine Haftung für Missverständnisse oder Fehlinterpretationen, die aus der Nutzung dieser Übersetzung entstehen.\n"
]
}
],
"metadata": {
"anaconda-cloud": "",
"kernelspec": {
"display_name": "R",
"langauge": "R",
"name": "ir"
},
"language_info": {
"codemirror_mode": "r",
"file_extension": ".r",
"mimetype": "text/x-r-source",
"name": "R",
"pygments_lexer": "r",
"version": "3.4.1"
},
"coopTranslator": {
"original_hash": "feaf125f481a89c468fa115bf2aed580",
"translation_date": "2025-09-04T01:26:08+00:00",
"source_file": "2-Regression/4-Logistic/solution/R/lesson_4-R.ipynb",
"language_code": "de"
}
},
"nbformat": 4,
"nbformat_minor": 1
}