{ "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-03T20:15:15+00:00", "source_file": "5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb", "language_code": "pl" } }, "cells": [ { "cell_type": "markdown", "metadata": { "id": "GULATlQXLXyR" }, "source": [ "## Eksploracja grupowania metodą K-Means w R z wykorzystaniem zasad Tidy data.\n", "\n", "### [**Quiz przed wykładem**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/29/)\n", "\n", "W tej lekcji nauczysz się tworzyć grupy za pomocą pakietu Tidymodels oraz innych pakietów z ekosystemu R (nazwiemy je przyjaciółmi 🧑‍🤝‍🧑), a także wykorzystując nigeryjski zestaw danych muzycznych, który zaimportowałeś wcześniej. Omówimy podstawy K-Means dla grupowania. Pamiętaj, że jak nauczyłeś się w poprzedniej lekcji, istnieje wiele sposobów pracy z grupami, a metoda, którą wybierzesz, zależy od Twoich danych. Spróbujemy K-Means, ponieważ jest to najczęściej stosowana technika grupowania. Zaczynajmy!\n", "\n", "Pojęcia, które poznasz:\n", "\n", "- Ocena sylwetki (Silhouette scoring)\n", "\n", "- Metoda łokcia (Elbow method)\n", "\n", "- Inercja\n", "\n", "- Wariancja\n", "\n", "### **Wprowadzenie**\n", "\n", "[Grupowanie metodą K-Means](https://wikipedia.org/wiki/K-means_clustering) to metoda wywodząca się z dziedziny przetwarzania sygnałów. Służy do dzielenia i grupowania danych w `k grupy` na podstawie podobieństw ich cech.\n", "\n", "Grupy można wizualizować jako [diagramy Voronoi](https://wikipedia.org/wiki/Voronoi_diagram), które zawierają punkt (lub 'nasiono') oraz odpowiadający mu obszar.\n", "\n", "

\n", " \n", "

Infografika autorstwa Jen Looper
\n", "\n", "\n", "Grupowanie metodą K-Means obejmuje następujące kroki:\n", "\n", "1. Data scientist zaczyna od określenia pożądanej liczby grup, które mają zostać utworzone.\n", "\n", "2. Następnie algorytm losowo wybiera K obserwacji z zestawu danych, które będą początkowymi centrami grup (czyli centroidami).\n", "\n", "3. Następnie każda z pozostałych obserwacji jest przypisywana do najbliższego centroidu.\n", "\n", "4. Następnie obliczana jest nowa średnia dla każdej grupy, a centroid przesuwany jest do tej średniej.\n", "\n", "5. Po przeliczeniu centrów każda obserwacja jest ponownie sprawdzana, aby zobaczyć, czy może być bliżej innej grupy. Wszystkie obiekty są ponownie przypisywane, korzystając z zaktualizowanych średnich grup. Kroki przypisywania grup i aktualizacji centroidów są powtarzane iteracyjnie, aż przypisania grup przestaną się zmieniać (czyli gdy osiągnięta zostanie konwergencja). Zazwyczaj algorytm kończy działanie, gdy każda nowa iteracja powoduje znikomy ruch centroidów, a grupy stają się statyczne.\n", "\n", "
\n", "\n", "> Zauważ, że ze względu na losowość początkowych k obserwacji używanych jako centroidy początkowe, możemy uzyskać nieco różne wyniki za każdym razem, gdy stosujemy procedurę. Z tego powodu większość algorytmów używa kilku *losowych startów* i wybiera iterację z najniższym WCSS. Dlatego zdecydowanie zaleca się zawsze uruchamiać K-Means z kilkoma wartościami *nstart*, aby uniknąć *niepożądanego lokalnego optimum.*\n", "\n", "
\n", "\n", "Ta krótka animacja wykorzystująca [grafikę](https://github.com/allisonhorst/stats-illustrations) autorstwa Allison Horst wyjaśnia proces grupowania:\n", "\n", "

\n", " \n", "

Grafika autorstwa @allison_horst
\n", "\n", "\n", "\n", "Podstawowe pytanie, które pojawia się w grupowaniu, brzmi: skąd wiadomo, na ile grup podzielić dane? Jednym z ograniczeń metody K-Means jest konieczność ustalenia `k`, czyli liczby `centroidów`. Na szczęście `metoda łokcia` pomaga oszacować dobrą wartość początkową dla `k`. Zaraz ją wypróbujesz.\n", "\n", "### \n", "\n", "**Wymagania wstępne**\n", "\n", "Zaczniemy dokładnie tam, gdzie skończyliśmy w [poprzedniej lekcji](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb), gdzie analizowaliśmy zestaw danych, tworzyliśmy wiele wizualizacji i filtrowaliśmy zestaw danych do interesujących obserwacji. Koniecznie sprawdź!\n", "\n", "Będziemy potrzebować kilku pakietów, aby ukończyć ten moduł. Możesz je zainstalować za pomocą: `install.packages(c('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork'))`\n", "\n", "Alternatywnie, poniższy skrypt sprawdza, czy masz wymagane pakiety do ukończenia tego modułu i instaluje je, jeśli brakuje niektórych.\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": [ "Zaczynajmy!\n", "\n", "## 1. Taniec z danymi: Wybierz 3 najpopularniejsze gatunki muzyczne\n", "\n", "To podsumowanie tego, co zrobiliśmy w poprzedniej lekcji. Czas na analizę danych!\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": [ "🤩 To poszło świetnie!\n", "\n", "## 2. Więcej eksploracji danych.\n", "\n", "Jak czyste są te dane? Sprawdźmy wartości odstające za pomocą wykresów pudełkowych. Skupimy się na kolumnach numerycznych z mniejszą liczbą wartości odstających (chociaż można oczyścić dane z wartości odstających). Wykresy pudełkowe mogą pokazać zakres danych i pomóc w wyborze kolumn do analizy. Pamiętaj, że wykresy pudełkowe nie pokazują wariancji, która jest istotnym elementem dobrych danych do klastrowania. Zobacz [tę dyskusję](https://stats.stackexchange.com/questions/91536/deduce-variance-from-boxplot) dla dalszych informacji.\n", "\n", "[Wykresy pudełkowe](https://en.wikipedia.org/wiki/Box_plot) są używane do graficznego przedstawienia rozkładu danych `numerycznych`, więc zacznijmy od *wyboru* wszystkich kolumn numerycznych wraz z popularnymi gatunkami muzycznymi.\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": [ "Zobacz, jak pomocnik wyboru `where` ułatwia to zadanie 💁? Odkryj inne podobne funkcje [tutaj](https://tidyselect.r-lib.org/).\n", "\n", "Ponieważ będziemy tworzyć wykres pudełkowy dla każdej cechy numerycznej i chcemy uniknąć używania pętli, przeformatujmy nasze dane na *dłuższy* format, który pozwoli nam skorzystać z `facets` - podwykresów, z których każdy przedstawia jeden podzbiór danych.\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": [ "Czas na coś dłuższego! Teraz pora na trochę `ggplots`! Jakiego `geom` użyjemy?\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", "Teraz widzimy, że dane są trochę \"szumne\": obserwując każdą kolumnę jako wykres pudełkowy, można zauważyć wartości odstające. Można by przejrzeć zestaw danych i usunąć te wartości odstające, ale wtedy dane stałyby się dość ograniczone.\n", "\n", "Na razie wybierzmy, które kolumny wykorzystamy do naszego ćwiczenia grupowania. Wybierzmy kolumny numeryczne o podobnych zakresach. Moglibyśmy zakodować `artist_top_genre` jako wartość numeryczną, ale na razie ją pominiemy.\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. Obliczanie klastrowania k-means w R\n", "\n", "Możemy obliczyć k-means w R za pomocą wbudowanej funkcji `kmeans`, zobacz `help(\"kmeans()\")`. Funkcja `kmeans()` przyjmuje ramkę danych, w której wszystkie kolumny są numeryczne, jako swój główny argument.\n", "\n", "Pierwszym krokiem przy użyciu klastrowania k-means jest określenie liczby klastrów (k), które zostaną wygenerowane w ostatecznym rozwiązaniu. Wiemy, że w zbiorze danych wyodrębniliśmy 3 gatunki muzyczne, więc spróbujmy z 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": [ "Obiekt kmeans zawiera kilka informacji, które są dobrze wyjaśnione w `help(\"kmeans()\")`. Na razie skupmy się na kilku z nich. Widzimy, że dane zostały podzielone na 3 klastry o rozmiarach 65, 110, 111. Wynik zawiera również centra klastrów (średnie) dla 3 grup w odniesieniu do 5 zmiennych.\n", "\n", "Wektor klastrowania to przypisanie klastra dla każdej obserwacji. Użyjmy funkcji `augment`, aby dodać przypisanie klastra do oryginalnego zestawu danych.\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": [ "Świetnie, właśnie podzieliliśmy nasz zbiór danych na 3 grupy. Jak dobrze wypadło nasze klastrowanie 🤷? Spójrzmy na `Silhouette score`.\n", "\n", "### **Silhouette score**\n", "\n", "[Analiza silhouette](https://en.wikipedia.org/wiki/Silhouette_(clustering)) może być używana do badania odległości separacyjnej między powstałymi klastrami. Wynik ten waha się od -1 do 1, a jeśli wynik jest bliski 1, oznacza to, że klaster jest gęsty i dobrze oddzielony od innych klastrów. Wartość bliska 0 oznacza nakładające się klastry, w których próbki znajdują się bardzo blisko granicy decyzyjnej sąsiednich klastrów. [źródło](https://dzone.com/articles/kmeans-silhouette-score-explained-with-python-exam).\n", "\n", "Metoda średniej silhouette oblicza średnią wartość silhouette dla różnych wartości *k*. Wysoki średni wynik silhouette wskazuje na dobre klastrowanie.\n", "\n", "Funkcja `silhouette` w pakiecie cluster służy do obliczania średniej szerokości silhouette.\n", "\n", "> Silhouette można obliczyć za pomocą dowolnej [metryki odległości](https://en.wikipedia.org/wiki/Distance \"Distance\"), takiej jak [odległość euklidesowa](https://en.wikipedia.org/wiki/Euclidean_distance \"Euclidean distance\") lub [odległość Manhattan](https://en.wikipedia.org/wiki/Manhattan_distance \"Manhattan distance\"), które omawialiśmy w [poprzedniej lekcji](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": [ "Nasz wynik to **.549**, czyli dokładnie w środku. Wskazuje to, że nasze dane nie są szczególnie dobrze dopasowane do tego rodzaju klastrowania. Zobaczmy, czy możemy potwierdzić tę intuicję wizualnie. Pakiet [factoextra](https://rpkgs.datanovia.com/factoextra/index.html) udostępnia funkcje (`fviz_cluster()`), które pozwalają na wizualizację klastrowania.\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": [ "Nakładanie się klastrów wskazuje, że nasze dane nie są szczególnie dobrze dopasowane do tego rodzaju klastrowania, ale kontynuujmy.\n", "\n", "## 4. Określenie optymalnej liczby klastrów\n", "\n", "Podstawowe pytanie, które często pojawia się w klastrowaniu metodą K-Means, brzmi: bez znanych etykiet klas, skąd wiadomo, na ile klastrów podzielić dane?\n", "\n", "Jednym ze sposobów, aby to sprawdzić, jest użycie próbki danych do `utworzenia serii modeli klastrowania` z rosnącą liczbą klastrów (np. od 1 do 10) i ocena metryk klastrowania, takich jak **Silhouette score.**\n", "\n", "Określmy optymalną liczbę klastrów, obliczając algorytm klastrowania dla różnych wartości *k* i oceniając **Sumę Kwadratów Wewnątrz Klastra** (WCSS). Całkowita suma kwadratów wewnątrz klastra (WCSS) mierzy zwartość klastrowania, a zależy nam na tym, aby była jak najmniejsza – niższe wartości oznaczają, że punkty danych są bliżej siebie.\n", "\n", "Przeanalizujmy wpływ różnych wyborów `k`, od 1 do 10, na to klastrowanie.\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": [ "Teraz, gdy mamy całkowitą sumę kwadratów wewnątrz klastrów (tot.withinss) dla każdego algorytmu klastrowania z centrum *k*, używamy [metody łokcia](https://en.wikipedia.org/wiki/Elbow_method_(clustering)) do znalezienia optymalnej liczby klastrów. Metoda polega na wykreśleniu WCSS jako funkcji liczby klastrów i wybraniu [punktu łokcia krzywej](https://en.wikipedia.org/wiki/Elbow_of_the_curve \"Elbow of the curve\") jako liczby klastrów do użycia.\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": [ "Wykres pokazuje znaczną redukcję WCSS (czyli większą *spójność*) wraz ze wzrostem liczby klastrów z jednego do dwóch, a następnie zauważalną redukcję z dwóch do trzech klastrów. Po tym redukcja jest mniej wyraźna, co skutkuje `łokciem` 💪 na wykresie przy około trzech klastrach. To dobry znak, że istnieją dwa do trzech stosunkowo dobrze oddzielonych klastrów punktów danych.\n", "\n", "Możemy teraz przejść do wyodrębnienia modelu klastrowania, gdzie `k = 3`:\n", "\n", "> `pull()`: używane do wyodrębnienia pojedynczej kolumny\n", ">\n", "> `pluck()`: używane do indeksowania struktur danych, takich jak listy\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": [ "Świetnie! Przejdźmy do wizualizacji uzyskanych klastrów. Masz ochotę na trochę interaktywności z użyciem `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": [ "Być może spodziewalibyśmy się, że każdy klaster (reprezentowany przez różne kolory) będzie miał odrębne gatunki (reprezentowane przez różne kształty).\n", "\n", "Przyjrzyjmy się dokładności modelu.\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": [ "Dokładność tego modelu nie jest zła, ale też nie jest świetna. Może się okazać, że dane nie nadają się dobrze do grupowania metodą K-Means. Dane są zbyt niezrównoważone, zbyt słabo skorelowane, a różnice między wartościami w kolumnach są zbyt duże, aby dobrze je pogrupować. W rzeczywistości grupy, które się tworzą, są prawdopodobnie mocno wpływane lub zniekształcone przez trzy kategorie gatunków, które zdefiniowaliśmy powyżej.\n", "\n", "Mimo to, była to całkiem pouczająca lekcja!\n", "\n", "W dokumentacji Scikit-learn można zauważyć, że model taki jak ten, z grupami niezbyt dobrze wyodrębnionymi, ma problem z \"wariancją\":\n", "\n", "

\n", " \n", "

Infografika z Scikit-learn
\n", "\n", "\n", "\n", "## **Wariancja**\n", "\n", "Wariancja jest definiowana jako \"średnia kwadratów różnic od średniej\" [źródło](https://www.mathsisfun.com/data/standard-deviation.html). W kontekście tego problemu grupowania odnosi się do danych, w których wartości naszego zbioru danych mają tendencję do zbytniego odchylenia od średniej.\n", "\n", "✅ To świetny moment, aby zastanowić się nad wszystkimi sposobami, w jakie można rozwiązać ten problem. Może warto trochę zmodyfikować dane? Użyć innych kolumn? Zastosować inny algorytm? Podpowiedź: Spróbuj [skalować dane](https://www.mygreatlearning.com/blog/learning-data-science-with-k-means-clustering/), aby je znormalizować i przetestować inne kolumny.\n", "\n", "> Wypróbuj ten '[kalkulator wariancji](https://www.calculatorsoup.com/calculators/statistics/variance-calculator.php)', aby lepiej zrozumieć ten koncept.\n", "\n", "------------------------------------------------------------------------\n", "\n", "## **🚀Wyzwanie**\n", "\n", "Poświęć trochę czasu na pracę z tym notebookiem, zmieniając parametry. Czy możesz poprawić dokładność modelu, bardziej oczyszczając dane (na przykład usuwając wartości odstające)? Możesz użyć wag, aby nadać większe znaczenie wybranym próbom danych. Co jeszcze możesz zrobić, aby stworzyć lepsze grupy?\n", "\n", "Podpowiedź: Spróbuj skalować dane. W notebooku znajduje się zakomentowany kod, który dodaje standardowe skalowanie, aby kolumny danych bardziej przypominały siebie nawzajem pod względem zakresu. Zauważysz, że chociaż wynik silhouette score spada, \"załamanie\" na wykresie łokcia wygładza się. Dzieje się tak, ponieważ pozostawienie danych nieskalowanych pozwala danym o mniejszej wariancji mieć większy wpływ. Przeczytaj więcej o tym problemie [tutaj](https://stats.stackexchange.com/questions/21222/are-mean-normalization-and-feature-scaling-needed-for-k-means-clustering/21226#21226).\n", "\n", "## [**Quiz po wykładzie**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/30/)\n", "\n", "## **Przegląd i samodzielna nauka**\n", "\n", "- Sprawdź symulator K-Means [taki jak ten](https://user.ceng.metu.edu.tr/~akifakkus/courses/ceng574/k-means/). Możesz użyć tego narzędzia, aby wizualizować przykładowe punkty danych i określić ich centroidy. Możesz edytować losowość danych, liczbę grup i liczbę centroidów. Czy pomaga to zrozumieć, jak dane mogą być grupowane?\n", "\n", "- Zajrzyj również do [tego materiału o K-Means](https://stanford.edu/~cpiech/cs221/handouts/kmeans.html) ze Stanfordu.\n", "\n", "Chcesz wypróbować swoje nowo zdobyte umiejętności grupowania na zestawach danych, które dobrze nadają się do grupowania metodą K-Means? Zobacz:\n", "\n", "- [Trenuj i oceniaj modele grupowania](https://rpubs.com/eR_ic/clustering) za pomocą Tidymodels i innych narzędzi\n", "\n", "- [Analiza grup K-Means](https://uc-r.github.io/kmeans_clustering), Przewodnik UC Business Analytics R Programming\n", "\n", "- [Grupowanie K-Means z zasadami tidy data](https://www.tidymodels.org/learn/statistics/k-means/)\n", "\n", "## **Zadanie**\n", "\n", "[Wypróbuj różne metody grupowania](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/2-K-Means/assignment.md)\n", "\n", "## PODZIĘKOWANIA DLA:\n", "\n", "[Jen Looper](https://www.twitter.com/jenlooper) za stworzenie oryginalnej wersji tego modułu w Pythonie ♥️\n", "\n", "[`Allison Horst`](https://twitter.com/allison_horst/) za stworzenie niesamowitych ilustracji, które sprawiają, że R jest bardziej przyjazny i angażujący. Znajdź więcej ilustracji w jej [galerii](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n", "\n", "Miłej nauki,\n", "\n", "[Eric](https://twitter.com/ericntay), Złoty Ambasador Studentów Microsoft Learn.\n", "\n", "

\n", " \n", "

Ilustracja autorstwa @allison_horst
\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n---\n\n**Zastrzeżenie**: \nTen dokument został przetłumaczony za pomocą usługi tłumaczenia AI [Co-op Translator](https://github.com/Azure/co-op-translator). Chociaż dokładamy wszelkich starań, aby tłumaczenie było precyzyjne, prosimy pamiętać, że automatyczne tłumaczenia mogą zawierać błędy lub nieścisłości. Oryginalny dokument w jego rodzimym języku powinien być uznawany za źródło autorytatywne. W przypadku informacji o kluczowym znaczeniu zaleca się skorzystanie z profesjonalnego tłumaczenia przez człowieka. Nie ponosimy odpowiedzialności za jakiekolwiek nieporozumienia lub błędne interpretacje wynikające z użycia tego tłumaczenia.\n" ] } ] }