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

639 lines
40 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-04T08:09:20+00:00",
"source_file": "5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb",
"language_code": "el"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "GULATlQXLXyR"
},
"source": [
"## Εξερευνήστε τη συσταδοποίηση K-Means χρησιμοποιώντας R και τις αρχές των Tidy δεδομένων.\n",
"\n",
"### [**Κουίζ πριν το μάθημα**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/29/)\n",
"\n",
"Σε αυτό το μάθημα, θα μάθετε πώς να δημιουργείτε συστάδες χρησιμοποιώντας το πακέτο Tidymodels και άλλα πακέτα στο οικοσύστημα του R (θα τα αποκαλούμε φίλους 🧑‍🤝‍🧑), καθώς και το σύνολο δεδομένων της νιγηριανής μουσικής που εισαγάγατε νωρίτερα. Θα καλύψουμε τα βασικά του K-Means για τη συσταδοποίηση. Να θυμάστε ότι, όπως μάθατε στο προηγούμενο μάθημα, υπάρχουν πολλοί τρόποι να δουλέψετε με συστάδες και η μέθοδος που χρησιμοποιείτε εξαρτάται από τα δεδομένα σας. Θα δοκιμάσουμε το K-Means, καθώς είναι η πιο κοινή τεχνική συσταδοποίησης. Ας ξεκινήσουμε!\n",
"\n",
"Όροι που θα μάθετε:\n",
"\n",
"- Βαθμολογία Silhouette\n",
"\n",
"- Μέθοδος Elbow\n",
"\n",
"- Αδράνεια\n",
"\n",
"- Διακύμανση\n",
"\n",
"### **Εισαγωγή**\n",
"\n",
"Η [Συσταδοποίηση K-Means](https://wikipedia.org/wiki/K-means_clustering) είναι μια μέθοδος που προέρχεται από τον τομέα της επεξεργασίας σήματος. Χρησιμοποιείται για τη διαίρεση και ομαδοποίηση δεδομένων σε `k συστάδες` με βάση τις ομοιότητες στα χαρακτηριστικά τους.\n",
"\n",
"Οι συστάδες μπορούν να οπτικοποιηθούν ως [Διαγράμματα Voronoi](https://wikipedia.org/wiki/Voronoi_diagram), τα οποία περιλαμβάνουν ένα σημείο (ή 'σπόρο') και την αντίστοιχη περιοχή του.\n",
"\n",
"<p >\n",
" <img src=\"../../images/voronoi.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Γραφικό από την Jen Looper</figcaption>\n",
"\n",
"Τα βήματα της συσταδοποίησης K-Means είναι τα εξής:\n",
"\n",
"1. Ο επιστήμονας δεδομένων ξεκινά καθορίζοντας τον επιθυμητό αριθμό συστάδων που θα δημιουργηθούν.\n",
"\n",
"2. Στη συνέχεια, ο αλγόριθμος επιλέγει τυχαία K παρατηρήσεις από το σύνολο δεδομένων για να χρησιμεύσουν ως αρχικά κέντρα για τις συστάδες (δηλαδή, κεντροειδή).\n",
"\n",
"3. Έπειτα, κάθε μία από τις υπόλοιπες παρατηρήσεις ανατίθεται στο πλησιέστερο κεντροειδές.\n",
"\n",
"4. Υπολογίζεται ο νέος μέσος όρος κάθε συστάδας και το κεντροειδές μετακινείται στον μέσο όρο.\n",
"\n",
"5. Τώρα που τα κέντρα έχουν επαναϋπολογιστεί, κάθε παρατήρηση ελέγχεται ξανά για να διαπιστωθεί αν μπορεί να είναι πιο κοντά σε μια διαφορετική συστάδα. Όλα τα αντικείμενα ανατίθενται ξανά χρησιμοποιώντας τους ενημερωμένους μέσους όρους συστάδων. Τα βήματα ανάθεσης συστάδων και ενημέρωσης κεντροειδών επαναλαμβάνονται επαναληπτικά μέχρι οι αναθέσεις συστάδων να σταματήσουν να αλλάζουν (δηλαδή, όταν επιτευχθεί σύγκλιση). Συνήθως, ο αλγόριθμος τερματίζεται όταν κάθε νέα επανάληψη οδηγεί σε αμελητέα μετακίνηση των κεντροειδών και οι συστάδες γίνονται στατικές.\n",
"\n",
"<div>\n",
"\n",
"> Σημειώστε ότι λόγω της τυχαιοποίησης των αρχικών k παρατηρήσεων που χρησιμοποιούνται ως αρχικά κεντροειδή, μπορούμε να έχουμε ελαφρώς διαφορετικά αποτελέσματα κάθε φορά που εφαρμόζουμε τη διαδικασία. Για αυτόν τον λόγο, οι περισσότεροι αλγόριθμοι χρησιμοποιούν αρκετές *τυχαίες εκκινήσεις* και επιλέγουν την επανάληψη με το χαμηλότερο WCSS. Ως εκ τούτου, συνιστάται έντονα να εκτελείτε πάντα το K-Means με αρκετές τιμές του *nstart* για να αποφύγετε ένα *ανεπιθύμητο τοπικό βέλτιστο.*\n",
"\n",
"</div>\n",
"\n",
"Αυτή η σύντομη κινούμενη εικόνα χρησιμοποιώντας το [έργο τέχνης](https://github.com/allisonhorst/stats-illustrations) της Allison Horst εξηγεί τη διαδικασία συσταδοποίησης:\n",
"\n",
"<p >\n",
" <img src=\"../../images/kmeans.gif\"\n",
" width=\"550\"/>\n",
" <figcaption>Έργο τέχνης από την @allison_horst</figcaption>\n",
"\n",
"Ένα θεμελιώδες ερώτημα που προκύπτει στη συσταδοποίηση είναι το εξής: πώς ξέρετε σε πόσες συστάδες να χωρίσετε τα δεδομένα σας; Ένα μειονέκτημα της χρήσης του K-Means είναι ότι θα χρειαστεί να καθορίσετε το `k`, δηλαδή τον αριθμό των `κεντροειδών`. Ευτυχώς, η `μέθοδος Elbow` βοηθά στην εκτίμηση μιας καλής αρχικής τιμής για το `k`. Θα τη δοκιμάσετε σε λίγο.\n",
"\n",
"### \n",
"\n",
"**Προαπαιτούμενα**\n",
"\n",
"Θα συνεχίσουμε από εκεί που σταματήσαμε στο [προηγούμενο μάθημα](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb), όπου αναλύσαμε το σύνολο δεδομένων, δημιουργήσαμε πολλές οπτικοποιήσεις και φιλτράραμε το σύνολο δεδομένων για παρατηρήσεις ενδιαφέροντος. Φροντίστε να το ελέγξετε!\n",
"\n",
"Θα χρειαστούμε κάποια πακέτα για να ολοκληρώσουμε αυτήν την ενότητα. Μπορείτε να τα εγκαταστήσετε ως εξής: `install.packages(c('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork'))`\n",
"\n",
"Εναλλακτικά, το παρακάτω σενάριο ελέγχει αν έχετε τα πακέτα που απαιτούνται για την ολοκλήρωση αυτής της ενότητας και τα εγκαθιστά για εσάς σε περίπτωση που λείπουν.\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": [
"Ας ξεκινήσουμε δυναμικά!\n",
"\n",
"## 1. Ένας χορός με δεδομένα: Εστιάστε στα 3 πιο δημοφιλή μουσικά είδη\n",
"\n",
"Αυτή είναι μια ανακεφαλαίωση όσων κάναμε στο προηγούμενο μάθημα. Ας επεξεργαστούμε και αναλύσουμε κάποια δεδομένα!\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": [
"🤩 Αυτό πήγε καλά!\n",
"\n",
"## 2. Περισσότερη εξερεύνηση δεδομένων.\n",
"\n",
"Πόσο καθαρά είναι αυτά τα δεδομένα; Ας ελέγξουμε για ακραίες τιμές χρησιμοποιώντας box plots. Θα επικεντρωθούμε σε αριθμητικές στήλες με λιγότερες ακραίες τιμές (αν και θα μπορούσατε να καθαρίσετε τις ακραίες τιμές). Τα box plots μπορούν να δείξουν το εύρος των δεδομένων και θα βοηθήσουν στην επιλογή των στηλών που θα χρησιμοποιηθούν. Σημειώστε ότι τα box plots δεν δείχνουν τη διακύμανση, ένα σημαντικό στοιχείο για καλά δεδομένα που μπορούν να ομαδοποιηθούν. Παρακαλώ δείτε [αυτή τη συζήτηση](https://stats.stackexchange.com/questions/91536/deduce-variance-from-boxplot) για περαιτέρω ανάγνωση.\n",
"\n",
"[Τα Boxplots](https://en.wikipedia.org/wiki/Box_plot) χρησιμοποιούνται για να απεικονίσουν γραφικά την κατανομή των `αριθμητικών` δεδομένων, οπότε ας ξεκινήσουμε *επιλέγοντας* όλες τις αριθμητικές στήλες μαζί με τα δημοφιλή μουσικά είδη.\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": [
"Δείτε πώς ο βοηθός επιλογής `where` κάνει αυτό τόσο εύκολο 💁. Εξερευνήστε άλλες παρόμοιες λειτουργίες [εδώ](https://tidyselect.r-lib.org/).\n",
"\n",
"Επειδή θα δημιουργήσουμε ένα boxplot για κάθε αριθμητικό χαρακτηριστικό και θέλουμε να αποφύγουμε τη χρήση βρόχων, ας αναδιαμορφώσουμε τα δεδομένα μας σε μια *πιο μακροσκελή* μορφή που θα μας επιτρέψει να εκμεταλλευτούμε τα `facets` - υποδιαγράμματα που το καθένα εμφανίζει ένα υποσύνολο των δεδομένων.\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": [
"Πολύ μεγαλύτερο! Τώρα είναι ώρα για μερικά `ggplots`! Λοιπόν, ποιο `geom` θα χρησιμοποιήσουμε;\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": [
"Εύκολο-gg!\n",
"\n",
"Τώρα μπορούμε να δούμε ότι αυτά τα δεδομένα είναι λίγο \"θορυβώδη\": παρατηρώντας κάθε στήλη ως boxplot, μπορείτε να δείτε ακραίες τιμές. Θα μπορούσατε να περάσετε από το σύνολο δεδομένων και να αφαιρέσετε αυτές τις ακραίες τιμές, αλλά αυτό θα έκανε τα δεδομένα αρκετά περιορισμένα.\n",
"\n",
"Προς το παρόν, ας επιλέξουμε ποιες στήλες θα χρησιμοποιήσουμε για την άσκηση ομαδοποίησης. Ας διαλέξουμε τις αριθμητικές στήλες με παρόμοια εύρη. Θα μπορούσαμε να κωδικοποιήσουμε το `artist_top_genre` ως αριθμητικό, αλλά θα το παραλείψουμε προς το παρόν.\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. Υπολογισμός k-means clustering στο R\n",
"\n",
"Μπορούμε να υπολογίσουμε το k-means στο R χρησιμοποιώντας την ενσωματωμένη συνάρτηση `kmeans`, δείτε `help(\"kmeans()\")`. Η συνάρτηση `kmeans()` δέχεται ένα data frame με όλες τις στήλες αριθμητικές ως το κύριο όρισμά της.\n",
"\n",
"Το πρώτο βήμα κατά τη χρήση του k-means clustering είναι να καθορίσουμε τον αριθμό των clusters (k) που θα δημιουργηθούν στη τελική λύση. Γνωρίζουμε ότι υπάρχουν 3 μουσικά είδη που έχουμε διαχωρίσει από το σύνολο δεδομένων, οπότε ας δοκιμάσουμε με 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": [
"Το αντικείμενο kmeans περιέχει αρκετές πληροφορίες που εξηγούνται καλά στο `help(\"kmeans()\")`. Προς το παρόν, ας επικεντρωθούμε σε μερικές. Βλέπουμε ότι τα δεδομένα έχουν ομαδοποιηθεί σε 3 συστάδες με μεγέθη 65, 110, 111. Η έξοδος περιλαμβάνει επίσης τα κέντρα των συστάδων (μέσους όρους) για τις 3 ομάδες στις 5 μεταβλητές.\n",
"\n",
"Το διανυσματικό clustering είναι η ανάθεση συστάδας για κάθε παρατήρηση. Ας χρησιμοποιήσουμε τη συνάρτηση `augment` για να προσθέσουμε την ανάθεση συστάδας στο αρχικό σύνολο δεδομένων.\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": [
"Τέλεια, μόλις χωρίσαμε το σύνολο δεδομένων μας σε ένα σύνολο από 3 ομάδες. Λοιπόν, πόσο καλό είναι το clustering μας 🤷; Ας ρίξουμε μια ματιά στο `Silhouette score`.\n",
"\n",
"### **Silhouette score**\n",
"\n",
"[Η ανάλυση Silhouette](https://en.wikipedia.org/wiki/Silhouette_(clustering)) μπορεί να χρησιμοποιηθεί για να μελετηθεί η απόσταση διαχωρισμού μεταξύ των προκύπτοντων clusters. Αυτή η βαθμολογία κυμαίνεται από -1 έως 1, και αν η βαθμολογία είναι κοντά στο 1, το cluster είναι πυκνό και καλά διαχωρισμένο από τα άλλα clusters. Μια τιμή κοντά στο 0 αντιπροσωπεύει επικαλυπτόμενα clusters με δείγματα πολύ κοντά στο όριο απόφασης των γειτονικών clusters. [πηγή](https://dzone.com/articles/kmeans-silhouette-score-explained-with-python-exam).\n",
"\n",
"Η μέθοδος μέσου silhouette υπολογίζει τον μέσο silhouette των παρατηρήσεων για διαφορετικές τιμές του *k*. Μια υψηλή μέση βαθμολογία silhouette υποδεικνύει καλό clustering.\n",
"\n",
"Η συνάρτηση `silhouette` στο πακέτο cluster χρησιμοποιείται για τον υπολογισμό του μέσου πλάτους silhouette.\n",
"\n",
"> Το silhouette μπορεί να υπολογιστεί με οποιαδήποτε [απόσταση](https://en.wikipedia.org/wiki/Distance \"Distance\"), όπως η [Ευκλείδεια απόσταση](https://en.wikipedia.org/wiki/Euclidean_distance \"Euclidean distance\") ή η [Manhattan απόσταση](https://en.wikipedia.org/wiki/Manhattan_distance \"Manhattan distance\") που συζητήσαμε στο [προηγούμενο μάθημα](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb).\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": [
"Η βαθμολογία μας είναι **.549**, δηλαδή ακριβώς στη μέση. Αυτό υποδεικνύει ότι τα δεδομένα μας δεν είναι ιδιαίτερα κατάλληλα για αυτόν τον τύπο ομαδοποίησης. Ας δούμε αν μπορούμε να επιβεβαιώσουμε αυτήν την υποψία οπτικά. Το [πακέτο factoextra](https://rpkgs.datanovia.com/factoextra/index.html) παρέχει συναρτήσεις (`fviz_cluster()`) για την οπτικοποίηση της ομαδοποίησης.\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": [
"Η επικάλυψη στους συστάδες υποδεικνύει ότι τα δεδομένα μας δεν είναι ιδιαίτερα κατάλληλα για αυτόν τον τύπο ομαδοποίησης, αλλά ας συνεχίσουμε.\n",
"\n",
"## 4. Καθορισμός του βέλτιστου αριθμού συστάδων\n",
"\n",
"Ένα θεμελιώδες ερώτημα που συχνά προκύπτει στην ομαδοποίηση K-Means είναι το εξής - χωρίς γνωστές ετικέτες κατηγοριών, πώς ξέρουμε σε πόσες συστάδες να χωρίσουμε τα δεδομένα μας;\n",
"\n",
"Ένας τρόπος για να το ανακαλύψουμε είναι να χρησιμοποιήσουμε ένα δείγμα δεδομένων για να `δημιουργήσουμε μια σειρά από μοντέλα ομαδοποίησης` με αυξανόμενο αριθμό συστάδων (π.χ. από 1-10) και να αξιολογήσουμε μετρικές ομαδοποίησης όπως το **Silhouette score.**\n",
"\n",
"Ας καθορίσουμε τον βέλτιστο αριθμό συστάδων υπολογίζοντας τον αλγόριθμο ομαδοποίησης για διαφορετικές τιμές του *k* και αξιολογώντας το **Άθροισμα Τετραγώνων Εντός Συστάδων** (WCSS). Το συνολικό άθροισμα τετραγώνων εντός συστάδων (WCSS) μετρά τη συμπαγότητα της ομαδοποίησης και θέλουμε να είναι όσο το δυνατόν μικρότερο, με χαμηλότερες τιμές να σημαίνουν ότι τα σημεία δεδομένων είναι πιο κοντά μεταξύ τους.\n",
"\n",
"Ας εξετάσουμε την επίδραση διαφορετικών επιλογών του `k`, από 1 έως 10, σε αυτήν την ομαδοποίηση.\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": [
"Τώρα που έχουμε το συνολικό άθροισμα των τετραγώνων εντός των συστάδων (tot.withinss) για κάθε αλγόριθμο ομαδοποίησης με κέντρο *k*, χρησιμοποιούμε τη [μέθοδο του αγκώνα](https://en.wikipedia.org/wiki/Elbow_method_(clustering)) για να βρούμε τον βέλτιστο αριθμό συστάδων. Η μέθοδος περιλαμβάνει την απεικόνιση του WCSS ως συνάρτηση του αριθμού των συστάδων και την επιλογή του [αγκώνα της καμπύλης](https://en.wikipedia.org/wiki/Elbow_of_the_curve \"Elbow of the curve\") ως τον αριθμό των συστάδων που θα χρησιμοποιηθούν.\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": [
"Η γραφική παράσταση δείχνει μια μεγάλη μείωση στο WCSS (άρα μεγαλύτερη *συνοχή*) καθώς ο αριθμός των συστάδων αυξάνεται από μία σε δύο, και μια περαιτέρω αισθητή μείωση από δύο σε τρεις συστάδες. Μετά από αυτό, η μείωση είναι λιγότερο έντονη, δημιουργώντας έναν `αγκώνα` 💪 στο διάγραμμα γύρω στις τρεις συστάδες. Αυτό αποτελεί μια καλή ένδειξη ότι υπάρχουν δύο έως τρεις σχετικά καλά διαχωρισμένες συστάδες σημείων δεδομένων.\n",
"\n",
"Μπορούμε τώρα να προχωρήσουμε και να εξαγάγουμε το μοντέλο συσταδοποίησης όπου `k = 3`:\n",
"\n",
"> `pull()`: χρησιμοποιείται για την εξαγωγή μιας μόνο στήλης\n",
">\n",
"> `pluck()`: χρησιμοποιείται για την πρόσβαση σε δομές δεδομένων όπως λίστες\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": [
"Ας προχωρήσουμε και να οπτικοποιήσουμε τα clusters που προέκυψαν. Θέλετε λίγη διαδραστικότητα χρησιμοποιώντας `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": [
"Ίσως θα περιμέναμε ότι κάθε σύμπλεγμα (που αναπαρίσταται από διαφορετικά χρώματα) θα είχε ξεχωριστά είδη (που αναπαρίστανται από διαφορετικά σχήματα).\n",
"\n",
"Ας ρίξουμε μια ματιά στην ακρίβεια του μοντέλου.\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": [
"Η ακρίβεια αυτού του μοντέλου δεν είναι κακή, αλλά ούτε και εξαιρετική. Ίσως τα δεδομένα να μην είναι κατάλληλα για την ομαδοποίηση με K-Means Clustering. Τα δεδομένα είναι υπερβολικά μη ισορροπημένα, έχουν πολύ μικρή συσχέτιση και υπάρχει υπερβολική διακύμανση μεταξύ των τιμών των στηλών για να δημιουργηθούν καλά clusters. Στην πραγματικότητα, τα clusters που σχηματίζονται πιθανότατα επηρεάζονται ή παραμορφώνονται έντονα από τις τρεις κατηγορίες ειδών που ορίσαμε παραπάνω.\n",
"\n",
"Παρ' όλα αυτά, ήταν μια αρκετά ενδιαφέρουσα διαδικασία μάθησης!\n",
"\n",
"Στην τεκμηρίωση του Scikit-learn, μπορείτε να δείτε ότι ένα μοντέλο σαν αυτό, με clusters που δεν είναι πολύ καλά καθορισμένα, έχει πρόβλημα \"διακύμανσης\":\n",
"\n",
"<p >\n",
" <img src=\"../../images/problems.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Γραφικό από το Scikit-learn</figcaption>\n",
"\n",
"\n",
"\n",
"## **Διακύμανση**\n",
"\n",
"Η διακύμανση ορίζεται ως \"ο μέσος όρος των τετραγωνικών διαφορών από τη μέση τιμή\" [πηγή](https://www.mathsisfun.com/data/standard-deviation.html). Στο πλαίσιο αυτού του προβλήματος ομαδοποίησης, αναφέρεται στα δεδομένα όπου οι αριθμοί του συνόλου δεδομένων μας τείνουν να αποκλίνουν υπερβολικά από τη μέση τιμή.\n",
"\n",
"✅ Αυτή είναι μια εξαιρετική στιγμή για να σκεφτείτε όλους τους τρόπους με τους οποίους θα μπορούσατε να διορθώσετε αυτό το ζήτημα. Να τροποποιήσετε λίγο τα δεδομένα; Να χρησιμοποιήσετε διαφορετικές στήλες; Να δοκιμάσετε έναν διαφορετικό αλγόριθμο; Υπόδειξη: Δοκιμάστε [να κλιμακώσετε τα δεδομένα σας](https://www.mygreatlearning.com/blog/learning-data-science-with-k-means-clustering/) για να τα κανονικοποιήσετε και να δοκιμάσετε άλλες στήλες.\n",
"\n",
"> Δοκιμάστε αυτόν τον '[υπολογιστή διακύμανσης](https://www.calculatorsoup.com/calculators/statistics/variance-calculator.php)' για να κατανοήσετε λίγο καλύτερα την έννοια.\n",
"\n",
"------------------------------------------------------------------------\n",
"\n",
"## **🚀Πρόκληση**\n",
"\n",
"Περάστε λίγο χρόνο με αυτό το notebook, τροποποιώντας παραμέτρους. Μπορείτε να βελτιώσετε την ακρίβεια του μοντέλου καθαρίζοντας περισσότερο τα δεδομένα (αφαιρώντας, για παράδειγμα, ακραίες τιμές); Μπορείτε να χρησιμοποιήσετε βάρη για να δώσετε μεγαλύτερη βαρύτητα σε συγκεκριμένα δείγματα δεδομένων. Τι άλλο μπορείτε να κάνετε για να δημιουργήσετε καλύτερα clusters;\n",
"\n",
"Υπόδειξη: Δοκιμάστε να κλιμακώσετε τα δεδομένα σας. Υπάρχει σχολιασμένος κώδικας στο notebook που προσθέτει τυπική κλιμάκωση για να κάνουν οι στήλες δεδομένων να μοιάζουν περισσότερο μεταξύ τους όσον αφορά το εύρος. Θα παρατηρήσετε ότι ενώ η βαθμολογία silhouette μειώνεται, η \"καμπή\" στο γράφημα του αγκώνα εξομαλύνεται. Αυτό συμβαίνει επειδή η μη κλιμάκωση των δεδομένων επιτρέπει στα δεδομένα με μικρότερη διακύμανση να έχουν μεγαλύτερη βαρύτητα. Διαβάστε περισσότερα για αυτό το πρόβλημα [εδώ](https://stats.stackexchange.com/questions/21222/are-mean-normalization-and-feature-scaling-needed-for-k-means-clustering/21226#21226).\n",
"\n",
"## [**Κουίζ μετά τη διάλεξη**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/30/)\n",
"\n",
"## **Ανασκόπηση & Αυτομελέτη**\n",
"\n",
"- Ρίξτε μια ματιά σε έναν προσομοιωτή K-Means [όπως αυτόν](https://user.ceng.metu.edu.tr/~akifakkus/courses/ceng574/k-means/). Μπορείτε να χρησιμοποιήσετε αυτό το εργαλείο για να οπτικοποιήσετε δείγματα δεδομένων και να προσδιορίσετε τα κέντρα τους. Μπορείτε να επεξεργαστείτε την τυχαιότητα των δεδομένων, τον αριθμό των clusters και τον αριθμό των κέντρων. Σας βοηθά αυτό να κατανοήσετε πώς μπορούν να ομαδοποιηθούν τα δεδομένα;\n",
"\n",
"- Επίσης, ρίξτε μια ματιά σε [αυτό το φυλλάδιο για το K-Means](https://stanford.edu/~cpiech/cs221/handouts/kmeans.html) από το Stanford.\n",
"\n",
"Θέλετε να δοκιμάσετε τις νέες σας δεξιότητες ομαδοποίησης σε σύνολα δεδομένων που ταιριάζουν καλά με το K-Means clustering; Δείτε:\n",
"\n",
"- [Εκπαίδευση και Αξιολόγηση Μοντέλων Ομαδοποίησης](https://rpubs.com/eR_ic/clustering) χρησιμοποιώντας Tidymodels και φίλους\n",
"\n",
"- [Ανάλυση Ομαδοποίησης K-means](https://uc-r.github.io/kmeans_clustering), UC Business Analytics R Programming Guide\n",
"\n",
"- [Ομαδοποίηση K-means με αρχές tidy data](https://www.tidymodels.org/learn/statistics/k-means/)\n",
"\n",
"## **Εργασία**\n",
"\n",
"[Δοκιμάστε διαφορετικές μεθόδους ομαδοποίησης](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/2-K-Means/assignment.md)\n",
"\n",
"## ΕΥΧΑΡΙΣΤΟΥΜΕ:\n",
"\n",
"[Jen Looper](https://www.twitter.com/jenlooper) για τη δημιουργία της αρχικής έκδοσης αυτού του module σε Python ♥️\n",
"\n",
"[`Allison Horst`](https://twitter.com/allison_horst/) για τη δημιουργία των καταπληκτικών εικονογραφήσεων που κάνουν τη R πιο φιλική και ενδιαφέρουσα. Βρείτε περισσότερες εικονογραφήσεις στη [συλλογή της](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n",
"\n",
"Καλή Μάθηση,\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>Έργο τέχνης από @allison_horst</figcaption>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Αποποίηση ευθύνης**: \nΑυτό το έγγραφο έχει μεταφραστεί χρησιμοποιώντας την υπηρεσία αυτόματης μετάφρασης [Co-op Translator](https://github.com/Azure/co-op-translator). Παρόλο που καταβάλλουμε προσπάθειες για ακρίβεια, παρακαλούμε να έχετε υπόψη ότι οι αυτόματες μεταφράσεις ενδέχεται να περιέχουν λάθη ή ανακρίβειες. Το πρωτότυπο έγγραφο στη μητρική του γλώσσα θα πρέπει να θεωρείται η αυθεντική πηγή. Για κρίσιμες πληροφορίες, συνιστάται επαγγελματική ανθρώπινη μετάφραση. Δεν φέρουμε ευθύνη για τυχόν παρεξηγήσεις ή εσφαλμένες ερμηνείες που προκύπτουν από τη χρήση αυτής της μετάφρασης.\n"
]
}
]
}