{ "nbformat": 4, "nbformat_minor": 2, "metadata": { "colab": { "name": "lesson_3-R.ipynb", "provenance": [], "collapsed_sections": [], "toc_visible": true }, "kernelspec": { "name": "ir", "display_name": "R" }, "language_info": { "name": "R" }, "coopTranslator": { "original_hash": "5015d65d61ba75a223bfc56c273aa174", "translation_date": "2025-09-06T13:14:27+00:00", "source_file": "2-Regression/3-Linear/solution/R/lesson_3-R.ipynb", "language_code": "sk" } }, "cells": [ { "cell_type": "markdown", "source": [], "metadata": { "id": "EgQw8osnsUV-" } }, { "cell_type": "markdown", "source": [ "## Lineárna a polynomiálna regresia pre stanovenie cien tekvíc - Lekcia 3\n", "

\n", " \n", "

Infografika od Dasani Madipalli
\n", "\n", "\n", "#### Úvod\n", "\n", "Doteraz ste preskúmali, čo je regresia, na základe vzorových údajov zo súboru údajov o cenách tekvíc, ktorý budeme používať počas celej tejto lekcie. Vizualizovali ste ju pomocou `ggplot2`.💪\n", "\n", "Teraz ste pripravení ponoriť sa hlbšie do regresie pre strojové učenie. V tejto lekcii sa dozviete viac o dvoch typoch regresie: *základná lineárna regresia* a *polynomiálna regresia*, spolu s niektorými matematickými základmi týchto techník.\n", "\n", "> Počas celého kurzu predpokladáme minimálne znalosti matematiky a snažíme sa ju sprístupniť študentom z iných oblastí, preto sledujte poznámky, 🧮 upozornenia, diagramy a ďalšie nástroje na učenie, ktoré vám pomôžu pochopiť.\n", "\n", "#### Príprava\n", "\n", "Pripomeňme si, že tieto údaje načítavate, aby ste si mohli klásť otázky.\n", "\n", "- Kedy je najlepší čas na kúpu tekvíc?\n", "\n", "- Akú cenu môžem očakávať za balenie miniatúrnych tekvíc?\n", "\n", "- Mal by som ich kúpiť v polovičných košoch alebo v krabici 1 1/9 bušlu? Poďme sa hlbšie ponoriť do týchto údajov.\n", "\n", "V predchádzajúcej lekcii ste vytvorili `tibble` (moderné prepracovanie dátového rámca) a naplnili ho časťou pôvodného súboru údajov, pričom ste štandardizovali ceny podľa bušlu. Týmto spôsobom ste však dokázali zhromaždiť iba približne 400 údajových bodov a iba pre jesenné mesiace. Možno môžeme získať trochu viac detailov o povahe údajov ich dôkladnejším čistením? Uvidíme... 🕵️‍♀️\n", "\n", "Pre túto úlohu budeme potrebovať nasledujúce balíky:\n", "\n", "- `tidyverse`: [tidyverse](https://www.tidyverse.org/) je [kolekcia balíkov pre R](https://www.tidyverse.org/packages), ktorá robí dátovú vedu rýchlejšou, jednoduchšou a zábavnejšou!\n", "\n", "- `tidymodels`: [tidymodels](https://www.tidymodels.org/) je [rámec balíkov](https://www.tidymodels.org/packages/) pre modelovanie a strojové učenie.\n", "\n", "- `janitor`: [janitor balík](https://github.com/sfirke/janitor) poskytuje jednoduché nástroje na skúmanie a čistenie špinavých údajov.\n", "\n", "- `corrplot`: [corrplot balík](https://cran.r-project.org/web/packages/corrplot/vignettes/corrplot-intro.html) poskytuje vizuálny prieskumný nástroj na korelačnú maticu, ktorý podporuje automatické preusporiadanie premenných na odhalenie skrytých vzorov medzi premennými.\n", "\n", "Môžete ich nainštalovať pomocou:\n", "\n", "`install.packages(c(\"tidyverse\", \"tidymodels\", \"janitor\", \"corrplot\"))`\n", "\n", "Nasledujúci skript skontroluje, či máte balíky potrebné na dokončenie tohto modulu, a v prípade ich absencie ich nainštaluje.\n" ], "metadata": { "id": "WqQPS1OAsg3H" } }, { "cell_type": "code", "execution_count": null, "source": [ "suppressWarnings(if (!require(\"pacman\")) install.packages(\"pacman\"))\n", "\n", "pacman::p_load(tidyverse, tidymodels, janitor, corrplot)" ], "outputs": [], "metadata": { "id": "tA4C2WN3skCf", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "c06cd805-5534-4edc-f72b-d0d1dab96ac0" } }, { "cell_type": "markdown", "source": [ "Neskôr načítame tieto skvelé balíčky a sprístupníme ich v našej aktuálnej R relácii. (Toto je len pre ilustráciu, `pacman::p_load()` to už za vás urobil)\n", "\n", "## 1. Lineárna regresná priamka\n", "\n", "Ako ste sa naučili v Lekcii 1, cieľom cvičenia s lineárnou regresiou je byť schopný vykresliť *priamku* *najlepšieho prispôsobenia*, aby sme:\n", "\n", "- **Ukázali vzťahy medzi premennými**. Zobraziť vzťah medzi premennými.\n", "\n", "- **Vytvárali predpovede**. Presne predpovedať, kde by nový dátový bod mohol spadnúť vo vzťahu k tejto priamke.\n", "\n", "Na vykreslenie tohto typu priamky používame štatistickú techniku nazývanú **Regresia najmenších štvorcov**. Termín `najmenšie štvorce` znamená, že všetky dátové body okolo regresnej priamky sú umocnené na druhú a potom sčítané. Ideálne je, aby tento konečný súčet bol čo najmenší, pretože chceme mať čo najmenej chýb, teda `najmenšie štvorce`. Preto je priamka najlepšieho prispôsobenia tá priamka, ktorá nám dáva najnižšiu hodnotu súčtu štvorcov chýb - odtiaľ názov *regresia najmenších štvorcov*.\n", "\n", "Robíme to preto, že chceme modelovať priamku, ktorá má najmenšiu kumulatívnu vzdialenosť od všetkých našich dátových bodov. Tiež umocňujeme hodnoty na druhú pred ich sčítaním, pretože nás zaujíma ich veľkosť, nie ich smer.\n", "\n", "> **🧮 Ukáž mi matematiku**\n", ">\n", "> Táto priamka, nazývaná *priamka najlepšieho prispôsobenia*, môže byť vyjadrená [rovnicou](https://en.wikipedia.org/wiki/Simple_linear_regression):\n", ">\n", "> Y = a + bX\n", ">\n", "> `X` je '`vysvetľujúca premenná` alebo `prediktor`'. `Y` je '`závislá premenná` alebo `výsledok`'. Sklon priamky je `b` a `a` je priesečník s osou y, ktorý označuje hodnotu `Y`, keď `X = 0`.\n", ">\n", "\n", "> ![](../../../../../../2-Regression/3-Linear/solution/images/slope.png \"sklon = $y/x$\")\n", " Infografika od Jen Looper\n", ">\n", "> Najprv vypočítajte sklon `b`.\n", ">\n", "> Inými slovami, a odkazujúc na pôvodnú otázku o údajoch o tekviciach: \"predpovedajte cenu tekvice za bušel podľa mesiaca\", `X` by označovalo cenu a `Y` by označovalo mesiac predaja.\n", ">\n", "> ![](../../../../../../2-Regression/3-Linear/solution/images/calculation.png)\n", " Infografika od Jen Looper\n", "> \n", "> Vypočítajte hodnotu Y. Ak platíte okolo 4 dolárov, musí byť apríl!\n", ">\n", "> Matematika, ktorá vypočíta priamku, musí ukázať sklon priamky, ktorý tiež závisí od priesečníka, teda od toho, kde sa `Y` nachádza, keď `X = 0`.\n", ">\n", "> Metódu výpočtu týchto hodnôt si môžete pozrieť na webovej stránke [Math is Fun](https://www.mathsisfun.com/data/least-squares-regression.html). Navštívte tiež [tento kalkulátor najmenších štvorcov](https://www.mathsisfun.com/data/least-squares-calculator.html), aby ste videli, ako hodnoty čísel ovplyvňujú priamku.\n", "\n", "Nie je to také strašidelné, však? 🤓\n", "\n", "#### Korelácia\n", "\n", "Ešte jeden pojem, ktorý treba pochopiť, je **Korelačný koeficient** medzi danými premennými X a Y. Pomocou bodového grafu môžete tento koeficient rýchlo vizualizovať. Graf s bodmi usporiadanými do úhľadnej priamky má vysokú koreláciu, ale graf s bodmi roztrúsenými všade medzi X a Y má nízku koreláciu.\n", "\n", "Dobrý model lineárnej regresie bude taký, ktorý má vysoký (bližší k 1 ako k 0) Korelačný koeficient, použitím metódy Regresie najmenších štvorcov s regresnou priamkou.\n" ], "metadata": { "id": "cdX5FRpvsoP5" } }, { "cell_type": "markdown", "source": [ "## **2. Tanec s dátami: vytvorenie dátového rámca na modelovanie**\n", "\n", "

\n", " \n", "

Ilustrácia od @allison_horst
\n", "\n", "\n", "\n" ], "metadata": { "id": "WdUKXk7Bs8-V" } }, { "cell_type": "markdown", "source": [ "Načítajte potrebné knižnice a dataset. Konvertujte údaje na dátový rámec obsahujúci podmnožinu údajov:\n", "\n", "- Získajte iba tekvice ocenené na základe ceny za bušel\n", "\n", "- Konvertujte dátum na mesiac\n", "\n", "- Vypočítajte cenu ako priemer vysokých a nízkych cien\n", "\n", "- Konvertujte cenu tak, aby odrážala cenu za množstvo v bušeloch\n", "\n", "> Tieto kroky sme pokryli v [predchádzajúcej lekcii](https://github.com/microsoft/ML-For-Beginners/blob/main/2-Regression/2-Data/solution/lesson_2-R.ipynb).\n" ], "metadata": { "id": "fMCtu2G2s-p8" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Load the core Tidyverse packages\n", "library(tidyverse)\n", "library(lubridate)\n", "\n", "# Import the pumpkins data\n", "pumpkins <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/2-Regression/data/US-pumpkins.csv\")\n", "\n", "\n", "# Get a glimpse and dimensions of the data\n", "glimpse(pumpkins)\n", "\n", "\n", "# Print the first 50 rows of the data set\n", "pumpkins %>% \n", " slice_head(n = 5)" ], "outputs": [], "metadata": { "id": "ryMVZEEPtERn" } }, { "cell_type": "markdown", "source": [ "V duchu čírej dobrodružnosti sa poďme pozrieť na [`janitor package`](../../../../../../2-Regression/3-Linear/solution/R/github.com/sfirke/janitor), ktorý poskytuje jednoduché funkcie na skúmanie a čistenie nečistých údajov. Napríklad sa pozrime na názvy stĺpcov našich údajov:\n" ], "metadata": { "id": "xcNxM70EtJjb" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Return column names\n", "pumpkins %>% \n", " names()" ], "outputs": [], "metadata": { "id": "5XtpaIigtPfW" } }, { "cell_type": "markdown", "source": [ "🤔 Môžeme to urobiť lepšie. Poďme zmeniť názvy týchto stĺpcov na `friendR` konvertovaním na konvenciu [snake_case](https://en.wikipedia.org/wiki/Snake_case) pomocou `janitor::clean_names`. Ak sa chcete dozvedieť viac o tejto funkcii: `?clean_names`\n" ], "metadata": { "id": "IbIqrMINtSHe" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Clean names to the snake_case convention\n", "pumpkins <- pumpkins %>% \n", " clean_names(case = \"snake\")\n", "\n", "# Return column names\n", "pumpkins %>% \n", " names()" ], "outputs": [], "metadata": { "id": "a2uYvclYtWvX" } }, { "cell_type": "markdown", "source": [ "Veľa poriadku s tidyR 🧹! Teraz si zatancujeme s dátami pomocou `dplyr`, ako v predchádzajúcej lekcii! 💃\n" ], "metadata": { "id": "HfhnuzDDtaDd" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Select desired columns\n", "pumpkins <- pumpkins %>% \n", " select(variety, city_name, package, low_price, high_price, date)\n", "\n", "\n", "\n", "# Extract the month from the dates to a new column\n", "pumpkins <- pumpkins %>%\n", " mutate(date = mdy(date),\n", " month = month(date)) %>% \n", " select(-date)\n", "\n", "\n", "\n", "# Create a new column for average Price\n", "pumpkins <- pumpkins %>% \n", " mutate(price = (low_price + high_price)/2)\n", "\n", "\n", "# Retain only pumpkins with the string \"bushel\"\n", "new_pumpkins <- pumpkins %>% \n", " filter(str_detect(string = package, pattern = \"bushel\"))\n", "\n", "\n", "# Normalize the pricing so that you show the pricing per bushel, not per 1 1/9 or 1/2 bushel\n", "new_pumpkins <- new_pumpkins %>% \n", " mutate(price = case_when(\n", " str_detect(package, \"1 1/9\") ~ price/(1.1),\n", " str_detect(package, \"1/2\") ~ price*2,\n", " TRUE ~ price))\n", "\n", "# Relocate column positions\n", "new_pumpkins <- new_pumpkins %>% \n", " relocate(month, .before = variety)\n", "\n", "\n", "# Display the first 5 rows\n", "new_pumpkins %>% \n", " slice_head(n = 5)" ], "outputs": [], "metadata": { "id": "X0wU3gQvtd9f" } }, { "cell_type": "markdown", "source": [ "Dobrá práca!👌 Teraz máte čistý a uprataný dátový súbor, na ktorom môžete postaviť svoj nový regresný model!\n", "\n", "Čo tak rozptylový graf?\n" ], "metadata": { "id": "UpaIwaxqth82" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Set theme\n", "theme_set(theme_light())\n", "\n", "# Make a scatter plot of month and price\n", "new_pumpkins %>% \n", " ggplot(mapping = aes(x = month, y = price)) +\n", " geom_point(size = 1.6)\n" ], "outputs": [], "metadata": { "id": "DXgU-j37tl5K" } }, { "cell_type": "markdown", "source": [ "Bodový graf nám pripomína, že máme údaje za mesiace iba od augusta do decembra. Pravdepodobne potrebujeme viac údajov, aby sme mohli vyvodiť závery lineárnym spôsobom.\n", "\n", "Pozrime sa znova na naše modelovacie údaje:\n" ], "metadata": { "id": "Ve64wVbwtobI" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Display first 5 rows\n", "new_pumpkins %>% \n", " slice_head(n = 5)" ], "outputs": [], "metadata": { "id": "HFQX2ng1tuSJ" } }, { "cell_type": "markdown", "source": [ "Čo ak by sme chceli predpovedať `cenu` tekvice na základe stĺpcov `mesto` alebo `balenie`, ktoré sú typu znakový reťazec? Alebo ešte jednoduchšie, ako by sme mohli nájsť koreláciu (ktorá vyžaduje, aby oba vstupy boli numerické) medzi, povedzme, `balenie` a `cena`? 🤷🤷\n", "\n", "Modely strojového učenia fungujú najlepšie s numerickými vlastnosťami namiesto textových hodnôt, takže vo všeobecnosti je potrebné previesť kategóriálne vlastnosti na numerické reprezentácie.\n", "\n", "To znamená, že musíme nájsť spôsob, ako upraviť naše prediktory, aby ich model mohol efektívne používať, proces známy ako `inžinierstvo vlastností`.\n" ], "metadata": { "id": "7hsHoxsStyjJ" } }, { "cell_type": "markdown", "source": [ "## 3. Predspracovanie údajov na modelovanie pomocou receptov 👩‍🍳👨‍🍳\n", "\n", "Aktivity, ktoré upravujú hodnoty prediktorov, aby ich model mohol efektívne využívať, sa nazývajú `inžinierstvo vlastností`.\n", "\n", "Rôzne modely majú rôzne požiadavky na predspracovanie. Napríklad metóda najmenších štvorcov vyžaduje `kódovanie kategóriálnych premenných`, ako sú mesiac, odroda a city_name. To jednoducho zahŕňa `preklad` stĺpca s `kategóriálnymi hodnotami` na jeden alebo viac `numerických stĺpcov`, ktoré nahradia pôvodný.\n", "\n", "Napríklad, predpokladajme, že vaše údaje obsahujú nasledujúcu kategóriálnu vlastnosť:\n", "\n", "| mesto |\n", "|:--------:|\n", "| Denver |\n", "| Nairobi |\n", "| Tokio |\n", "\n", "Môžete použiť *ordinálne kódovanie*, aby ste nahradili každú kategóriu jedinečnou celočíselnou hodnotou, napríklad takto:\n", "\n", "| mesto |\n", "|:-----:|\n", "| 0 |\n", "| 1 |\n", "| 2 |\n", "\n", "A presne to urobíme s našimi údajmi!\n", "\n", "V tejto časti preskúmame ďalší úžasný balík Tidymodels: [recipes](https://tidymodels.github.io/recipes/) - ktorý je navrhnutý tak, aby vám pomohol predspracovať vaše údaje **predtým**, než začnete trénovať váš model. V jadre receptu je objekt, ktorý definuje, aké kroky by sa mali aplikovať na dátovú množinu, aby bola pripravená na modelovanie.\n", "\n", "Teraz si vytvoríme recept, ktorý pripraví naše údaje na modelovanie tým, že nahradí jedinečné celé číslo za všetky pozorovania v stĺpcoch prediktorov:\n" ], "metadata": { "id": "AD5kQbcvt3Xl" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Specify a recipe\n", "pumpkins_recipe <- recipe(price ~ ., data = new_pumpkins) %>% \n", " step_integer(all_predictors(), zero_based = TRUE)\n", "\n", "\n", "# Print out the recipe\n", "pumpkins_recipe" ], "outputs": [], "metadata": { "id": "BNaFKXfRt9TU" } }, { "cell_type": "markdown", "source": [ "Úžasné! 👏 Práve sme vytvorili náš prvý recept, ktorý špecifikuje výsledok (cenu) a jeho zodpovedajúce prediktory, pričom všetky stĺpce prediktorov by mali byť zakódované ako sada celých čísel 🙌! Poďme si to rýchlo rozobrať:\n", "\n", "- Volanie `recipe()` s formulou určuje receptu *úlohy* premenných pomocou údajov `new_pumpkins` ako referencie. Napríklad stĺpec `price` bol priradený úlohe `outcome`, zatiaľ čo ostatné stĺpce boli priradené úlohe `predictor`.\n", "\n", "- `step_integer(all_predictors(), zero_based = TRUE)` špecifikuje, že všetky prediktory by mali byť konvertované na sadu celých čísel, pričom číslovanie začína od 0.\n", "\n", "Sme si istí, že vás možno napadli myšlienky ako: \"Toto je tak super!! Ale čo ak by som potreboval potvrdiť, že recepty robia presne to, čo od nich očakávam? 🤔\"\n", "\n", "To je skvelá myšlienka! Vidíte, keď je váš recept definovaný, môžete odhadnúť parametre potrebné na skutočné predspracovanie údajov a potom extrahovať spracované údaje. Zvyčajne to nemusíte robiť, keď používate Tidymodels (o chvíľu uvidíme bežnú konvenciu -> `workflows`), ale môže to byť užitočné, keď chcete vykonať určitú kontrolu správnosti, aby ste si potvrdili, že recepty robia to, čo očakávate.\n", "\n", "Na to budete potrebovať ďalšie dva príkazy: `prep()` a `bake()`, a ako vždy, naši malí R kamaráti od [`Allison Horst`](https://github.com/allisonhorst/stats-illustrations) vám pomôžu lepšie pochopiť túto tému!\n", "\n", "

\n", " \n", "

Ilustrácia od @allison_horst
\n" ], "metadata": { "id": "KEiO0v7kuC9O" } }, { "cell_type": "markdown", "source": [ "[`prep()`](https://recipes.tidymodels.org/reference/prep.html): odhaduje potrebné parametre z tréningovej množiny, ktoré môžu byť neskôr aplikované na iné dátové množiny. Napríklad, pre daný stĺpec prediktora, ktorá hodnota bude priradená ako celé číslo 0, 1, 2 atď.\n", "\n", "[`bake()`](https://recipes.tidymodels.org/reference/bake.html): vezme pripravený recept a aplikuje operácie na akúkoľvek dátovú množinu.\n", "\n", "Takže, poďme pripraviť a aplikovať naše recepty, aby sme naozaj potvrdili, že v pozadí budú stĺpce prediktorov najskôr zakódované pred tým, ako sa model prispôsobí.\n" ], "metadata": { "id": "Q1xtzebuuTCP" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Prep the recipe\n", "pumpkins_prep <- prep(pumpkins_recipe)\n", "\n", "# Bake the recipe to extract a preprocessed new_pumpkins data\n", "baked_pumpkins <- bake(pumpkins_prep, new_data = NULL)\n", "\n", "# Print out the baked data set\n", "baked_pumpkins %>% \n", " slice_head(n = 10)" ], "outputs": [], "metadata": { "id": "FGBbJbP_uUUn" } }, { "cell_type": "markdown", "source": [ "Hurá! 🥳 Spracované dáta `baked_pumpkins` majú všetky svoje prediktory zakódované, čo potvrdzuje, že kroky predspracovania definované ako náš recept fungujú podľa očakávania. Pre vás to môže byť ťažšie na čítanie, ale pre Tidymodels je to oveľa zrozumiteľnejšie! Nájdite si chvíľu na zistenie, ktorá pozorovaná hodnota bola namapovaná na zodpovedajúce celé číslo.\n", "\n", "Stojí tiež za zmienku, že `baked_pumpkins` je dátový rámec, na ktorom môžeme vykonávať výpočty.\n", "\n", "Napríklad, poďme sa pokúsiť nájsť dobrú koreláciu medzi dvoma bodmi vašich dát, aby sme potenciálne vytvorili dobrý prediktívny model. Na to použijeme funkciu `cor()`. Napíšte `?cor()`, aby ste sa dozvedeli viac o tejto funkcii.\n" ], "metadata": { "id": "1dvP0LBUueAW" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Find the correlation between the city_name and the price\n", "cor(baked_pumpkins$city_name, baked_pumpkins$price)\n", "\n", "# Find the correlation between the package and the price\n", "cor(baked_pumpkins$package, baked_pumpkins$price)\n" ], "outputs": [], "metadata": { "id": "3bQzXCjFuiSV" } }, { "cell_type": "markdown", "source": [ "Ako sa ukazuje, medzi mestom a cenou existuje iba slabá korelácia. Avšak medzi balíkom a jeho cenou je o niečo lepšia korelácia. To dáva zmysel, však? Zvyčajne platí, že čím väčšia je krabica s produktmi, tým vyššia je cena.\n", "\n", "Keď už sme pri tom, poďme sa pokúsiť vizualizovať korelačnú maticu všetkých stĺpcov pomocou balíka `corrplot`.\n" ], "metadata": { "id": "BToPWbgjuoZw" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Load the corrplot package\n", "library(corrplot)\n", "\n", "# Obtain correlation matrix\n", "corr_mat <- cor(baked_pumpkins %>% \n", " # Drop columns that are not really informative\n", " select(-c(low_price, high_price)))\n", "\n", "# Make a correlation plot between the variables\n", "corrplot(corr_mat, method = \"shade\", shade.col = NA, tl.col = \"black\", tl.srt = 45, addCoef.col = \"black\", cl.pos = \"n\", order = \"original\")" ], "outputs": [], "metadata": { "id": "ZwAL3ksmutVR" } }, { "cell_type": "markdown", "source": [ "🤩🤩 Oveľa lepšie.\n", "\n", "Dobrá otázka, ktorú si teraz môžeme položiť na základe týchto údajov, je: '`Akú cenu môžem očakávať za daný balík tekvíc?`' Poďme na to!\n", "\n", "> Poznámka: Keď **`bake()`** použijete na pripravený recept **`pumpkins_prep`** s **`new_data = NULL`**, získate spracované (t.j. zakódované) tréningové dáta. Ak by ste mali iný súbor údajov, napríklad testovaciu množinu, a chceli by ste vidieť, ako by recept tieto údaje predspracoval, jednoducho by ste použili **`bake()`** na **`pumpkins_prep`** s **`new_data = test_set`**.\n", "\n", "## 4. Vytvorenie lineárneho regresného modelu\n", "\n", "

\n", " \n", "

Infografika od Dasani Madipalli
\n" ], "metadata": { "id": "YqXjLuWavNxW" } }, { "cell_type": "markdown", "source": [ "Teraz, keď sme vytvorili recept a skutočne potvrdili, že údaje budú správne predspracované, poďme vytvoriť regresný model, aby sme odpovedali na otázku: `Akú cenu môžem očakávať za dané balenie tekvice?`\n", "\n", "#### Natrénujte lineárny regresný model pomocou tréningovej množiny\n", "\n", "Ako ste už pravdepodobne zistili, stĺpec *price* je `výsledná` premenná, zatiaľ čo stĺpec *package* je `prediktorová` premenná.\n", "\n", "Na to najskôr rozdelíme údaje tak, že 80 % pôjde do tréningovej množiny a 20 % do testovacej množiny, potom definujeme recept, ktorý zakóduje stĺpec prediktora do množiny celých čísel, a následne vytvoríme špecifikáciu modelu. Recept nebudeme pripravovať a piecť, pretože už vieme, že údaje predspracuje podľa očakávania.\n" ], "metadata": { "id": "Pq0bSzCevW-h" } }, { "cell_type": "code", "execution_count": null, "source": [ "set.seed(2056)\n", "# Split the data into training and test sets\n", "pumpkins_split <- new_pumpkins %>% \n", " initial_split(prop = 0.8)\n", "\n", "\n", "# Extract training and test data\n", "pumpkins_train <- training(pumpkins_split)\n", "pumpkins_test <- testing(pumpkins_split)\n", "\n", "\n", "\n", "# Create a recipe for preprocessing the data\n", "lm_pumpkins_recipe <- recipe(price ~ package, data = pumpkins_train) %>% \n", " step_integer(all_predictors(), zero_based = TRUE)\n", "\n", "\n", "\n", "# Create a linear model specification\n", "lm_spec <- linear_reg() %>% \n", " set_engine(\"lm\") %>% \n", " set_mode(\"regression\")" ], "outputs": [], "metadata": { "id": "CyoEh_wuvcLv" } }, { "cell_type": "markdown", "source": [ "Skvelá práca! Teraz, keď máme recept a špecifikáciu modelu, musíme nájsť spôsob, ako ich spojiť do objektu, ktorý najprv predspracuje dáta (v zákulisí prep+bake), natrénuje model na predspracovaných dátach a zároveň umožní aj prípadné aktivity po spracovaní. Čo poviete na takýto pokoj na duši!🤩\n", "\n", "V Tidymodels sa tento praktický objekt nazýva [`workflow`](https://workflows.tidymodels.org/) a pohodlne uchováva vaše modelovacie komponenty! Toto by sme v *Python-e* nazvali *pipelines*.\n", "\n", "Tak poďme všetko zabaliť do workflow!📦\n" ], "metadata": { "id": "G3zF_3DqviFJ" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Hold modelling components in a workflow\n", "lm_wf <- workflow() %>% \n", " add_recipe(lm_pumpkins_recipe) %>% \n", " add_model(lm_spec)\n", "\n", "# Print out the workflow\n", "lm_wf" ], "outputs": [], "metadata": { "id": "T3olroU3v-WX" } }, { "cell_type": "markdown", "source": [ "👌 Navyše, pracovný postup môže byť prispôsobený/vytrénovaný podobne ako model.\n" ], "metadata": { "id": "zd1A5tgOwEPX" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Train the model\n", "lm_wf_fit <- lm_wf %>% \n", " fit(data = pumpkins_train)\n", "\n", "# Print the model coefficients learned \n", "lm_wf_fit" ], "outputs": [], "metadata": { "id": "NhJagFumwFHf" } }, { "cell_type": "markdown", "source": [ "Z výstupu modelu môžeme vidieť koeficienty naučené počas tréningu. Predstavujú koeficienty priamky najlepšieho prispôsobenia, ktorá nám poskytuje najnižšiu celkovú chybu medzi skutočnou a predpovedanou premennou.\n", "\n", "#### Vyhodnotenie výkonu modelu pomocou testovacej množiny\n", "\n", "Je čas zistiť, ako si model viedol 📏! Ako to urobíme?\n", "\n", "Teraz, keď sme model natrénovali, môžeme ho použiť na predpovede pre testovaciu množinu pomocou `parsnip::predict()`. Potom môžeme tieto predpovede porovnať so skutočnými hodnotami štítkov, aby sme zhodnotili, ako dobre (alebo nie!) model funguje.\n", "\n", "Začnime vytváraním predpovedí pre testovaciu množinu a následným pripojením stĺpcov k testovacej množine.\n" ], "metadata": { "id": "_4QkGtBTwItF" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Make predictions for the test set\n", "predictions <- lm_wf_fit %>% \n", " predict(new_data = pumpkins_test)\n", "\n", "\n", "# Bind predictions to the test set\n", "lm_results <- pumpkins_test %>% \n", " select(c(package, price)) %>% \n", " bind_cols(predictions)\n", "\n", "\n", "# Print the first ten rows of the tibble\n", "lm_results %>% \n", " slice_head(n = 10)" ], "outputs": [], "metadata": { "id": "UFZzTG0gwTs9" } }, { "cell_type": "markdown", "source": [ "Áno, práve ste natrénovali model a použili ho na predikcie!🔮 Je dobrý? Poďme vyhodnotiť výkon modelu!\n", "\n", "V Tidymodels to robíme pomocou `yardstick::metrics()`! Pre lineárnu regresiu sa zamerajme na nasledujúce metriky:\n", "\n", "- `Root Mean Square Error (RMSE)`: Odmocnina z [MSE](https://en.wikipedia.org/wiki/Mean_squared_error). Poskytuje absolútnu metriku v rovnakých jednotkách ako cieľová hodnota (v tomto prípade cena tekvice). Čím menšia hodnota, tým lepší model (v jednoduchom zmysle predstavuje priemernú cenu, o ktorú sa predikcie mýlia!).\n", "\n", "- `Coefficient of Determination (zvyčajne známy ako R-squared alebo R2)`: Relatívna metrika, pri ktorej vyššia hodnota znamená lepšie prispôsobenie modelu. V podstate táto metrika reprezentuje, koľko variability medzi predikovanými a skutočnými hodnotami cieľovej premenné dokáže model vysvetliť.\n" ], "metadata": { "id": "0A5MjzM7wW9M" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Evaluate performance of linear regression\n", "metrics(data = lm_results,\n", " truth = price,\n", " estimate = .pred)" ], "outputs": [], "metadata": { "id": "reJ0UIhQwcEH" } }, { "cell_type": "markdown", "source": [ "Tam ide výkon modelu. Pozrime sa, či môžeme získať lepšiu predstavu vizualizáciou bodového grafu balíka a ceny, a potom použijeme predpovede na prekrytie najlepšej prispôsobenej čiary.\n", "\n", "To znamená, že budeme musieť pripraviť a spracovať testovaciu množinu, aby sme zakódovali stĺpec balíka, a potom to spojiť s predpoveďami vytvorenými naším modelom.\n" ], "metadata": { "id": "fdgjzjkBwfWt" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Encode package column\n", "package_encode <- lm_pumpkins_recipe %>% \n", " prep() %>% \n", " bake(new_data = pumpkins_test) %>% \n", " select(package)\n", "\n", "\n", "# Bind encoded package column to the results\n", "lm_results <- lm_results %>% \n", " bind_cols(package_encode %>% \n", " rename(package_integer = package)) %>% \n", " relocate(package_integer, .after = package)\n", "\n", "\n", "# Print new results data frame\n", "lm_results %>% \n", " slice_head(n = 5)\n", "\n", "\n", "# Make a scatter plot\n", "lm_results %>% \n", " ggplot(mapping = aes(x = package_integer, y = price)) +\n", " geom_point(size = 1.6) +\n", " # Overlay a line of best fit\n", " geom_line(aes(y = .pred), color = \"orange\", size = 1.2) +\n", " xlab(\"package\")\n", " \n" ], "outputs": [], "metadata": { "id": "R0nw719lwkHE" } }, { "cell_type": "markdown", "source": [ "Skvelé! Ako môžete vidieť, lineárny regresný model nedokáže veľmi dobre generalizovať vzťah medzi balíkom a jeho zodpovedajúcou cenou.\n", "\n", "🎃 Gratulujeme, práve ste vytvorili model, ktorý dokáže predpovedať cenu niekoľkých druhov tekvíc. Vaša sviatočná tekvicová záhrada bude nádherná. Ale pravdepodobne dokážete vytvoriť ešte lepší model!\n", "\n", "## 5. Vytvorte polynomiálny regresný model\n", "\n", "

\n", " \n", "

Infografika od Dasani Madipalli
\n", "\n", "\n", "\n" ], "metadata": { "id": "HOCqJXLTwtWI" } }, { "cell_type": "markdown", "source": [ "Niekedy naše údaje nemusia mať lineárny vzťah, no aj tak chceme predpovedať výsledok. Polynomická regresia nám môže pomôcť robiť predpovede pre zložitejšie nelineárne vzťahy.\n", "\n", "Vezmime si napríklad vzťah medzi balením a cenou v našej dátovej sade tekvíc. Zatiaľ čo niekedy existuje lineárny vzťah medzi premennými – čím väčší objem tekvice, tým vyššia cena – niekedy tieto vzťahy nemožno znázorniť ako rovinu alebo priamku.\n", "\n", "> ✅ Tu sú [ďalšie príklady](https://online.stat.psu.edu/stat501/lesson/9/9.8) údajov, ktoré by mohli využiť polynomickú regresiu\n", ">\n", "> Pozrite sa znova na vzťah medzi odrodou a cenou v predchádzajúcom grafe. Zdá sa, že by tento bodový graf mal byť nevyhnutne analyzovaný priamkou? Možno nie. V tomto prípade môžete vyskúšať polynomickú regresiu.\n", ">\n", "> ✅ Polynómy sú matematické výrazy, ktoré môžu pozostávať z jednej alebo viacerých premenných a koeficientov\n", "\n", "#### Natrénujte model polynomickej regresie pomocou tréningovej množiny\n", "\n", "Polynomická regresia vytvára *zakrivenú čiaru*, ktorá lepšie zodpovedá nelineárnym údajom.\n", "\n", "Pozrime sa, či polynomický model bude lepší pri predpovedaní. Budeme postupovať podobným spôsobom ako predtým:\n", "\n", "- Vytvorte recept, ktorý špecifikuje kroky predspracovania, ktoré by sa mali vykonať na našich údajoch, aby boli pripravené na modelovanie, t. j.: kódovanie prediktorov a výpočet polynómov stupňa *n*\n", "\n", "- Vytvorte špecifikáciu modelu\n", "\n", "- Spojte recept a špecifikáciu modelu do pracovného postupu\n", "\n", "- Vytvorte model prispôsobením pracovného postupu\n", "\n", "- Vyhodnoťte, ako dobre model funguje na testovacích údajoch\n", "\n", "Poďme na to!\n" ], "metadata": { "id": "VcEIpRV9wzYr" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Specify a recipe\r\n", "poly_pumpkins_recipe <-\r\n", " recipe(price ~ package, data = pumpkins_train) %>%\r\n", " step_integer(all_predictors(), zero_based = TRUE) %>% \r\n", " step_poly(all_predictors(), degree = 4)\r\n", "\r\n", "\r\n", "# Create a model specification\r\n", "poly_spec <- linear_reg() %>% \r\n", " set_engine(\"lm\") %>% \r\n", " set_mode(\"regression\")\r\n", "\r\n", "\r\n", "# Bundle recipe and model spec into a workflow\r\n", "poly_wf <- workflow() %>% \r\n", " add_recipe(poly_pumpkins_recipe) %>% \r\n", " add_model(poly_spec)\r\n", "\r\n", "\r\n", "# Create a model\r\n", "poly_wf_fit <- poly_wf %>% \r\n", " fit(data = pumpkins_train)\r\n", "\r\n", "\r\n", "# Print learned model coefficients\r\n", "poly_wf_fit\r\n", "\r\n", " " ], "outputs": [], "metadata": { "id": "63n_YyRXw3CC" } }, { "cell_type": "markdown", "source": [ "#### Vyhodnotenie výkonu modelu\n", "\n", "👏👏Vytvorili ste polynomiálny model, poďme urobiť predpovede na testovacej množine!\n" ], "metadata": { "id": "-LHZtztSxDP0" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Make price predictions on test data\r\n", "poly_results <- poly_wf_fit %>% predict(new_data = pumpkins_test) %>% \r\n", " bind_cols(pumpkins_test %>% select(c(package, price))) %>% \r\n", " relocate(.pred, .after = last_col())\r\n", "\r\n", "\r\n", "# Print the results\r\n", "poly_results %>% \r\n", " slice_head(n = 10)" ], "outputs": [], "metadata": { "id": "YUFpQ_dKxJGx" } }, { "cell_type": "markdown", "source": [ "Hurá, poďme vyhodnotiť, ako model fungoval na testovacej množine pomocou `yardstick::metrics()`.\n" ], "metadata": { "id": "qxdyj86bxNGZ" } }, { "cell_type": "code", "execution_count": null, "source": [ "metrics(data = poly_results, truth = price, estimate = .pred)" ], "outputs": [], "metadata": { "id": "8AW5ltkBxXDm" } }, { "cell_type": "markdown", "source": [ "🤩🤩 Oveľa lepší výkon.\n", "\n", "`rmse` kleslo z približne 7 na približne 3, čo naznačuje zníženie chyby medzi skutočnou cenou a predpovedanou cenou. Môžete to *voľne* interpretovať tak, že nesprávne predpovede sú v priemere nesprávne o približne 3 $. `rsq` sa zvýšilo z približne 0,4 na 0,8.\n", "\n", "Všetky tieto metriky naznačujú, že polynomiálny model funguje oveľa lepšie ako lineárny model. Skvelá práca!\n", "\n", "Pozrime sa, či to dokážeme vizualizovať!\n" ], "metadata": { "id": "6gLHNZDwxYaS" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Bind encoded package column to the results\r\n", "poly_results <- poly_results %>% \r\n", " bind_cols(package_encode %>% \r\n", " rename(package_integer = package)) %>% \r\n", " relocate(package_integer, .after = package)\r\n", "\r\n", "\r\n", "# Print new results data frame\r\n", "poly_results %>% \r\n", " slice_head(n = 5)\r\n", "\r\n", "\r\n", "# Make a scatter plot\r\n", "poly_results %>% \r\n", " ggplot(mapping = aes(x = package_integer, y = price)) +\r\n", " geom_point(size = 1.6) +\r\n", " # Overlay a line of best fit\r\n", " geom_line(aes(y = .pred), color = \"midnightblue\", size = 1.2) +\r\n", " xlab(\"package\")\r\n" ], "outputs": [], "metadata": { "id": "A83U16frxdF1" } }, { "cell_type": "markdown", "source": [ "Môžete vidieť zakrivenú čiaru, ktorá lepšie zodpovedá vašim údajom! 🤩\n", "\n", "Môžete ju urobiť ešte plynulejšou tým, že do `geom_smooth` zadáte polynomiálny vzorec, napríklad takto:\n" ], "metadata": { "id": "4U-7aHOVxlGU" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Make a scatter plot\r\n", "poly_results %>% \r\n", " ggplot(mapping = aes(x = package_integer, y = price)) +\r\n", " geom_point(size = 1.6) +\r\n", " # Overlay a line of best fit\r\n", " geom_smooth(method = lm, formula = y ~ poly(x, degree = 4), color = \"midnightblue\", size = 1.2, se = FALSE) +\r\n", " xlab(\"package\")" ], "outputs": [], "metadata": { "id": "5vzNT0Uexm-w" } }, { "cell_type": "markdown", "source": [ "Podobne ako hladká krivka!🤩\n", "\n", "Tu je postup, ako vytvoriť novú predikciu:\n" ], "metadata": { "id": "v9u-wwyLxq4G" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Make a hypothetical data frame\r\n", "hypo_tibble <- tibble(package = \"bushel baskets\")\r\n", "\r\n", "# Make predictions using linear model\r\n", "lm_pred <- lm_wf_fit %>% predict(new_data = hypo_tibble)\r\n", "\r\n", "# Make predictions using polynomial model\r\n", "poly_pred <- poly_wf_fit %>% predict(new_data = hypo_tibble)\r\n", "\r\n", "# Return predictions in a list\r\n", "list(\"linear model prediction\" = lm_pred, \r\n", " \"polynomial model prediction\" = poly_pred)\r\n" ], "outputs": [], "metadata": { "id": "jRPSyfQGxuQv" } }, { "cell_type": "markdown", "source": [ "Predikcia pomocou `polynomial model` dáva zmysel, vzhľadom na bodové grafy `price` a `package`! A ak je tento model lepší ako ten predchádzajúci, pri pohľade na tie isté údaje, budete musieť plánovať rozpočet na tieto drahšie tekvice!\n", "\n", "🏆 Skvelá práca! Vytvorili ste dva regresné modely v jednej lekcii. V poslednej časti o regresii sa naučíte o logistickej regresii na určenie kategórií.\n", "\n", "## **🚀Výzva**\n", "\n", "Otestujte niekoľko rôznych premenných v tomto notebooku, aby ste zistili, ako korelácia súvisí s presnosťou modelu.\n", "\n", "## [**Kvíz po prednáške**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/14/)\n", "\n", "## **Prehľad & Samoštúdium**\n", "\n", "V tejto lekcii sme sa naučili o lineárnej regresii. Existujú aj iné dôležité typy regresie. Prečítajte si o technikách Stepwise, Ridge, Lasso a Elasticnet. Dobrou možnosťou na štúdium je [Stanford Statistical Learning course](https://online.stanford.edu/courses/sohs-ystatslearning-statistical-learning).\n", "\n", "Ak sa chcete dozvedieť viac o používaní úžasného frameworku Tidymodels, pozrite si nasledujúce zdroje:\n", "\n", "- Webová stránka Tidymodels: [Začnite s Tidymodels](https://www.tidymodels.org/start/)\n", "\n", "- Max Kuhn a Julia Silge, [*Tidy Modeling with R*](https://www.tmwr.org/)*.*\n", "\n", "###### **ĎAKUJEME:**\n", "\n", "[Allison Horst](https://twitter.com/allison_horst?lang=en) za vytvorenie úžasných ilustrácií, ktoré robia R prístupnejším a zábavnejším. Viac ilustrácií nájdete v jej [galérii](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n" ], "metadata": { "id": "8zOLOWqMxzk5" } }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n---\n\n**Upozornenie**: \nTento dokument bol preložený pomocou služby na automatický preklad [Co-op Translator](https://github.com/Azure/co-op-translator). Aj keď sa snažíme o presnosť, upozorňujeme, že automatické preklady môžu obsahovať chyby alebo nepresnosti. Pôvodný dokument v jeho pôvodnom jazyku by mal byť považovaný za autoritatívny zdroj. Pre dôležité informácie sa odporúča profesionálny ľudský preklad. Nezodpovedáme za akékoľvek nedorozumenia alebo nesprávne interpretácie vyplývajúce z použitia tohto prekladu.\n" ] } ] }