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

639 lines
29 KiB

{
"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-08-29T15:21:01+00:00",
"source_file": "5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb",
"language_code": "tl"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "GULATlQXLXyR"
},
"source": [
"## Tuklasin ang K-Means clustering gamit ang R at mga prinsipyo ng Tidy data.\n",
"\n",
"### [**Pre-lecture quiz**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/29/)\n",
"\n",
"Sa araling ito, matututuhan mo kung paano lumikha ng mga cluster gamit ang Tidymodels package at iba pang mga package sa ecosystem ng R (tatawagin natin silang mga kaibigan 🧑‍🤝‍🧑), at ang Nigerian music dataset na na-import mo kanina. Tatalakayin natin ang mga pangunahing kaalaman ng K-Means para sa Clustering. Tandaan na, tulad ng natutunan mo sa nakaraang aralin, maraming paraan upang magtrabaho sa mga cluster at ang pamamaraan na gagamitin mo ay nakadepende sa iyong data. Susubukan natin ang K-Means dahil ito ang pinakakaraniwang clustering technique. Tara na!\n",
"\n",
"Mga terminong matututuhan mo:\n",
"\n",
"- Silhouette scoring\n",
"\n",
"- Elbow method\n",
"\n",
"- Inertia\n",
"\n",
"- Variance\n",
"\n",
"### **Panimula**\n",
"\n",
"Ang [K-Means Clustering](https://wikipedia.org/wiki/K-means_clustering) ay isang pamamaraan na nagmula sa larangan ng signal processing. Ginagamit ito upang hatiin at i-partition ang mga grupo ng data sa `k clusters` batay sa pagkakapareho ng kanilang mga katangian.\n",
"\n",
"Ang mga cluster ay maaaring i-visualize bilang [Voronoi diagrams](https://wikipedia.org/wiki/Voronoi_diagram), na binubuo ng isang punto (o 'seed') at ang kaukulang rehiyon nito.\n",
"\n",
"<p >\n",
" <img src=\"../../images/voronoi.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Infographic ni Jen Looper</figcaption>\n",
"\n",
"Ang K-Means clustering ay may mga sumusunod na hakbang:\n",
"\n",
"1. Sinisimulan ng data scientist sa pamamagitan ng pagtukoy ng nais na bilang ng mga cluster na gagawin.\n",
"\n",
"2. Susunod, ang algorithm ay random na pumipili ng K na obserbasyon mula sa data set upang magsilbing mga paunang sentro para sa mga cluster (i.e., centroids).\n",
"\n",
"3. Pagkatapos, ang bawat natitirang obserbasyon ay itinalaga sa pinakamalapit na centroid.\n",
"\n",
"4. Susunod, kinakalkula ang bagong mean ng bawat cluster at ang centroid ay inilipat sa mean.\n",
"\n",
"5. Ngayon na ang mga sentro ay muling na-kalkula, ang bawat obserbasyon ay muling sinusuri upang makita kung mas malapit ito sa ibang cluster. Ang lahat ng mga bagay ay muling itinalaga gamit ang na-update na mga mean ng cluster. Ang mga hakbang ng cluster assignment at centroid update ay paulit-ulit na inuulit hanggang sa ang mga assignment ng cluster ay tumigil sa pagbabago (i.e., kapag naabot ang convergence). Karaniwan, ang algorithm ay nagtatapos kapag ang bawat bagong iteration ay nagreresulta sa napakaliit na paggalaw ng mga centroid at ang mga cluster ay nagiging static.\n",
"\n",
"<div>\n",
"\n",
"> Tandaan na dahil sa randomization ng mga paunang k obserbasyon na ginamit bilang mga panimulang centroid, maaari tayong makakuha ng bahagyang magkaibang resulta sa bawat pagkakataon na ilalapat natin ang pamamaraan. Dahil dito, karamihan sa mga algorithm ay gumagamit ng ilang *random starts* at pinipili ang iteration na may pinakamababang WCSS. Kaya't mariing inirerekomenda na palaging patakbuhin ang K-Means gamit ang ilang halaga ng *nstart* upang maiwasan ang *hindi kanais-nais na local optimum.*\n",
"\n",
"</div>\n",
"\n",
"Ang maikling animation na ito gamit ang [artwork](https://github.com/allisonhorst/stats-illustrations) ni Allison Horst ay nagpapaliwanag ng proseso ng clustering:\n",
"\n",
"<p >\n",
" <img src=\"../../images/kmeans.gif\"\n",
" width=\"550\"/>\n",
" <figcaption>Artwork ni @allison_horst</figcaption>\n",
"\n",
"Isang mahalagang tanong na lumalabas sa clustering ay ito: paano mo malalaman kung ilang cluster ang dapat mong paghiwalayin ang iyong data? Isa sa mga kahinaan ng paggamit ng K-Means ay ang pangangailangan na tukuyin ang `k`, o ang bilang ng mga `centroids`. Sa kabutihang-palad, ang `elbow method` ay tumutulong upang tantyahin ang isang magandang panimulang halaga para sa `k`. Susubukan mo ito sa ilang sandali.\n",
"\n",
"### \n",
"\n",
"**Paunang Kaalaman**\n",
"\n",
"Ipagpapatuloy natin mula sa kung saan tayo tumigil sa [nakaraang aralin](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb), kung saan sinuri natin ang data set, gumawa ng maraming visualization, at na-filter ang data set sa mga obserbasyong mahalaga. Siguraduhing balikan ito!\n",
"\n",
"Kakailanganin natin ng ilang mga package upang matapos ang module na ito. Maaari mo silang mai-install gamit ang: `install.packages(c('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork'))`\n",
"\n",
"Bilang alternatibo, ang script sa ibaba ay sinusuri kung mayroon ka ng mga kinakailangang package upang makumpleto ang module na ito at awtomatikong ini-install ang mga nawawala.\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": [
"Tara, simulan na natin!\n",
"\n",
"## 1. Isang sayaw kasama ang datos: Piliin ang 3 pinakapopular na genre ng musika\n",
"\n",
"Ito ay isang pagbalik-tanaw sa ginawa natin sa nakaraang aralin. Halika't himayin natin ang datos!\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": [
"🤩 Ang galing nun!\n",
"\n",
"## 2. Mas malalim na pagsusuri ng datos.\n",
"\n",
"Gaano kalinis ang datos na ito? Tingnan natin kung may mga outlier gamit ang mga box plot. Magtuon tayo sa mga numeric na column na may mas kaunting outlier (bagamat maaari mong linisin ang mga outlier). Ang mga box plot ay maaaring magpakita ng saklaw ng datos at makakatulong sa pagpili kung aling mga column ang gagamitin. Tandaan, ang mga box plot ay hindi nagpapakita ng variance, isang mahalagang elemento ng mahusay na clusterable na datos. Mangyaring tingnan ang [talakayang ito](https://stats.stackexchange.com/questions/91536/deduce-variance-from-boxplot) para sa karagdagang impormasyon.\n",
"\n",
"Ang mga [Boxplot](https://en.wikipedia.org/wiki/Box_plot) ay ginagamit upang ipakita nang grapikal ang distribusyon ng `numeric` na datos, kaya magsimula tayo sa *pagpili* ng lahat ng numeric na column kasama ang mga sikat na genre ng musika.\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": [
"Tingnan kung paano pinapadali ng selection helper na `where` ang prosesong ito 💁? Tuklasin ang iba pang mga function na tulad nito [dito](https://tidyselect.r-lib.org/).\n",
"\n",
"Dahil gagawa tayo ng boxplot para sa bawat numeric na katangian at nais nating iwasan ang paggamit ng mga loop, ire-reformat natin ang ating data sa isang *mas mahaba* na format na magpapahintulot sa atin na magamit ang `facets` - mga subplot na nagpapakita ng bawat subset ng data.\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": [
"Mas mahaba! Oras na para sa ilang `ggplots`! Kaya anong `geom` ang gagamitin natin?\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",
"Ngayon makikita natin na medyo magulo ang datos: sa pamamagitan ng pag-obserba sa bawat column gamit ang boxplot, makikita mo ang mga outlier. Pwede mong suriin ang dataset at alisin ang mga outlier na ito, pero magiging masyadong limitado ang datos kung gagawin iyon.\n",
"\n",
"Sa ngayon, piliin natin kung aling mga column ang gagamitin para sa ating clustering exercise. Piliin natin ang mga numeric na column na may magkatulad na range. Pwede nating i-encode ang `artist_top_genre` bilang numeric pero iiwan muna natin ito sa ngayon.\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. Pag-compute ng k-means clustering sa R\n",
"\n",
"Maaaring i-compute ang k-means sa R gamit ang built-in na `kmeans` function, tingnan ang `help(\"kmeans()\")`. Ang `kmeans()` function ay tumatanggap ng data frame na may lahat ng numeric na column bilang pangunahing argumento nito.\n",
"\n",
"Ang unang hakbang sa paggamit ng k-means clustering ay ang pagtukoy ng bilang ng clusters (k) na bubuuin sa final na solusyon. Alam natin na mayroong 3 genre ng kanta na nakuha mula sa dataset, kaya subukan natin ang 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": [
"Ang kmeans object ay naglalaman ng ilang impormasyon na mahusay na ipinaliwanag sa `help(\"kmeans()\")`. Sa ngayon, mag-focus tayo sa ilang bahagi nito. Nakikita natin na ang datos ay nahati sa 3 clusters na may mga sukat na 65, 110, 111. Ang output ay naglalaman din ng mga sentro ng cluster (means) para sa 3 grupo sa kabuuan ng 5 variables.\n",
"\n",
"Ang clustering vector ay ang cluster assignment para sa bawat obserbasyon. Gamitin natin ang `augment` function upang idagdag ang cluster assignment sa orihinal na data set.\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": [
"Perfecto, nahati na natin ang ating data set sa 3 grupo. Kaya, gaano nga ba kaganda ang ating clustering 🤷? Tingnan natin ang `Silhouette score`.\n",
"\n",
"### **Silhouette score**\n",
"\n",
"Ang [Silhouette analysis](https://en.wikipedia.org/wiki/Silhouette_(clustering)) ay maaaring gamitin upang pag-aralan ang distansya ng paghihiwalay sa pagitan ng mga nabuong cluster. Ang score na ito ay nagbabago mula -1 hanggang 1, at kung ang score ay malapit sa 1, ang cluster ay siksik at maayos na nahihiwalay mula sa ibang mga cluster. Ang halaga na malapit sa 0 ay kumakatawan sa mga cluster na nag-o-overlap, kung saan ang mga sample ay napakalapit sa decision boundary ng mga kalapit na cluster. [source](https://dzone.com/articles/kmeans-silhouette-score-explained-with-python-exam).\n",
"\n",
"Ang average silhouette method ay kinakalkula ang average silhouette ng mga obserbasyon para sa iba't ibang halaga ng *k*. Ang mataas na average silhouette score ay nagpapahiwatig ng magandang clustering.\n",
"\n",
"Ang `silhouette` function sa cluster package ay ginagamit upang kalkulahin ang average silhouette width.\n",
"\n",
"> Ang silhouette ay maaaring kalkulahin gamit ang anumang [distance](https://en.wikipedia.org/wiki/Distance \"Distance\") metric, tulad ng [Euclidean distance](https://en.wikipedia.org/wiki/Euclidean_distance \"Euclidean distance\") o [Manhattan distance](https://en.wikipedia.org/wiki/Manhattan_distance \"Manhattan distance\") na tinalakay natin sa [nakaraang aralin](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": [
"Ang ating score ay **.549**, kaya nasa gitna lang. Ipinapakita nito na ang ating data ay hindi gaanong angkop para sa ganitong uri ng clustering. Tingnan natin kung makukumpirma natin ang hinalang ito sa pamamagitan ng visual. Ang [factoextra package](https://rpkgs.datanovia.com/factoextra/index.html) ay nagbibigay ng mga function (`fviz_cluster()`) para i-visualize ang clustering.\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": [
"Ang overlap sa mga cluster ay nagpapahiwatig na ang ating datos ay hindi gaanong angkop para sa ganitong uri ng clustering, ngunit magpatuloy tayo.\n",
"\n",
"## 4. Pagtukoy sa pinakamainam na bilang ng mga cluster\n",
"\n",
"Isang mahalagang tanong na madalas lumalabas sa K-Means clustering ay ito - kung walang kilalang mga label ng klase, paano mo malalaman kung ilang cluster ang dapat paghiwalayin ang iyong datos?\n",
"\n",
"Isang paraan upang malaman ito ay ang paggamit ng isang sample ng datos upang `lumikha ng serye ng mga clustering model` na may dumaraming bilang ng mga cluster (hal. mula 1-10), at suriin ang mga clustering metric tulad ng **Silhouette score.**\n",
"\n",
"Tukuyin natin ang pinakamainam na bilang ng mga cluster sa pamamagitan ng pagkalkula ng clustering algorithm para sa iba't ibang halaga ng *k* at pagsusuri sa **Within Cluster Sum of Squares** (WCSS). Ang kabuuang within-cluster sum of square (WCSS) ay sumusukat sa pagkakabuklod ng clustering, at nais natin itong maging kasing-liit hangga't maaari, kung saan ang mas mababang halaga ay nangangahulugang mas malapit ang mga datos.\n",
"\n",
"Suriin natin ang epekto ng iba't ibang pagpipilian ng `k`, mula 1 hanggang 10, sa clustering na ito.\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": [
"Ngayon na mayroon na tayong kabuuang within-cluster sum-of-squares (tot.withinss) para sa bawat clustering algorithm na may center *k*, gagamitin natin ang [elbow method](https://en.wikipedia.org/wiki/Elbow_method_(clustering)) upang mahanap ang pinakamainam na bilang ng clusters. Ang pamamaraang ito ay binubuo ng pag-plot ng WCSS bilang isang function ng bilang ng clusters, at pagpili sa [elbow ng kurba](https://en.wikipedia.org/wiki/Elbow_of_the_curve \"Elbow of the curve\") bilang bilang ng clusters na gagamitin.\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": [
"Ang grap ay nagpapakita ng malaking pagbaba sa WCSS (kaya mas *mahigpit*) habang ang bilang ng mga cluster ay tumataas mula isa hanggang dalawa, at isa pang kapansin-pansing pagbaba mula dalawa hanggang tatlong cluster. Pagkatapos nito, ang pagbaba ay hindi na gaanong kapansin-pansin, na nagreresulta sa isang `elbow` 💪 sa chart sa bandang tatlong cluster. Ito ay isang magandang indikasyon na may dalawa hanggang tatlong makatuwirang hiwalay na mga cluster ng mga data point.\n",
"\n",
"Maaari na nating kunin ang clustering model kung saan `k = 3`:\n",
"\n",
"> `pull()`: ginagamit upang kunin ang isang column\n",
">\n",
"> `pluck()`: ginagamit upang i-index ang mga data structure tulad ng mga list\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": [
"Sige! Tingnan natin ang mga cluster na nakuha. Gusto mo ba ng kaunting interaktibidad gamit ang `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": [
"Maaaring inaasahan natin na ang bawat cluster (kinakatawan ng iba't ibang kulay) ay magkakaroon ng magkakaibang genre (kinakatawan ng iba't ibang hugis).\n",
"\n",
"Tingnan natin ang katumpakan ng modelo.\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": [
"Ang katumpakan ng modelong ito ay hindi masama, ngunit hindi rin magaling. Maaaring ang datos ay hindi angkop para sa K-Means Clustering. Ang datos na ito ay masyadong hindi balanse, masyadong kaunti ang kaugnayan, at masyadong malaki ang pagkakaiba-iba sa pagitan ng mga halaga ng column para makabuo ng maayos na cluster. Sa katunayan, ang mga cluster na nabuo ay malamang na malaki ang impluwensya o pagkiling mula sa tatlong kategorya ng genre na tinukoy natin sa itaas.\n",
"\n",
"Gayunpaman, ito ay isang magandang proseso ng pagkatuto!\n",
"\n",
"Sa dokumentasyon ng Scikit-learn, makikita mo na ang isang modelong tulad nito, na may mga cluster na hindi masyadong malinaw ang pagkakahati, ay may problema sa 'variance':\n",
"\n",
"<p >\n",
" <img src=\"../../images/problems.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Infographic mula sa Scikit-learn</figcaption>\n",
"\n",
"\n",
"\n",
"## **Variance**\n",
"\n",
"Ang variance ay tinutukoy bilang \"ang average ng mga squared differences mula sa Mean\" [source](https://www.mathsisfun.com/data/standard-deviation.html). Sa konteksto ng problemang clustering na ito, tumutukoy ito sa datos kung saan ang mga numero sa ating dataset ay may tendensiyang lumayo nang sobra mula sa mean.\n",
"\n",
"✅ Ito ay isang magandang pagkakataon para pag-isipan ang lahat ng paraan kung paano mo maaayos ang isyung ito. Ayusin pa ang datos? Gumamit ng ibang mga column? Gumamit ng ibang algorithm? Pahiwatig: Subukang [i-scale ang iyong datos](https://www.mygreatlearning.com/blog/learning-data-science-with-k-means-clustering/) upang gawing normal ito at subukan ang ibang mga column.\n",
"\n",
"> Subukan ang '[variance calculator](https://www.calculatorsoup.com/calculators/statistics/variance-calculator.php)' upang mas maunawaan ang konsepto.\n",
"\n",
"------------------------------------------------------------------------\n",
"\n",
"## **🚀Hamunin**\n",
"\n",
"Maglaan ng oras sa notebook na ito, at ayusin ang mga parameter. Kaya mo bang mapabuti ang katumpakan ng modelo sa pamamagitan ng mas maayos na paglilinis ng datos (halimbawa, pag-aalis ng mga outlier)? Maaari kang gumamit ng weights upang bigyan ng mas malaking timbang ang ilang data samples. Ano pa ang maaari mong gawin upang makabuo ng mas magagandang cluster?\n",
"\n",
"Pahiwatig: Subukang i-scale ang iyong datos. Mayroong commented code sa notebook na nagdadagdag ng standard scaling upang gawing mas magkatulad ang mga column ng datos sa kanilang saklaw. Mapapansin mo na habang bumababa ang silhouette score, ang 'kink' sa elbow graph ay nagiging mas maayos. Ito ay dahil ang hindi pag-scale sa datos ay nagbibigay-daan sa datos na may mas kaunting variance na magkaroon ng mas malaking timbang. Basahin pa ang tungkol sa problemang ito [dito](https://stats.stackexchange.com/questions/21222/are-mean-normalization-and-feature-scaling-needed-for-k-means-clustering/21226#21226).\n",
"\n",
"## [**Post-lecture quiz**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/30/)\n",
"\n",
"## **Review & Self Study**\n",
"\n",
"- Tingnan ang isang K-Means Simulator [tulad nito](https://user.ceng.metu.edu.tr/~akifakkus/courses/ceng574/k-means/). Maaari mong gamitin ang tool na ito upang i-visualize ang mga sample data points at tukuyin ang mga centroid nito. Maaari mong i-edit ang randomness ng datos, bilang ng mga cluster, at bilang ng mga centroid. Nakakatulong ba ito upang magkaroon ka ng ideya kung paano maaaring ma-grupo ang datos?\n",
"\n",
"- Tingnan din ang [handout na ito tungkol sa K-Means](https://stanford.edu/~cpiech/cs221/handouts/kmeans.html) mula sa Stanford.\n",
"\n",
"Gusto mo bang subukan ang iyong bagong natutunang clustering skills sa mga dataset na angkop para sa K-Means clustering? Tingnan ang:\n",
"\n",
"- [Train and Evaluate Clustering Models](https://rpubs.com/eR_ic/clustering) gamit ang Tidymodels at mga kaibigan\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",
"## **Takdang-Aralin**\n",
"\n",
"[Subukan ang iba't ibang clustering methods](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/2-K-Means/assignment.md)\n",
"\n",
"## SALAMAT SA:\n",
"\n",
"[Jen Looper](https://www.twitter.com/jenlooper) para sa paglikha ng orihinal na Python na bersyon ng module na ito ♥️\n",
"\n",
"[`Allison Horst`](https://twitter.com/allison_horst/) para sa paglikha ng mga kamangha-manghang ilustrasyon na ginagawang mas welcoming at engaging ang R. Hanapin ang higit pang mga ilustrasyon sa kanyang [gallery](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n",
"\n",
"Masayang Pag-aaral,\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>Artwork ni @allison_horst</figcaption>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Paunawa**: \nAng dokumentong ito ay isinalin gamit ang AI translation service na [Co-op Translator](https://github.com/Azure/co-op-translator). Bagama't sinisikap naming maging tumpak, tandaan na ang mga awtomatikong pagsasalin ay maaaring maglaman ng mga pagkakamali o hindi pagkakatugma. Ang orihinal na dokumento sa kanyang katutubong wika ang dapat ituring na opisyal na sanggunian. Para sa mahalagang impormasyon, inirerekomenda ang propesyonal na pagsasalin ng tao. Hindi kami mananagot sa anumang hindi pagkakaunawaan o maling interpretasyon na dulot ng paggamit ng pagsasaling ito.\n"
]
}
]
}