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

642 lines
26 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-11-18T19:31:34+00:00",
"source_file": "5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb",
"language_code": "pcm"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "GULATlQXLXyR"
},
"source": [
"## Learn K-Means Clustering wit R and Tidy Data Principles\n",
"\n",
"### [**Pre-lecture quiz**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/29/)\n",
"\n",
"For dis lesson, you go sabi how to create clusters wit Tidymodels package and oda packages wey dey R ecosystem (we go call dem friends 🧑‍🤝‍🧑), and di Nigerian music dataset wey you don import before. We go talk about di basics of K-Means for Clustering. Remember say, as you don learn for di earlier lesson, plenty ways dey to work wit clusters and di method wey you go use depend on your data. We go try K-Means because na di most common clustering technique. Make we start!\n",
"\n",
"Terms wey you go sabi:\n",
"\n",
"- Silhouette scoring\n",
"\n",
"- Elbow method\n",
"\n",
"- Inertia\n",
"\n",
"- Variance\n",
"\n",
"### **Introduction**\n",
"\n",
"[K-Means Clustering](https://wikipedia.org/wiki/K-means_clustering) na method wey dem take from signal processing domain. E dey used to divide and arrange groups of data into `k clusters` based on similarities for dia features.\n",
"\n",
"Di clusters fit show as [Voronoi diagrams](https://wikipedia.org/wiki/Voronoi_diagram), wey get one point (or 'seed') and di region wey dey follow am.\n",
"\n",
"<p >\n",
" <img src=\"../../../../../../translated_images/pcm/voronoi.1dc1613fb0439b95.webp\"\n",
" width=\"500\"/>\n",
" <figcaption>Infographic by Jen Looper</figcaption>\n",
"\n",
"\n",
"Steps for K-Means clustering be like dis:\n",
"\n",
"1. Di data scientist go first specify di number of clusters wey dem wan create.\n",
"\n",
"2. Di algorithm go randomly select K observations from di dataset to serve as di first centers for di clusters (we dey call dem centroids).\n",
"\n",
"3. Next, dem go assign each of di remaining observations to di centroid wey dey closest to am.\n",
"\n",
"4. Next, dem go calculate di new means for each cluster and move di centroid go di mean.\n",
"\n",
"5. Now wey dem don recalculate di centers, dem go check every observation again to see if e fit dey closer to another cluster. Dem go reassign all di objects again using di updated cluster means. Di cluster assignment and centroid update steps go dey repeat until di cluster assignments no dey change again (i.e., when e don converge). Normally, di algorithm go stop when each new iteration no dey move di centroids much and di clusters don static.\n",
"\n",
"<div>\n",
"\n",
"> Remember say because of di randomization of di first k observations wey dem use as di starting centroids, we fit get small different results each time we apply di procedure. Because of dis, most algorithms dey use plenty *random starts* and dem dey choose di iteration wey get di lowest WCSS. So e dey very important to always run K-Means wit plenty values of *nstart* to avoid *undesirable local optimum.*\n",
"\n",
"</div>\n",
"\n",
"Dis short animation wey use di [artwork](https://github.com/allisonhorst/stats-illustrations) of Allison Horst dey explain di clustering process:\n",
"\n",
"<p >\n",
" <img src=\"../../images/kmeans.gif\"\n",
" width=\"550\"/>\n",
" <figcaption>Artwork by @allison_horst</figcaption>\n",
"\n",
"\n",
"\n",
"One big question wey dey come up for clustering be dis: how you go sabi how many clusters to separate your data into? One wahala wey dey wit K-Means be say you go need to decide `k`, wey be di number of `centroids`. But di `elbow method` dey help to estimate one good starting value for `k`. You go try am soon.\n",
"\n",
"### \n",
"\n",
"**Prerequisite**\n",
"\n",
"We go continue from where we stop for di [previous lesson](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb), where we analyze di dataset, make plenty visualizations and filter di dataset to observations wey dey important. Make sure say you check am!\n",
"\n",
"We go need some packages to finish dis module. You fit install dem like dis: `install.packages(c('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork'))`\n",
"\n",
"Or, di script below go check whether you get di packages wey you need to complete dis module and e go install dem for you if some dey miss.\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": [
"Make we start sharp sharp!\n",
"\n",
"## 1. Dance wit data: Pick di 3 most popular music genres\n",
"\n",
"Dis na small reminder of wetin we do for di last lesson. Make we chop di data small small!\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": [
"🤩 E go well!\n",
"\n",
"## 2. More data exploration.\n",
"\n",
"How clean dis data be? Make we check for outliers wit box plots. We go focus on numeric columns wey get small outliers (even though you fit clean out di outliers). Boxplots fit show di range of di data and e go help us choose which columns to use. Note say, Boxplots no dey show variance, wey be one important thing for good clusterable data. Abeg check [dis discussion](https://stats.stackexchange.com/questions/91536/deduce-variance-from-boxplot) for more reading.\n",
"\n",
"[Boxplots](https://en.wikipedia.org/wiki/Box_plot) dey used to show di distribution of `numeric` data, so make we start by *selecting* all di numeric columns plus di popular music genres.\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": [
"See as di selection helper `where` make am easy 💁? Check out other functions like dat [here](https://tidyselect.r-lib.org/).\n",
"\n",
"Since we go dey make boxplot for each numeric features and we no wan use loops, make we reformat our data into one *longer* format wey go allow us use `facets` - subplots wey go show one subset of di data for each one.\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": [
"Much longer! Now na time for some `ggplots`! So which `geom` we go use?\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",
"Now we fit see say dis data get small wahala: if you look each column as boxplot, you go see outliers. You fit waka through di dataset and comot dis outliers, but e go make di data small well well.\n",
"\n",
"For now, make we choose which columns we go use for our clustering exercise. Make we pick di numeric columns wey get similar ranges. We fit change `artist_top_genre` to numeric but we go leave am for now.\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. How to do k-means clustering for R\n",
"\n",
"We fit do k-means for R wit di built-in `kmeans` function, check `help(\"kmeans()\")`. Di `kmeans()` function dey take data frame wey get all di numeric columns as im main argument.\n",
"\n",
"Di first step wen you wan use k-means clustering na to talk how many clusters (k) wey go dey for di final solution. We sabi say na 3 song genres wey we commot from di dataset, so make we try 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": [
"The kmeans object get plenty information wey dem explain well for `help(\"kmeans()\")`. For now, make we focus on some. We fit see say dem group di data into 3 clusters wey get size 65, 110, 111. Di output still show di cluster centers (means) for di 3 groups across di 5 variables.\n",
"\n",
"Di clustering vector na di cluster wey dem assign for each observation. Make we use di `augment` function take add di cluster assignment to di original 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": [
"Perfect, we don divide our data set into 3 groups. So, how we go take know say our clustering dey good 🤷? Make we check `Silhouette score`.\n",
"\n",
"### **Silhouette score**\n",
"\n",
"[Silhouette analysis](https://en.wikipedia.org/wiki/Silhouette_(clustering)) fit help us study how far apart di clusters wey we get dey from each other. Dis score dey range from -1 to 1, and if di score near 1, e mean say di cluster dey tight and e dey well-separated from other clusters. If e near 0, e mean say di clusters dey overlap and di samples dey close to di decision boundary of di clusters wey dey near each other. [source](https://dzone.com/articles/kmeans-silhouette-score-explained-with-python-exam).\n",
"\n",
"Di average silhouette method dey calculate di average silhouette of di observations for different values of *k*. If di average silhouette score high, e mean say di clustering dey good.\n",
"\n",
"Di `silhouette` function wey dey di cluster package fit calculate di average silhouette width.\n",
"\n",
"> You fit calculate di silhouette with any [distance](https://en.wikipedia.org/wiki/Distance \"Distance\") metric, like [Euclidean distance](https://en.wikipedia.org/wiki/Euclidean_distance \"Euclidean distance\") or [Manhattan distance](https://en.wikipedia.org/wiki/Manhattan_distance \"Manhattan distance\") wey we talk about for di [previous lesson](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": [
"Our score na **.549**, so e dey right for middle. Dis one mean say our data no too fit well for dis kain clustering. Make we see whether we fit confirm dis idea wit eye. Di [factoextra package](https://rpkgs.datanovia.com/factoextra/index.html) get functions (`fviz_cluster()`) wey fit help us see di 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": [
"Di overlap wey dey for di clusters show say our data no too fit well for dis kain clustering, but make we still dey go.\n",
"\n",
"## 4. How to sabi di best clusters\n",
"\n",
"One big question wey dey always show for K-Means clustering na dis - if we no get class labels wey we sabi, how we go sabi how many clusters we go use take divide di data?\n",
"\n",
"One way we fit try sabi na to use one data sample take `create series of clustering models` wey go dey increase di number of clusters (like from 1-10), and check di clustering metrics like **Silhouette score.**\n",
"\n",
"Make we find di best number of clusters by calculating di clustering algorithm for different values of *k* and check di **Within Cluster Sum of Squares** (WCSS). Di total within-cluster sum of square (WCSS) dey measure how tight di clustering be, and we want make e dey small as e fit be, because lower values mean say di data points dey close.\n",
"\n",
"Make we see wetin go happen if we choose different `k` values, from 1 to 10, for dis clustering.\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": [
"Now wey we don get di total within-cluster sum-of-squares (tot.withinss) for each clustering algorithm wey get center *k*, we go use di [elbow method](https://en.wikipedia.org/wiki/Elbow_method_(clustering)) to find di correct number of clusters. Dis method na to plot di WCSS as e dey relate to di number of clusters, and then choose di [elbow of di curve](https://en.wikipedia.org/wiki/Elbow_of_the_curve \"Elbow of the curve\") as di number of clusters wey we go use.\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": [
"Di plot dey show say WCSS reduce well well (so e tight pass) as di number of clusters dey increase from one go two, and e still reduce wey person fit notice from two go three clusters. After dat one, di reduction no too dey obvious again, e come form one `elbow` 💪 for di chart around three clusters. Dis one mean say e dey show well say di data points get two to three clusters wey dey separate well.\n",
"\n",
"We fit now move go extract di clustering model wey `k = 3`:\n",
"\n",
"> `pull()`: e dey use to comot one column\n",
">\n",
"> `pluck()`: e dey use to index data structures like lists\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": [
"Nice one! Make we go ahead show di clusters wey we get. You wan try some interactive stuff wit `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": [
"Maybe we for don expect say each cluster (wey different colors dey represent) go get im own clear genres (wey different shapes dey represent).\n",
"\n",
"Make we check how correct di model be.\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": [
"Dis model accuracy no too bad, but e no too beta either. E fit be say di data no too fit well for K-Means Clustering. Di data dey too imbalanced, e no too correlate, and di variance between di column values dey too much to cluster well. In fact, di clusters wey form fit dey heavily influenced or skewed by di three genre categories wey we define before.\n",
"\n",
"Sha sha, e be good learning process!\n",
"\n",
"For Scikit-learn documentation, you go see say model like dis one, wey di clusters no dey well demarcated, get 'variance' problem:\n",
"\n",
"<p >\n",
" <img src=\"../../../../../../translated_images/pcm/problems.f7fb539ccd80608e.webp\"\n",
" width=\"500\"/>\n",
" <figcaption>Infographic from Scikit-learn</figcaption>\n",
"\n",
"\n",
"\n",
"## **Variance**\n",
"\n",
"Variance na \"di average of di squared differences from di Mean\" [source](https://www.mathsisfun.com/data/standard-deviation.html). For di context of dis clustering problem, e mean say di numbers for our dataset dey diverge small too much from di mean.\n",
"\n",
"✅ Dis na good time to think about all di ways wey you fit take correct dis issue. You fit tweak di data small more? Use different columns? Try different algorithm? Hint: Try [scaling your data](https://www.mygreatlearning.com/blog/learning-data-science-with-k-means-clustering/) to normalize am and test other columns.\n",
"\n",
"> Try dis '[variance calculator](https://www.calculatorsoup.com/calculators/statistics/variance-calculator.php)' to understand di concept well well.\n",
"\n",
"------------------------------------------------------------------------\n",
"\n",
"## **🚀Challenge**\n",
"\n",
"Spend time with dis notebook, dey tweak di parameters. You fit improve di accuracy of di model by cleaning di data more (like removing outliers)? You fit use weights to give more weight to some data samples. Wetin else you fit do to create better clusters?\n",
"\n",
"Hint: Try to scale your data. Di notebook get commented code wey fit add standard scaling to make di data columns dey resemble each other more for range. You go notice say di silhouette score go reduce, but di 'kink' for di elbow graph go smooth out. Dis na because if you leave di data unscaled, e go make data wey get less variance carry more weight. Read more about dis problem [here](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",
"- Check out K-Means Simulator [like dis one](https://user.ceng.metu.edu.tr/~akifakkus/courses/ceng574/k-means/). You fit use dis tool to visualize sample data points and determine di centroids. You fit edit di data randomness, number of clusters, and number of centroids. E dey help you get idea of how di data fit group?\n",
"\n",
"- Also, check [dis handout on K-Means](https://stanford.edu/~cpiech/cs221/handouts/kmeans.html) from Stanford.\n",
"\n",
"You wan try your new clustering skills for datasets wey fit well for K-Means clustering? Check:\n",
"\n",
"- [Train and Evaluate Clustering Models](https://rpubs.com/eR_ic/clustering) using Tidymodels and friends\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",
"## **Assignment**\n",
"\n",
"[Try different clustering methods](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/2-K-Means/assignment.md)\n",
"\n",
"## THANK YOU TO:\n",
"\n",
"[Jen Looper](https://www.twitter.com/jenlooper) for creating di original Python version of dis module ♥️\n",
"\n",
"[`Allison Horst`](https://twitter.com/allison_horst/) for creating di amazing illustrations wey make R more welcoming and engaging. Find more illustrations for her [gallery](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n",
"\n",
"Happy Learning,\n",
"\n",
"[Eric](https://twitter.com/ericntay), Gold Microsoft Learn Student Ambassador.\n",
"\n",
"<p >\n",
" <img src=\"../../../../../../translated_images/pcm/r_learners_sm.e4a71b113ffbedfe.webp\"\n",
" width=\"500\"/>\n",
" <figcaption>Artwork by @allison_horst</figcaption>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n\n<!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**Disclaimer**: \nDis dokyument don translate wit AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). Even as we dey try make sure say e correct, abeg make you sabi say machine translation fit get mistake or no dey accurate well. Di original dokyument for im native language na di main correct source. For important information, e good make you use professional human translation. We no go fit take blame for any misunderstanding or wrong interpretation wey fit happen because you use dis translation.\n<!-- CO-OP TRANSLATOR DISCLAIMER END -->\n"
]
}
]
}