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

640 lines
28 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:10:31+00:00",
"source_file": "5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb",
"language_code": "fi"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "GULATlQXLXyR"
},
"source": [
"## Tutustu K-Means-klusterointiin R:llä ja Tidy data -periaatteilla.\n",
"\n",
"### [**Esiluennon kysely**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/29/)\n",
"\n",
"Tässä oppitunnissa opit luomaan klustereita käyttämällä Tidymodels-pakettia ja muita R-ekosysteemin paketteja (kutsumme niitä ystäviksi 🧑‍🤝‍🧑) sekä aiemmin tuomaasi Nigerian musiikkidataa. Käymme läpi K-Means-klusteroinnin perusteet. Muista, että kuten opit aiemmassa oppitunnissa, klustereiden kanssa työskentelyyn on monia tapoja, ja käyttämäsi menetelmä riippuu datastasi. Kokeilemme K-Means-menetelmää, koska se on yleisin klusterointitekniikka. Aloitetaan!\n",
"\n",
"Termit, joista opit lisää:\n",
"\n",
"- Silhouette-pisteytys\n",
"\n",
"- Kyynärpäämenetelmä\n",
"\n",
"- Inertia\n",
"\n",
"- Varianssi\n",
"\n",
"### **Johdanto**\n",
"\n",
"[K-Means-klusterointi](https://wikipedia.org/wiki/K-means_clustering) on menetelmä, joka on peräisin signaalinkäsittelyn alalta. Sitä käytetään jakamaan ja ryhmittelemään dataa `k klusteriin` niiden ominaisuuksien samankaltaisuuden perusteella.\n",
"\n",
"Klusterit voidaan visualisoida [Voronoi-diagrammeina](https://wikipedia.org/wiki/Voronoi_diagram), jotka sisältävät pisteen (tai 'siemenen') ja sen vastaavan alueen.\n",
"\n",
"<p >\n",
" <img src=\"../../images/voronoi.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Infografiikka: Jen Looper</figcaption>\n",
"\n",
"\n",
"K-Means-klusteroinnissa on seuraavat vaiheet:\n",
"\n",
"1. Data-analyytikko määrittää ensin halutun klustereiden lukumäärän.\n",
"\n",
"2. Seuraavaksi algoritmi valitsee satunnaisesti K havaintoa datasta, jotka toimivat klustereiden alkuperäisinä keskuksina (eli centroidit).\n",
"\n",
"3. Tämän jälkeen jokainen jäljellä oleva havainto liitetään lähimpään centroidiin.\n",
"\n",
"4. Seuraavaksi lasketaan jokaisen klusterin uusi keskiarvo, ja centroidi siirretään keskiarvoon.\n",
"\n",
"5. Kun keskukset on laskettu uudelleen, jokainen havainto tarkistetaan uudelleen, jotta nähdään, voisiko se olla lähempänä toista klusteria. Kaikki objektit jaetaan uudelleen päivitettyjen klusterikeskiarvojen perusteella. Klusterin jakaminen ja centroidin päivitys toistetaan iteratiivisesti, kunnes klusterien jakaminen ei enää muutu (eli kun konvergenssi saavutetaan). Tyypillisesti algoritmi lopettaa, kun jokainen uusi iteraatio aiheuttaa vain vähäistä centroidien liikettä ja klusterit muuttuvat staattisiksi.\n",
"\n",
"<div>\n",
"\n",
"> Huomaa, että koska alkuperäisten k havaintojen valinta centroidiksi tapahtuu satunnaisesti, voimme saada hieman erilaisia tuloksia joka kerta, kun menetelmää sovelletaan. Tästä syystä useimmat algoritmit käyttävät useita *satunnaisia aloituksia* ja valitsevat iteraation, jolla on pienin WCSS. Siksi on erittäin suositeltavaa aina suorittaa K-Means useilla *nstart*-arvoilla, jotta vältetään *ei-toivottu paikallinen optimi.*\n",
"\n",
"</div>\n",
"\n",
"Tämä lyhyt animaatio, joka käyttää Allison Horstin [taidetta](https://github.com/allisonhorst/stats-illustrations), selittää klusterointiprosessin:\n",
"\n",
"<p >\n",
" <img src=\"../../images/kmeans.gif\"\n",
" width=\"550\"/>\n",
" <figcaption>Taide: @allison_horst</figcaption>\n",
"\n",
"\n",
"\n",
"Klusteroinnissa herää perustavanlaatuinen kysymys: mistä tiedät, kuinka moneen klusteriin datasi tulisi jakaa? Yksi K-Means-menetelmän haittapuolista on se, että sinun täytyy määrittää `k`, eli `centroidien` lukumäärä. Onneksi `kyynärpäämenetelmä` auttaa arvioimaan hyvän lähtöarvon `k`:lle. Kokeilet sitä kohta.\n",
"\n",
"### \n",
"\n",
"**Edellytykset**\n",
"\n",
"Jatkamme suoraan siitä, mihin jäimme [edellisessä oppitunnissa](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb), jossa analysoimme dataa, teimme paljon visualisointeja ja suodattelimme datasta kiinnostavia havaintoja. Muista tarkistaa se!\n",
"\n",
"Tarvitsemme joitakin paketteja tämän moduulin suorittamiseen. Voit asentaa ne seuraavasti: `install.packages(c('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork'))`\n",
"\n",
"Vaihtoehtoisesti alla oleva skripti tarkistaa, onko sinulla tarvittavat paketit tämän moduulin suorittamiseen, ja asentaa ne puolestasi, jos jotkin puuttuvat.\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": [
"Lähdetään vauhdilla liikkeelle!\n",
"\n",
"## 1. Tanssi datan kanssa: Rajaa kolmeen suosituimpaan musiikkigenreen\n",
"\n",
"Tämä on kertaus siitä, mitä teimme edellisessä oppitunnissa. Pilkotaan ja analysoidaan hieman dataa!\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": [
"🤩 Se meni hyvin!\n",
"\n",
"## 2. Lisää datan tutkimista.\n",
"\n",
"Kuinka puhdasta tämä data on? Tarkistetaan poikkeamat käyttämällä laatikkokaavioita. Keskitymme numeerisiin sarakkeisiin, joissa on vähemmän poikkeamia (vaikka voisitkin siivota poikkeamat pois). Laatikkokaaviot voivat näyttää datan vaihteluvälin ja auttaa valitsemaan, mitä sarakkeita käyttää. Huomaa, että laatikkokaaviot eivät näytä varianssia, joka on tärkeä osa hyvää klusteroitavaa dataa. Katso [tämä keskustelu](https://stats.stackexchange.com/questions/91536/deduce-variance-from-boxplot) lisälukemista varten.\n",
"\n",
"[Laatikkokaaviot](https://en.wikipedia.org/wiki/Box_plot) käytetään numeerisen datan jakauman graafiseen esittämiseen, joten aloitetaan *valitsemalla* kaikki numeeriset sarakkeet yhdessä suosittujen musiikkigenrejen kanssa.\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": [
"Katso, kuinka valintatyökalu `where` tekee tämän helpoksi 💁? Tutustu muihin vastaaviin toimintoihin [täällä](https://tidyselect.r-lib.org/).\n",
"\n",
"Koska aiomme tehdä laatikkokaavion jokaiselle numeeriselle ominaisuudelle ja haluamme välttää silmukoiden käyttöä, muotoillaan datamme *pidempään* muotoon, joka mahdollistaa `facets`-ominaisuuden hyödyntämisen - alikuvioita, jotka näyttävät kunkin datan osajoukon.\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": [
"Paljon pidempään! Nyt on aika käyttää `ggplotseja`! Joten mitä `geomia` käytämme?\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": [
"Nyt voimme nähdä, että nämä tiedot ovat hieman meluisia: tarkastelemalla kutakin saraketta laatikkokaaviona, voit havaita poikkeavia arvoja. Voisit käydä datasetin läpi ja poistaa nämä poikkeamat, mutta se tekisi datasta melko vähäistä.\n",
"\n",
"Tällä kertaa valitaan sarakkeet, joita käytämme ryhmittelyharjoituksessa. Valitaan numeeriset sarakkeet, joilla on samankaltaiset vaihteluvälit. Voisimme koodata `artist_top_genre` numeeriseksi, mutta jätämme sen pois tällä kertaa.\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-klusteroinnin laskeminen R:ssä\n",
"\n",
"Voimme laskea k-means-klusteroinnin R:ssä sisäänrakennetulla `kmeans`-funktiolla, katso `help(\"kmeans()\")`. `kmeans()`-funktio hyväksyy ensisijaisena argumenttinaan dataframen, jossa kaikki sarakkeet ovat numeerisia.\n",
"\n",
"Ensimmäinen vaihe k-means-klusterointia käytettäessä on määrittää klustereiden (k) lukumäärä, jotka muodostuvat lopullisessa ratkaisussa. Tiedämme, että aineistosta on eroteltu kolme musiikkigenreä, joten kokeillaan kolmea:\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-objekti sisältää useita tietoja, jotka on hyvin selitetty kohdassa `help(\"kmeans()\")`. Keskitytään nyt muutamaan niistä. Näemme, että data on ryhmitelty kolmeen klusteriin, joiden koot ovat 65, 110 ja 111. Tuloste sisältää myös klustereiden keskukset (keskiarvot) näille kolmelle ryhmälle viiden muuttujan osalta.\n",
"\n",
"Klusterointivektori on klusterin määrittely jokaiselle havainnolle. Käytetään `augment`-funktiota, jotta klusterin määrittely lisätään alkuperäiseen datajoukkoon.\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": [
"Loistavaa, olemme juuri jakaneet tietojoukon kolmeen ryhmään. Mutta kuinka hyvä onkaan ryhmittelymme 🤷? Katsotaanpa `Silhouette-pistemäärää`.\n",
"\n",
"### **Silhouette-pistemäärä**\n",
"\n",
"[Silhouette-analyysi](https://en.wikipedia.org/wiki/Silhouette_(clustering)) voidaan käyttää tutkimaan etäisyyttä muodostettujen ryhmien välillä. Tämä pistemäärä vaihtelee välillä -1 ja 1, ja jos pistemäärä on lähellä 1, ryhmä on tiivis ja hyvin erillään muista ryhmistä. Arvo lähellä 0 edustaa päällekkäisiä ryhmiä, joissa näytteet ovat hyvin lähellä naapuriryhmien päätösrajaa. [Lähde](https://dzone.com/articles/kmeans-silhouette-score-explained-with-python-exam).\n",
"\n",
"Keskimääräinen silhouette-menetelmä laskee havaintojen keskimääräisen silhouette-pistemäärän eri *k*-arvoille. Korkea keskimääräinen silhouette-pistemäärä osoittaa hyvää ryhmittelyä.\n",
"\n",
"`silhouette`-funktiota klusteripaketissa käytetään laskemaan keskimääräinen silhouette-leveys.\n",
"\n",
"> Silhouette voidaan laskea millä tahansa [etäisyys](https://en.wikipedia.org/wiki/Distance \"Distance\")-metriikalla, kuten [Euklidinen etäisyys](https://en.wikipedia.org/wiki/Euclidean_distance \"Euclidean distance\") tai [Manhattanin etäisyys](https://en.wikipedia.org/wiki/Manhattan_distance \"Manhattan distance\"), joita käsittelimme [edellisessä oppitunnissa](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": [
"Pisteemme on **0.549**, eli aivan keskivaiheilla. Tämä osoittaa, että datamme ei ole erityisen hyvin soveltuvaa tämän tyyppiseen klusterointiin. Katsotaan, voimmeko vahvistaa tätä epäilystä visuaalisesti. [factoextra-paketti](https://rpkgs.datanovia.com/factoextra/index.html) tarjoaa toimintoja (`fviz_cluster()`) klusteroinnin visualisointiin.\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": [
"Klustereiden päällekkäisyys osoittaa, että datamme ei ole erityisen hyvin soveltuva tämän tyyppiseen klusterointiin, mutta jatketaan silti.\n",
"\n",
"## 4. Optimaalisten klustereiden määrittäminen\n",
"\n",
"K-Means-klusteroinnissa usein herää perustavanlaatuinen kysymys - ilman tunnettuja luokkamerkintöjä, miten tiedät, mihin määrään klustereita data tulisi jakaa?\n",
"\n",
"Yksi tapa selvittää tämä on käyttää datanäytettä `luodaksesi sarjan klusterointimalleja`, joissa klustereiden määrä kasvaa asteittain (esim. 1-10), ja arvioida klusterointimittareita, kuten **Silhouette-pisteytys.**\n",
"\n",
"Määritetään optimaalinen klustereiden määrä laskemalla klusterointialgoritmi eri *k*-arvoille ja arvioimalla **Within Cluster Sum of Squares** (WCSS). Kokonais-WCSS mittaa klusteroinnin tiiviyttä, ja haluamme sen olevan mahdollisimman pieni, sillä pienemmät arvot tarkoittavat, että datapisteet ovat lähempänä toisiaan.\n",
"\n",
"Tutkitaan, miten eri `k`-valinnat, välillä 110, vaikuttavat tähän klusterointiin.\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": [
"Nyt kun meillä on kokonaisklusterin sisäinen neliösumma (tot.withinss) jokaiselle klusterointialgoritmille keskuksella *k*, käytämme [kyynärpäämenetelmää](https://en.wikipedia.org/wiki/Elbow_method_(clustering)) löytääksemme optimaalisen klustereiden määrän. Menetelmä koostuu WCSS:n piirtämisestä klustereiden määrän funktiona ja [käyrän kyynärpään](https://en.wikipedia.org/wiki/Elbow_of_the_curve \"Elbow of the curve\") valitsemisesta käytettäväksi klustereiden määräksi.\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": [
"Kuvaaja näyttää merkittävän vähennyksen WCSS:ssä (eli suurempi *tiiviys*), kun klustereiden määrä kasvaa yhdestä kahteen, ja edelleen huomattavan vähennyksen kahdesta kolmeen klusteriin. Tämän jälkeen vähennys on vähemmän merkittävä, mikä johtaa `kyynärpään` 💪 kaaviossa noin kolmen klusterin kohdalla. Tämä on hyvä merkki siitä, että datan pisteet muodostavat kaksi tai kolme kohtuullisen hyvin erillistä klusteria.\n",
"\n",
"Voimme nyt jatkaa ja ottaa käyttöön klusterointimallin, jossa `k = 3`:\n",
"\n",
"> `pull()`: käytetään yhden sarakkeen poimimiseen\n",
">\n",
"> `pluck()`: käytetään tietorakenteiden, kuten listojen, indeksointiin\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": [
"Hienoa! Visualisoidaan nyt saadut klusterit. Kiinnostaisiko hieman interaktiivisuutta käyttämällä `plotly`-kirjastoa?\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": [
"Ehkä olisimme odottaneet, että jokaisella klusterilla (esitetty eri väreillä) olisi selkeästi erottuvat genret (esitetty eri muodoilla).\n",
"\n",
"Katsotaanpa mallin tarkkuutta.\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": [
"Tämän mallin tarkkuus ei ole huono, mutta ei myöskään erinomainen. On mahdollista, että data ei sovellu hyvin K-Means-klusterointiin. Tämä data on liian epätasapainoista, liian vähän korreloitunutta ja sarakkeiden arvojen välillä on liikaa vaihtelua, jotta klusterointi toimisi hyvin. Itse asiassa muodostuvat klusterit ovat todennäköisesti vahvasti vinoutuneita tai vaikuttavat suuresti niistä kolmesta genre-kategoriasta, jotka määrittelimme aiemmin.\n",
"\n",
"Siitä huolimatta, tämä oli varsin opettavainen prosessi!\n",
"\n",
"Scikit-learnin dokumentaatiosta voit nähdä, että tällaisella mallilla, jossa klusterit eivät ole kovin selkeästi rajattuja, on \"varianssi\"-ongelma:\n",
"\n",
"<p >\n",
" <img src=\"../../images/problems.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Infografiikka Scikit-learnilta</figcaption>\n",
"\n",
"\n",
"\n",
"## **Varianssi**\n",
"\n",
"Varianssi määritellään \"keskiarvosta laskettujen neliöityjen poikkeamien keskiarvona\" [lähde](https://www.mathsisfun.com/data/standard-deviation.html). Tämän klusterointiongelman yhteydessä se viittaa dataan, jossa datasetin luvut poikkeavat keskiarvosta hieman liikaa.\n",
"\n",
"✅ Tämä on loistava hetki miettiä kaikkia tapoja, joilla voisit korjata tämän ongelman. Voisiko dataa muokata vielä hieman? Käyttää eri sarakkeita? Käyttää eri algoritmia? Vinkki: Kokeile [skaalata dataasi](https://www.mygreatlearning.com/blog/learning-data-science-with-k-means-clustering/) normalisoidaksesi sen ja testaa muita sarakkeita.\n",
"\n",
"> Kokeile tätä '[varianssilaskuria](https://www.calculatorsoup.com/calculators/statistics/variance-calculator.php)' ymmärtääksesi konseptia hieman paremmin.\n",
"\n",
"------------------------------------------------------------------------\n",
"\n",
"## **🚀Haaste**\n",
"\n",
"Käytä aikaa tämän notebookin parissa ja säädä parametreja. Voitko parantaa mallin tarkkuutta puhdistamalla dataa enemmän (esimerkiksi poistamalla poikkeavia arvoja)? Voit käyttää painotuksia antaaksesi enemmän painoarvoa tietyille datasampleille. Mitä muuta voisit tehdä luodaksesi parempia klustereita?\n",
"\n",
"Vinkki: Kokeile skaalata dataasi. Notebookissa on kommentoitua koodia, joka lisää standardisoinnin, jotta datan sarakkeet muistuttaisivat toisiaan enemmän vaihteluvälin suhteen. Huomaat, että vaikka siluettipisteet laskevat, kyynärpääkäyrän \"mutka\" tasoittuu. Tämä johtuu siitä, että skaalaamaton data antaa vähemmän vaihtelevalle datalle enemmän painoarvoa. Lue lisää tästä ongelmasta [täältä](https://stats.stackexchange.com/questions/21222/are-mean-normalization-and-feature-scaling-needed-for-k-means-clustering/21226#21226).\n",
"\n",
"## [**Luentojälkeinen kysely**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/30/)\n",
"\n",
"## **Kertaus ja itseopiskelu**\n",
"\n",
"- Tutustu K-Means-simulaattoriin [kuten tähän](https://user.ceng.metu.edu.tr/~akifakkus/courses/ceng574/k-means/). Voit käyttää tätä työkalua visualisoidaksesi esimerkkidatapisteitä ja määrittääksesi niiden keskipisteet. Voit muokata datan satunnaisuutta, klustereiden määrää ja keskipisteiden määrää. Auttaako tämä sinua hahmottamaan, miten data voidaan ryhmitellä?\n",
"\n",
"- Tutustu myös [tähän K-Means-materiaaliin](https://stanford.edu/~cpiech/cs221/handouts/kmeans.html) Stanfordilta.\n",
"\n",
"Haluatko kokeilla juuri oppimiasi klusterointitaitoja datasetteihin, jotka soveltuvat hyvin K-Means-klusterointiin? Katso:\n",
"\n",
"- [Klusterointimallien koulutus ja arviointi](https://rpubs.com/eR_ic/clustering) käyttäen Tidymodelsia ja muita työkaluja\n",
"\n",
"- [K-means-klusterianalyysi](https://uc-r.github.io/kmeans_clustering), UC Business Analytics R Programming Guide\n",
"\n",
"- [K-means-klusterointi tidy data -periaatteilla](https://www.tidymodels.org/learn/statistics/k-means/)\n",
"\n",
"## **Tehtävä**\n",
"\n",
"[Kokeile erilaisia klusterointimenetelmiä](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/2-K-Means/assignment.md)\n",
"\n",
"## KIITOKSET:\n",
"\n",
"[Jen Looper](https://www.twitter.com/jenlooper) alkuperäisen Python-version luomisesta tästä moduulista ♥️\n",
"\n",
"[`Allison Horst`](https://twitter.com/allison_horst/) upeiden kuvitusten luomisesta, jotka tekevät R:stä lähestyttävämmän ja kiinnostavamman. Löydät lisää kuvituksia hänen [galleriastaan](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n",
"\n",
"Iloisia oppimishetkiä,\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>Kuvitus: @allison_horst</figcaption>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Vastuuvapauslauseke**: \nTämä asiakirja on käännetty käyttämällä tekoälypohjaista käännöspalvelua [Co-op Translator](https://github.com/Azure/co-op-translator). Vaikka pyrimme tarkkuuteen, huomioithan, että automaattiset käännökset voivat sisältää virheitä tai epätarkkuuksia. Alkuperäistä asiakirjaa sen alkuperäisellä kielellä tulee pitää ensisijaisena lähteenä. Kriittisen tiedon osalta suositellaan ammattimaista ihmiskääntämistä. Emme ole vastuussa väärinkäsityksistä tai virhetulkinnoista, jotka johtuvat tämän käännöksen käytöstä.\n"
]
}
]
}