{ "nbformat": 4, "nbformat_minor": 2, "metadata": { "colab": { "name": "lesson_10-R.ipynb", "provenance": [], "collapsed_sections": [] }, "kernelspec": { "name": "ir", "display_name": "R" }, "language_info": { "name": "R" }, "coopTranslator": { "original_hash": "2621e24705e8100893c9bf84e0fc8aef", "translation_date": "2025-09-04T08:54:43+00:00", "source_file": "4-Classification/1-Introduction/solution/R/lesson_10-R.ipynb", "language_code": "fi" } }, "cells": [ { "cell_type": "markdown", "source": [ "# Rakenna luokittelumalli: Herkulliset aasialaiset ja intialaiset keittiöt\n" ], "metadata": { "id": "ItETB4tSFprR" } }, { "cell_type": "markdown", "source": [ "## Johdanto luokitteluun: Puhdista, valmistele ja visualisoi datasi\n", "\n", "Näissä neljässä oppitunnissa tutustut klassisen koneoppimisen keskeiseen osa-alueeseen - *luokitteluun*. Käymme läpi erilaisten luokittelualgoritmien käyttöä datasetillä, joka käsittelee Aasian ja Intian upeita keittiöitä. Toivottavasti olet nälkäinen!\n", "\n", "

\n", " \n", "

Juhlista pan-aasialaisia keittiöitä näissä oppitunneissa! Kuva: Jen Looper
\n", "\n", "\n", "\n", "\n", "Luokittelu on eräs [valvotun oppimisen](https://wikipedia.org/wiki/Supervised_learning) muoto, joka muistuttaa paljon regressiotekniikoita. Luokittelussa koulutat mallin ennustamaan, mihin `kategoriaan` tietty kohde kuuluu. Jos koneoppiminen keskittyy arvojen tai nimien ennustamiseen datasetien avulla, luokittelu jakautuu yleensä kahteen ryhmään: *binääriluokittelu* ja *moniluokittelu*.\n", "\n", "Muista:\n", "\n", "- **Lineaarinen regressio** auttoi sinua ennustamaan muuttujien välisiä suhteita ja tekemään tarkkoja ennusteita siitä, mihin uusi datapiste sijoittuu suhteessa viivaan. Esimerkiksi, voit ennustaa numeerisia arvoja, kuten *mikä kurpitsan hinta olisi syyskuussa verrattuna joulukuuhun*.\n", "\n", "- **Logistinen regressio** auttoi sinua löytämään \"binäärikategorioita\": tietyllä hintatasolla, *onko kurpitsa oranssi vai ei-oranssi*?\n", "\n", "Luokittelu käyttää erilaisia algoritmeja määrittääkseen muita tapoja, joilla datapisteen etiketti tai luokka voidaan määrittää. Työskentelemme tämän keittiödata-aineiston kanssa nähdäksemme, voimmeko ainesosaryhmää tarkkailemalla määrittää sen alkuperäisen keittiön.\n", "\n", "### [**Ennakkokysely**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/19/)\n", "\n", "### **Johdanto**\n", "\n", "Luokittelu on yksi koneoppimisen tutkijan ja data-analyytikon keskeisistä tehtävistä. Perusluokittelusta binäärisen arvon (\"onko tämä sähköposti roskapostia vai ei?\") monimutkaiseen kuvien luokitteluun ja segmentointiin tietokonenäön avulla, on aina hyödyllistä pystyä järjestämään dataa luokkiin ja esittämään kysymyksiä siitä.\n", "\n", "Tieteellisemmin ilmaistuna luokittelumenetelmäsi luo ennustavan mallin, joka mahdollistaa syöttömuuttujien ja tulosmuuttujien välisen suhteen kartoittamisen.\n", "\n", "

\n", " \n", "

Binääriset vs. moniluokkaiset ongelmat, joita luokittelualgoritmit käsittelevät. Infografiikka: Jen Looper
\n", "\n", "\n", "\n", "Ennen kuin aloitamme datan puhdistamisen, visualisoinnin ja valmistelun koneoppimistehtäviämme varten, opitaan hieman siitä, miten koneoppimista voidaan hyödyntää datan luokittelussa.\n", "\n", "Luokittelu, joka on johdettu [tilastotieteestä](https://wikipedia.org/wiki/Statistical_classification), käyttää klassisessa koneoppimisessa ominaisuuksia, kuten `tupakoitsija`, `paino` ja `ikä`, määrittääkseen *todennäköisyyden sairastua X-tautiin*. Valvottuna oppimistekniikkana, joka muistuttaa aiemmin suorittamiasi regressioharjoituksia, datasi on merkitty, ja koneoppimisalgoritmit käyttävät näitä merkintöjä luokitellakseen ja ennustaakseen datasetin luokkia (tai 'ominaisuuksia') ja liittääkseen ne ryhmään tai lopputulokseen.\n", "\n", "✅ Mieti hetki datasettiä, joka käsittelee keittiöitä. Mitä moniluokkamalli voisi vastata? Mitä binäärimalli voisi vastata? Entä jos haluaisit selvittää, käyttääkö tietty keittiö todennäköisesti sarviapilaa? Entä jos haluaisit nähdä, voisitko tähden aniksesta, artisokasta, kukkakaalista ja piparjuuresta koostuvan ruokakassin avulla valmistaa tyypillisen intialaisen ruokalajin?\n", "\n", "### **Hei 'luokittelija'**\n", "\n", "Kysymys, jonka haluamme esittää tästä keittiödatasta, on itse asiassa **moniluokkainen kysymys**, sillä meillä on useita mahdollisia kansallisia keittiöitä, joiden kanssa työskennellä. Kun meillä on joukko ainesosia, mihin näistä monista luokista data sopii?\n", "\n", "Tidymodels tarjoaa useita erilaisia algoritmeja datan luokitteluun riippuen siitä, millaisen ongelman haluat ratkaista. Seuraavissa kahdessa oppitunnissa opit useista näistä algoritmeista.\n", "\n", "#### **Edellytykset**\n", "\n", "Tätä oppituntia varten tarvitsemme seuraavat paketit datan puhdistamiseen, valmisteluun ja visualisointiin:\n", "\n", "- `tidyverse`: [tidyverse](https://www.tidyverse.org/) on [R-pakettien kokoelma](https://www.tidyverse.org/packages), joka tekee data-analytiikasta nopeampaa, helpompaa ja hauskempaa!\n", "\n", "- `tidymodels`: [tidymodels](https://www.tidymodels.org/) -kehys on [pakettikokoelma](https://www.tidymodels.org/packages/) mallinnukseen ja koneoppimiseen.\n", "\n", "- `DataExplorer`: [DataExplorer-paketti](https://cran.r-project.org/web/packages/DataExplorer/vignettes/dataexplorer-intro.html) on tarkoitettu yksinkertaistamaan ja automatisoimaan EDA-prosessia ja raporttien luomista.\n", "\n", "- `themis`: [themis-paketti](https://themis.tidymodels.org/) tarjoaa lisäreseptejä epätasapainoisen datan käsittelyyn.\n", "\n", "Voit asentaa ne seuraavasti:\n", "\n", "`install.packages(c(\"tidyverse\", \"tidymodels\", \"DataExplorer\", \"here\"))`\n", "\n", "Vaihtoehtoisesti alla oleva skripti tarkistaa, onko sinulla tarvittavat paketit tämän moduulin suorittamiseen, ja asentaa ne puolestasi, jos ne puuttuvat.\n" ], "metadata": { "id": "ri5bQxZ-Fz_0" } }, { "cell_type": "code", "execution_count": null, "source": [ "suppressWarnings(if (!require(\"pacman\"))install.packages(\"pacman\"))\r\n", "\r\n", "pacman::p_load(tidyverse, tidymodels, DataExplorer, themis, here)" ], "outputs": [], "metadata": { "id": "KIPxa4elGAPI" } }, { "cell_type": "markdown", "source": [ "Lataamme myöhemmin nämä mahtavat paketit ja teemme ne saataville nykyisessä R-istunnossamme. (Tämä on vain havainnollistamista varten, `pacman::p_load()` teki sen jo puolestasi)\n" ], "metadata": { "id": "YkKAxOJvGD4C" } }, { "cell_type": "markdown", "source": [ "## Harjoitus - puhdista ja tasapainota datasi\n", "\n", "Ensimmäinen tehtävä ennen tämän projektin aloittamista on puhdistaa ja **tasapainottaa** datasi, jotta saat parempia tuloksia.\n", "\n", "Tutustutaan dataan! 🕵️\n" ], "metadata": { "id": "PFkQDlk0GN5O" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Import data\r\n", "df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/4-Classification/data/cuisines.csv\")\r\n", "\r\n", "# View the first 5 rows\r\n", "df %>% \r\n", " slice_head(n = 5)\r\n" ], "outputs": [], "metadata": { "id": "Qccw7okxGT0S" } }, { "cell_type": "markdown", "source": [ "Mielenkiintoista! Näyttää siltä, että ensimmäinen sarake on eräänlainen `id`-sarake. Otetaan hieman enemmän tietoa datasta.\n" ], "metadata": { "id": "XrWnlgSrGVmR" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Basic information about the data\r\n", "df %>%\r\n", " introduce()\r\n", "\r\n", "# Visualize basic information above\r\n", "df %>% \r\n", " plot_intro(ggtheme = theme_light())" ], "outputs": [], "metadata": { "id": "4UcGmxRxGieA" } }, { "cell_type": "markdown", "source": [ "Tuloksista näemme heti, että meillä on `2448` riviä ja `385` saraketta sekä `0` puuttuvaa arvoa. Meillä on myös yksi diskreetti sarake, *cuisine*.\n", "\n", "## Harjoitus - tutustuminen keittiötyyleihin\n", "\n", "Nyt työ alkaa muuttua mielenkiintoisemmaksi. Tutkitaan datan jakaumaa keittiötyyleittäin.\n" ], "metadata": { "id": "AaPubl__GmH5" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Count observations per cuisine\r\n", "df %>% \r\n", " count(cuisine) %>% \r\n", " arrange(n)\r\n", "\r\n", "# Plot the distribution\r\n", "theme_set(theme_light())\r\n", "df %>% \r\n", " count(cuisine) %>% \r\n", " ggplot(mapping = aes(x = n, y = reorder(cuisine, -n))) +\r\n", " geom_col(fill = \"midnightblue\", alpha = 0.7) +\r\n", " ylab(\"cuisine\")" ], "outputs": [], "metadata": { "id": "FRsBVy5eGrrv" } }, { "cell_type": "markdown", "source": [ "On olemassa rajallinen määrä keittiöitä, mutta datan jakautuminen on epätasaista. Voit korjata sen! Ennen kuin teet niin, tutki hieman lisää.\n", "\n", "Seuraavaksi määritellään jokainen keittiö omaan tibbleen ja selvitetään, kuinka paljon dataa (rivit, sarakkeet) on saatavilla per keittiö.\n", "\n", "> [Tibble](https://tibble.tidyverse.org/) on moderni data frame.\n", "\n", "

\n", " \n", "

Taiteilija: @allison_horst
\n" ], "metadata": { "id": "vVvyDb1kG2in" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Create individual tibble for the cuisines\r\n", "thai_df <- df %>% \r\n", " filter(cuisine == \"thai\")\r\n", "japanese_df <- df %>% \r\n", " filter(cuisine == \"japanese\")\r\n", "chinese_df <- df %>% \r\n", " filter(cuisine == \"chinese\")\r\n", "indian_df <- df %>% \r\n", " filter(cuisine == \"indian\")\r\n", "korean_df <- df %>% \r\n", " filter(cuisine == \"korean\")\r\n", "\r\n", "\r\n", "# Find out how much data is available per cuisine\r\n", "cat(\" thai df:\", dim(thai_df), \"\\n\",\r\n", " \"japanese df:\", dim(japanese_df), \"\\n\",\r\n", " \"chinese_df:\", dim(chinese_df), \"\\n\",\r\n", " \"indian_df:\", dim(indian_df), \"\\n\",\r\n", " \"korean_df:\", dim(korean_df))" ], "outputs": [], "metadata": { "id": "0TvXUxD3G8Bk" } }, { "cell_type": "markdown", "source": [ "## **Harjoitus - Parhaiden ainesosien löytäminen keittiöittäin dplyr:n avulla**\n", "\n", "Nyt voit syventyä dataan ja selvittää, mitkä ovat tyypilliset ainesosat eri keittiöissä. Sinun tulisi poistaa toistuvaa dataa, joka aiheuttaa sekaannusta keittiöiden välillä, joten tutustutaan tähän ongelmaan.\n", "\n", "Luo R:ssä funktio `create_ingredient()`, joka palauttaa ainesosadataframen. Tämä funktio aloittaa poistamalla hyödyttömän sarakkeen ja lajittelee ainesosat niiden määrän mukaan.\n", "\n", "R-funktion perusrakenne on:\n", "\n", "`myFunction <- function(arglist){`\n", "\n", "**`...`**\n", "\n", "**`return`**`(value)`\n", "\n", "`}`\n", "\n", "Selkeä johdatus R-funktioihin löytyy [täältä](https://skirmer.github.io/presentations/functions_with_r.html#1).\n", "\n", "Aloitetaan heti! Käytämme [dplyr-verbejä](https://dplyr.tidyverse.org/), joita olemme oppineet aiemmilla tunneilla. Muistin virkistykseksi:\n", "\n", "- `dplyr::select()`: auttaa valitsemaan, mitkä **sarakkeet** säilytetään tai poistetaan.\n", "\n", "- `dplyr::pivot_longer()`: auttaa \"pidentämään\" dataa, lisäämällä rivien määrää ja vähentämällä sarakkeiden määrää.\n", "\n", "- `dplyr::group_by()` ja `dplyr::summarise()`: auttavat löytämään ryhmien tilastolliset yhteenvedot ja järjestämään ne siistiin taulukkoon.\n", "\n", "- `dplyr::filter()`: luo datasta alijoukon, joka sisältää vain ehdot täyttävät rivit.\n", "\n", "- `dplyr::mutate()`: auttaa luomaan tai muokkaamaan sarakkeita.\n", "\n", "Tutustu tähän [*taiteelliseen* learnr-oppaaseen](https://allisonhorst.shinyapps.io/dplyr-learnr/#section-welcome), jonka on tehnyt Allison Horst. Se esittelee hyödyllisiä datan käsittelytoimintoja dplyr:ssä *(osa Tidyverseä)*.\n" ], "metadata": { "id": "K3RF5bSCHC76" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Creates a functions that returns the top ingredients by class\r\n", "\r\n", "create_ingredient <- function(df){\r\n", " \r\n", " # Drop the id column which is the first colum\r\n", " ingredient_df = df %>% select(-1) %>% \r\n", " # Transpose data to a long format\r\n", " pivot_longer(!cuisine, names_to = \"ingredients\", values_to = \"count\") %>% \r\n", " # Find the top most ingredients for a particular cuisine\r\n", " group_by(ingredients) %>% \r\n", " summarise(n_instances = sum(count)) %>% \r\n", " filter(n_instances != 0) %>% \r\n", " # Arrange by descending order\r\n", " arrange(desc(n_instances)) %>% \r\n", " mutate(ingredients = factor(ingredients) %>% fct_inorder())\r\n", " \r\n", " \r\n", " return(ingredient_df)\r\n", "} # End of function" ], "outputs": [], "metadata": { "id": "uB_0JR82HTPa" } }, { "cell_type": "markdown", "source": [ "Nyt voimme käyttää funktiota saadaksemme käsityksen kymmenestä suosituimmasta ainesosasta keittiöittäin. Kokeillaan sitä `thai_df`-datan kanssa.\n" ], "metadata": { "id": "h9794WF8HWmc" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Call create_ingredient and display popular ingredients\r\n", "thai_ingredient_df <- create_ingredient(df = thai_df)\r\n", "\r\n", "thai_ingredient_df %>% \r\n", " slice_head(n = 10)" ], "outputs": [], "metadata": { "id": "agQ-1HrcHaEA" } }, { "cell_type": "markdown", "source": [ "Edellisessä osiossa käytimme `geom_col()`, katsotaanpa, kuinka voit käyttää myös `geom_bar`-funktiota pylväskaavioiden luomiseen. Käytä `?geom_bar` lisälukemista varten.\n" ], "metadata": { "id": "kHu9ffGjHdcX" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Make a bar chart for popular thai cuisines\r\n", "thai_ingredient_df %>% \r\n", " slice_head(n = 10) %>% \r\n", " ggplot(aes(x = n_instances, y = ingredients)) +\r\n", " geom_bar(stat = \"identity\", width = 0.5, fill = \"steelblue\") +\r\n", " xlab(\"\") + ylab(\"\")" ], "outputs": [], "metadata": { "id": "fb3Bx_3DHj6e" } }, { "cell_type": "markdown", "source": [ "Tehdään sama japanilaisille tiedoille\n" ], "metadata": { "id": "RHP_xgdkHnvM" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Get popular ingredients for Japanese cuisines and make bar chart\r\n", "create_ingredient(df = japanese_df) %>% \r\n", " slice_head(n = 10) %>%\r\n", " ggplot(aes(x = n_instances, y = ingredients)) +\r\n", " geom_bar(stat = \"identity\", width = 0.5, fill = \"darkorange\", alpha = 0.8) +\r\n", " xlab(\"\") + ylab(\"\")\r\n" ], "outputs": [], "metadata": { "id": "019v8F0XHrRU" } }, { "cell_type": "markdown", "source": [ "Entä kiinalaiset keittiöt?\n" ], "metadata": { "id": "iIGM7vO8Hu3v" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Get popular ingredients for Chinese cuisines and make bar chart\r\n", "create_ingredient(df = chinese_df) %>% \r\n", " slice_head(n = 10) %>%\r\n", " ggplot(aes(x = n_instances, y = ingredients)) +\r\n", " geom_bar(stat = \"identity\", width = 0.5, fill = \"cyan4\", alpha = 0.8) +\r\n", " xlab(\"\") + ylab(\"\")" ], "outputs": [], "metadata": { "id": "lHd9_gd2HyzU" } }, { "cell_type": "markdown", "source": [], "metadata": { "id": "ir8qyQbNH1c7" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Get popular ingredients for Indian cuisines and make bar chart\r\n", "create_ingredient(df = indian_df) %>% \r\n", " slice_head(n = 10) %>%\r\n", " ggplot(aes(x = n_instances, y = ingredients)) +\r\n", " geom_bar(stat = \"identity\", width = 0.5, fill = \"#041E42FF\", alpha = 0.8) +\r\n", " xlab(\"\") + ylab(\"\")" ], "outputs": [], "metadata": { "id": "ApukQtKjH5FO" } }, { "cell_type": "markdown", "source": [ "Lopuksi, piirrä korealaiset ainesosat.\n" ], "metadata": { "id": "qv30cwY1H-FM" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Get popular ingredients for Korean cuisines and make bar chart\r\n", "create_ingredient(df = korean_df) %>% \r\n", " slice_head(n = 10) %>%\r\n", " ggplot(aes(x = n_instances, y = ingredients)) +\r\n", " geom_bar(stat = \"identity\", width = 0.5, fill = \"#852419FF\", alpha = 0.8) +\r\n", " xlab(\"\") + ylab(\"\")" ], "outputs": [], "metadata": { "id": "lumgk9cHIBie" } }, { "cell_type": "markdown", "source": [ "Tietovisualisointien perusteella voimme nyt poistaa yleisimmät ainesosat, jotka aiheuttavat sekaannusta eri keittiöiden välillä, käyttämällä `dplyr::select()`.\n", "\n", "Kaikki rakastavat riisiä, valkosipulia ja inkivääriä!\n" ], "metadata": { "id": "iO4veMXuIEta" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Drop id column, rice, garlic and ginger from our original data set\r\n", "df_select <- df %>% \r\n", " select(-c(1, rice, garlic, ginger))\r\n", "\r\n", "# Display new data set\r\n", "df_select %>% \r\n", " slice_head(n = 5)" ], "outputs": [], "metadata": { "id": "iHJPiG6rIUcK" } }, { "cell_type": "markdown", "source": [ "## Esikäsitellään dataa reseptien avulla 👩‍🍳👨‍🍳 - Epätasapainoisen datan käsittely ⚖️\n", "\n", "

\n", " \n", "

Taiteilija: @allison_horst
\n", "\n", "Koska tämä oppitunti käsittelee ruokia, meidän täytyy asettaa `reseptit` kontekstiin.\n", "\n", "Tidymodels tarjoaa jälleen yhden kätevän paketin: `recipes` - paketti datan esikäsittelyyn.\n" ], "metadata": { "id": "kkFd-JxdIaL6" } }, { "cell_type": "markdown", "source": [ "Katsotaanpa uudelleen keittiöidemme jakaumaa.\n" ], "metadata": { "id": "6l2ubtTPJAhY" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Distribution of cuisines\r\n", "old_label_count <- df_select %>% \r\n", " count(cuisine) %>% \r\n", " arrange(desc(n))\r\n", "\r\n", "old_label_count" ], "outputs": [], "metadata": { "id": "1e-E9cb7JDVi" } }, { "cell_type": "markdown", "source": [ "Kuten huomaat, keittiöiden lukumäärässä on melko epätasainen jakauma. Korealaisia keittiöitä on lähes kolme kertaa enemmän kuin thaimaalaisia keittiöitä. Epätasapainoinen data vaikuttaa usein negatiivisesti mallin suorituskykyyn. Mieti esimerkiksi binääriluokittelua. Jos suurin osa datasta kuuluu yhteen luokkaan, koneoppimismalli ennustaa todennäköisemmin juuri sitä luokkaa, yksinkertaisesti siksi, että sille on enemmän dataa. Datan tasapainottaminen korjaa vinoutuneen datan ja auttaa poistamaan tämän epätasapainon. Monet mallit toimivat parhaiten, kun havaintojen määrä on tasainen, ja siksi ne usein kamppailevat epätasapainoisen datan kanssa.\n", "\n", "Epätasapainoisten datajoukkojen käsittelyyn on pääasiassa kaksi tapaa:\n", "\n", "- havaintojen lisääminen vähemmistöluokkaan: `Yliotanta` esim. käyttämällä SMOTE-algoritmia\n", "\n", "- havaintojen poistaminen enemmistöluokasta: `Aliotanta`\n", "\n", "Näytetään nyt, kuinka epätasapainoisia datajoukkoja käsitellään käyttämällä `reseptiä`. Reseptiä voi ajatella suunnitelmana, joka kuvaa, mitä vaiheita datajoukolle tulisi soveltaa, jotta se olisi valmis data-analyysiin.\n" ], "metadata": { "id": "soAw6826JKx9" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Load themis package for dealing with imbalanced data\r\n", "library(themis)\r\n", "\r\n", "# Create a recipe for preprocessing data\r\n", "cuisines_recipe <- recipe(cuisine ~ ., data = df_select) %>% \r\n", " step_smote(cuisine)\r\n", "\r\n", "cuisines_recipe" ], "outputs": [], "metadata": { "id": "HS41brUIJVJy" } }, { "cell_type": "markdown", "source": [ "Käydään läpi esikäsittelyvaiheemme.\n", "\n", "- Kutsu `recipe()`-funktiolle kaavan kanssa määrittää muuttujien *roolit* käyttämällä `df_select`-datan viitteenä. Esimerkiksi `cuisine`-sarake on määritelty `outcome`-rooliin, kun taas muut sarakkeet on määritelty `predictor`-rooliin.\n", "\n", "- [`step_smote(cuisine)`](https://themis.tidymodels.org/reference/step_smote.html) luo reseptivaiheen *määrittelyn*, joka synteettisesti tuottaa uusia esimerkkejä vähemmistön luokasta käyttämällä näiden tapausten lähimpiä naapureita.\n", "\n", "Jos haluaisimme nyt tarkastella esikäsiteltyä dataa, meidän täytyisi [**`prep()`**](https://recipes.tidymodels.org/reference/prep.html) ja [**`bake()`**](https://recipes.tidymodels.org/reference/bake.html) reseptimme.\n", "\n", "`prep()`: arvioi tarvittavat parametrit harjoitusaineistosta, joita voidaan myöhemmin soveltaa muihin aineistoihin.\n", "\n", "`bake()`: ottaa esikäsitellyn reseptin ja soveltaa toimenpiteet mihin tahansa aineistoon.\n" ], "metadata": { "id": "Yb-7t7XcJaC8" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Prep and bake the recipe\r\n", "preprocessed_df <- cuisines_recipe %>% \r\n", " prep() %>% \r\n", " bake(new_data = NULL) %>% \r\n", " relocate(cuisine)\r\n", "\r\n", "# Display data\r\n", "preprocessed_df %>% \r\n", " slice_head(n = 5)\r\n", "\r\n", "# Quick summary stats\r\n", "preprocessed_df %>% \r\n", " introduce()" ], "outputs": [], "metadata": { "id": "9QhSgdpxJl44" } }, { "cell_type": "markdown", "source": [ "Tarkastellaan nyt keittiöidemme jakautumista ja verrataan niitä epätasapainoiseen dataan.\n" ], "metadata": { "id": "dmidELh_LdV7" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Distribution of cuisines\r\n", "new_label_count <- preprocessed_df %>% \r\n", " count(cuisine) %>% \r\n", " arrange(desc(n))\r\n", "\r\n", "list(new_label_count = new_label_count,\r\n", " old_label_count = old_label_count)" ], "outputs": [], "metadata": { "id": "aSh23klBLwDz" } }, { "cell_type": "markdown", "source": [ "Nam! Data on siistiä, tasapainoista ja erittäin herkullista 😋!\n", "\n", "> Yleensä reseptiä käytetään esiprosessorina mallinnusta varten, jossa se määrittelee, mitä vaiheita datajoukolle tulee soveltaa, jotta se olisi valmis mallinnukseen. Tällöin käytetään tyypillisesti `workflow()`-funktiota (kuten olemme jo nähneet aiemmilla tunneilla) sen sijaan, että resepti arvioitaisiin manuaalisesti.\n", ">\n", "> Näin ollen sinun ei yleensä tarvitse käyttää **`prep()`**- ja **`bake()`**-toimintoja reseptien kanssa, kun käytät tidymodels-kirjastoa, mutta ne ovat hyödyllisiä työkaluja varmistaaksesi, että reseptit toimivat odotetusti, kuten meidän tapauksessamme.\n", ">\n", "> Kun käytät **`bake()`**-toimintoa esivalmistellulle reseptille ja asetat **`new_data = NULL`**, saat takaisin datan, jonka annoit reseptin määrittelyvaiheessa, mutta siihen on sovellettu esiprosessointivaiheet.\n", "\n", "Tallennetaan nyt kopio tästä datasta tulevia tunteja varten:\n" ], "metadata": { "id": "HEu80HZ8L7ae" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Save preprocessed data\r\n", "write_csv(preprocessed_df, \"../../../data/cleaned_cuisines_R.csv\")" ], "outputs": [], "metadata": { "id": "cBmCbIgrMOI6" } }, { "cell_type": "markdown", "source": [ "Tämä uusi CSV-tiedosto löytyy nyt juurihakemiston data-kansiosta.\n", "\n", "**🚀Haaste**\n", "\n", "Tämä opintokokonaisuus sisältää useita mielenkiintoisia aineistoja. Tutki `data`-kansioita ja katso, sisältävätkö ne aineistoja, jotka sopisivat binaari- tai moniluokkaluokitteluun? Mitä kysymyksiä esittäisit tästä aineistosta?\n", "\n", "## [**Luennon jälkeinen kysely**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/20/)\n", "\n", "## **Kertaus & Itseopiskelu**\n", "\n", "- Tutustu [themis-pakettiin](https://github.com/tidymodels/themis). Mitä muita tekniikoita voisimme käyttää epätasapainoisen datan käsittelyyn?\n", "\n", "- Tidy models [viitesivusto](https://www.tidymodels.org/start/).\n", "\n", "- H. Wickham ja G. Grolemund, [*R for Data Science: Visualize, Model, Transform, Tidy, and Import Data*](https://r4ds.had.co.nz/).\n", "\n", "#### KIITOS:\n", "\n", "[`Allison Horst`](https://twitter.com/allison_horst/) upeista kuvituksista, jotka tekevät R:stä lähestyttävämmän ja innostavamman. Löydä 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", "[Cassie Breviu](https://www.twitter.com/cassieview) ja [Jen Looper](https://www.twitter.com/jenlooper) alkuperäisen Python-version luomisesta ♥️\n", "\n", "

\n", " \n", "

Taide: @allison_horst
\n" ], "metadata": { "id": "WQs5621pMGwf" } }, { "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). Pyrimme tarkkuuteen, mutta 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" ] } ] }