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.
499 lines
27 KiB
499 lines
27 KiB
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## **Nigerialainen musiikki Spotifyssa - analyysi**\n",
|
|
"\n",
|
|
"Klusterointi on eräänlainen [valvomaton oppiminen](https://wikipedia.org/wiki/Unsupervised_learning), joka olettaa, että datasetti on merkitsemätön tai että sen syötteet eivät ole yhdistetty ennalta määriteltyihin tuloksiin. Se käyttää erilaisia algoritmeja käydäkseen läpi merkitsemätöntä dataa ja luodakseen ryhmiä datasta havaitsemiensa kuvioiden perusteella.\n",
|
|
"\n",
|
|
"[**Esiluennon kysely**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/27/)\n",
|
|
"\n",
|
|
"### **Johdanto**\n",
|
|
"\n",
|
|
"[Klusterointi](https://link.springer.com/referenceworkentry/10.1007%2F978-0-387-30164-8_124) on erittäin hyödyllinen datan tutkimiseen. Katsotaanpa, voiko se auttaa löytämään trendejä ja kuvioita siitä, miten nigerialaiset yleisöt kuluttavat musiikkia.\n",
|
|
"\n",
|
|
"> ✅ Mieti hetki klusteroinnin käyttötarkoituksia. Arkielämässä klusterointi tapahtuu aina, kun sinulla on kasa pyykkiä ja sinun täytyy lajitella perheenjäsenten vaatteet 🧦👕👖🩲. Data-analytiikassa klusterointi tapahtuu, kun yritetään analysoida käyttäjän mieltymyksiä tai määrittää minkä tahansa merkitsemättömän datasetin ominaisuuksia. Klusterointi auttaa tavallaan tuomaan järjestystä kaaokseen, kuten sukkalaatikkoon.\n",
|
|
"\n",
|
|
"Ammatillisessa ympäristössä klusterointia voidaan käyttää esimerkiksi markkinasegmentointiin, kuten määrittämään, mitkä ikäryhmät ostavat mitäkin tuotteita. Toinen käyttötarkoitus voisi olla poikkeavuuksien havaitseminen, esimerkiksi luottokorttitapahtumien datasetistä petosten tunnistamiseen. Tai klusterointia voisi käyttää kasvainten tunnistamiseen lääketieteellisten skannauksien joukosta.\n",
|
|
"\n",
|
|
"✅ Mieti hetki, miten olet saattanut kohdata klusterointia \"luonnossa\", esimerkiksi pankkitoiminnassa, verkkokaupassa tai liiketoiminnassa.\n",
|
|
"\n",
|
|
"> 🎓 Mielenkiintoista on, että klusterianalyysi sai alkunsa antropologian ja psykologian aloilla 1930-luvulla. Voitko kuvitella, miten sitä saatettiin käyttää?\n",
|
|
"\n",
|
|
"Vaihtoehtoisesti sitä voisi käyttää hakutulosten ryhmittelyyn - esimerkiksi ostoslinkkien, kuvien tai arvostelujen mukaan. Klusterointi on hyödyllistä, kun sinulla on suuri datasetti, jonka haluat pienentää ja jolle haluat tehdä tarkempaa analyysiä. Tekniikkaa voidaan käyttää datan tutkimiseen ennen muiden mallien rakentamista.\n",
|
|
"\n",
|
|
"✅ Kun datasi on järjestetty klustereihin, sille annetaan klusteri-ID, ja tämä tekniikka voi olla hyödyllinen datasetin yksityisyyden säilyttämisessä; voit viitata datapisteeseen klusteri-ID:n avulla sen sijaan, että käyttäisit paljastavampia tunnistettavia tietoja. Voitko keksiä muita syitä, miksi käyttäisit klusteri-ID:tä sen sijaan, että viittaisit klusterin muihin elementteihin?\n",
|
|
"\n",
|
|
"### Klusteroinnin aloittaminen\n",
|
|
"\n",
|
|
"> 🎓 Klusterien luominen liittyy vahvasti siihen, miten datan pisteet ryhmitellään. Puretaanpa hieman sanastoa:\n",
|
|
">\n",
|
|
"> 🎓 ['Transduktiivinen' vs. 'induktiivinen'](https://wikipedia.org/wiki/Transduction_(machine_learning))\n",
|
|
">\n",
|
|
"> Transduktiivinen päättely johdetaan havaituista harjoitustapauksista, jotka vastaavat tiettyjä testitapauksia. Induktiivinen päättely johdetaan harjoitustapauksista, jotka johtavat yleisiin sääntöihin, joita sovelletaan vasta testitapauksiin.\n",
|
|
">\n",
|
|
"> Esimerkki: Kuvittele, että sinulla on datasetti, joka on vain osittain merkitty. Jotkut asiat ovat 'levyjä', jotkut 'CD-levyjä', ja jotkut ovat tyhjiä. Tehtäväsi on antaa tyhjille kohteille merkinnät. Jos valitset induktiivisen lähestymistavan, kouluttaisit mallin etsimään 'levyjä' ja 'CD-levyjä' ja soveltaisit näitä merkintöjä merkitsemättömään dataan. Tämä lähestymistapa kohtaisi vaikeuksia luokitella asioita, jotka ovat oikeasti 'kasetteja'. Transduktiivinen lähestymistapa sen sijaan käsittelee tuntematonta dataa tehokkaammin, koska se pyrkii ryhmittelemään samankaltaiset kohteet yhteen ja antaa ryhmälle merkinnän. Tässä tapauksessa klusterit saattaisivat kuvastaa 'pyöreitä musiikkiesineitä' ja 'neliömäisiä musiikkiesineitä'.\n",
|
|
">\n",
|
|
"> 🎓 ['Ei-tasainen' vs. 'tasainen geometria'](https://datascience.stackexchange.com/questions/52260/terminology-flat-geometry-in-the-context-of-clustering)\n",
|
|
">\n",
|
|
"> Matemaattisesta terminologiasta johdettuna ei-tasainen vs. tasainen geometria viittaa pisteiden välisten etäisyyksien mittaamiseen joko 'tasaisilla' ([euklidisilla](https://wikipedia.org/wiki/Euclidean_geometry)) tai 'ei-tasaisilla' (ei-euklidisilla) geometrisilla menetelmillä.\n",
|
|
">\n",
|
|
"> 'Tasainen' tässä yhteydessä viittaa euklidiseen geometriaan (osaa siitä opetetaan 'tasogeometriana'), ja ei-tasainen viittaa ei-euklidiseen geometriaan. Mitä geometrialla on tekemistä koneoppimisen kanssa? No, koska molemmat alat perustuvat matematiikkaan, täytyy olla yhteinen tapa mitata pisteiden välisiä etäisyyksiä klustereissa, ja tämä voidaan tehdä 'tasaisella' tai 'ei-tasaisella' tavalla datan luonteen mukaan. [Euklidiset etäisyydet](https://wikipedia.org/wiki/Euclidean_distance) mitataan kahden pisteen välisenä viivan pituutena. [Ei-euklidiset etäisyydet](https://wikipedia.org/wiki/Non-Euclidean_geometry) mitataan käyrän pitkin. Jos datasi, visualisoituna, ei näytä olevan tasossa, saatat tarvita erikoistuneen algoritmin sen käsittelemiseen.\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/flat-nonflat.png\"\n",
|
|
" width=\"600\"/>\n",
|
|
" <figcaption>Infografiikka: Dasani Madipalli</figcaption>\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"> 🎓 ['Etäisyydet'](https://web.stanford.edu/class/cs345a/slides/12-clustering.pdf)\n",
|
|
">\n",
|
|
"> Klusterit määritellään niiden etäisyysmatriisin perusteella, eli pisteiden välisillä etäisyyksillä. Tämä etäisyys voidaan mitata muutamalla tavalla. Euklidiset klusterit määritellään pistearvojen keskiarvon perusteella, ja niillä on 'centroidi' eli keskipiste. Etäisyydet mitataan siis etäisyytenä centroidiin. Ei-euklidiset etäisyydet viittaavat 'clustroideihin', pisteeseen, joka on lähimpänä muita pisteitä. Clustroidit voidaan puolestaan määritellä eri tavoin.\n",
|
|
">\n",
|
|
"> 🎓 ['Rajoitettu'](https://wikipedia.org/wiki/Constrained_clustering)\n",
|
|
">\n",
|
|
"> [Rajoitettu klusterointi](https://web.cs.ucdavis.edu/~davidson/Publications/ICDMTutorial.pdf) tuo 'puolivalvotun' oppimisen tähän valvomattomaan menetelmään. Pisteiden väliset suhteet merkitään 'ei voi yhdistää' tai 'täytyy yhdistää', joten datasettiin asetetaan joitakin sääntöjä.\n",
|
|
">\n",
|
|
"> Esimerkki: Jos algoritmi päästetään vapaaksi joukkoon merkitsemätöntä tai osittain merkittyä dataa, sen tuottamat klusterit voivat olla huonolaatuisia. Esimerkissä yllä klusterit saattaisivat ryhmitellä 'pyöreät musiikkiesineet', 'neliömäiset musiikkiesineet', 'kolmiomaiset esineet' ja 'keksit'. Jos algoritmille annetaan joitakin rajoituksia tai sääntöjä (\"esineen täytyy olla muovista valmistettu\", \"esineen täytyy pystyä tuottamaan musiikkia\"), tämä voi auttaa 'rajoittamaan' algoritmia tekemään parempia valintoja.\n",
|
|
">\n",
|
|
"> 🎓 'Tiheys'\n",
|
|
">\n",
|
|
"> Data, joka on 'meluisaa', katsotaan olevan 'tiheää'. Pisteiden väliset etäisyydet kussakin klusterissa voivat osoittautua tarkastelussa enemmän tai vähemmän tiheiksi, tai 'ruuhkaisiksi', ja näin ollen tämä data täytyy analysoida sopivalla klusterointimenetelmällä. [Tämä artikkeli](https://www.kdnuggets.com/2020/02/understanding-density-based-clustering.html) havainnollistaa eroa K-Means-klusteroinnin ja HDBSCAN-algoritmien välillä meluisan datasetin tutkimisessa, jossa klusterien tiheys on epätasainen.\n",
|
|
"\n",
|
|
"Syvennä ymmärrystäsi klusterointitekniikoista tässä [Learn-moduulissa](https://docs.microsoft.com/learn/modules/train-evaluate-cluster-models?WT.mc_id=academic-77952-leestott)\n",
|
|
"\n",
|
|
"### **Klusterointialgoritmit**\n",
|
|
"\n",
|
|
"Klusterointialgoritmeja on yli 100, ja niiden käyttö riippuu käsillä olevan datan luonteesta. Keskustellaanpa joistakin tärkeimmistä:\n",
|
|
"\n",
|
|
"- **Hierarkkinen klusterointi**. Jos objekti luokitellaan sen läheisyyden perusteella lähellä olevaan objektiin, eikä kauempana olevaan, klusterit muodostuvat jäsentensä etäisyyden perusteella muihin objekteihin. Hierarkkinen klusterointi on luonteenomaista kahden klusterin toistuvalla yhdistämisellä.\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/hierarchical.png\"\n",
|
|
" width=\"600\"/>\n",
|
|
" <figcaption>Infografiikka: Dasani Madipalli</figcaption>\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"- **Centroid-klusterointi**. Tämä suosittu algoritmi vaatii 'k':n eli muodostettavien klusterien lukumäärän valinnan, minkä jälkeen algoritmi määrittää klusterin keskipisteen ja kerää dataa sen ympärille. [K-means-klusterointi](https://wikipedia.org/wiki/K-means_clustering) on suosittu versio centroid-klusteroinnista, joka jakaa datasetin ennalta määriteltyihin K-ryhmiin. Keskipiste määritetään lähimmän keskiarvon perusteella, mistä nimi juontuu. Klusterin neliöetäisyys minimoidaan.\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/centroid.png\"\n",
|
|
" width=\"600\"/>\n",
|
|
" <figcaption>Infografiikka: Dasani Madipalli</figcaption>\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"- **Jakautumispohjainen klusterointi**. Tilastolliseen mallinnukseen perustuva jakautumispohjainen klusterointi keskittyy määrittämään todennäköisyyden, että datapiste kuuluu klusteriin, ja jakaa sen sen mukaisesti. Gaussian-sekoitusmenetelmät kuuluvat tähän tyyppiin.\n",
|
|
"\n",
|
|
"- **Tiheysperusteinen klusterointi**. Datapisteet jaetaan klustereihin niiden tiheyden eli ryhmittymisen perusteella. Datapisteet, jotka ovat kaukana ryhmästä, katsotaan poikkeamiksi tai meluksi. DBSCAN, Mean-shift ja OPTICS kuuluvat tähän klusterointityyppiin.\n",
|
|
"\n",
|
|
"- **Ruudukkoon perustuva klusterointi**. Moniulotteisille dataseteille luodaan ruudukko, ja data jaetaan ruudukon soluihin, jolloin muodostuu klustereita.\n",
|
|
"\n",
|
|
"Paras tapa oppia klusteroinnista on kokeilla sitä itse, ja juuri sitä teet tässä harjoituksessa.\n",
|
|
"\n",
|
|
"Tarvitsemme joitakin paketteja tämän moduulin suorittamiseen. Voit asentaa ne komennolla: `install.packages(c('tidyverse', 'tidymodels', 'DataExplorer', 'summarytools', 'plotly', 'paletteer', 'corrplot', '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"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\r\n",
|
|
"\r\n",
|
|
"pacman::p_load('tidyverse', 'tidymodels', 'DataExplorer', 'summarytools', 'plotly', 'paletteer', 'corrplot', 'patchwork')\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## Harjoitus - ryhmittele tietosi\n",
|
|
"\n",
|
|
"Ryhmittelytekniikkaa tukee merkittävästi asianmukainen visualisointi, joten aloitetaan musiikkidatan visualisoinnilla. Tämä harjoitus auttaa meitä päättämään, mikä ryhmittelymenetelmä sopii parhaiten tämän datan luonteeseen.\n",
|
|
"\n",
|
|
"Aloitetaan heti tuomalla data.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Load the core tidyverse and make it available in your current R session\r\n",
|
|
"library(tidyverse)\r\n",
|
|
"\r\n",
|
|
"# Import the data into a tibble\r\n",
|
|
"df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/5-Clustering/data/nigerian-songs.csv\")\r\n",
|
|
"\r\n",
|
|
"# View the first 5 rows of the data set\r\n",
|
|
"df %>% \r\n",
|
|
" slice_head(n = 5)\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Joskus saatamme haluta hieman enemmän tietoa datastamme. Voimme tarkastella `dataa` ja `sen rakennetta` käyttämällä [*glimpse()*](https://pillar.r-lib.org/reference/glimpse.html)-funktiota:\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Glimpse into the data set\r\n",
|
|
"df %>% \r\n",
|
|
" glimpse()\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Hyvää työtä!💪\n",
|
|
"\n",
|
|
"Voimme huomata, että `glimpse()` näyttää sinulle rivien (havaintojen) ja sarakkeiden (muuttujien) kokonaismäärän, sekä muutaman ensimmäisen merkinnän jokaisesta muuttujasta rivillä muuttujan nimen jälkeen. Lisäksi muuttujan *tietotyyppi* annetaan heti muuttujan nimen jälkeen `< >`-merkkien sisällä.\n",
|
|
"\n",
|
|
"`DataExplorer::introduce()` voi tiivistää tämän tiedon siististi:\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Describe basic information for our data\r\n",
|
|
"df %>% \r\n",
|
|
" introduce()\r\n",
|
|
"\r\n",
|
|
"# A visual display of the same\r\n",
|
|
"df %>% \r\n",
|
|
" plot_intro()\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Mahtavaa! Olemme juuri oppineet, että datassamme ei ole puuttuvia arvoja.\n",
|
|
"\n",
|
|
"Samalla voimme tutkia yleisiä keskiluvun tilastoja (esim. [keskiarvo](https://en.wikipedia.org/wiki/Arithmetic_mean) ja [mediaani](https://en.wikipedia.org/wiki/Median)) sekä hajontalukuja (esim. [keskihajonta](https://en.wikipedia.org/wiki/Standard_deviation)) käyttämällä `summarytools::descr()`\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Describe common statistics\r\n",
|
|
"df %>% \r\n",
|
|
" descr(stats = \"common\")\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Katsotaan yleisiä arvoja datasta. Huomaa, että suosio voi olla `0`, mikä tarkoittaa kappaleita, joilla ei ole sijoitusta. Poistamme ne pian.\n",
|
|
"\n",
|
|
"> 🤔 Jos käytämme klusterointia, valvomatonta menetelmää, joka ei vaadi merkittyä dataa, miksi näytämme tämän datan merkintöjen kanssa? Datan tutkimusvaiheessa niistä on hyötyä, mutta ne eivät ole välttämättömiä klusterointialgoritmien toimimiselle.\n",
|
|
"\n",
|
|
"### 1. Tutki suosittuja genrejä\n",
|
|
"\n",
|
|
"Selvitetään, mitkä genret ovat suosituimpia 🎶 laskemalla, kuinka monta kertaa ne esiintyvät.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Popular genres\r\n",
|
|
"top_genres <- df %>% \r\n",
|
|
" count(artist_top_genre, sort = TRUE) %>% \r\n",
|
|
"# Encode to categorical and reorder the according to count\r\n",
|
|
" mutate(artist_top_genre = factor(artist_top_genre) %>% fct_inorder())\r\n",
|
|
"\r\n",
|
|
"# Print the top genres\r\n",
|
|
"top_genres\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Se meni hyvin! Sanotaan, että kuva kertoo enemmän kuin tuhat riviä dataa (vaikka kukaan ei oikeasti sano niin 😅). Mutta ymmärrät pointin, eikö?\n",
|
|
"\n",
|
|
"Yksi tapa visualisoida kategorista dataa (merkkijono- tai faktori-muuttujia) on käyttää pylväsdiagrammeja. Tehdään pylväsdiagrammi kymmenestä suosituimmasta genrestä:\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Change the default gray theme\r\n",
|
|
"theme_set(theme_light())\r\n",
|
|
"\r\n",
|
|
"# Visualize popular genres\r\n",
|
|
"top_genres %>%\r\n",
|
|
" slice(1:10) %>% \r\n",
|
|
" ggplot(mapping = aes(x = artist_top_genre, y = n,\r\n",
|
|
" fill = artist_top_genre)) +\r\n",
|
|
" geom_col(alpha = 0.8) +\r\n",
|
|
" paletteer::scale_fill_paletteer_d(\"rcartocolor::Vivid\") +\r\n",
|
|
" ggtitle(\"Top genres\") +\r\n",
|
|
" theme(plot.title = element_text(hjust = 0.5),\r\n",
|
|
" # Rotates the X markers (so we can read them)\r\n",
|
|
" axis.text.x = element_text(angle = 90))\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Nyt on paljon helpompi tunnistaa, että meillä on `puuttuvia` genrejä 🧐!\n",
|
|
"\n",
|
|
"> Hyvä visualisointi paljastaa asioita, joita et odottanut, tai herättää uusia kysymyksiä datasta - Hadley Wickham ja Garrett Grolemund, [R For Data Science](https://r4ds.had.co.nz/introduction.html)\n",
|
|
"\n",
|
|
"Huomaa, kun päägenre on merkitty `Puuttuva`, se tarkoittaa, että Spotify ei luokitellut sitä, joten poistetaan se.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Visualize popular genres\r\n",
|
|
"top_genres %>%\r\n",
|
|
" filter(artist_top_genre != \"Missing\") %>% \r\n",
|
|
" slice(1:10) %>% \r\n",
|
|
" ggplot(mapping = aes(x = artist_top_genre, y = n,\r\n",
|
|
" fill = artist_top_genre)) +\r\n",
|
|
" geom_col(alpha = 0.8) +\r\n",
|
|
" paletteer::scale_fill_paletteer_d(\"rcartocolor::Vivid\") +\r\n",
|
|
" ggtitle(\"Top genres\") +\r\n",
|
|
" theme(plot.title = element_text(hjust = 0.5),\r\n",
|
|
" # Rotates the X markers (so we can read them)\r\n",
|
|
" axis.text.x = element_text(angle = 90))\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Pienestä datan tutkimisesta opimme, että kolme suosituinta genreä hallitsevat tätä datasettiä. Keskitytään `afro dancehall`, `afropop` ja `nigerian pop` -genreihin, ja lisäksi suodatetaan datasetti poistamalla kaikki, joiden suosioarvo on 0 (mikä tarkoittaa, että niitä ei ole luokiteltu datasetissä suosioarvolla ja niitä voidaan pitää meluna tarkoituksiamme varten):\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"nigerian_songs <- df %>% \r\n",
|
|
" # Concentrate on top 3 genres\r\n",
|
|
" filter(artist_top_genre %in% c(\"afro dancehall\", \"afropop\",\"nigerian pop\")) %>% \r\n",
|
|
" # Remove unclassified observations\r\n",
|
|
" filter(popularity != 0)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Visualize popular genres\r\n",
|
|
"nigerian_songs %>%\r\n",
|
|
" count(artist_top_genre) %>%\r\n",
|
|
" ggplot(mapping = aes(x = artist_top_genre, y = n,\r\n",
|
|
" fill = artist_top_genre)) +\r\n",
|
|
" geom_col(alpha = 0.8) +\r\n",
|
|
" paletteer::scale_fill_paletteer_d(\"ggsci::category10_d3\") +\r\n",
|
|
" ggtitle(\"Top genres\") +\r\n",
|
|
" theme(plot.title = element_text(hjust = 0.5))\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Tarkastellaan, onko numeeristen muuttujien välillä ilmeistä lineaarista yhteyttä aineistossamme. Tämä yhteys määritetään matemaattisesti [korrelaatiotilastolla](https://en.wikipedia.org/wiki/Correlation).\n",
|
|
"\n",
|
|
"Korrelaatiotilasto on arvo välillä -1 ja 1, joka ilmaisee yhteyden vahvuuden. Arvot yli 0 osoittavat *positiivista* korrelaatiota (yhden muuttujan korkeat arvot esiintyvät yleensä toisen muuttujan korkeiden arvojen kanssa), kun taas arvot alle 0 osoittavat *negatiivista* korrelaatiota (yhden muuttujan korkeat arvot esiintyvät yleensä toisen muuttujan matalien arvojen kanssa).\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Narrow down to numeric variables and fid correlation\r\n",
|
|
"corr_mat <- nigerian_songs %>% \r\n",
|
|
" select(where(is.numeric)) %>% \r\n",
|
|
" cor()\r\n",
|
|
"\r\n",
|
|
"# Visualize correlation matrix\r\n",
|
|
"corrplot(corr_mat, order = 'AOE', col = c('white', 'black'), bg = 'gold2') \r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Data ei ole vahvasti korreloitunutta, paitsi `energy` ja `loudness` välillä, mikä on järkevää, sillä äänekäs musiikki on yleensä melko energistä. `Popularity` liittyy `release date`-tietoon, mikä on myös loogista, sillä uudemmat kappaleet ovat todennäköisesti suositumpia. Pituudella ja energialla näyttää olevan myös korrelaatiota.\n",
|
|
"\n",
|
|
"On mielenkiintoista nähdä, mitä klusterointialgoritmi voi tehdä tämän datan kanssa!\n",
|
|
"\n",
|
|
"> 🎓 Huomaa, että korrelaatio ei tarkoita kausaatiota! Meillä on todiste korrelaatiosta, mutta ei kausaatiosta. [Hauska verkkosivusto](https://tylervigen.com/spurious-correlations) tarjoaa visuaalisia esimerkkejä, jotka korostavat tätä asiaa.\n",
|
|
"\n",
|
|
"### 2. Tutki datan jakaumaa\n",
|
|
"\n",
|
|
"Kysytään hieman hienovaraisempia kysymyksiä. Ovatko genret merkittävästi erilaisia tanssittavuuden osalta, kun otetaan huomioon niiden suosio? Tarkastellaan kolmen suosituimman genren datan jakaumaa suosion ja tanssittavuuden osalta annetulla x- ja y-akselilla käyttäen [tiheyskäyriä](https://www.khanacademy.org/math/ap-statistics/density-curves-normal-distribution-ap/density-curves/v/density-curves).\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Perform 2D kernel density estimation\r\n",
|
|
"density_estimate_2d <- nigerian_songs %>% \r\n",
|
|
" ggplot(mapping = aes(x = popularity, y = danceability, color = artist_top_genre)) +\r\n",
|
|
" geom_density_2d(bins = 5, size = 1) +\r\n",
|
|
" paletteer::scale_color_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n",
|
|
" xlim(-20, 80) +\r\n",
|
|
" ylim(0, 1.2)\r\n",
|
|
"\r\n",
|
|
"# Density plot based on the popularity\r\n",
|
|
"density_estimate_pop <- nigerian_songs %>% \r\n",
|
|
" ggplot(mapping = aes(x = popularity, fill = artist_top_genre, color = artist_top_genre)) +\r\n",
|
|
" geom_density(size = 1, alpha = 0.5) +\r\n",
|
|
" paletteer::scale_fill_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n",
|
|
" paletteer::scale_color_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n",
|
|
" theme(legend.position = \"none\")\r\n",
|
|
"\r\n",
|
|
"# Density plot based on the danceability\r\n",
|
|
"density_estimate_dance <- nigerian_songs %>% \r\n",
|
|
" ggplot(mapping = aes(x = danceability, fill = artist_top_genre, color = artist_top_genre)) +\r\n",
|
|
" geom_density(size = 1, alpha = 0.5) +\r\n",
|
|
" paletteer::scale_fill_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n",
|
|
" paletteer::scale_color_paletteer_d(\"RSkittleBrewer::wildberry\")\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Patch everything together\r\n",
|
|
"library(patchwork)\r\n",
|
|
"density_estimate_2d / (density_estimate_pop + density_estimate_dance)\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Huomaamme, että on keskenään samankeskisiä ympyröitä, jotka asettuvat kohdalleen riippumatta genrestä. Voisiko olla niin, että nigerialaiset mieltymykset lähentyvät tiettyä tanssittavuuden tasoa tässä genressä?\n",
|
|
"\n",
|
|
"Yleisesti ottaen nämä kolme genreä ovat samankaltaisia suosionsa ja tanssittavuutensa suhteen. Klustereiden määrittäminen tässä löyhästi järjestäytyneessä datassa tulee olemaan haastavaa. Katsotaan, voisiko hajontakaavio auttaa tässä.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# A scatter plot of popularity and danceability\r\n",
|
|
"scatter_plot <- nigerian_songs %>% \r\n",
|
|
" ggplot(mapping = aes(x = popularity, y = danceability, color = artist_top_genre, shape = artist_top_genre)) +\r\n",
|
|
" geom_point(size = 2, alpha = 0.8) +\r\n",
|
|
" paletteer::scale_color_paletteer_d(\"futurevisions::mars\")\r\n",
|
|
"\r\n",
|
|
"# Add a touch of interactivity\r\n",
|
|
"ggplotly(scatter_plot)\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Hajontakaavio samoilla akseleilla näyttää samanlaisen lähentymismallin.\n",
|
|
"\n",
|
|
"Yleisesti ottaen klusterointia varten voit käyttää hajontakaavioita datan klustereiden esittämiseen, joten tämän tyyppisen visualisoinnin hallitseminen on erittäin hyödyllistä. Seuraavassa oppitunnissa otamme tämän suodatetun datan ja käytämme k-means-klusterointia löytääksemme ryhmiä, jotka näyttävät limittyvän mielenkiintoisilla tavoilla.\n",
|
|
"\n",
|
|
"## **🚀 Haaste**\n",
|
|
"\n",
|
|
"Valmistaudu seuraavaan oppituntiin tekemällä kaavio erilaisista klusterointialgoritmeista, joita saatat löytää ja käyttää tuotantoympäristössä. Minkä tyyppisiä ongelmia klusterointi yrittää ratkaista?\n",
|
|
"\n",
|
|
"## [**Oppitunnin jälkeinen visailu**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/28/)\n",
|
|
"\n",
|
|
"## **Kertaus ja itseopiskelu**\n",
|
|
"\n",
|
|
"Ennen kuin sovellat klusterointialgoritmeja, kuten olemme oppineet, on hyvä ymmärtää datasetin luonne. Lue lisää tästä aiheesta [täältä](https://www.kdnuggets.com/2019/10/right-clustering-algorithm.html).\n",
|
|
"\n",
|
|
"Syvennä ymmärrystäsi klusterointitekniikoista:\n",
|
|
"\n",
|
|
"- [Kouluta ja arvioi klusterointimalleja käyttämällä Tidymodelsia ja muita työkaluja](https://rpubs.com/eR_ic/clustering)\n",
|
|
"\n",
|
|
"- Bradley Boehmke & Brandon Greenwell, [*Hands-On Machine Learning with R*](https://bradleyboehmke.github.io/HOML/)*.*\n",
|
|
"\n",
|
|
"## **Tehtävä**\n",
|
|
"\n",
|
|
"[Tutki muita klusteroinnin visualisointitapoja](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/assignment.md)\n",
|
|
"\n",
|
|
"## KIITOKSET:\n",
|
|
"\n",
|
|
"[Jen Looper](https://www.twitter.com/jenlooper) alkuperäisen Python-version luomisesta tälle moduulille ♥️\n",
|
|
"\n",
|
|
"[`Dasani Madipalli`](https://twitter.com/dasani_decoded) upeiden kuvitusten luomisesta, jotka tekevät koneoppimisen käsitteistä helpommin ymmärrettäviä ja tulkittavia.\n",
|
|
"\n",
|
|
"Iloisia oppimishetkiä,\n",
|
|
"\n",
|
|
"[Eric](https://twitter.com/ericntay), Gold Microsoft Learn Student Ambassador.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"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 tämän käännöksen käytöstä aiheutuvista väärinkäsityksistä tai virhetulkinnoista.\n"
|
|
]
|
|
}
|
|
],
|
|
"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"
|
|
},
|
|
"coopTranslator": {
|
|
"original_hash": "99c36449cad3708a435f6798cfa39972",
|
|
"translation_date": "2025-09-04T07:52:10+00:00",
|
|
"source_file": "5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb",
|
|
"language_code": "fi"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 1
|
|
} |