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

642 lines
27 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-09-06T12:20:18+00:00",
"source_file": "5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb",
"language_code": "no"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "GULATlQXLXyR"
},
"source": [
"## Utforsk K-Means-klustering med R og prinsipper for ryddige data.\n",
"\n",
"### [**Quiz før forelesning**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/29/)\n",
"\n",
"I denne leksjonen vil du lære hvordan du oppretter klynger ved hjelp av Tidymodels-pakken og andre pakker i R-økosystemet (vi kaller dem venner 🧑‍🤝‍🧑), samt det nigerianske musikkdatasettet du importerte tidligere. Vi skal dekke det grunnleggende om K-Means for klustering. Husk at, som du lærte i den forrige leksjonen, finnes det mange måter å jobbe med klynger på, og metoden du bruker avhenger av dataene dine. Vi skal prøve K-Means, da det er den mest vanlige klusteringsteknikken. La oss komme i gang!\n",
"\n",
"Begreper du vil lære om:\n",
"\n",
"- Silhuettscore\n",
"\n",
"- Albuemetoden\n",
"\n",
"- Inerti\n",
"\n",
"- Varians\n",
"\n",
"### **Introduksjon**\n",
"\n",
"[K-Means-klustering](https://wikipedia.org/wiki/K-means_clustering) er en metode som stammer fra signalbehandling. Den brukes til å dele og gruppere data i `k klynger` basert på likheter i deres egenskaper.\n",
"\n",
"Klyngene kan visualiseres som [Voronoi-diagrammer](https://wikipedia.org/wiki/Voronoi_diagram), som inkluderer et punkt (eller 'frø') og dets tilsvarende område.\n",
"\n",
"<p >\n",
" <img src=\"../../images/voronoi.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Infografikk av Jen Looper</figcaption>\n",
"\n",
"\n",
"K-Means-klustering har følgende steg:\n",
"\n",
"1. Dataanalytikeren starter med å spesifisere ønsket antall klynger som skal opprettes.\n",
"\n",
"2. Deretter velger algoritmen tilfeldig K observasjoner fra datasettet som skal fungere som de første sentrene for klyngene (dvs. sentroidene).\n",
"\n",
"3. Deretter blir hver av de gjenværende observasjonene tilordnet sin nærmeste sentroid.\n",
"\n",
"4. Deretter beregnes det nye gjennomsnittet for hver klynge, og sentroiden flyttes til gjennomsnittet.\n",
"\n",
"5. Nå som sentrene er blitt oppdatert, sjekkes hver observasjon igjen for å se om den kan være nærmere en annen klynge. Alle objektene blir tilordnet på nytt ved hjelp av de oppdaterte klynge-gjennomsnittene. Stegene for klyngetildeling og oppdatering av sentroidene gjentas iterativt til klyngetildelingene slutter å endre seg (dvs. når konvergens er oppnådd). Vanligvis avsluttes algoritmen når hver ny iterasjon resulterer i ubetydelig bevegelse av sentroidene, og klyngene blir statiske.\n",
"\n",
"<div>\n",
"\n",
"> Merk at på grunn av tilfeldigheten i valg av de første k observasjonene som brukes som start-sentroidene, kan vi få litt forskjellige resultater hver gang vi bruker prosedyren. Av denne grunn bruker de fleste algoritmer flere *tilfeldige starter* og velger iterasjonen med lavest WCSS. Det anbefales derfor sterkt å alltid kjøre K-Means med flere verdier av *nstart* for å unngå et *uønsket lokalt optimum.*\n",
"\n",
"</div>\n",
"\n",
"Denne korte animasjonen ved hjelp av [illustrasjoner](https://github.com/allisonhorst/stats-illustrations) av Allison Horst forklarer klusteringsprosessen:\n",
"\n",
"<p >\n",
" <img src=\"../../images/kmeans.gif\"\n",
" width=\"550\"/>\n",
" <figcaption>Illustrasjon av @allison_horst</figcaption>\n",
"\n",
"\n",
"\n",
"Et grunnleggende spørsmål som oppstår i klustering er dette: hvordan vet du hvor mange klynger du skal dele dataene dine inn i? En ulempe med å bruke K-Means er at du må fastsette `k`, altså antallet `sentroider`. Heldigvis hjelper `albuemetoden` med å estimere en god startverdi for `k`. Du skal prøve det om et øyeblikk.\n",
"\n",
"### \n",
"\n",
"**Forutsetning**\n",
"\n",
"Vi fortsetter der vi avsluttet i [forrige leksjon](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb), hvor vi analyserte datasettet, laget mange visualiseringer og filtrerte datasettet til interessante observasjoner. Sørg for å sjekke det ut!\n",
"\n",
"Vi trenger noen pakker for å fullføre denne modulen. Du kan installere dem slik: `install.packages(c('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork'))`\n",
"\n",
"Alternativt sjekker skriptet nedenfor om du har de nødvendige pakkene for å fullføre denne modulen og installerer dem for deg hvis noen mangler.\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": [
"La oss komme i gang!\n",
"\n",
"## 1. En dans med data: Begrens deg til de 3 mest populære musikksjangrene\n",
"\n",
"Dette er en oppsummering av hva vi gjorde i forrige leksjon. La oss analysere og bearbeide litt data!\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": [
"🤩 Det gikk bra!\n",
"\n",
"## 2. Mer utforsking av data.\n",
"\n",
"Hvor ren er denne dataen? La oss sjekke for uteliggere ved hjelp av boksplott. Vi vil fokusere på numeriske kolonner med færre uteliggere (selv om du kan fjerne uteliggere). Boksplott kan vise rekkevidden av dataen og vil hjelpe med å velge hvilke kolonner som skal brukes. Merk at boksplott ikke viser varians, et viktig element for god klustringsvennlig data. Vennligst se [denne diskusjonen](https://stats.stackexchange.com/questions/91536/deduce-variance-from-boxplot) for videre lesing.\n",
"\n",
"[Boksplott](https://en.wikipedia.org/wiki/Box_plot) brukes til å grafisk fremstille fordelingen av `numerisk` data, så la oss starte med å *velge* alle numeriske kolonner sammen med de populære musikksjangrene.\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": [
"Se hvordan utvalgsfunksjonen `where` gjør dette enkelt 💁? Utforsk andre slike funksjoner [her](https://tidyselect.r-lib.org/).\n",
"\n",
"Siden vi skal lage et boksplott for hver numeriske egenskap og ønsker å unngå å bruke løkker, la oss omformatere dataene våre til et *lengre* format som lar oss dra nytte av `facets` - delplott som hver viser en delmengde av dataene.\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": [
"Mye lengre! Nå er det tid for noen `ggplots`! Så hvilken `geom` skal vi bruke?\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": [
"Enkelt-gg!\n",
"\n",
"Nå kan vi se at disse dataene er litt støyete: ved å observere hver kolonne som et boksplott, kan du se uteliggere. Du kunne gått gjennom datasettet og fjernet disse uteliggerne, men det ville gjort dataene ganske minimale.\n",
"\n",
"For nå, la oss velge hvilke kolonner vi skal bruke til vår klyngingsøvelse. La oss velge de numeriske kolonnene med lignende intervaller. Vi kunne kodet `artist_top_genre` som numerisk, men vi dropper den foreløpig.\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. Beregning av k-means klynging i R\n",
"\n",
"Vi kan beregne k-means i R ved hjelp av den innebygde `kmeans`-funksjonen, se `help(\"kmeans()\")`. `kmeans()`-funksjonen aksepterer en data frame med kun numeriske kolonner som sitt primære argument.\n",
"\n",
"Det første steget når man bruker k-means klynging er å spesifisere antall klynger (k) som skal genereres i den endelige løsningen. Vi vet at det er 3 musikksjangre som vi har skilt ut fra datasettet, så la oss prøve med 3:\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "uC4EQ5w7LXy5"
},
"source": [
"set.seed(2056)\n",
"# Kmeans clustering for 3 clusters\n",
"kclust <- kmeans(\n",
" df_numeric_select,\n",
" # Specify the number of clusters\n",
" centers = 3,\n",
" # How many random initial configurations\n",
" nstart = 25\n",
")\n",
"\n",
"# Display clustering object\n",
"kclust\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "hzfhscWrLXy-"
},
"source": [
"Kmeans-objektet inneholder flere biter med informasjon som er godt forklart i `help(\"kmeans()\")`. For nå, la oss fokusere på noen få. Vi ser at dataene har blitt gruppert i 3 klynger med størrelser 65, 110, 111. Utdataene inneholder også klyngesentrene (gjennomsnitt) for de 3 gruppene på tvers av de 5 variablene.\n",
"\n",
"Klyngingsvektoren er klyngeoppgaven for hver observasjon. La oss bruke funksjonen `augment` for å legge til klyngeoppgaven i det opprinnelige datasettet.\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": [
"Perfekt, vi har nettopp delt datasettet vårt inn i 3 grupper. Så, hvor bra er vår klyngedeling 🤷? La oss ta en titt på `Silhouette score`.\n",
"\n",
"### **Silhouette score**\n",
"\n",
"[Silhouette-analyse](https://en.wikipedia.org/wiki/Silhouette_(clustering)) kan brukes til å studere avstanden mellom de resulterende klyngene. Denne scoren varierer fra -1 til 1, og hvis scoren er nær 1, er klyngen tett og godt adskilt fra andre klynger. En verdi nær 0 representerer overlappende klynger med prøver som ligger veldig nær beslutningsgrensen til naboklyngene. [kilde](https://dzone.com/articles/kmeans-silhouette-score-explained-with-python-exam).\n",
"\n",
"Metoden for gjennomsnittlig silhouette beregner gjennomsnittlig silhouette for observasjoner for ulike verdier av *k*. En høy gjennomsnittlig silhouette-score indikerer en god klyngedeling.\n",
"\n",
"`silhouette`-funksjonen i cluster-pakken brukes til å beregne gjennomsnittlig silhouette-bredde.\n",
"\n",
"> Silhouetten kan beregnes med hvilken som helst [avstand](https://en.wikipedia.org/wiki/Distance \"Distance\")-metrik, som [Euklidsk avstand](https://en.wikipedia.org/wiki/Euclidean_distance \"Euclidean distance\") eller [Manhattan-avstand](https://en.wikipedia.org/wiki/Manhattan_distance \"Manhattan distance\") som vi diskuterte i [forrige leksjon](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": [
"Vår score er **.549**, altså midt på treet. Dette indikerer at dataene våre ikke er spesielt godt egnet for denne typen klyngedannelse. La oss se om vi kan bekrefte denne antagelsen visuelt. [factoextra-pakken](https://rpkgs.datanovia.com/factoextra/index.html) tilbyr funksjoner (`fviz_cluster()`) for å visualisere klyngedannelse.\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": [
"Overlappen i klyngene indikerer at dataene våre ikke er spesielt godt egnet for denne typen klynging, men la oss fortsette.\n",
"\n",
"## 4. Bestemme optimale klynger\n",
"\n",
"Et grunnleggende spørsmål som ofte oppstår i K-Means klynging er dette - uten kjente klasseetiketter, hvordan vet du hvor mange klynger du skal dele dataene dine inn i?\n",
"\n",
"En måte vi kan prøve å finne ut av dette på er å bruke et datasett til å `lage en serie med klyngemodeller` med et økende antall klynger (f.eks. fra 1-10), og evaluere klyngemetrikker som **Silhouette score.**\n",
"\n",
"La oss bestemme det optimale antallet klynger ved å beregne klyngealgoritmen for forskjellige verdier av *k* og evaluere **Within Cluster Sum of Squares** (WCSS). Den totale within-cluster sum of squares (WCSS) måler hvor kompakt klyngene er, og vi ønsker at den skal være så liten som mulig, der lavere verdier betyr at datapunktene er nærmere hverandre.\n",
"\n",
"La oss undersøke effekten av forskjellige valg av `k`, fra 1 til 10, på denne klyngingen.\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": [
"Nå som vi har den totale sum av kvadrater innenfor klyngene (tot.withinss) for hver klyngealgoritme med sentrum *k*, bruker vi [albuemetoden](https://en.wikipedia.org/wiki/Elbow_method_(clustering)) for å finne det optimale antallet klynger. Metoden består i å plotte WCSS som en funksjon av antallet klynger, og velge [albuen på kurven](https://en.wikipedia.org/wiki/Elbow_of_the_curve \"Albuen på kurven\") som antallet klynger som skal brukes.\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": [
"Plottet viser en stor reduksjon i WCSS (altså større *tetthet*) når antall klynger øker fra én til to, og en ytterligere merkbar reduksjon fra to til tre klynger. Etter dette blir reduksjonen mindre tydelig, noe som resulterer i en `knekk` 💪 i diagrammet rundt tre klynger. Dette er en god indikasjon på at det finnes to til tre rimelig godt separerte klynger av datapunkter.\n",
"\n",
"Vi kan nå gå videre og hente ut klyngemodellen der `k = 3`:\n",
"\n",
"> `pull()`: brukes til å hente ut en enkelt kolonne\n",
">\n",
"> `pluck()`: brukes til å indeksere datastrukturer som lister\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": [
"Flott! La oss visualisere klyngene vi har fått. Hva med litt interaktivitet ved hjelp av `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": [
"Kanskje vi ville ha forventet at hver klynge (representert med forskjellige farger) hadde tydelige sjangre (representert med forskjellige former).\n",
"\n",
"La oss se på modellens nøyaktighet.\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": [
"Denne modellens nøyaktighet er ikke dårlig, men heller ikke fantastisk. Det kan være at dataene ikke egner seg godt for K-Means Clustering. Disse dataene er for ubalanserte, har for lite korrelasjon, og det er for stor variasjon mellom verdiene i kolonnene til å danne gode klynger. Faktisk er det sannsynlig at klyngene som dannes er sterkt påvirket eller skjevfordelt av de tre sjangerkategoriene vi definerte ovenfor.\n",
"\n",
"Likevel, dette var en ganske lærerik prosess!\n",
"\n",
"I Scikit-learn-dokumentasjonen kan du se at en modell som denne, med klynger som ikke er veldig godt avgrenset, har et 'varians'-problem:\n",
"\n",
"<p >\n",
" <img src=\"../../images/problems.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Infografikk fra Scikit-learn</figcaption>\n",
"\n",
"\n",
"\n",
"## **Varians**\n",
"\n",
"Varians er definert som \"gjennomsnittet av de kvadrerte avvikene fra gjennomsnittet\" [kilde](https://www.mathsisfun.com/data/standard-deviation.html). I konteksten av dette klyngeproblemet refererer det til data der verdiene i datasettet vårt har en tendens til å avvike litt for mye fra gjennomsnittet.\n",
"\n",
"✅ Dette er et flott øyeblikk for å tenke på alle måtene du kan løse dette problemet. Justere dataene litt mer? Bruke andre kolonner? Bruke en annen algoritme? Hint: Prøv [å skalere dataene dine](https://www.mygreatlearning.com/blog/learning-data-science-with-k-means-clustering/) for å normalisere dem og teste andre kolonner.\n",
"\n",
"> Prøv denne '[varianskalkulatoren](https://www.calculatorsoup.com/calculators/statistics/variance-calculator.php)' for å forstå konseptet litt bedre.\n",
"\n",
"------------------------------------------------------------------------\n",
"\n",
"## **🚀Utfordring**\n",
"\n",
"Bruk litt tid på denne notatboken og juster parametere. Kan du forbedre modellens nøyaktighet ved å rense dataene mer (for eksempel fjerne uteliggere)? Du kan bruke vekter for å gi mer vekt til visse datasettprøver. Hva annet kan du gjøre for å lage bedre klynger?\n",
"\n",
"Hint: Prøv å skalere dataene dine. Det finnes kommentert kode i notatboken som legger til standard skalering for å få datakolonnene til å ligne hverandre mer når det gjelder rekkevidde. Du vil oppdage at selv om silhuettscoren går ned, jevner 'knekkpunktet' i albuegrafen seg ut. Dette skyldes at når dataene ikke er skalert, får data med mindre varians mer vekt. Les litt mer om dette problemet [her](https://stats.stackexchange.com/questions/21222/are-mean-normalization-and-feature-scaling-needed-for-k-means-clustering/21226#21226).\n",
"\n",
"## [**Quiz etter forelesning**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/30/)\n",
"\n",
"## **Gjennomgang & Selvstudium**\n",
"\n",
"- Ta en titt på en K-Means Simulator [som denne](https://user.ceng.metu.edu.tr/~akifakkus/courses/ceng574/k-means/). Du kan bruke dette verktøyet til å visualisere prøvedatapunkter og bestemme deres sentroider. Du kan redigere dataenes tilfeldighet, antall klynger og antall sentroider. Hjelper dette deg med å få en idé om hvordan dataene kan grupperes?\n",
"\n",
"- Ta også en titt på [dette handoutet om K-Means](https://stanford.edu/~cpiech/cs221/handouts/kmeans.html) fra Stanford.\n",
"\n",
"Vil du prøve ut dine nyervervede klyngeferdigheter på datasett som egner seg godt for K-Means clustering? Se:\n",
"\n",
"- [Tren og evaluer klyngemodeller](https://rpubs.com/eR_ic/clustering) ved hjelp av Tidymodels og venner\n",
"\n",
"- [K-means Cluster Analysis](https://uc-r.github.io/kmeans_clustering), UC Business Analytics R Programming Guide\n",
"\n",
"- [K-means clustering med prinsipper for ryddige data](https://www.tidymodels.org/learn/statistics/k-means/)\n",
"\n",
"## **Oppgave**\n",
"\n",
"[Prøv forskjellige klynge-metoder](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/2-K-Means/assignment.md)\n",
"\n",
"## TAKK TIL:\n",
"\n",
"[Jen Looper](https://www.twitter.com/jenlooper) for å ha laget den originale Python-versjonen av dette modulen ♥️\n",
"\n",
"[`Allison Horst`](https://twitter.com/allison_horst/) for å ha laget de fantastiske illustrasjonene som gjør R mer innbydende og engasjerende. Finn flere illustrasjoner i hennes [galleri](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n",
"\n",
"Lykke til med læringen,\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>Kunstverk av @allison_horst</figcaption>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Ansvarsfraskrivelse**: \nDette dokumentet er oversatt ved hjelp av AI-oversettelsestjenesten [Co-op Translator](https://github.com/Azure/co-op-translator). Selv om vi tilstreber nøyaktighet, vennligst vær oppmerksom på at automatiske oversettelser kan inneholde feil eller unøyaktigheter. Det originale dokumentet på sitt opprinnelige språk bør anses som den autoritative kilden. For kritisk informasjon anbefales profesjonell menneskelig oversettelse. Vi er ikke ansvarlige for eventuelle misforståelser eller feiltolkninger som oppstår ved bruk av denne oversettelsen.\n"
]
}
]
}