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/5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb

642 lines
29 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.

{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"anaconda-cloud": "",
"kernelspec": {
"display_name": "R",
"language": "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"
},
"colab": {
"name": "lesson_14.ipynb",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true
},
"coopTranslator": {
"original_hash": "ad65fb4aad0a156b42216e4929f490fc",
"translation_date": "2025-09-04T02:19:15+00:00",
"source_file": "5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb",
"language_code": "de"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "GULATlQXLXyR"
},
"source": [
"## Erkunde K-Means-Clustering mit R und den Prinzipien von Tidy Data.\n",
"\n",
"### [**Quiz vor der Lektion**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/29/)\n",
"\n",
"In dieser Lektion lernst du, wie du mit dem Tidymodels-Paket und anderen Paketen aus dem R-Ökosystem (wir nennen sie Freunde 🧑‍🤝‍🧑) sowie dem nigerianischen Musikdatensatz, den du zuvor importiert hast, Cluster erstellen kannst. Wir behandeln die Grundlagen von K-Means für das Clustering. Denke daran, dass es, wie du in der vorherigen Lektion gelernt hast, viele Möglichkeiten gibt, mit Clustern zu arbeiten, und die Methode, die du wählst, von deinen Daten abhängt. Wir werden K-Means ausprobieren, da es die am häufigsten verwendete Clustering-Technik ist. Los geht's!\n",
"\n",
"Begriffe, die du kennenlernen wirst:\n",
"\n",
"- Silhouettenbewertung\n",
"\n",
"- Elbow-Methode\n",
"\n",
"- Trägheit\n",
"\n",
"- Varianz\n",
"\n",
"### **Einführung**\n",
"\n",
"[K-Means-Clustering](https://wikipedia.org/wiki/K-means_clustering) ist eine Methode, die aus dem Bereich der Signalverarbeitung stammt. Sie wird verwendet, um Gruppen von Daten basierend auf Ähnlichkeiten ihrer Merkmale in `k Cluster` zu unterteilen und zu partitionieren.\n",
"\n",
"Die Cluster können als [Voronoi-Diagramme](https://wikipedia.org/wiki/Voronoi_diagram) visualisiert werden, die einen Punkt (oder 'Seed') und dessen entsprechende Region enthalten.\n",
"\n",
"<p >\n",
" <img src=\"../../images/voronoi.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Infografik von Jen Looper</figcaption>\n",
"\n",
"\n",
"Die Schritte des K-Means-Clustering sind wie folgt:\n",
"\n",
"1. Der Datenwissenschaftler beginnt damit, die gewünschte Anzahl von Clustern festzulegen, die erstellt werden sollen.\n",
"\n",
"2. Anschließend wählt der Algorithmus zufällig K Beobachtungen aus dem Datensatz aus, die als anfängliche Zentren der Cluster (d. h. Zentroiden) dienen.\n",
"\n",
"3. Danach wird jede der verbleibenden Beobachtungen ihrem nächstgelegenen Zentroiden zugewiesen.\n",
"\n",
"4. Anschließend werden die neuen Mittelwerte jedes Clusters berechnet und der Zentroid wird zum Mittelwert verschoben.\n",
"\n",
"5. Nun, da die Zentren neu berechnet wurden, wird jede Beobachtung erneut überprüft, um festzustellen, ob sie möglicherweise näher an einem anderen Cluster liegt. Alle Objekte werden erneut unter Verwendung der aktualisierten Cluster-Mittelwerte zugewiesen. Die Schritte der Clusterzuweisung und der Aktualisierung der Zentroiden werden iterativ wiederholt, bis sich die Clusterzuweisungen nicht mehr ändern (d. h. wenn Konvergenz erreicht ist). Typischerweise endet der Algorithmus, wenn jede neue Iteration zu einer vernachlässigbaren Bewegung der Zentroiden führt und die Cluster statisch werden.\n",
"\n",
"<div>\n",
"\n",
"> Beachte, dass aufgrund der Zufälligkeit der anfänglichen k Beobachtungen, die als Startzentroiden verwendet werden, jedes Mal, wenn wir das Verfahren anwenden, leicht unterschiedliche Ergebnisse erzielt werden können. Aus diesem Grund verwenden die meisten Algorithmen mehrere *zufällige Starts* und wählen die Iteration mit dem niedrigsten WCSS. Daher wird dringend empfohlen, K-Means immer mit mehreren Werten von *nstart* auszuführen, um ein *unerwünschtes lokales Optimum* zu vermeiden.\n",
"\n",
"</div>\n",
"\n",
"Diese kurze Animation, die die [Illustrationen](https://github.com/allisonhorst/stats-illustrations) von Allison Horst verwendet, erklärt den Clustering-Prozess:\n",
"\n",
"<p >\n",
" <img src=\"../../images/kmeans.gif\"\n",
" width=\"550\"/>\n",
" <figcaption>Illustration von @allison_horst</figcaption>\n",
"\n",
"\n",
"\n",
"Eine grundlegende Frage, die beim Clustering aufkommt, ist: Wie weißt du, in wie viele Cluster du deine Daten aufteilen sollst? Ein Nachteil der Verwendung von K-Means ist, dass du `k`, also die Anzahl der `Zentroiden`, festlegen musst. Glücklicherweise hilft die `Elbow-Methode`, einen guten Ausgangswert für `k` zu schätzen. Du wirst es gleich ausprobieren.\n",
"\n",
"### \n",
"\n",
"**Voraussetzung**\n",
"\n",
"Wir machen genau dort weiter, wo wir in der [vorherigen Lektion](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb) aufgehört haben, in der wir den Datensatz analysiert, viele Visualisierungen erstellt und den Datensatz auf interessante Beobachtungen gefiltert haben. Schau sie dir unbedingt an!\n",
"\n",
"Wir benötigen einige Pakete, um dieses Modul abzuschließen. Du kannst sie wie folgt installieren: `install.packages(c('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork'))`\n",
"\n",
"Alternativ überprüft das folgende Skript, ob du die für dieses Modul erforderlichen Pakete hast, und installiert sie für dich, falls einige fehlen.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "ah_tBi58LXyi"
},
"source": [
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\n",
"\n",
"pacman::p_load('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork')\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "7e--UCUTLXym"
},
"source": [
"Los geht's!\n",
"\n",
"## 1. Ein Tanz mit Daten: Eingrenzen auf die 3 beliebtesten Musikgenres\n",
"\n",
"Dies ist eine Zusammenfassung dessen, was wir in der vorherigen Lektion gemacht haben. Lass uns ein paar Daten analysieren!\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "Ycamx7GGLXyn"
},
"source": [
"# Load the core tidyverse and make it available in your current R session\n",
"library(tidyverse)\n",
"\n",
"# Import the data into a tibble\n",
"df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/5-Clustering/data/nigerian-songs.csv\", show_col_types = FALSE)\n",
"\n",
"# Narrow down to top 3 popular genres\n",
"nigerian_songs <- df %>% \n",
" # Concentrate on top 3 genres\n",
" filter(artist_top_genre %in% c(\"afro dancehall\", \"afropop\",\"nigerian pop\")) %>% \n",
" # Remove unclassified observations\n",
" filter(popularity != 0)\n",
"\n",
"\n",
"\n",
"# Visualize popular genres using bar plots\n",
"theme_set(theme_light())\n",
"nigerian_songs %>%\n",
" count(artist_top_genre) %>%\n",
" ggplot(mapping = aes(x = artist_top_genre, y = n,\n",
" fill = artist_top_genre)) +\n",
" geom_col(alpha = 0.8) +\n",
" paletteer::scale_fill_paletteer_d(\"ggsci::category10_d3\") +\n",
" ggtitle(\"Top genres\") +\n",
" theme(plot.title = element_text(hjust = 0.5))\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "b5h5zmkPLXyp"
},
"source": [
"🤩 Das lief gut!\n",
"\n",
"## 2. Mehr Datenexploration.\n",
"\n",
"Wie sauber sind diese Daten? Lassen Sie uns Ausreißer mithilfe von Boxplots überprüfen. Wir konzentrieren uns auf numerische Spalten mit weniger Ausreißern (auch wenn Sie die Ausreißer bereinigen könnten). Boxplots können den Wertebereich der Daten zeigen und helfen, auszuwählen, welche Spalten verwendet werden sollen. Beachten Sie, dass Boxplots keine Varianz darstellen, ein wichtiger Aspekt für gut clustbare Daten. Weitere Informationen finden Sie in [dieser Diskussion](https://stats.stackexchange.com/questions/91536/deduce-variance-from-boxplot).\n",
"\n",
"[Boxplots](https://de.wikipedia.org/wiki/Box-Plot) werden verwendet, um die Verteilung von `numerischen` Daten grafisch darzustellen. Beginnen wir also damit, alle numerischen Spalten zusammen mit den beliebten Musikgenres *auszuwählen*.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "HhNreJKLLXyq"
},
"source": [
"# Select top genre column and all other numeric columns\n",
"df_numeric <- nigerian_songs %>% \n",
" select(artist_top_genre, where(is.numeric)) \n",
"\n",
"# Display the data\n",
"df_numeric %>% \n",
" slice_head(n = 5)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "uYXrwJRaLXyq"
},
"source": [
"Sehen Sie, wie der Auswahlhelfer `where` das so einfach macht 💁? Entdecken Sie weitere solche Funktionen [hier](https://tidyselect.r-lib.org/).\n",
"\n",
"Da wir für jede numerische Eigenschaft ein Boxplot erstellen werden und Schleifen vermeiden möchten, formatieren wir unsere Daten in ein *längeres* Format um. Dadurch können wir `facets` nutzen Unterdiagramme, die jeweils einen Teil der Daten anzeigen.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "gd5bR3f8LXys"
},
"source": [
"# Pivot data from wide to long\n",
"df_numeric_long <- df_numeric %>% \n",
" pivot_longer(!artist_top_genre, names_to = \"feature_names\", values_to = \"values\") \n",
"\n",
"# Print out data\n",
"df_numeric_long %>% \n",
" slice_head(n = 15)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "-7tE1swnLXyv"
},
"source": [
"Viel länger! Jetzt ist es Zeit für einige `ggplots`! Welches `geom` werden wir verwenden?\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "r88bIsyuLXyy"
},
"source": [
"# Make a box plot\n",
"df_numeric_long %>% \n",
" ggplot(mapping = aes(x = feature_names, y = values, fill = feature_names)) +\n",
" geom_boxplot() +\n",
" facet_wrap(~ feature_names, ncol = 4, scales = \"free\") +\n",
" theme(legend.position = \"none\")\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "EYVyKIUELXyz"
},
"source": [
"Easy-gg!\n",
"\n",
"Jetzt können wir sehen, dass diese Daten etwas unruhig sind: Wenn man jede Spalte als Boxplot betrachtet, erkennt man Ausreißer. Man könnte den Datensatz durchgehen und diese Ausreißer entfernen, aber das würde die Daten ziemlich minimal machen.\n",
"\n",
"Für den Moment wählen wir aus, welche Spalten wir für unsere Cluster-Übung verwenden werden. Lassen Sie uns die numerischen Spalten mit ähnlichen Bereichen auswählen. Wir könnten `artist_top_genre` als numerisch codieren, aber wir lassen es vorerst weg.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "-wkpINyZLXy0"
},
"source": [
"# Select variables with similar ranges\n",
"df_numeric_select <- df_numeric %>% \n",
" select(popularity, danceability, acousticness, loudness, energy) \n",
"\n",
"# Normalize data\n",
"# df_numeric_select <- scale(df_numeric_select)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "D7dLzgpqLXy1"
},
"source": [
"## 3. Berechnung von k-means Clustering in R\n",
"\n",
"Wir können k-means in R mit der integrierten Funktion `kmeans` berechnen, siehe `help(\"kmeans()\")`. Die Funktion `kmeans()` akzeptiert als Hauptargument einen Data Frame mit ausschließlich numerischen Spalten.\n",
"\n",
"Der erste Schritt bei der Verwendung von k-means Clustering besteht darin, die Anzahl der Cluster (k) festzulegen, die in der endgültigen Lösung erzeugt werden sollen. Wir wissen, dass es 3 Musikgenres gibt, die wir aus dem Datensatz herausgearbeitet haben, also probieren wir es mit 3:\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "uC4EQ5w7LXy5"
},
"source": [
"set.seed(2056)\n",
"# Kmeans clustering for 3 clusters\n",
"kclust <- kmeans(\n",
" df_numeric_select,\n",
" # Specify the number of clusters\n",
" centers = 3,\n",
" # How many random initial configurations\n",
" nstart = 25\n",
")\n",
"\n",
"# Display clustering object\n",
"kclust\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "hzfhscWrLXy-"
},
"source": [
"Das kmeans-Objekt enthält mehrere Informationen, die in `help(\"kmeans()\")` gut erklärt werden. Für den Moment konzentrieren wir uns auf einige davon. Wir sehen, dass die Daten in 3 Cluster mit den Größen 65, 110, 111 gruppiert wurden. Die Ausgabe enthält außerdem die Clusterzentren (Mittelwerte) für die 3 Gruppen über die 5 Variablen.\n",
"\n",
"Der Clustering-Vektor ist die Clusterzuweisung für jede Beobachtung. Nutzen wir die Funktion `augment`, um die Clusterzuweisung dem ursprünglichen Datensatz hinzuzufügen.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "0XwwpFGQLXy_"
},
"source": [
"# Add predicted cluster assignment to data set\n",
"augment(kclust, df_numeric_select) %>% \n",
" relocate(.cluster) %>% \n",
" slice_head(n = 10)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "NXIVXXACLXzA"
},
"source": [
"Perfekt, wir haben gerade unseren Datensatz in 3 Gruppen aufgeteilt. Aber wie gut ist unser Clustering 🤷? Schauen wir uns den `Silhouette-Score` an.\n",
"\n",
"### **Silhouette-Score**\n",
"\n",
"[Silhouette-Analyse](https://en.wikipedia.org/wiki/Silhouette_(clustering)) kann verwendet werden, um die Trennungsdistanz zwischen den resultierenden Clustern zu untersuchen. Dieser Score variiert zwischen -1 und 1. Wenn der Score nahe bei 1 liegt, ist das Cluster dicht und gut von anderen Clustern getrennt. Ein Wert nahe 0 repräsentiert sich überlappende Cluster, bei denen die Datenpunkte sehr nah an der Entscheidungsgrenze der benachbarten Cluster liegen. [Quelle](https://dzone.com/articles/kmeans-silhouette-score-explained-with-python-exam).\n",
"\n",
"Die Methode des durchschnittlichen Silhouette-Scores berechnet den durchschnittlichen Silhouette-Wert der Beobachtungen für verschiedene Werte von *k*. Ein hoher durchschnittlicher Silhouette-Score deutet auf ein gutes Clustering hin.\n",
"\n",
"Die `silhouette`-Funktion im Cluster-Paket wird verwendet, um die durchschnittliche Silhouette-Breite zu berechnen.\n",
"\n",
"> Der Silhouette-Score kann mit jeder [Distanz](https://en.wikipedia.org/wiki/Distance \"Distance\")-Metrik berechnet werden, wie z. B. der [euklidischen Distanz](https://en.wikipedia.org/wiki/Euclidean_distance \"Euclidean distance\") oder der [Manhattan-Distanz](https://en.wikipedia.org/wiki/Manhattan_distance \"Manhattan distance\"), die wir in der [vorherigen Lektion](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb) besprochen haben.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "Jn0McL28LXzB"
},
"source": [
"# Load cluster package\n",
"library(cluster)\n",
"\n",
"# Compute average silhouette score\n",
"ss <- silhouette(kclust$cluster,\n",
" # Compute euclidean distance\n",
" dist = dist(df_numeric_select))\n",
"mean(ss[, 3])\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "QyQRn97nLXzC"
},
"source": [
"Unser Score ist **0,549**, also genau in der Mitte. Das deutet darauf hin, dass unsere Daten nicht besonders gut für diese Art der Clusterbildung geeignet sind. Schauen wir, ob wir diese Vermutung visuell bestätigen können. Das [factoextra-Paket](https://rpkgs.datanovia.com/factoextra/index.html) stellt Funktionen (`fviz_cluster()`) zur Verfügung, um Cluster visuell darzustellen.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "7a6Km1_FLXzD"
},
"source": [
"library(factoextra)\n",
"\n",
"# Visualize clustering results\n",
"fviz_cluster(kclust, df_numeric_select)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "IBwCWt-0LXzD"
},
"source": [
"Die Überlappung der Cluster zeigt, dass unsere Daten für diese Art der Clusterbildung nicht besonders gut geeignet sind, aber lassen Sie uns trotzdem weitermachen.\n",
"\n",
"## 4. Bestimmung der optimalen Anzahl von Clustern\n",
"\n",
"Eine grundlegende Frage, die bei der K-Means-Clusterbildung häufig auftritt, lautet: Ohne bekannte Klassenlabels, wie wissen wir, in wie viele Cluster die Daten unterteilt werden sollen?\n",
"\n",
"Eine Möglichkeit, dies herauszufinden, besteht darin, eine Datenprobe zu verwenden, um `eine Reihe von Clustering-Modellen` mit einer steigenden Anzahl von Clustern zu erstellen (z. B. von 1 bis 10) und Clustering-Metriken wie den **Silhouette-Score** zu bewerten.\n",
"\n",
"Lassen Sie uns die optimale Anzahl von Clustern bestimmen, indem wir den Clustering-Algorithmus für verschiedene Werte von *k* berechnen und die **Summe der Quadrate innerhalb der Cluster** (WCSS) bewerten. Die gesamte Summe der Quadrate innerhalb der Cluster (WCSS) misst die Kompaktheit der Clusterbildung, und wir möchten, dass sie so klein wie möglich ist. Niedrigere Werte bedeuten, dass die Datenpunkte näher beieinander liegen.\n",
"\n",
"Lassen Sie uns die Auswirkungen verschiedener Werte von `k`, von 1 bis 10, auf diese Clusterbildung untersuchen.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "hSeIiylDLXzE"
},
"source": [
"# Create a series of clustering models\n",
"kclusts <- tibble(k = 1:10) %>% \n",
" # Perform kmeans clustering for 1,2,3 ... ,10 clusters\n",
" mutate(model = map(k, ~ kmeans(df_numeric_select, centers = .x, nstart = 25)),\n",
" # Farm out clustering metrics eg WCSS\n",
" glanced = map(model, ~ glance(.x))) %>% \n",
" unnest(cols = glanced)\n",
" \n",
"\n",
"# View clustering rsulsts\n",
"kclusts\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "m7rS2U1eLXzE"
},
"source": [
"Nun, da wir die gesamte innerhalb-Cluster-Summe der Quadrate (tot.withinss) für jeden Clustering-Algorithmus mit Zentrum *k* haben, verwenden wir die [Elbow-Methode](https://en.wikipedia.org/wiki/Elbow_method_(clustering)), um die optimale Anzahl von Clustern zu finden. Die Methode besteht darin, die WCSS als Funktion der Anzahl der Cluster zu plotten und den [Knick der Kurve](https://en.wikipedia.org/wiki/Elbow_of_the_curve \"Knick der Kurve\") als die Anzahl der zu verwendenden Cluster auszuwählen.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "o_DjHGItLXzF"
},
"source": [
"set.seed(2056)\n",
"# Use elbow method to determine optimum number of clusters\n",
"kclusts %>% \n",
" ggplot(mapping = aes(x = k, y = tot.withinss)) +\n",
" geom_line(size = 1.2, alpha = 0.8, color = \"#FF7F0EFF\") +\n",
" geom_point(size = 2, color = \"#FF7F0EFF\")\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "pLYyt5XSLXzG"
},
"source": [
"Die Grafik zeigt eine deutliche Reduktion des WCSS (also eine größere *Kompaktheit*), wenn die Anzahl der Cluster von eins auf zwei steigt, sowie eine weitere merkliche Reduktion von zwei auf drei Cluster. Danach wird die Reduktion weniger ausgeprägt, was zu einem `Knick` 💪 im Diagramm bei etwa drei Clustern führt. Dies ist ein guter Hinweis darauf, dass es zwei bis drei einigermaßen gut getrennte Cluster von Datenpunkten gibt.\n",
"\n",
"Wir können nun das Clustering-Modell extrahieren, bei dem `k = 3` ist:\n",
"\n",
"> `pull()`: wird verwendet, um eine einzelne Spalte zu extrahieren\n",
">\n",
"> `pluck()`: wird verwendet, um Datenstrukturen wie Listen zu indexieren\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "JP_JPKBILXzG"
},
"source": [
"# Extract k = 3 clustering\n",
"final_kmeans <- kclusts %>% \n",
" filter(k == 3) %>% \n",
" pull(model) %>% \n",
" pluck(1)\n",
"\n",
"\n",
"final_kmeans\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "l_PDTu8tLXzI"
},
"source": [
"Super! Lassen Sie uns die erhaltenen Cluster visualisieren. Lust auf etwas Interaktivität mit `plotly`?\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "dNcleFe-LXzJ"
},
"source": [
"# Add predicted cluster assignment to data set\n",
"results <- augment(final_kmeans, df_numeric_select) %>% \n",
" bind_cols(df_numeric %>% select(artist_top_genre)) \n",
"\n",
"# Plot cluster assignments\n",
"clust_plt <- results %>% \n",
" ggplot(mapping = aes(x = popularity, y = danceability, color = .cluster, shape = artist_top_genre)) +\n",
" geom_point(size = 2, alpha = 0.8) +\n",
" paletteer::scale_color_paletteer_d(\"ggthemes::Tableau_10\")\n",
"\n",
"ggplotly(clust_plt)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "6JUM_51VLXzK"
},
"source": [
"Vielleicht hätten wir erwartet, dass jeder Cluster (repräsentiert durch verschiedene Farben) unterschiedliche Genres (repräsentiert durch verschiedene Formen) aufweist.\n",
"\n",
"Werfen wir einen Blick auf die Genauigkeit des Modells.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "HdIMUGq7LXzL"
},
"source": [
"# Assign genres to predefined integers\n",
"label_count <- results %>% \n",
" group_by(artist_top_genre) %>% \n",
" mutate(id = cur_group_id()) %>% \n",
" ungroup() %>% \n",
" summarise(correct_labels = sum(.cluster == id))\n",
"\n",
"\n",
"# Print results \n",
"cat(\"Result:\", label_count$correct_labels, \"out of\", nrow(results), \"samples were correctly labeled.\")\n",
"\n",
"cat(\"\\nAccuracy score:\", label_count$correct_labels/nrow(results))\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "C50wvaAOLXzM"
},
"source": [
"Die Genauigkeit dieses Modells ist nicht schlecht, aber auch nicht besonders gut. Es könnte daran liegen, dass die Daten sich nicht gut für K-Means-Clustering eignen. Die Daten sind zu unausgewogen, zu wenig korreliert, und es gibt zu viel Varianz zwischen den Spaltenwerten, um gut zu clustern. Tatsächlich werden die gebildeten Cluster wahrscheinlich stark von den drei oben definierten Genre-Kategorien beeinflusst oder verzerrt.\n",
"\n",
"Nichtsdestotrotz war das ein ziemlich lehrreicher Prozess!\n",
"\n",
"In der Dokumentation von Scikit-learn kann man sehen, dass ein Modell wie dieses, bei dem die Cluster nicht klar abgegrenzt sind, ein 'Varianz'-Problem hat:\n",
"\n",
"<p >\n",
" <img src=\"../../images/problems.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Infografik von Scikit-learn</figcaption>\n",
"\n",
"\n",
"\n",
"## **Varianz**\n",
"\n",
"Varianz wird definiert als \"der Durchschnitt der quadrierten Abweichungen vom Mittelwert\" [Quelle](https://www.mathsisfun.com/data/standard-deviation.html). Im Kontext dieses Clustering-Problems bezieht sich dies darauf, dass die Zahlen in unserem Datensatz dazu neigen, sich zu stark vom Mittelwert zu entfernen.\n",
"\n",
"✅ Dies ist ein großartiger Moment, um über alle Möglichkeiten nachzudenken, wie man dieses Problem beheben könnte. Die Daten noch etwas anpassen? Andere Spalten verwenden? Einen anderen Algorithmus ausprobieren? Tipp: Versuchen Sie, [Ihre Daten zu skalieren](https://www.mygreatlearning.com/blog/learning-data-science-with-k-means-clustering/), um sie zu normalisieren, und testen Sie andere Spalten.\n",
"\n",
"> Probieren Sie diesen '[Varianzrechner](https://www.calculatorsoup.com/calculators/statistics/variance-calculator.php)' aus, um das Konzept besser zu verstehen.\n",
"\n",
"------------------------------------------------------------------------\n",
"\n",
"## **🚀Herausforderung**\n",
"\n",
"Verbringen Sie etwas Zeit mit diesem Notebook und passen Sie die Parameter an. Können Sie die Genauigkeit des Modells verbessern, indem Sie die Daten weiter bereinigen (z. B. Ausreißer entfernen)? Sie können Gewichte verwenden, um bestimmten Datenproben mehr Gewicht zu geben. Was können Sie sonst noch tun, um bessere Cluster zu erstellen?\n",
"\n",
"Tipp: Versuchen Sie, Ihre Daten zu skalieren. Im Notebook gibt es auskommentierten Code, der eine Standard-Skalierung hinzufügt, um die Daten-Spalten in Bezug auf den Wertebereich einander ähnlicher zu machen. Sie werden feststellen, dass der Silhouetten-Score zwar sinkt, aber der 'Knick' im Elbogen-Diagramm geglättet wird. Das liegt daran, dass unskalierte Daten es Daten mit weniger Varianz ermöglichen, mehr Gewicht zu tragen. Lesen Sie mehr über dieses Problem [hier](https://stats.stackexchange.com/questions/21222/are-mean-normalization-and-feature-scaling-needed-for-k-means-clustering/21226#21226).\n",
"\n",
"## [**Quiz nach der Vorlesung**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/30/)\n",
"\n",
"## **Überblick & Selbststudium**\n",
"\n",
"- Schauen Sie sich einen K-Means-Simulator [wie diesen hier](https://user.ceng.metu.edu.tr/~akifakkus/courses/ceng574/k-means/) an. Mit diesem Tool können Sie Beispieldatenpunkte visualisieren und deren Zentroiden bestimmen. Sie können die Zufälligkeit der Daten, die Anzahl der Cluster und die Anzahl der Zentroiden bearbeiten. Hilft Ihnen das, eine Vorstellung davon zu bekommen, wie die Daten gruppiert werden können?\n",
"\n",
"- Werfen Sie auch einen Blick auf [dieses Handout zu K-Means](https://stanford.edu/~cpiech/cs221/handouts/kmeans.html) von Stanford.\n",
"\n",
"Möchten Sie Ihre neu erworbenen Clustering-Fähigkeiten an Datensätzen ausprobieren, die sich gut für K-Means-Clustering eignen? Schauen Sie sich Folgendes an:\n",
"\n",
"- [Train and Evaluate Clustering Models](https://rpubs.com/eR_ic/clustering) mit Tidymodels und Co.\n",
"\n",
"- [K-means Cluster Analysis](https://uc-r.github.io/kmeans_clustering), UC Business Analytics R Programming Guide\n",
"\n",
"- [K-means clustering with tidy data principles](https://www.tidymodels.org/learn/statistics/k-means/)\n",
"\n",
"## **Aufgabe**\n",
"\n",
"[Probieren Sie verschiedene Clustering-Methoden aus](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/2-K-Means/assignment.md)\n",
"\n",
"## EIN GROSSES DANKESCHÖN AN:\n",
"\n",
"[Jen Looper](https://www.twitter.com/jenlooper) für die Erstellung der ursprünglichen Python-Version dieses Moduls ♥️\n",
"\n",
"[`Allison Horst`](https://twitter.com/allison_horst/) für die Erstellung der großartigen Illustrationen, die R einladender und ansprechender machen. Weitere Illustrationen finden Sie in ihrer [Galerie](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n",
"\n",
"Viel Spaß beim Lernen,\n",
"\n",
"[Eric](https://twitter.com/ericntay), Gold Microsoft Learn Student Ambassador.\n",
"\n",
"<p >\n",
" <img src=\"../../images/r_learners_sm.jpeg\"\n",
" width=\"500\"/>\n",
" <figcaption>Kunstwerk von @allison_horst</figcaption>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Haftungsausschluss**: \nDieses Dokument wurde mithilfe des KI-Übersetzungsdienstes [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"
]
}
]
}