🌐 Update translations via Co-op Translator

pull/866/head
leestott 1 month ago committed by GitHub
parent 24643f68e5
commit c796f3dda8

@ -0,0 +1,447 @@
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {
"colab": {
"name": "lesson_1-R.ipynb",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true
},
"kernelspec": {
"name": "ir",
"display_name": "R"
},
"language_info": {
"name": "R"
},
"coopTranslator": {
"original_hash": "c18d3bd0bd8ae3878597e89dcd1fa5c1",
"translation_date": "2025-09-06T13:40:43+00:00",
"source_file": "2-Regression/1-Tools/solution/R/lesson_1-R.ipynb",
"language_code": "sk"
}
},
"cells": [
{
"cell_type": "markdown",
"source": [],
"metadata": {
"id": "YJUHCXqK57yz"
}
},
{
"cell_type": "markdown",
"source": [
"## Úvod do regresie - Lekcia 1\n",
"\n",
"#### Uvedenie do kontextu\n",
"\n",
"✅ Existuje mnoho typov regresných metód a výber tej správnej závisí od odpovede, ktorú hľadáte. Ak chcete predpovedať pravdepodobnú výšku osoby v určitom veku, použijete `lineárnu regresiu`, pretože hľadáte **číselnú hodnotu**. Ak vás zaujíma, či by určitý typ kuchyne mal byť považovaný za vegánsky alebo nie, hľadáte **priradenie kategórie**, a preto by ste použili `logistickú regresiu`. O logistickej regresii sa dozviete viac neskôr. Zamyslite sa nad niektorými otázkami, ktoré môžete klásť na základe údajov, a nad tým, ktorá z týchto metód by bola vhodnejšia.\n",
"\n",
"V tejto časti budete pracovať s [malým datasetom o cukrovke](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html). Predstavte si, že by ste chceli otestovať liečbu pre pacientov s cukrovkou. Modely strojového učenia by vám mohli pomôcť určiť, ktorí pacienti by na liečbu reagovali lepšie, na základe kombinácií premenných. Dokonca aj veľmi základný regresný model, keď je vizualizovaný, môže ukázať informácie o premenných, ktoré by vám mohli pomôcť zorganizovať vaše teoretické klinické štúdie.\n",
"\n",
"Tak teda, poďme sa pustiť do tejto úlohy!\n",
"\n",
"<p >\n",
" <img src=\"../../images/encouRage.jpg\"\n",
" width=\"630\"/>\n",
" <figcaption>Ilustrácia od @allison_horst</figcaption>\n",
"\n",
"<!--![Ilustrácia od \\@allison_horst](../../../../../../2-Regression/1-Tools/images/encouRage.jpg)<br>Ilustrácia od @allison_horst-->\n"
],
"metadata": {
"id": "LWNNzfqd6feZ"
}
},
{
"cell_type": "markdown",
"source": [
"## 1. Načítanie našej sady nástrojov\n",
"\n",
"Pre túto úlohu budeme potrebovať nasledujúce balíky:\n",
"\n",
"- `tidyverse`: [tidyverse](https://www.tidyverse.org/) je [kolekcia balíkov v R](https://www.tidyverse.org/packages), ktorá je navrhnutá tak, aby robila 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/) určený na modelovanie a strojové učenie.\n",
"\n",
"Môžete ich nainštalovať pomocou:\n",
"\n",
"`install.packages(c(\"tidyverse\", \"tidymodels\"))`\n",
"\n",
"Nasledujúci skript skontroluje, či máte nainštalované balíky potrebné na dokončenie tohto modulu, a v prípade, že niektoré chýbajú, ich pre vás nainštaluje.\n"
],
"metadata": {
"id": "FIo2YhO26wI9"
}
},
{
"cell_type": "code",
"execution_count": 2,
"source": [
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\n",
"pacman::p_load(tidyverse, tidymodels)"
],
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"Loading required package: pacman\n",
"\n"
]
}
],
"metadata": {
"id": "cIA9fz9v7Dss",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "2df7073b-86b2-4b32-cb86-0da605a0dc11"
}
},
{
"cell_type": "markdown",
"source": [
"Teraz načítajme tieto úžasné balíky a sprístupnime ich v našej aktuálnej R relácii. (Toto je len na ilustráciu, `pacman::p_load()` to už za vás urobil)\n"
],
"metadata": {
"id": "gpO_P_6f9WUG"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# load the core Tidyverse packages\r\n",
"library(tidyverse)\r\n",
"\r\n",
"# load the core Tidymodels packages\r\n",
"library(tidymodels)\r\n"
],
"outputs": [],
"metadata": {
"id": "NLMycgG-9ezO"
}
},
{
"cell_type": "markdown",
"source": [
"## 2. Dataset o cukrovke\n",
"\n",
"V tomto cvičení si precvičíme naše schopnosti regresie tým, že budeme robiť predpovede na datasete o cukrovke. [Dataset o cukrovke](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt) obsahuje `442 vzoriek` údajov týkajúcich sa cukrovky, s 10 prediktívnymi premennými: `vek`, `pohlavie`, `index telesnej hmotnosti`, `priemerný krvný tlak` a `šesť meraní krvného séra`, ako aj výstupnú premennú `y`: kvantitatívne meranie progresie ochorenia jeden rok po základnom vyšetrení.\n",
"\n",
"|Počet pozorovaní|442|\n",
"|----------------|:---|\n",
"|Počet prediktorov|Prvých 10 stĺpcov sú číselné prediktívne premenné|\n",
"|Výstup/Cieľ|Stĺpec 11 je kvantitatívne meranie progresie ochorenia jeden rok po základnom vyšetrení|\n",
"|Informácie o prediktoroch|- vek v rokoch\n",
"||- pohlavie\n",
"||- bmi index telesnej hmotnosti\n",
"||- bp priemerný krvný tlak\n",
"||- s1 tc, celkový cholesterol v sére\n",
"||- s2 ldl, lipoproteíny s nízkou hustotou\n",
"||- s3 hdl, lipoproteíny s vysokou hustotou\n",
"||- s4 tch, celkový cholesterol / HDL\n",
"||- s5 ltg, pravdepodobne logaritmus hladiny triglyceridov v sére\n",
"||- s6 glu, hladina cukru v krvi|\n",
"\n",
"> 🎓 Pamätajte, že ide o učenie s učiteľom (supervised learning), a potrebujeme cieľovú premennú nazvanú 'y'.\n",
"\n",
"Predtým, než budete môcť manipulovať s údajmi v R, musíte údaje importovať do pamäte R alebo vytvoriť spojenie s údajmi, ktoré R môže použiť na vzdialený prístup k údajom.\n",
"\n",
"> Balík [readr](https://readr.tidyverse.org/), ktorý je súčasťou Tidyverse, poskytuje rýchly a priateľský spôsob, ako načítať obdĺžnikové údaje do R.\n",
"\n",
"Teraz načítajme dataset o cukrovke z poskytnutého zdrojového URL: <https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html>\n",
"\n",
"Tiež vykonáme kontrolu údajov pomocou `glimpse()` a zobrazíme prvých 5 riadkov pomocou `slice()`.\n",
"\n",
"Predtým, než budeme pokračovať ďalej, predstavme si niečo, s čím sa často stretnete v kóde R 🥁🥁: operátor pipe `%>%`\n",
"\n",
"Operátor pipe (`%>%`) vykonáva operácie v logickej postupnosti tým, že posúva objekt ďalej do funkcie alebo výrazu. Môžete si operátor pipe predstaviť ako \"a potom\" vo vašom kóde.\n"
],
"metadata": {
"id": "KM6iXLH996Cl"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Import the data set\r\n",
"diabetes <- read_table2(file = \"https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt\")\r\n",
"\r\n",
"\r\n",
"# Get a glimpse and dimensions of the data\r\n",
"glimpse(diabetes)\r\n",
"\r\n",
"\r\n",
"# Select the first 5 rows of the data\r\n",
"diabetes %>% \r\n",
" slice(1:5)"
],
"outputs": [],
"metadata": {
"id": "Z1geAMhM-bSP"
}
},
{
"cell_type": "markdown",
"source": [
"`glimpse()` nám ukazuje, že tieto dáta obsahujú 442 riadkov a 11 stĺpcov, pričom všetky stĺpce majú dátový typ `double`.\n",
"\n",
"<br>\n",
"\n",
"> glimpse() a slice() sú funkcie v [`dplyr`](https://dplyr.tidyverse.org/). Dplyr, ktorý je súčasťou Tidyverse, predstavuje gramatiku manipulácie s dátami a poskytuje konzistentnú sadu slovies, ktoré vám pomôžu riešiť najbežnejšie výzvy pri práci s dátami.\n",
"\n",
"<br>\n",
"\n",
"Teraz, keď máme dáta, zamerajme sa na jednu vlastnosť (`bmi`), ktorú použijeme ako cieľ pre toto cvičenie. To si bude vyžadovať výber požadovaných stĺpcov. Ako to môžeme urobiť?\n",
"\n",
"[`dplyr::select()`](https://dplyr.tidyverse.org/reference/select.html) nám umožňuje *vybrať* (a prípadne premenovať) stĺpce v dátovom rámci.\n"
],
"metadata": {
"id": "UwjVT1Hz-c3Z"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Select predictor feature `bmi` and outcome `y`\r\n",
"diabetes_select <- diabetes %>% \r\n",
" select(c(bmi, y))\r\n",
"\r\n",
"# Print the first 5 rows\r\n",
"diabetes_select %>% \r\n",
" slice(1:10)"
],
"outputs": [],
"metadata": {
"id": "RDY1oAKI-m80"
}
},
{
"cell_type": "markdown",
"source": [
"## 3. Tréningové a testovacie dáta\n",
"\n",
"V supervidovanom učení je bežnou praxou *rozdeliť* dáta na dva podmnožiny; (zvyčajne väčšiu) množinu, s ktorou sa model trénuje, a menšiu „rezervnú“ množinu, na ktorej sa overí, ako model fungoval.\n",
"\n",
"Teraz, keď máme dáta pripravené, môžeme zistiť, či nám stroj dokáže pomôcť určiť logické rozdelenie čísel v tejto dátovej sade. Môžeme použiť balík [rsample](https://tidymodels.github.io/rsample/), ktorý je súčasťou rámca Tidymodels, na vytvorenie objektu obsahujúceho informácie o *tom, ako* rozdeliť dáta, a potom ďalšie dve funkcie rsample na extrakciu vytvorených tréningových a testovacích množín:\n"
],
"metadata": {
"id": "SDk668xK-tc3"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"set.seed(2056)\r\n",
"# Split 67% of the data for training and the rest for tesing\r\n",
"diabetes_split <- diabetes_select %>% \r\n",
" initial_split(prop = 0.67)\r\n",
"\r\n",
"# Extract the resulting train and test sets\r\n",
"diabetes_train <- training(diabetes_split)\r\n",
"diabetes_test <- testing(diabetes_split)\r\n",
"\r\n",
"# Print the first 3 rows of the training set\r\n",
"diabetes_train %>% \r\n",
" slice(1:10)"
],
"outputs": [],
"metadata": {
"id": "EqtHx129-1h-"
}
},
{
"cell_type": "markdown",
"source": [
"## 4. Natrénujte lineárny regresný model pomocou Tidymodels\n",
"\n",
"Teraz sme pripravení natrénovať náš model!\n",
"\n",
"V Tidymodels špecifikujete modely pomocou `parsnip()` tým, že definujete tri koncepty:\n",
"\n",
"- **Typ** modelu rozlišuje medzi modelmi, ako sú lineárna regresia, logistická regresia, modely rozhodovacích stromov a podobne.\n",
"\n",
"- **Režim** modelu zahŕňa bežné možnosti, ako sú regresia a klasifikácia; niektoré typy modelov podporujú obe možnosti, zatiaľ čo iné majú iba jeden režim.\n",
"\n",
"- **Engine** modelu je výpočtový nástroj, ktorý sa použije na natrénovanie modelu. Často ide o balíky v R, ako napríklad **`\"lm\"`** alebo **`\"ranger\"`**\n",
"\n",
"Tieto informácie o modelovaní sú zachytené v špecifikácii modelu, takže si jednu vytvorme!\n"
],
"metadata": {
"id": "sBOS-XhB-6v7"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Build a linear model specification\r\n",
"lm_spec <- \r\n",
" # Type\r\n",
" linear_reg() %>% \r\n",
" # Engine\r\n",
" set_engine(\"lm\") %>% \r\n",
" # Mode\r\n",
" set_mode(\"regression\")\r\n",
"\r\n",
"\r\n",
"# Print the model specification\r\n",
"lm_spec"
],
"outputs": [],
"metadata": {
"id": "20OwEw20--t3"
}
},
{
"cell_type": "markdown",
"source": [
"Po tom, čo je model *špecifikovaný*, môže byť `odhadnutý` alebo `natrénovaný` pomocou funkcie [`fit()`](https://parsnip.tidymodels.org/reference/fit.html), zvyčajne s použitím vzorca a nejakých údajov.\n",
"\n",
"`y ~ .` znamená, že budeme prispôsobovať `y` ako predpovedanú hodnotu/cieľ, vysvetlenú všetkými prediktormi/vlastnosťami, teda `.` (v tomto prípade máme iba jeden prediktor: `bmi`).\n"
],
"metadata": {
"id": "_oDHs89k_CJj"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Build a linear model specification\r\n",
"lm_spec <- linear_reg() %>% \r\n",
" set_engine(\"lm\") %>%\r\n",
" set_mode(\"regression\")\r\n",
"\r\n",
"\r\n",
"# Train a linear regression model\r\n",
"lm_mod <- lm_spec %>% \r\n",
" fit(y ~ ., data = diabetes_train)\r\n",
"\r\n",
"# Print the model\r\n",
"lm_mod"
],
"outputs": [],
"metadata": {
"id": "YlsHqd-q_GJQ"
}
},
{
"cell_type": "markdown",
"source": [
"Z modelového výstupu 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",
"<br>\n",
"\n",
"## 5. Predikcia na testovacej množine\n",
"\n",
"Teraz, keď sme natrénovali model, môžeme ho použiť na predikciu progresie ochorenia y pre testovaciu množinu dát pomocou [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html). Toto sa použije na vykreslenie čiary medzi skupinami dát.\n"
],
"metadata": {
"id": "kGZ22RQj_Olu"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Make predictions for the test set\r\n",
"predictions <- lm_mod %>% \r\n",
" predict(new_data = diabetes_test)\r\n",
"\r\n",
"# Print out some of the predictions\r\n",
"predictions %>% \r\n",
" slice(1:5)"
],
"outputs": [],
"metadata": {
"id": "nXHbY7M2_aao"
}
},
{
"cell_type": "markdown",
"source": [
"Hurá! 💃🕺 Práve sme natrénovali model a použili ho na vytváranie predpovedí!\n",
"\n",
"Pri vytváraní predpovedí je v súlade s konvenciou tidymodels vždy vytvoriť tibble/dátový rámec s výsledkami, ktoré majú štandardizované názvy stĺpcov. To umožňuje jednoducho skombinovať pôvodné dáta a predpovede do použiteľného formátu pre ďalšie operácie, ako je napríklad vizualizácia.\n",
"\n",
"`dplyr::bind_cols()` efektívne spája viacero dátových rámcov podľa stĺpcov.\n"
],
"metadata": {
"id": "R_JstwUY_bIs"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Combine the predictions and the original test set\r\n",
"results <- diabetes_test %>% \r\n",
" bind_cols(predictions)\r\n",
"\r\n",
"\r\n",
"results %>% \r\n",
" slice(1:5)"
],
"outputs": [],
"metadata": {
"id": "RybsMJR7_iI8"
}
},
{
"cell_type": "markdown",
"source": [
"## 6. Zobrazenie výsledkov modelovania\n",
"\n",
"Teraz je čas vidieť to vizuálne 📈. Vytvoríme bodový graf všetkých hodnôt `y` a `bmi` z testovacej množiny a potom použijeme predpovede na nakreslenie čiary na najvhodnejšom mieste medzi skupinami údajov modelu.\n",
"\n",
"R má niekoľko systémov na tvorbu grafov, ale `ggplot2` je jedným z najelegantnejších a najvšestrannejších. Umožňuje vám vytvárať grafy **kombinovaním nezávislých komponentov**.\n"
],
"metadata": {
"id": "XJbYbMZW_n_s"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Set a theme for the plot\r\n",
"theme_set(theme_light())\r\n",
"# Create a scatter plot\r\n",
"results %>% \r\n",
" ggplot(aes(x = bmi)) +\r\n",
" # Add a scatter plot\r\n",
" geom_point(aes(y = y), size = 1.6) +\r\n",
" # Add a line plot\r\n",
" geom_line(aes(y = .pred), color = \"blue\", size = 1.5)"
],
"outputs": [],
"metadata": {
"id": "R9tYp3VW_sTn"
}
},
{
"cell_type": "markdown",
"source": [
"✅ Zamyslite sa trochu nad tým, čo sa tu deje. Priama čiara prechádza cez množstvo malých bodov údajov, ale čo presne robí? Vidíte, ako by ste mali byť schopní použiť túto čiaru na predpovedanie, kam by mal nový, nevidený údaj zapadnúť vo vzťahu k osi y grafu? Skúste slovami vyjadriť praktické využitie tohto modelu.\n",
"\n",
"Gratulujeme, vytvorili ste svoj prvý model lineárnej regresie, urobili ste s ním predpoveď a zobrazili ste ju v grafe!\n"
],
"metadata": {
"id": "zrPtHIxx_tNI"
}
},
{
"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). Hoci 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 odporúčame 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"
]
}
]
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,46 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.3-final"
},
"orig_nbformat": 2,
"kernelspec": {
"name": "python3",
"display_name": "Python 3",
"language": "python"
},
"coopTranslator": {
"original_hash": "1b2ab303ac6c604a34c6ca7a49077fc7",
"translation_date": "2025-09-06T13:45:49+00:00",
"source_file": "2-Regression/2-Data/notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"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). Hoci 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 odporúčame 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"
]
}
]
}

@ -0,0 +1,685 @@
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {
"colab": {
"name": "lesson_2-R.ipynb",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true
},
"kernelspec": {
"name": "ir",
"display_name": "R"
},
"language_info": {
"name": "R"
},
"coopTranslator": {
"original_hash": "f3c335f9940cfd76528b3ef918b9b342",
"translation_date": "2025-09-06T13:47:59+00:00",
"source_file": "2-Regression/2-Data/solution/R/lesson_2-R.ipynb",
"language_code": "sk"
}
},
"cells": [
{
"cell_type": "markdown",
"source": [
"# Vytvorenie regresného modelu: príprava a vizualizácia dát\n",
"\n",
"## **Lineárna regresia pre tekvice - Lekcia 2**\n",
"#### Úvod\n",
"\n",
"Teraz, keď máte pripravené nástroje na budovanie modelov strojového učenia pomocou Tidymodels a Tidyverse, ste pripravení začať klásť otázky o svojich dátach. Pri práci s dátami a aplikovaní riešení strojového učenia je veľmi dôležité vedieť, ako položiť správnu otázku, aby ste mohli plne využiť potenciál svojho datasetu.\n",
"\n",
"V tejto lekcii sa naučíte:\n",
"\n",
"- Ako pripraviť svoje dáta na budovanie modelov.\n",
"\n",
"- Ako používať `ggplot2` na vizualizáciu dát.\n",
"\n",
"Otázka, na ktorú potrebujete odpoveď, určí, aký typ algoritmov strojového učenia budete používať. Kvalita odpovede, ktorú dostanete, bude výrazne závisieť od povahy vašich dát.\n",
"\n",
"Pozrime sa na to prostredníctvom praktického cvičenia.\n",
"\n",
"\n",
"<p >\n",
" <img src=\"../../images/unruly_data.jpg\"\n",
" width=\"700\"/>\n",
" <figcaption>Ilustrácia od @allison_horst</figcaption>\n",
"\n",
"\n",
"<!--![Ilustrácia od \\@allison_horst](../../../../../../2-Regression/2-Data/images/unruly_data.jpg)<br>Ilustrácia od \\@allison_horst-->\n"
],
"metadata": {
"id": "Pg5aexcOPqAZ"
}
},
{
"cell_type": "markdown",
"source": [
"## 1. Importovanie údajov o tekviciach a privolanie Tidyverse\n",
"\n",
"Na spracovanie tejto lekcie 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á je navrhnutá tak, aby robila dátovú vedu rýchlejšou, jednoduchšou a zábavnejšou!\n",
"\n",
"Môžete ich nainštalovať pomocou:\n",
"\n",
"`install.packages(c(\"tidyverse\"))`\n",
"\n",
"Nasledujúci skript skontroluje, či máte nainštalované balíky potrebné na dokončenie tohto modulu, a v prípade, že niektoré chýbajú, ich pre vás nainštaluje.\n"
],
"metadata": {
"id": "dc5WhyVdXAjR"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\n",
"pacman::p_load(tidyverse)"
],
"outputs": [],
"metadata": {
"id": "GqPYUZgfXOBt"
}
},
{
"cell_type": "markdown",
"source": [
"Teraz si spustime niektoré balíčky a načítajme [dáta](https://github.com/microsoft/ML-For-Beginners/blob/main/2-Regression/data/US-pumpkins.csv) poskytnuté pre túto lekciu!\n"
],
"metadata": {
"id": "kvjDTPDSXRr2"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Load the core Tidyverse packages\n",
"library(tidyverse)\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 =50)"
],
"outputs": [],
"metadata": {
"id": "VMri-t2zXqgD"
}
},
{
"cell_type": "markdown",
"source": [
"Rýchly pohľad pomocou `glimpse()` okamžite ukáže, že existujú prázdne hodnoty a mix reťazcov (`chr`) a číselných údajov (`dbl`). `Date` je typu znakový reťazec a je tu aj zvláštny stĺpec s názvom `Package`, kde sú údaje zmiešané medzi `sacks`, `bins` a inými hodnotami. Údaje sú, úprimne povedané, trochu chaotické 😤.\n",
"\n",
"V skutočnosti nie je veľmi bežné dostať dataset, ktorý je úplne pripravený na použitie na vytvorenie ML modelu hneď po rozbalení. Ale nebojte sa, v tejto lekcii sa naučíte, ako pripraviť surový dataset pomocou štandardných knižníc v R 🧑‍🔧. Taktiež sa naučíte rôzne techniky na vizualizáciu údajov. 📈📊\n",
"<br>\n",
"\n",
"> Pripomenutie: Operátor pipe (`%>%`) vykonáva operácie v logickej postupnosti tým, že posúva objekt ďalej do funkcie alebo výrazu. Môžete si operátor pipe predstaviť ako výraz „a potom“ vo vašom kóde.\n"
],
"metadata": {
"id": "REWcIv9yX29v"
}
},
{
"cell_type": "markdown",
"source": [
"## 2. Kontrola chýbajúcich údajov\n",
"\n",
"Jedným z najbežnejších problémov, s ktorými sa dátoví analytici musia vysporiadať, sú neúplné alebo chýbajúce údaje. R reprezentuje chýbajúce alebo neznáme hodnoty pomocou špeciálnej hodnoty: `NA` (Not Available).\n",
"\n",
"Ako teda zistíme, že dátový rámec obsahuje chýbajúce hodnoty?\n",
"<br>\n",
"- Jedným z priamych spôsobov je použitie základnej funkcie R `anyNA`, ktorá vracia logické objekty `TRUE` alebo `FALSE`.\n"
],
"metadata": {
"id": "Zxfb3AM5YbUe"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" anyNA()"
],
"outputs": [],
"metadata": {
"id": "G--DQutAYltj"
}
},
{
"cell_type": "markdown",
"source": [
"Zdá sa, že niektoré údaje chýbajú! To je dobré miesto, kde začať.\n",
"\n",
"- Ďalším spôsobom by bolo použiť funkciu `is.na()`, ktorá označuje, ktoré jednotlivé prvky stĺpcov chýbajú pomocou logickej hodnoty `TRUE`.\n"
],
"metadata": {
"id": "mU-7-SB6YokF"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" is.na() %>% \n",
" head(n = 7)"
],
"outputs": [],
"metadata": {
"id": "W-DxDOR4YxSW"
}
},
{
"cell_type": "markdown",
"source": [
"Dobre, práca je hotová, ale s takým veľkým dátovým rámcom by bolo neefektívne a prakticky nemožné kontrolovať všetky riadky a stĺpce jednotlivo😴.\n",
"\n",
"- Intuitívnejší spôsob by bol vypočítať súčet chýbajúcich hodnôt pre každý stĺpec:\n"
],
"metadata": {
"id": "xUWxipKYY0o7"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" is.na() %>% \n",
" colSums()"
],
"outputs": [],
"metadata": {
"id": "ZRBWV6P9ZArL"
}
},
{
"cell_type": "markdown",
"source": [
"Oveľa lepšie! Chýbajú niektoré údaje, ale možno to nebude mať vplyv na danú úlohu. Uvidíme, aké ďalšie analýzy prinesú výsledky.\n",
"\n",
"> Okrem skvelých balíkov a funkcií má R veľmi dobrú dokumentáciu. Napríklad použite `help(colSums)` alebo `?colSums`, aby ste sa dozvedeli viac o funkcii.\n"
],
"metadata": {
"id": "9gv-crB6ZD1Y"
}
},
{
"cell_type": "markdown",
"source": [
"## 3. Dplyr: Gramatika manipulácie s dátami\n",
"\n",
"<p >\n",
" <img src=\"../../images/dplyr_wrangling.png\"\n",
" width=\"569\"/>\n",
" <figcaption>Ilustrácia od @allison_horst</figcaption>\n",
"\n",
"\n",
"<!--![Ilustrácia od \\@allison_horst](../../../../../../2-Regression/2-Data/images/dplyr_wrangling.png)<br/>Ilustrácia od \\@allison_horst-->\n"
],
"metadata": {
"id": "o4jLY5-VZO2C"
}
},
{
"cell_type": "markdown",
"source": [
"[`dplyr`](https://dplyr.tidyverse.org/), balík v Tidyverse, je gramatika manipulácie s dátami, ktorá poskytuje konzistentnú sadu slovies, ktoré vám pomôžu vyriešiť najbežnejšie výzvy pri manipulácii s dátami. V tejto sekcii preskúmame niektoré zo slovies dplyr!\n"
],
"metadata": {
"id": "i5o33MQBZWWw"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::select()\n",
"\n",
"`select()` je funkcia v balíku `dplyr`, ktorá vám pomáha vybrať stĺpce na ponechanie alebo vylúčenie.\n",
"\n",
"Aby ste uľahčili prácu s vaším dátovým rámcom, odstráňte niekoľko jeho stĺpcov pomocou `select()`, pričom ponechajte iba tie, ktoré potrebujete.\n",
"\n",
"Napríklad v tomto cvičení bude naša analýza zahŕňať stĺpce `Package`, `Low Price`, `High Price` a `Date`. Vyberme tieto stĺpce.\n"
],
"metadata": {
"id": "x3VGMAGBZiUr"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Select desired columns\n",
"pumpkins <- pumpkins %>% \n",
" select(Package, `Low Price`, `High Price`, Date)\n",
"\n",
"\n",
"# Print data set\n",
"pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "F_FgxQnVZnM0"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::mutate()\n",
"\n",
"`mutate()` je funkcia v balíku `dplyr`, ktorá vám umožňuje vytvárať alebo upravovať stĺpce, pričom zachováva existujúce stĺpce.\n",
"\n",
"Všeobecná štruktúra funkcie mutate je:\n",
"\n",
"`data %>% mutate(new_column_name = what_it_contains)`\n",
"\n",
"Poďme si vyskúšať `mutate` na stĺpci `Date` vykonaním nasledujúcich operácií:\n",
"\n",
"1. Konvertovať dátumy (aktuálne typu character) na formát mesiaca (ide o americké dátumy, takže formát je `MM/DD/YYYY`).\n",
"\n",
"2. Extrahovať mesiac z dátumov do nového stĺpca.\n",
"\n",
"V R balík [lubridate](https://lubridate.tidyverse.org/) uľahčuje prácu s dátumovo-časovými údajmi. Takže použijeme `dplyr::mutate()`, `lubridate::mdy()`, `lubridate::month()` a pozrieme sa, ako dosiahnuť vyššie uvedené ciele. Stĺpec Date môžeme vynechať, pretože ho už nebudeme potrebovať v ďalších operáciách.\n"
],
"metadata": {
"id": "2KKo0Ed9Z1VB"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Load lubridate\n",
"library(lubridate)\n",
"\n",
"pumpkins <- pumpkins %>% \n",
" # Convert the Date column to a date object\n",
" mutate(Date = mdy(Date)) %>% \n",
" # Extract month from Date\n",
" mutate(Month = month(Date)) %>% \n",
" # Drop Date column\n",
" select(-Date)\n",
"\n",
"# View the first few rows\n",
"pumpkins %>% \n",
" slice_head(n = 7)"
],
"outputs": [],
"metadata": {
"id": "5joszIVSZ6xe"
}
},
{
"cell_type": "markdown",
"source": [
"Hurá! 🤩\n",
"\n",
"Ďalej vytvorme nový stĺpec `Price`, ktorý bude predstavovať priemernú cenu tekvice. Teraz vypočítajme priemer stĺpcov `Low Price` a `High Price`, aby sme naplnili nový stĺpec Price. \n",
"<br>\n"
],
"metadata": {
"id": "nIgLjNMCZ-6Y"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Create a new column Price\n",
"pumpkins <- pumpkins %>% \n",
" mutate(Price = (`Low Price` + `High Price`)/2)\n",
"\n",
"# View the first few rows of the data\n",
"pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "Zo0BsqqtaJw2"
}
},
{
"cell_type": "markdown",
"source": [
"Yeees!💪\n",
"\n",
"„Ale počkaj!“, poviete si po rýchlom prehliadnutí celého dátového súboru pomocou `View(pumpkins)`, „Tu je niečo zvláštne!“🤔\n",
"\n",
"Ak sa pozriete na stĺpec `Package`, tekvice sa predávajú v rôznych konfiguráciách. Niektoré sa predávajú v mierach `1 1/9 bushel`, niektoré v mierach `1/2 bushel`, niektoré na kusy, niektoré na váhu a niektoré vo veľkých škatuliach s rôznymi šírkami.\n",
"\n",
"Poďme si to overiť:\n"
],
"metadata": {
"id": "p77WZr-9aQAR"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Verify the distinct observations in Package column\n",
"pumpkins %>% \n",
" distinct(Package)"
],
"outputs": [],
"metadata": {
"id": "XISGfh0IaUy6"
}
},
{
"cell_type": "markdown",
"source": [
"Úžasné!👏\n",
"\n",
"Zdá sa, že tekvice je veľmi ťažké vážiť konzistentne, takže ich vyfiltrujme tak, že vyberieme iba tekvice, ktoré obsahujú reťazec *bushel* v stĺpci `Package`, a uložme to do nového dátového rámca `new_pumpkins`.\n"
],
"metadata": {
"id": "7sMjiVujaZxY"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::filter() a stringr::str_detect()\n",
"\n",
"[`dplyr::filter()`](https://dplyr.tidyverse.org/reference/filter.html): vytvára podmnožinu údajov obsahujúcu iba **riadky**, ktoré spĺňajú vaše podmienky, v tomto prípade tekvice so slovom *bushel* v stĺpci `Package`.\n",
"\n",
"[stringr::str_detect()](https://stringr.tidyverse.org/reference/str_detect.html): zisťuje prítomnosť alebo neprítomnosť vzoru v reťazci.\n",
"\n",
"Balík [`stringr`](https://github.com/tidyverse/stringr) poskytuje jednoduché funkcie pre bežné operácie s reťazcami.\n"
],
"metadata": {
"id": "L8Qfcs92ageF"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Retain only pumpkins with \"bushel\"\n",
"new_pumpkins <- pumpkins %>% \n",
" filter(str_detect(Package, \"bushel\"))\n",
"\n",
"# Get the dimensions of the new data\n",
"dim(new_pumpkins)\n",
"\n",
"# View a few rows of the new data\n",
"new_pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "hy_SGYREampd"
}
},
{
"cell_type": "markdown",
"source": [
"Môžete vidieť, že sme zúžili výber na približne 415 riadkov údajov obsahujúcich tekvice na veľké množstvo.🤩 \n",
"<br>\n"
],
"metadata": {
"id": "VrDwF031avlR"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::case_when()\n",
"\n",
"**Ale počkajte! Ešte je tu jedna vec, ktorú treba urobiť**\n",
"\n",
"Všimli ste si, že množstvo v bušloch sa líši v jednotlivých riadkoch? Musíte normalizovať ceny tak, aby ste zobrazili cenu za bušel, nie za 1 1/9 alebo 1/2 bušela. Je čas na trochu matematiky, aby ste to štandardizovali.\n",
"\n",
"Použijeme funkciu [`case_when()`](https://dplyr.tidyverse.org/reference/case_when.html) na *mutáciu* stĺpca Price v závislosti od určitých podmienok. `case_when` umožňuje vektorovo spracovať viacero `if_else()` vyjadrení.\n"
],
"metadata": {
"id": "mLpw2jH4a0tx"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Convert the price if the Package contains fractional bushel values\n",
"new_pumpkins <- new_pumpkins %>% \n",
" mutate(Price = case_when(\n",
" str_detect(Package, \"1 1/9\") ~ Price/(1 + 1/9),\n",
" str_detect(Package, \"1/2\") ~ Price/(1/2),\n",
" TRUE ~ Price))\n",
"\n",
"# View the first few rows of the data\n",
"new_pumpkins %>% \n",
" slice_head(n = 30)"
],
"outputs": [],
"metadata": {
"id": "P68kLVQmbM6I"
}
},
{
"cell_type": "markdown",
"source": [
"Teraz môžeme analyzovať cenu za jednotku na základe ich merania v bušloch. Celá táto štúdia o bušloch tekvíc však ukazuje, aké veľmi `dôležité` je `pochopiť povahu vašich údajov`!\n",
"\n",
"> ✅ Podľa [The Spruce Eats](https://www.thespruceeats.com/how-much-is-a-bushel-1389308) hmotnosť bušľa závisí od typu produktu, pretože ide o objemové meranie. \"Bušel paradajok, napríklad, by mal vážiť 56 libier... Listy a zelené rastliny zaberajú viac miesta s menšou hmotnosťou, takže bušel špenátu váži iba 20 libier.\" Je to všetko dosť komplikované! Nezaoberajme sa konverziou bušlov na libry, namiesto toho stanovme cenu za bušel. Celá táto štúdia o bušloch tekvíc však ukazuje, aké veľmi dôležité je pochopiť povahu vašich údajov!\n",
">\n",
"> ✅ Všimli ste si, že tekvice predávané na pol bušľa sú veľmi drahé? Dokážete zistiť prečo? Tip: malé tekvice sú oveľa drahšie ako veľké, pravdepodobne preto, že ich je oveľa viac na bušel, vzhľadom na nevyužitý priestor, ktorý zaberá jedna veľká dutá tekvica na koláč.\n"
],
"metadata": {
"id": "pS2GNPagbSdb"
}
},
{
"cell_type": "markdown",
"source": [
"DÔLEŽITÉ PRAVIDLÁ: \n",
"1. NEPRIDÁVAJTE '''markdown alebo akékoľvek iné značky okolo prekladu \n",
"2. Uistite sa, že preklad neznie príliš doslovne \n",
"3. Preložte aj komentáre \n",
"4. Tento súbor je napísaný vo formáte Markdown - nezaobchádzajte s ním ako s XML alebo HTML \n",
"5. Neprekladajte: \n",
" - [!NOTE], [!WARNING], [!TIP], [!IMPORTANT], [!CAUTION] \n",
" - Názvy premenných, funkcií, tried \n",
" - Zástupné symboly ako @@INLINE_CODE_x@@ alebo @@CODE_BLOCK_x@@ \n",
" - URL alebo cesty \n",
"6. Zachovajte všetko pôvodné formátovanie Markdownu \n",
"7. Vráťte IBA preložený obsah bez akýchkoľvek dodatočných značiek alebo formátovania \n",
"\n",
"A teraz nakoniec, len pre dobrodružstvo 💁‍♀️, presuňme stĺpec Month na prvú pozíciu, teda `pred` stĺpec `Package`. \n",
"\n",
"Na zmenu pozícií stĺpcov sa používa `dplyr::relocate()`. \n"
],
"metadata": {
"id": "qql1SowfbdnP"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Create a new data frame new_pumpkins\n",
"new_pumpkins <- new_pumpkins %>% \n",
" relocate(Month, .before = Package)\n",
"\n",
"new_pumpkins %>% \n",
" slice_head(n = 7)"
],
"outputs": [],
"metadata": {
"id": "JJ1x6kw8bixF"
}
},
{
"cell_type": "markdown",
"source": [
"Skvelá práca!👌 Teraz máte čistý, uprataný dataset, na ktorom môžete postaviť svoj nový regresný model! \n",
"<br>\n"
],
"metadata": {
"id": "y8TJ0Za_bn5Y"
}
},
{
"cell_type": "markdown",
"source": [
"## 4. Vizualizácia dát s ggplot2\n",
"\n",
"<p >\n",
" <img src=\"../../images/data-visualization.png\"\n",
" width=\"600\"/>\n",
" <figcaption>Infografika od Dasani Madipalli</figcaption>\n",
"\n",
"\n",
"<!--![Infografika od Dasani Madipalli](../../../../../../2-Regression/2-Data/images/data-visualization.png){width=\"600\"}-->\n",
"\n",
"Existuje *múdre* príslovie, ktoré hovorí:\n",
"\n",
"> \"Jednoduchý graf priniesol analytikovi dát viac informácií než akékoľvek iné zariadenie.\" --- John Tukey\n",
"\n",
"Úlohou dátového vedca je ukázať kvalitu a charakter dát, s ktorými pracuje. Na tento účel často vytvára zaujímavé vizualizácie, ako sú grafy, diagramy a tabuľky, ktoré zobrazujú rôzne aspekty dát. Týmto spôsobom dokáže vizuálne ukázať vzťahy a medzery, ktoré by inak bolo ťažké odhaliť.\n",
"\n",
"Vizualizácie môžu tiež pomôcť určiť, ktorá technika strojového učenia je pre dané dáta najvhodnejšia. Napríklad bodový graf, ktorý sa zdá sledovať líniu, naznačuje, že dáta sú vhodným kandidátom na cvičenie s lineárnou regresiou.\n",
"\n",
"R ponúka niekoľko systémov na tvorbu grafov, ale [`ggplot2`](https://ggplot2.tidyverse.org/index.html) je jedným z najelegantnejších a najuniverzálnejších. `ggplot2` vám umožňuje vytvárať grafy **kombinovaním nezávislých komponentov**.\n",
"\n",
"Začnime jednoduchým bodovým grafom pre stĺpce Price a Month.\n",
"\n",
"V tomto prípade začneme s [`ggplot()`](https://ggplot2.tidyverse.org/reference/ggplot.html), poskytneme dataset a estetické mapovanie (pomocou [`aes()`](https://ggplot2.tidyverse.org/reference/aes.html)), a potom pridáme vrstvy (ako [`geom_point()`](https://ggplot2.tidyverse.org/reference/geom_point.html)) pre bodové grafy.\n"
],
"metadata": {
"id": "mYSH6-EtbvNa"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Set a theme for the plots\n",
"theme_set(theme_light())\n",
"\n",
"# Create a scatter plot\n",
"p <- ggplot(data = new_pumpkins, aes(x = Price, y = Month))\n",
"p + geom_point()"
],
"outputs": [],
"metadata": {
"id": "g2YjnGeOcLo4"
}
},
{
"cell_type": "markdown",
"source": [
"Je to užitočný graf 🤷? Prekvapilo vás na ňom niečo?\n",
"\n",
"Nie je obzvlášť užitočný, pretože iba zobrazuje vaše údaje ako rozptyl bodov v danom mesiaci. \n",
"<br>\n"
],
"metadata": {
"id": "Ml7SDCLQcPvE"
}
},
{
"cell_type": "markdown",
"source": [
"### **Ako to urobiť užitočným?**\n",
"\n",
"Aby grafy zobrazovali užitočné údaje, zvyčajne je potrebné údaje nejako zoskupiť. Napríklad v našom prípade by zistenie priemernej ceny tekvíc za každý mesiac poskytlo viac informácií o základných vzoroch v našich údajoch. To nás privádza k ďalšiemu preletu nad **dplyr**:\n",
"\n",
"#### `dplyr::group_by() %>% summarize()`\n",
"\n",
"Zoskupenú agregáciu v R je možné jednoducho vypočítať pomocou\n",
"\n",
"`dplyr::group_by() %>% summarize()`\n",
"\n",
"- `dplyr::group_by()` mení jednotku analýzy z celého datasetu na jednotlivé skupiny, napríklad podľa mesiacov.\n",
"\n",
"- `dplyr::summarize()` vytvára nový dátový rámec s jedným stĺpcom pre každú zoskupovaciu premennú a jedným stĺpcom pre každú štatistiku, ktorú ste špecifikovali.\n",
"\n",
"Napríklad môžeme použiť `dplyr::group_by() %>% summarize()` na zoskupenie tekvíc do skupín na základe stĺpca **Month** a potom vypočítať **priemernú cenu** za každý mesiac.\n"
],
"metadata": {
"id": "jMakvJZIcVkh"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Find the average price of pumpkins per month\r\n",
"new_pumpkins %>%\r\n",
" group_by(Month) %>% \r\n",
" summarise(mean_price = mean(Price))"
],
"outputs": [],
"metadata": {
"id": "6kVSUa2Bcilf"
}
},
{
"cell_type": "markdown",
"source": [
"Stručne!✨\n",
"\n",
"Kategorické prvky, ako sú mesiace, sú lepšie znázornené pomocou stĺpcového grafu 📊. Vrstvy zodpovedné za stĺpcové grafy sú `geom_bar()` a `geom_col()`. Viac informácií nájdete v `?geom_bar`.\n",
"\n",
"Poďme si jeden vytvoriť!\n"
],
"metadata": {
"id": "Kds48GUBcj3W"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Find the average price of pumpkins per month then plot a bar chart\r\n",
"new_pumpkins %>%\r\n",
" group_by(Month) %>% \r\n",
" summarise(mean_price = mean(Price)) %>% \r\n",
" ggplot(aes(x = Month, y = mean_price)) +\r\n",
" geom_col(fill = \"midnightblue\", alpha = 0.7) +\r\n",
" ylab(\"Pumpkin Price\")"
],
"outputs": [],
"metadata": {
"id": "VNbU1S3BcrxO"
}
},
{
"cell_type": "markdown",
"source": [
"🤩🤩 Toto je užitočnejšia vizualizácia dát! Zdá sa, že najvyššia cena za tekvice sa vyskytuje v septembri a októbri. Zodpovedá to vašim očakávaniam? Prečo áno alebo prečo nie?\n",
"\n",
"Gratulujeme k dokončeniu druhej lekcie 👏! Pripravili ste svoje dáta na vytváranie modelov a potom ste odhalili ďalšie poznatky pomocou vizualizácií!\n"
],
"metadata": {
"id": "zDm0VOzzcuzR"
}
},
{
"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 odporúčame profesionálny ľudský preklad. Nezodpovedáme za žiadne nedorozumenia alebo nesprávne interpretácie vyplývajúce z použitia tohto prekladu.\n"
]
}
]
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,128 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Ceny tekvíc\n",
"\n",
"Načítajte potrebné knižnice a dataset. Preveďte údaje do dátového rámca obsahujúceho podmnožinu údajov:\n",
"\n",
"- Zahrňte iba tekvice ocenené na základe bušlov\n",
"- Preveďte dátum na mesiac\n",
"- Vypočítajte cenu ako priemer vysokých a nízkych cien\n",
"- Preveďte cenu tak, aby odrážala cenu podľa množstva v bušloch\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"from datetime import datetime\n",
"\n",
"pumpkins = pd.read_csv('../data/US-pumpkins.csv')\n",
"\n",
"pumpkins.head()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"pumpkins = pumpkins[pumpkins['Package'].str.contains('bushel', case=True, regex=True)]\n",
"\n",
"columns_to_select = ['Package', 'Variety', 'City Name', 'Low Price', 'High Price', 'Date']\n",
"pumpkins = pumpkins.loc[:, columns_to_select]\n",
"\n",
"price = (pumpkins['Low Price'] + pumpkins['High Price']) / 2\n",
"\n",
"month = pd.DatetimeIndex(pumpkins['Date']).month\n",
"day_of_year = pd.to_datetime(pumpkins['Date']).apply(lambda dt: (dt-datetime(dt.year,1,1)).days)\n",
"\n",
"new_pumpkins = pd.DataFrame(\n",
" {'Month': month, \n",
" 'DayOfYear' : day_of_year, \n",
" 'Variety': pumpkins['Variety'], \n",
" 'City': pumpkins['City Name'], \n",
" 'Package': pumpkins['Package'], \n",
" 'Low Price': pumpkins['Low Price'],\n",
" 'High Price': pumpkins['High Price'], \n",
" 'Price': price})\n",
"\n",
"new_pumpkins.loc[new_pumpkins['Package'].str.contains('1 1/9'), 'Price'] = price/1.1\n",
"new_pumpkins.loc[new_pumpkins['Package'].str.contains('1/2'), 'Price'] = price*2\n",
"\n",
"new_pumpkins.head()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Základný bodový graf nám pripomína, že máme údaje iba od augusta do decembra. Pravdepodobne potrebujeme viac údajov, aby sme mohli vyvodiť závery lineárnym spôsobom.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"plt.scatter('Month','Price',data=new_pumpkins)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"\n",
"plt.scatter('DayOfYear','Price',data=new_pumpkins)"
]
},
{
"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). Hoci 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 odporúčame 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"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.3-final"
},
"orig_nbformat": 2,
"coopTranslator": {
"original_hash": "b032d371c75279373507f003439a577e",
"translation_date": "2025-09-06T13:08:32+00:00",
"source_file": "2-Regression/3-Linear/notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,269 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Druhy tekvíc a farba\n",
"\n",
"Načítajte potrebné knižnice a dataset. Preveďte údaje na dataframe obsahujúci podmnožinu údajov:\n",
"\n",
"Pozrime sa na vzťah medzi farbou a druhom.\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>City Name</th>\n",
" <th>Type</th>\n",
" <th>Package</th>\n",
" <th>Variety</th>\n",
" <th>Sub Variety</th>\n",
" <th>Grade</th>\n",
" <th>Date</th>\n",
" <th>Low Price</th>\n",
" <th>High Price</th>\n",
" <th>Mostly Low</th>\n",
" <th>...</th>\n",
" <th>Unit of Sale</th>\n",
" <th>Quality</th>\n",
" <th>Condition</th>\n",
" <th>Appearance</th>\n",
" <th>Storage</th>\n",
" <th>Crop</th>\n",
" <th>Repack</th>\n",
" <th>Trans Mode</th>\n",
" <th>Unnamed: 24</th>\n",
" <th>Unnamed: 25</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>BALTIMORE</td>\n",
" <td>NaN</td>\n",
" <td>24 inch bins</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>4/29/17</td>\n",
" <td>270.0</td>\n",
" <td>280.0</td>\n",
" <td>270.0</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>E</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>BALTIMORE</td>\n",
" <td>NaN</td>\n",
" <td>24 inch bins</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>5/6/17</td>\n",
" <td>270.0</td>\n",
" <td>280.0</td>\n",
" <td>270.0</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>E</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>BALTIMORE</td>\n",
" <td>NaN</td>\n",
" <td>24 inch bins</td>\n",
" <td>HOWDEN TYPE</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>9/24/16</td>\n",
" <td>160.0</td>\n",
" <td>160.0</td>\n",
" <td>160.0</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>N</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>BALTIMORE</td>\n",
" <td>NaN</td>\n",
" <td>24 inch bins</td>\n",
" <td>HOWDEN TYPE</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>9/24/16</td>\n",
" <td>160.0</td>\n",
" <td>160.0</td>\n",
" <td>160.0</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>N</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>BALTIMORE</td>\n",
" <td>NaN</td>\n",
" <td>24 inch bins</td>\n",
" <td>HOWDEN TYPE</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>11/5/16</td>\n",
" <td>90.0</td>\n",
" <td>100.0</td>\n",
" <td>90.0</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>N</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5 rows × 26 columns</p>\n",
"</div>"
],
"text/plain": [
" City Name Type Package Variety Sub Variety Grade Date \\\n",
"0 BALTIMORE NaN 24 inch bins NaN NaN NaN 4/29/17 \n",
"1 BALTIMORE NaN 24 inch bins NaN NaN NaN 5/6/17 \n",
"2 BALTIMORE NaN 24 inch bins HOWDEN TYPE NaN NaN 9/24/16 \n",
"3 BALTIMORE NaN 24 inch bins HOWDEN TYPE NaN NaN 9/24/16 \n",
"4 BALTIMORE NaN 24 inch bins HOWDEN TYPE NaN NaN 11/5/16 \n",
"\n",
" Low Price High Price Mostly Low ... Unit of Sale Quality Condition \\\n",
"0 270.0 280.0 270.0 ... NaN NaN NaN \n",
"1 270.0 280.0 270.0 ... NaN NaN NaN \n",
"2 160.0 160.0 160.0 ... NaN NaN NaN \n",
"3 160.0 160.0 160.0 ... NaN NaN NaN \n",
"4 90.0 100.0 90.0 ... NaN NaN NaN \n",
"\n",
" Appearance Storage Crop Repack Trans Mode Unnamed: 24 Unnamed: 25 \n",
"0 NaN NaN NaN E NaN NaN NaN \n",
"1 NaN NaN NaN E NaN NaN NaN \n",
"2 NaN NaN NaN N NaN NaN NaN \n",
"3 NaN NaN NaN N NaN NaN NaN \n",
"4 NaN NaN NaN N NaN NaN NaN \n",
"\n",
"[5 rows x 26 columns]"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"\n",
"full_pumpkins = pd.read_csv('../data/US-pumpkins.csv')\n",
"\n",
"full_pumpkins.head()\n"
]
},
{
"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"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.1"
},
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
}
},
"orig_nbformat": 2,
"coopTranslator": {
"original_hash": "dee08c2b49057b0de8b6752c4dbca368",
"translation_date": "2025-09-06T13:26:21+00:00",
"source_file": "2-Regression/4-Logistic/notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

@ -0,0 +1,686 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Vytvorenie modelu logistickej regresie - Lekcia 4\n",
"\n",
"![Infografika: Logistická vs. lineárna regresia](../../../../../../2-Regression/4-Logistic/images/linear-vs-logistic.png)\n",
"\n",
"#### **[Kvíz pred prednáškou](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/15/)**\n",
"\n",
"#### Úvod\n",
"\n",
"V tejto záverečnej lekcii o regresii, jednej zo základných *klasických* techník strojového učenia, sa pozrieme na logistickú regresiu. Túto techniku by ste použili na objavenie vzorcov na predpovedanie binárnych kategórií. Je táto cukrovinka čokoláda alebo nie? Je táto choroba nákazlivá alebo nie? Vyberie si tento zákazník tento produkt alebo nie?\n",
"\n",
"V tejto lekcii sa naučíte:\n",
"\n",
"- Techniky logistickej regresie\n",
"\n",
"✅ Prehĺbte si svoje porozumenie práce s týmto typom regresie v tomto [učebnom module](https://learn.microsoft.com/training/modules/introduction-classification-models/?WT.mc_id=academic-77952-leestott)\n",
"\n",
"## Predpoklady\n",
"\n",
"Keďže sme pracovali s údajmi o tekviciach, sme už dostatočne oboznámení s tým, že existuje jedna binárna kategória, s ktorou môžeme pracovať: `Color`.\n",
"\n",
"Vytvorme model logistickej regresie na predpovedanie toho, *akú farbu bude mať daná tekvica* (oranžová 🎃 alebo biela 👻).\n",
"\n",
"> Prečo hovoríme o binárnej klasifikácii v lekcii zameranej na regresiu? Len z jazykového pohodlia, keďže logistická regresia je [v skutočnosti metóda klasifikácie](https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression), hoci založená na lineárnom prístupe. O ďalších spôsoboch klasifikácie údajov sa dozviete v nasledujúcej skupine lekcií.\n",
"\n",
"Pre túto lekciu 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 [kolekcie balíkov](https://www.tidymodels.org/packages/) na modelovanie a strojové učenie.\n",
"\n",
"- `janitor`: Balík [janitor](https://github.com/sfirke/janitor) poskytuje jednoduché nástroje na skúmanie a čistenie nečistých údajov.\n",
"\n",
"- `ggbeeswarm`: Balík [ggbeeswarm](https://github.com/eclarke/ggbeeswarm) poskytuje metódy na vytváranie grafov v štýle \"beeswarm\" pomocou ggplot2.\n",
"\n",
"Môžete ich nainštalovať pomocou:\n",
"\n",
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"janitor\", \"ggbeeswarm\"))`\n",
"\n",
"Alternatívne, skript nižšie skontroluje, či máte balíky potrebné na dokončenie tohto modulu, a nainštaluje ich za vás, ak chýbajú.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"suppressWarnings(if (!require(\"pacman\"))install.packages(\"pacman\"))\n",
"\n",
"pacman::p_load(tidyverse, tidymodels, janitor, ggbeeswarm)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## **Definovanie otázky**\n",
"\n",
"Pre naše účely vyjadríme otázku ako binárnu: 'Biela' alebo 'Nie biela'. V našej dátovej sade sa nachádza aj kategória 'pruhovaná', ale má len málo záznamov, takže ju nebudeme používať. Táto kategória aj tak zmizne, keď odstránime nulové hodnoty z dátovej sady.\n",
"\n",
"> 🎃 Zaujímavosť: biele tekvice niekedy nazývame 'duchové' tekvice. Nie sú veľmi ľahké na vyrezávanie, takže nie sú také populárne ako oranžové, ale vyzerajú zaujímavo! Mohli by sme teda našu otázku preformulovať ako: 'Duch' alebo 'Nie duch'. 👻\n",
"\n",
"## **O logistickej regresii**\n",
"\n",
"Logistická regresia sa v niekoľkých dôležitých aspektoch líši od lineárnej regresie, ktorú ste sa učili predtým.\n",
"\n",
"#### **Binárna klasifikácia**\n",
"\n",
"Logistická regresia neponúka rovnaké funkcie ako lineárna regresia. Prvá ponúka predikciu o `binárnej kategórii` (\"oranžová alebo nie oranžová\"), zatiaľ čo druhá dokáže predpovedať `kontinuálne hodnoty`, napríklad na základe pôvodu tekvice a času zberu *o koľko sa zvýši jej cena*.\n",
"\n",
"![Infografika od Dasani Madipalli](../../../../../../2-Regression/4-Logistic/images/pumpkin-classifier.png)\n",
"\n",
"### Iné typy klasifikácií\n",
"\n",
"Existujú aj iné typy logistickej regresie, vrátane multinomiálnej a ordinálnej:\n",
"\n",
"- **Multinomiálna**, ktorá zahŕňa viac ako jednu kategóriu - \"Oranžová, Biela a Pruhovaná\".\n",
"\n",
"- **Ordinálna**, ktorá zahŕňa usporiadané kategórie, užitočné, ak chceme logicky zoradiť naše výsledky, napríklad naše tekvice zoradené podľa konečného počtu veľkostí (mini, malá, stredná, veľká, XL, XXL).\n",
"\n",
"![Multinomiálna vs ordinálna regresia](../../../../../../2-Regression/4-Logistic/images/multinomial-vs-ordinal.png)\n",
"\n",
"#### **Premenné NEMUSIA korelovať**\n",
"\n",
"Pamätáte si, ako lineárna regresia fungovala lepšie s viac korelovanými premennými? Logistická regresia je opakom - premenné nemusia byť v súlade. To je výhodné pre tieto dáta, ktoré majú pomerne slabé korelácie.\n",
"\n",
"#### **Potrebujete veľa čistých dát**\n",
"\n",
"Logistická regresia poskytne presnejšie výsledky, ak použijete viac dát; naša malá dátová sada nie je pre túto úlohu optimálna, takže to majte na pamäti.\n",
"\n",
"✅ Zamyslite sa nad typmi dát, ktoré by sa dobre hodili na logistickú regresiu.\n",
"\n",
"## Cvičenie - upravte dáta\n",
"\n",
"Najprv trochu upravte dáta, odstráňte nulové hodnoty a vyberte len niektoré stĺpce:\n",
"\n",
"1. Pridajte nasledujúci kód:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Load the core tidyverse packages\n",
"library(tidyverse)\n",
"\n",
"# Import the data and clean column names\n",
"pumpkins <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/2-Regression/data/US-pumpkins.csv\") %>% \n",
" clean_names()\n",
"\n",
"# Select desired columns\n",
"pumpkins_select <- pumpkins %>% \n",
" select(c(city_name, package, variety, origin, item_size, color)) \n",
"\n",
"# Drop rows containing missing values and encode color as factor (category)\n",
"pumpkins_select <- pumpkins_select %>% \n",
" drop_na() %>% \n",
" mutate(color = factor(color))\n",
"\n",
"# View the first few rows\n",
"pumpkins_select %>% \n",
" slice_head(n = 5)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Vždy sa môžete pozrieť na svoj nový dataframe pomocou funkcie [*glimpse()*](https://pillar.r-lib.org/reference/glimpse.html), ako je uvedené nižšie:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"pumpkins_select %>% \n",
" glimpse()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Poďme si potvrdiť, že sa skutočne budeme zaoberať problémom binárnej klasifikácie:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Subset distinct observations in outcome column\n",
"pumpkins_select %>% \n",
" distinct(color)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Vizualizácia - kategóriálny graf\n",
"Teraz ste znova načítali údaje o tekviciach a vyčistili ich tak, aby ste zachovali dataset obsahujúci niekoľko premenných, vrátane farby (Color). Poďme si vizualizovať dataframe v notebooku pomocou knižnice ggplot.\n",
"\n",
"Knižnica ggplot ponúka niekoľko skvelých spôsobov, ako vizualizovať vaše údaje. Napríklad môžete porovnať rozdelenia údajov pre každú odrodu (Variety) a farbu (Color) v kategóriálnom grafe.\n",
"\n",
"1. Vytvorte takýto graf pomocou funkcie geombar, pričom použijete naše údaje o tekviciach a špecifikujete farebné mapovanie pre každú kategóriu tekvíc (oranžová alebo biela):\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "python"
}
},
"outputs": [],
"source": [
"# Specify colors for each value of the hue variable\n",
"palette <- c(ORANGE = \"orange\", WHITE = \"wheat\")\n",
"\n",
"# Create the bar plot\n",
"ggplot(pumpkins_select, aes(y = variety, fill = color)) +\n",
" geom_bar(position = \"dodge\") +\n",
" scale_fill_manual(values = palette) +\n",
" labs(y = \"Variety\", fill = \"Color\") +\n",
" theme_minimal()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Pozorovaním údajov môžete vidieť, ako sa údaje o Farbe vzťahujú k Odrode.\n",
"\n",
"✅ Na základe tohto kategóriálneho grafu, aké zaujímavé skúmania si dokážete predstaviť?\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Predspracovanie údajov: kódovanie vlastností\n",
"\n",
"Náš dataset tekvíc obsahuje textové hodnoty vo všetkých svojich stĺpcoch. Práca s kategorizovanými údajmi je pre ľudí intuitívna, ale pre stroje nie. Algoritmy strojového učenia pracujú dobre s číslami. Preto je kódovanie veľmi dôležitým krokom vo fáze predspracovania údajov, pretože nám umožňuje premeniť kategorizované údaje na číselné údaje bez straty informácií. Dobré kódovanie vedie k vytvoreniu dobrého modelu.\n",
"\n",
"Pre kódovanie vlastností existujú dva hlavné typy kóderov:\n",
"\n",
"1. Ordinálny kóder: je vhodný pre ordinálne premenné, čo sú kategorizované premenné, kde ich údaje nasledujú logické poradie, ako napríklad stĺpec `item_size` v našom datasete. Vytvára mapovanie, kde každá kategória je reprezentovaná číslom, ktoré zodpovedá poradiu kategórie v stĺpci.\n",
"\n",
"2. Kategorizovaný kóder: je vhodný pre nominálne premenné, čo sú kategorizované premenné, kde ich údaje nenasledujú logické poradie, ako všetky vlastnosti okrem `item_size` v našom datasete. Ide o kódovanie typu one-hot, čo znamená, že každá kategória je reprezentovaná binárnym stĺpcom: kódovaná premenná je rovná 1, ak tekvica patrí do danej Variety, a 0 v opačnom prípade.\n",
"\n",
"Tidymodels poskytuje ďalší šikovný balík: [recipes](https://recipes.tidymodels.org/) - balík na predspracovanie údajov. Definujeme `recipe`, ktorý špecifikuje, že všetky stĺpce prediktorov by mali byť kódované do množiny celých čísel, `prep` na odhad potrebných množstiev a štatistík potrebných pre akékoľvek operácie a nakoniec `bake` na aplikáciu výpočtov na nové údaje.\n",
"\n",
"> Bežne sa recipes zvyčajne používa ako predspracovateľ pre modelovanie, kde definuje, aké kroky by sa mali aplikovať na dataset, aby bol pripravený na modelovanie. V takom prípade je **veľmi odporúčané**, aby ste použili `workflow()` namiesto manuálneho odhadu receptu pomocou prep a bake. Všetko toto si ukážeme už čoskoro.\n",
">\n",
"> Avšak momentálne používame recipes + prep + bake na špecifikáciu krokov, ktoré by sa mali aplikovať na dataset, aby bol pripravený na analýzu údajov, a následne extrahujeme predspracované údaje s aplikovanými krokmi.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Preprocess and extract data to allow some data analysis\n",
"baked_pumpkins <- recipe(color ~ ., data = pumpkins_select) %>%\n",
" # Define ordering for item_size column\n",
" step_mutate(item_size = ordered(item_size, levels = c('sml', 'med', 'med-lge', 'lge', 'xlge', 'jbo', 'exjbo'))) %>%\n",
" # Convert factors to numbers using the order defined above (Ordinal encoding)\n",
" step_integer(item_size, zero_based = F) %>%\n",
" # Encode all other predictors using one hot encoding\n",
" step_dummy(all_nominal(), -all_outcomes(), one_hot = TRUE) %>%\n",
" prep(data = pumpkin_select) %>%\n",
" bake(new_data = NULL)\n",
"\n",
"# Display the first few rows of preprocessed data\n",
"baked_pumpkins %>% \n",
" slice_head(n = 5)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"✅ Aké sú výhody použitia ordinálneho enkodéra pre stĺpec Item Size?\n",
"\n",
"### Analyzujte vzťahy medzi premennými\n",
"\n",
"Teraz, keď sme predspracovali naše údaje, môžeme analyzovať vzťahy medzi vlastnosťami a štítkom, aby sme získali predstavu o tom, ako dobre bude model schopný predpovedať štítok na základe vlastností. Najlepší spôsob, ako vykonať tento typ analýzy, je vizualizácia údajov. \n",
"Opäť použijeme funkciu ggplot geom_boxplot_, aby sme zobrazili vzťahy medzi Item Size, Variety a Color v kategóriálnom grafe. Na lepšiu vizualizáciu údajov použijeme enkódovaný stĺpec Item Size a neenkódovaný stĺpec Variety.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Define the color palette\n",
"palette <- c(ORANGE = \"orange\", WHITE = \"wheat\")\n",
"\n",
"# We need the encoded Item Size column to use it as the x-axis values in the plot\n",
"pumpkins_select_plot<-pumpkins_select\n",
"pumpkins_select_plot$item_size <- baked_pumpkins$item_size\n",
"\n",
"# Create the grouped box plot\n",
"ggplot(pumpkins_select_plot, aes(x = `item_size`, y = color, fill = color)) +\n",
" geom_boxplot() +\n",
" facet_grid(variety ~ ., scales = \"free_x\") +\n",
" scale_fill_manual(values = palette) +\n",
" labs(x = \"Item Size\", y = \"\") +\n",
" theme_minimal() +\n",
" theme(strip.text = element_text(size = 12)) +\n",
" theme(axis.text.x = element_text(size = 10)) +\n",
" theme(axis.title.x = element_text(size = 12)) +\n",
" theme(axis.title.y = element_blank()) +\n",
" theme(legend.position = \"bottom\") +\n",
" guides(fill = guide_legend(title = \"Color\")) +\n",
" theme(panel.spacing = unit(0.5, \"lines\"))+\n",
" theme(strip.text.y = element_text(size = 4, hjust = 0)) \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Použitie swarm grafu\n",
"\n",
"Keďže Color je binárna kategória (Biela alebo Nie), vyžaduje si '[špeciálny prístup](https://github.com/rstudio/cheatsheets/blob/main/data-visualization.pdf)' k vizualizácii.\n",
"\n",
"Vyskúšajte `swarm graf`, aby ste zobrazili rozloženie farby vo vzťahu k item_size.\n",
"\n",
"Použijeme balík [ggbeeswarm](https://github.com/eclarke/ggbeeswarm), ktorý poskytuje metódy na vytváranie grafov v štýle beeswarm pomocou ggplot2. Beeswarm grafy sú spôsob, ako zobrazovať body, ktoré by sa za normálnych okolností prekrývali, tak, aby boli vedľa seba.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Create beeswarm plots of color and item_size\n",
"baked_pumpkins %>% \n",
" mutate(color = factor(color)) %>% \n",
" ggplot(mapping = aes(x = color, y = item_size, color = color)) +\n",
" geom_quasirandom() +\n",
" scale_color_brewer(palette = \"Dark2\", direction = -1) +\n",
" theme(legend.position = \"none\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Teraz, keď máme predstavu o vzťahu medzi binárnymi kategóriami farieb a väčšou skupinou veľkostí, poďme preskúmať logistickú regresiu na určenie pravdepodobnej farby danej tekvice.\n",
"\n",
"## Vytvorte svoj model\n",
"\n",
"Vyberte premenné, ktoré chcete použiť vo svojom klasifikačnom modeli, a rozdeľte údaje na tréningovú a testovaciu množinu. [rsample](https://rsample.tidymodels.org/), balík v rámci Tidymodels, poskytuje infraštruktúru na efektívne delenie a resamplovanie údajov:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Split data into 80% for training and 20% for testing\n",
"set.seed(2056)\n",
"pumpkins_split <- pumpkins_select %>% \n",
" initial_split(prop = 0.8)\n",
"\n",
"# Extract the data in each split\n",
"pumpkins_train <- training(pumpkins_split)\n",
"pumpkins_test <- testing(pumpkins_split)\n",
"\n",
"# Print out the first 5 rows of the training set\n",
"pumpkins_train %>% \n",
" slice_head(n = 5)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"🙌 Teraz sme pripravení trénovať model prispôsobením tréningových vlastností tréningovej značke (farba).\n",
"\n",
"Začneme vytvorením receptu, ktorý špecifikuje kroky predspracovania, ktoré by sa mali vykonať na našich údajoch, aby boli pripravené na modelovanie, t.j. kódovanie kategóriálnych premenných na množinu celých čísel. Rovnako ako `baked_pumpkins`, vytvoríme `pumpkins_recipe`, ale nebudeme používať `prep` a `bake`, pretože to bude zahrnuté do pracovného toku, čo uvidíte o pár krokov neskôr.\n",
"\n",
"Existuje pomerne veľa spôsobov, ako špecifikovať logistickú regresiu v Tidymodels. Pozrite si `?logistic_reg()`. Zatiaľ špecifikujeme logistickú regresiu prostredníctvom predvoleného enginu `stats::glm()`.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Create a recipe that specifies preprocessing steps for modelling\n",
"pumpkins_recipe <- recipe(color ~ ., data = pumpkins_train) %>% \n",
" step_mutate(item_size = ordered(item_size, levels = c('sml', 'med', 'med-lge', 'lge', 'xlge', 'jbo', 'exjbo'))) %>%\n",
" step_integer(item_size, zero_based = F) %>% \n",
" step_dummy(all_nominal(), -all_outcomes(), one_hot = TRUE)\n",
"\n",
"# Create a logistic model specification\n",
"log_reg <- logistic_reg() %>% \n",
" set_engine(\"glm\") %>% \n",
" set_mode(\"classification\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Teraz, keď máme recept a špecifikáciu modelu, musíme nájsť spôsob, ako ich spojiť do objektu, ktorý najskôr predspracuje údaje (príprava + pečenie na pozadí), prispôsobí model na predspracovaných údajoch a zároveň umožní potenciálne aktivity po spracovaní.\n",
"\n",
"V Tidymodels sa tento praktický objekt nazýva [`workflow`](https://workflows.tidymodels.org/) a pohodlne uchováva vaše modelovacie komponenty.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Bundle modelling components in a workflow\n",
"log_reg_wf <- workflow() %>% \n",
" add_recipe(pumpkins_recipe) %>% \n",
" add_model(log_reg)\n",
"\n",
"# Print out the workflow\n",
"log_reg_wf\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Po definovaní *pracovného postupu* môže byť model `natrénovaný` pomocou funkcie [`fit()`](https://tidymodels.github.io/parsnip/reference/fit.html). Pracovný postup odhadne recept a pred spracovaním údajov ich predpripraví, takže to nebudeme musieť robiť manuálne pomocou funkcií prep a bake.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Train the model\n",
"wf_fit <- log_reg_wf %>% \n",
" fit(data = pumpkins_train)\n",
"\n",
"# Print the trained workflow\n",
"wf_fit\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Model vytlačí koeficienty naučené počas tréningu.\n",
"\n",
"Teraz, keď sme model natrénovali pomocou tréningových dát, môžeme robiť predpovede na testovacích dátach pomocou [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html). Začnime tým, že použijeme model na predpovedanie štítkov pre náš testovací súbor a pravdepodobností pre každý štítok. Keď je pravdepodobnosť vyššia ako 0.5, predpovedaná trieda je `WHITE`, inak `ORANGE`.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Make predictions for color and corresponding probabilities\n",
"results <- pumpkins_test %>% select(color) %>% \n",
" bind_cols(wf_fit %>% \n",
" predict(new_data = pumpkins_test)) %>%\n",
" bind_cols(wf_fit %>%\n",
" predict(new_data = pumpkins_test, type = \"prob\"))\n",
"\n",
"# Compare predictions\n",
"results %>% \n",
" slice_head(n = 10)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Veľmi pekné! Toto poskytuje ďalší pohľad na to, ako funguje logistická regresia.\n",
"\n",
"### Lepšie pochopenie pomocou matice zámien\n",
"\n",
"Porovnávanie každej predikcie s jej zodpovedajúcou „skutočnou hodnotou“ nie je veľmi efektívny spôsob, ako určiť, ako dobre model predikuje. Našťastie má Tidymodels v rukáve ešte niekoľko trikov: [`yardstick`](https://yardstick.tidymodels.org/) - balík používaný na meranie efektívnosti modelov pomocou metrík výkonnosti.\n",
"\n",
"Jednou z metrík výkonnosti spojených s klasifikačnými problémami je [`matica zámien`](https://wikipedia.org/wiki/Confusion_matrix). Matica zámien opisuje, ako dobre klasifikačný model funguje. Matica zámien zaznamenáva, koľko príkladov v každej triede bolo modelom správne klasifikovaných. V našom prípade vám ukáže, koľko oranžových tekvíc bolo klasifikovaných ako oranžové a koľko bielych tekvíc bolo klasifikovaných ako biele; matica zámien vám tiež ukáže, koľko ich bolo klasifikovaných do **nesprávnych** kategórií.\n",
"\n",
"Funkcia [**`conf_mat()`**](https://tidymodels.github.io/yardstick/reference/conf_mat.html) z yardstick vypočíta túto krížovú tabuľku pozorovaných a predikovaných tried.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Confusion matrix for prediction results\n",
"conf_mat(data = results, truth = color, estimate = .pred_class)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Poďme interpretovať maticu zámien. Náš model má za úlohu klasifikovať tekvice do dvoch binárnych kategórií, kategórie `biela` a kategórie `nie-biela`.\n",
"\n",
"- Ak váš model predpovedá tekvicu ako bielu a v skutočnosti patrí do kategórie 'biela', nazývame to `pravý pozitívny`, čo je znázornené číslom v ľavom hornom rohu.\n",
"\n",
"- Ak váš model predpovedá tekvicu ako nie-bielu a v skutočnosti patrí do kategórie 'biela', nazývame to `falošný negatívny`, čo je znázornené číslom v ľavom dolnom rohu.\n",
"\n",
"- Ak váš model predpovedá tekvicu ako bielu a v skutočnosti patrí do kategórie 'nie-biela', nazývame to `falošný pozitívny`, čo je znázornené číslom v pravom hornom rohu.\n",
"\n",
"- Ak váš model predpovedá tekvicu ako nie-bielu a v skutočnosti patrí do kategórie 'nie-biela', nazývame to `pravý negatívny`, čo je znázornené číslom v pravom dolnom rohu.\n",
"\n",
"| Pravda |\n",
"|:-----:|\n",
"\n",
"\n",
"| | | |\n",
"|---------------|--------|-------|\n",
"| **Predikcia** | BIELA | ORANŽOVÁ |\n",
"| BIELA | TP | FP |\n",
"| ORANŽOVÁ | FN | TN |\n",
"\n",
"Ako ste možno uhádli, je preferované mať vyšší počet pravých pozitívnych a pravých negatívnych a nižší počet falošných pozitívnych a falošných negatívnych, čo naznačuje, že model funguje lepšie.\n",
"\n",
"Matica zámien je užitočná, pretože umožňuje odvodiť ďalšie metriky, ktoré nám môžu pomôcť lepšie vyhodnotiť výkon klasifikačného modelu. Poďme si ich prejsť:\n",
"\n",
"🎓 Presnosť: `TP/(TP + FP)` definovaná ako podiel predpokladaných pozitívnych, ktoré sú skutočne pozitívne. Tiež nazývaná [pozitívna prediktívna hodnota](https://en.wikipedia.org/wiki/Positive_predictive_value \"Positive predictive value\").\n",
"\n",
"🎓 Návratnosť: `TP/(TP + FN)` definovaná ako podiel pozitívnych výsledkov z počtu vzoriek, ktoré boli skutočne pozitívne. Tiež známa ako `citlivosť`.\n",
"\n",
"🎓 Špecifickosť: `TN/(TN + FP)` definovaná ako podiel negatívnych výsledkov z počtu vzoriek, ktoré boli skutočne negatívne.\n",
"\n",
"🎓 Presnosť modelu: `TP + TN/(TP + TN + FP + FN)` Percento správne predpovedaných označení pre vzorku.\n",
"\n",
"🎓 F Miera: Vážený priemer presnosti a návratnosti, pričom najlepšia hodnota je 1 a najhoršia je 0.\n",
"\n",
"Poďme vypočítať tieto metriky!\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Combine metric functions and calculate them all at once\n",
"eval_metrics <- metric_set(ppv, recall, spec, f_meas, accuracy)\n",
"eval_metrics(data = results, truth = color, estimate = .pred_class)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Vizualizácia ROC krivky tohto modelu\n",
"\n",
"Urobme ešte jednu vizualizáciu, aby sme si pozreli tzv. [`ROC krivku`](https://en.wikipedia.org/wiki/Receiver_operating_characteristic):\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Make a roc_curve\n",
"results %>% \n",
" roc_curve(color, .pred_ORANGE) %>% \n",
" autoplot()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"ROC krivky sa často používajú na zobrazenie výstupu klasifikátora z hľadiska jeho skutočných vs. falošných pozitívnych výsledkov. ROC krivky zvyčajne zobrazujú `True Positive Rate`/citlivosť na osi Y a `False Positive Rate`/1-špecifickosť na osi X. Preto je dôležitá strmosť krivky a priestor medzi stredovou čiarou a krivkou: chcete krivku, ktorá rýchlo stúpa a prechádza nad čiaru. V našom prípade sú na začiatku falošné pozitívne výsledky, a potom krivka správne stúpa a prechádza nad čiaru.\n",
"\n",
"Nakoniec použime `yardstick::roc_auc()` na výpočet skutočnej plochy pod krivkou (Area Under the Curve). Jedným zo spôsobov interpretácie AUC je pravdepodobnosť, že model hodnotí náhodný pozitívny príklad vyššie ako náhodný negatívny príklad.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Calculate area under curve\n",
"results %>% \n",
" roc_auc(color, .pred_ORANGE)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Výsledok je približne `0.975`. Keďže AUC sa pohybuje v rozmedzí od 0 do 1, chcete dosiahnuť vysoké skóre, pretože model, ktorý je na 100 % presný vo svojich predpovediach, bude mať AUC rovné 1; v tomto prípade je model *celkom dobrý*.\n",
"\n",
"V budúcich lekciách o klasifikáciách sa naučíte, ako zlepšiť skóre vášho modelu (napríklad riešením problémov s nevyváženými údajmi, ako v tomto prípade).\n",
"\n",
"## 🚀Výzva\n",
"\n",
"Logistická regresia ponúka veľa možností na preskúmanie! Najlepší spôsob, ako sa ju naučiť, je experimentovať. Nájdite dataset, ktorý sa hodí na tento typ analýzy, a vytvorte s ním model. Čo ste sa naučili? tip: skúste [Kaggle](https://www.kaggle.com/search?q=logistic+regression+datasets) pre zaujímavé datasety.\n",
"\n",
"## Prehľad a samostatné štúdium\n",
"\n",
"Prečítajte si prvé strany [tohto článku zo Stanfordu](https://web.stanford.edu/~jurafsky/slp3/5.pdf) o niektorých praktických využitiach logistickej regresie. Zamyslite sa nad úlohami, ktoré sú lepšie prispôsobené jednému alebo druhému typu regresných úloh, ktoré sme doteraz študovali. Čo by fungovalo najlepšie?\n"
]
},
{
"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 žiadne nedorozumenia alebo nesprávne interpretácie vyplývajúce z použitia tohto prekladu.\n"
]
}
],
"metadata": {
"anaconda-cloud": "",
"kernelspec": {
"display_name": "R",
"langauge": "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": "feaf125f481a89c468fa115bf2aed580",
"translation_date": "2025-09-06T13:29:46+00:00",
"source_file": "2-Regression/4-Logistic/solution/R/lesson_4-R.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 1
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,267 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"orig_nbformat": 2,
"kernelspec": {
"name": "python37364bit8d3b438fb5fc4430a93ac2cb74d693a7",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
}
},
"coopTranslator": {
"original_hash": "5fa2e8f4584c78250ca9729b46562ceb",
"translation_date": "2025-09-06T14:32:02+00:00",
"source_file": "3-Web-App/1-Web-App/solution/notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"source": [],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" datetime city state country shape \\\n",
"0 10/10/1949 20:30 san marcos tx us cylinder \n",
"1 10/10/1949 21:00 lackland afb tx NaN light \n",
"2 10/10/1955 17:00 chester (uk/england) NaN gb circle \n",
"3 10/10/1956 21:00 edna tx us circle \n",
"4 10/10/1960 20:00 kaneohe hi us light \n",
"\n",
" duration (seconds) duration (hours/min) \\\n",
"0 2700.0 45 minutes \n",
"1 7200.0 1-2 hrs \n",
"2 20.0 20 seconds \n",
"3 20.0 1/2 hour \n",
"4 900.0 15 minutes \n",
"\n",
" comments date posted latitude \\\n",
"0 This event took place in early fall around 194... 4/27/2004 29.883056 \n",
"1 1949 Lackland AFB&#44 TX. Lights racing acros... 12/16/2005 29.384210 \n",
"2 Green/Orange circular disc over Chester&#44 En... 1/21/2008 53.200000 \n",
"3 My older brother and twin sister were leaving ... 1/17/2004 28.978333 \n",
"4 AS a Marine 1st Lt. flying an FJ4B fighter/att... 1/22/2004 21.418056 \n",
"\n",
" longitude \n",
"0 -97.941111 \n",
"1 -98.581082 \n",
"2 -2.916667 \n",
"3 -96.645833 \n",
"4 -157.803611 "
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>datetime</th>\n <th>city</th>\n <th>state</th>\n <th>country</th>\n <th>shape</th>\n <th>duration (seconds)</th>\n <th>duration (hours/min)</th>\n <th>comments</th>\n <th>date posted</th>\n <th>latitude</th>\n <th>longitude</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>10/10/1949 20:30</td>\n <td>san marcos</td>\n <td>tx</td>\n <td>us</td>\n <td>cylinder</td>\n <td>2700.0</td>\n <td>45 minutes</td>\n <td>This event took place in early fall around 194...</td>\n <td>4/27/2004</td>\n <td>29.883056</td>\n <td>-97.941111</td>\n </tr>\n <tr>\n <th>1</th>\n <td>10/10/1949 21:00</td>\n <td>lackland afb</td>\n <td>tx</td>\n <td>NaN</td>\n <td>light</td>\n <td>7200.0</td>\n <td>1-2 hrs</td>\n <td>1949 Lackland AFB&amp;#44 TX. Lights racing acros...</td>\n <td>12/16/2005</td>\n <td>29.384210</td>\n <td>-98.581082</td>\n </tr>\n <tr>\n <th>2</th>\n <td>10/10/1955 17:00</td>\n <td>chester (uk/england)</td>\n <td>NaN</td>\n <td>gb</td>\n <td>circle</td>\n <td>20.0</td>\n <td>20 seconds</td>\n <td>Green/Orange circular disc over Chester&amp;#44 En...</td>\n <td>1/21/2008</td>\n <td>53.200000</td>\n <td>-2.916667</td>\n </tr>\n <tr>\n <th>3</th>\n <td>10/10/1956 21:00</td>\n <td>edna</td>\n <td>tx</td>\n <td>us</td>\n <td>circle</td>\n <td>20.0</td>\n <td>1/2 hour</td>\n <td>My older brother and twin sister were leaving ...</td>\n <td>1/17/2004</td>\n <td>28.978333</td>\n <td>-96.645833</td>\n </tr>\n <tr>\n <th>4</th>\n <td>10/10/1960 20:00</td>\n <td>kaneohe</td>\n <td>hi</td>\n <td>us</td>\n <td>light</td>\n <td>900.0</td>\n <td>15 minutes</td>\n <td>AS a Marine 1st Lt. flying an FJ4B fighter/att...</td>\n <td>1/22/2004</td>\n <td>21.418056</td>\n <td>-157.803611</td>\n </tr>\n </tbody>\n</table>\n</div>"
},
"metadata": {},
"execution_count": 23
}
],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"\n",
"ufos = pd.read_csv('../data/ufos.csv')\n",
"ufos.head()\n"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"array(['us', nan, 'gb', 'ca', 'au', 'de'], dtype=object)"
]
},
"metadata": {},
"execution_count": 24
}
],
"source": [
"\n",
"ufos = pd.DataFrame({'Seconds': ufos['duration (seconds)'], 'Country': ufos['country'],'Latitude': ufos['latitude'],'Longitude': ufos['longitude']})\n",
"\n",
"ufos.Country.unique()\n",
"\n",
"# 0 au, 1 ca, 2 de, 3 gb, 4 us"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"<class 'pandas.core.frame.DataFrame'>\nInt64Index: 25863 entries, 2 to 80330\nData columns (total 4 columns):\n # Column Non-Null Count Dtype \n--- ------ -------------- ----- \n 0 Seconds 25863 non-null float64\n 1 Country 25863 non-null object \n 2 Latitude 25863 non-null float64\n 3 Longitude 25863 non-null float64\ndtypes: float64(3), object(1)\nmemory usage: 1010.3+ KB\n"
]
}
],
"source": [
"ufos.dropna(inplace=True)\n",
"\n",
"ufos = ufos[(ufos['Seconds'] >= 1) & (ufos['Seconds'] <= 60)]\n",
"\n",
"ufos.info()"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Seconds Country Latitude Longitude\n",
"2 20.0 3 53.200000 -2.916667\n",
"3 20.0 4 28.978333 -96.645833\n",
"14 30.0 4 35.823889 -80.253611\n",
"23 60.0 4 45.582778 -122.352222\n",
"24 3.0 3 51.783333 -0.783333"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>Seconds</th>\n <th>Country</th>\n <th>Latitude</th>\n <th>Longitude</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>2</th>\n <td>20.0</td>\n <td>3</td>\n <td>53.200000</td>\n <td>-2.916667</td>\n </tr>\n <tr>\n <th>3</th>\n <td>20.0</td>\n <td>4</td>\n <td>28.978333</td>\n <td>-96.645833</td>\n </tr>\n <tr>\n <th>14</th>\n <td>30.0</td>\n <td>4</td>\n <td>35.823889</td>\n <td>-80.253611</td>\n </tr>\n <tr>\n <th>23</th>\n <td>60.0</td>\n <td>4</td>\n <td>45.582778</td>\n <td>-122.352222</td>\n </tr>\n <tr>\n <th>24</th>\n <td>3.0</td>\n <td>3</td>\n <td>51.783333</td>\n <td>-0.783333</td>\n </tr>\n </tbody>\n</table>\n</div>"
},
"metadata": {},
"execution_count": 26
}
],
"source": [
"from sklearn.preprocessing import LabelEncoder\n",
"\n",
"ufos['Country'] = LabelEncoder().fit_transform(ufos['Country'])\n",
"\n",
"ufos.head()"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.model_selection import train_test_split\n",
"\n",
"Selected_features = ['Seconds','Latitude','Longitude']\n",
"\n",
"X = ufos[Selected_features]\n",
"y = ufos['Country']\n",
"\n",
"\n",
"X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)\n"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n",
" FutureWarning)\n",
"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:469: FutureWarning: Default multi_class will be changed to 'auto' in 0.22. Specify the multi_class option to silence this warning.\n",
" \"this warning.\", FutureWarning)\n",
" precision recall f1-score support\n",
"\n",
" 0 1.00 1.00 1.00 41\n",
" 1 1.00 0.02 0.05 250\n",
" 2 0.00 0.00 0.00 8\n",
" 3 0.94 1.00 0.97 131\n",
" 4 0.95 1.00 0.97 4743\n",
"\n",
" accuracy 0.95 5173\n",
" macro avg 0.78 0.60 0.60 5173\n",
"weighted avg 0.95 0.95 0.93 5173\n",
"\n",
"Predicted labels: [4 4 4 ... 3 4 4]\n",
"Accuracy: 0.9512855209742895\n",
"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/metrics/classification.py:1437: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples.\n",
" 'precision', 'predicted', average, warn_for)\n"
]
}
],
"source": [
"from sklearn.model_selection import train_test_split\n",
"from sklearn.metrics import accuracy_score, classification_report \n",
"from sklearn.linear_model import LogisticRegression\n",
"model = LogisticRegression()\n",
"model.fit(X_train, y_train)\n",
"predictions = model.predict(X_test)\n",
"\n",
"print(classification_report(y_test, predictions))\n",
"print('Predicted labels: ', predictions)\n",
"print('Accuracy: ', accuracy_score(y_test, predictions))\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"[3]\n"
]
}
],
"source": [
"import pickle\n",
"model_filename = 'ufo-model.pkl'\n",
"pickle.dump(model, open(model_filename,'wb'))\n",
"\n",
"model = pickle.load(open('ufo-model.pkl','rb'))\n",
"print(model.predict([[50,44,-12]]))\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Upozornenie**: \nTento dokument bol preložený pomocou služby AI prekladu [Co-op Translator](https://github.com/Azure/co-op-translator). Aj keď sa snažíme o presnosť, prosím, berte na vedomie, že automatizované 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 kritické informácie sa odporúča profesionálny ľudský preklad. Nie sme zodpovední za akékoľvek nedorozumenia alebo nesprávne interpretácie vyplývajúce z použitia tohto prekladu.\n"
]
}
]
}

@ -0,0 +1,39 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": 3
},
"orig_nbformat": 2,
"coopTranslator": {
"original_hash": "d544ef384b7ba73757d830a72372a7f2",
"translation_date": "2025-09-06T14:50:40+00:00",
"source_file": "4-Classification/1-Introduction/notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"source": [],
"cell_type": "markdown",
"metadata": {}
},
{
"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"
]
}
]
}

@ -0,0 +1,721 @@
{
"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-06T14:54:24+00:00",
"source_file": "4-Classification/1-Introduction/solution/R/lesson_10-R.ipynb",
"language_code": "sk"
}
},
"cells": [
{
"cell_type": "markdown",
"source": [],
"metadata": {
"id": "ItETB4tSFprR"
}
},
{
"cell_type": "markdown",
"source": [
"## Úvod do klasifikácie: Čistenie, príprava a vizualizácia dát\n",
"\n",
"V týchto štyroch lekciách sa zameriame na základný aspekt klasického strojového učenia - *klasifikáciu*. Prejdeme si používanie rôznych klasifikačných algoritmov na dátovom súbore o všetkých úžasných kuchyniach Ázie a Indie. Dúfame, že máte chuť na jedlo!\n",
"\n",
"<p >\n",
" <img src=\"../../images/pinch.png\"\n",
" width=\"600\"/>\n",
" <figcaption>Oslávte panázijské kuchyne v týchto lekciách! Obrázok od Jen Looper</figcaption>\n",
"\n",
"\n",
"<!--![Oslávte panázijské kuchyne v týchto lekciách! Obrázok od Jen Looper](../../../../../../4-Classification/1-Introduction/solution/R/images/pinch.png)-->\n",
"\n",
"Klasifikácia je forma [supervised learning](https://wikipedia.org/wiki/Supervised_learning), ktorá má veľa spoločného s regresnými technikami. Pri klasifikácii trénujete model, aby predpovedal, do akej `kategórie` položka patrí. Ak je strojové učenie o predpovedaní hodnôt alebo názvov vecí pomocou dátových súborov, potom klasifikácia všeobecne spadá do dvoch skupín: *binárna klasifikácia* a *multiklasová klasifikácia*.\n",
"\n",
"Pamätajte:\n",
"\n",
"- **Lineárna regresia** vám pomohla predpovedať vzťahy medzi premennými a presne určiť, kde by nový dátový bod spadal vo vzťahu k tejto línii. Napríklad ste mohli predpovedať číselné hodnoty, ako *aká bude cena tekvice v septembri vs. decembri*.\n",
"\n",
"- **Logistická regresia** vám pomohla objaviť \"binárne kategórie\": pri tejto cenovej úrovni, *je táto tekvica oranžová alebo nie-oranžová*?\n",
"\n",
"Klasifikácia používa rôzne algoritmy na určenie ďalších spôsobov, ako priradiť dátovému bodu štítok alebo triedu. Poďme pracovať s týmito dátami o kuchyniach, aby sme zistili, či na základe skupiny ingrediencií dokážeme určiť jej pôvodnú kuchyňu.\n",
"\n",
"### [**Kvíz pred prednáškou**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/19/)\n",
"\n",
"### **Úvod**\n",
"\n",
"Klasifikácia je jednou zo základných aktivít výskumníka strojového učenia a dátového vedca. Od základnej klasifikácie binárnej hodnoty (\"je tento e-mail spam alebo nie?\") až po komplexnú klasifikáciu a segmentáciu obrázkov pomocou počítačového videnia, je vždy užitočné vedieť triediť dáta do tried a klásť im otázky.\n",
"\n",
"Ak to vyjadríme vedeckejšie, vaša klasifikačná metóda vytvára prediktívny model, ktorý vám umožňuje mapovať vzťah medzi vstupnými premennými a výstupnými premennými.\n",
"\n",
"<p >\n",
" <img src=\"../../images/binary-multiclass.png\"\n",
" width=\"600\"/>\n",
" <figcaption>Binárne vs. multiklasové problémy, ktoré klasifikačné algoritmy riešia. Infografika od Jen Looper</figcaption>\n",
"\n",
"\n",
"\n",
"Predtým, než začneme proces čistenia našich dát, ich vizualizácie a prípravy na úlohy strojového učenia, poďme sa naučiť niečo o rôznych spôsoboch, ako môže byť strojové učenie využité na klasifikáciu dát.\n",
"\n",
"Odvodené zo [štatistiky](https://wikipedia.org/wiki/Statistical_classification), klasifikácia pomocou klasického strojového učenia používa vlastnosti, ako `fajčiar`, `hmotnosť` a `vek`, na určenie *pravdepodobnosti vývoja X choroby*. Ako technika supervised learning podobná regresným cvičeniam, ktoré ste vykonávali skôr, vaše dáta sú označené a algoritmy strojového učenia používajú tieto označenia na klasifikáciu a predpovedanie tried (alebo 'vlastností') dátového súboru a ich priradenie do skupiny alebo výsledku.\n",
"\n",
"✅ Predstavte si na chvíľu dátový súbor o kuchyniach. Na čo by mohol odpovedať multiklasový model? Na čo by mohol odpovedať binárny model? Čo ak by ste chceli určiť, či daná kuchyňa pravdepodobne používa senovku grécku? Čo ak by ste chceli zistiť, či by ste na základe daru tašky s potravinami plnej badiánu, artičokov, karfiolu a chrenu mohli vytvoriť typické indické jedlo?\n",
"\n",
"### **Ahoj 'klasifikátor'**\n",
"\n",
"Otázka, ktorú chceme položiť tomuto dátovému súboru o kuchyniach, je vlastne **multiklasová otázka**, pretože máme niekoľko potenciálnych národných kuchýň, s ktorými môžeme pracovať. Na základe dávky ingrediencií, do ktorej z týchto mnohých tried budú dáta patriť?\n",
"\n",
"Tidymodels ponúka niekoľko rôznych algoritmov na klasifikáciu dát, v závislosti od typu problému, ktorý chcete vyriešiť. V nasledujúcich dvoch lekciách sa naučíte o niekoľkých z týchto algoritmov.\n",
"\n",
"#### **Predpoklad**\n",
"\n",
"Pre túto lekciu budeme potrebovať nasledujúce balíky na čistenie, prípravu a vizualizáciu našich dát:\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 [kolekcie balíkov](https://www.tidymodels.org/packages/) na modelovanie a strojové učenie.\n",
"\n",
"- `DataExplorer`: Balík [DataExplorer](https://cran.r-project.org/web/packages/DataExplorer/vignettes/dataexplorer-intro.html) je určený na zjednodušenie a automatizáciu procesu EDA a generovania správ.\n",
"\n",
"- `themis`: Balík [themis](https://themis.tidymodels.org/) poskytuje extra kroky receptov na riešenie nevyvážených dát.\n",
"\n",
"Môžete ich nainštalovať pomocou:\n",
"\n",
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"DataExplorer\", \"here\"))`\n",
"\n",
"Alternatívne, skript nižšie skontroluje, či máte balíky potrebné na dokončenie tohto modulu, a nainštaluje ich za vás, ak chýbajú.\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": [
"Neskôr načítame tieto úžasné balíky a sprístupníme ich v našej aktuálnej R relácii. (Toto je len na ilustráciu, `pacman::p_load()` to už za vás urobil)\n"
],
"metadata": {
"id": "YkKAxOJvGD4C"
}
},
{
"cell_type": "markdown",
"source": [
"## Cvičenie - vyčistite a vyvážte svoje dáta\n",
"\n",
"Prvým krokom pred začatím tohto projektu je vyčistiť a **vyvážiť** svoje dáta, aby ste dosiahli lepšie výsledky.\n",
"\n",
"Zoznámme sa s dátami! 🕵️\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": [
"Zaujímavé! Podľa vzhľadu to vyzerá, že prvý stĺpec je akýsi stĺpec `id`. Poďme získať trochu viac informácií o údajoch.\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": [
"Z výstupu môžeme okamžite vidieť, že máme `2448` riadkov a `385` stĺpcov a `0` chýbajúcich hodnôt. Máme tiež 1 diskrétny stĺpec, *cuisine*.\n",
"\n",
"## Cvičenie - učenie sa o kuchyniach\n",
"\n",
"Teraz sa práca začína stávať zaujímavejšou. Poďme objaviť rozdelenie údajov podľa kuchyne.\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": [
"Existuje konečný počet kuchýň, ale rozloženie údajov je nerovnomerné. Môžete to napraviť! Predtým však preskúmajte trochu viac.\n",
"\n",
"Ďalej priraďme každú kuchyňu do jej vlastného tibble a zistime, koľko údajov je k dispozícii (riadky, stĺpce) na jednu kuchyňu.\n",
"\n",
"> [Tibble](https://tibble.tidyverse.org/) je moderný dátový rámec.\n",
"\n",
"<p >\n",
" <img src=\"../../images/dplyr_filter.jpg\"\n",
" width=\"600\"/>\n",
" <figcaption>Ilustrácia od @allison_horst</figcaption>\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": [
"## **Cvičenie - Objavovanie hlavných ingrediencií podľa kuchyne pomocou dplyr**\n",
"\n",
"Teraz sa môžete hlbšie ponoriť do údajov a zistiť, aké sú typické ingrediencie pre jednotlivé kuchyne. Mali by ste odstrániť opakujúce sa údaje, ktoré spôsobujú zmätok medzi kuchyňami, takže sa poďme pozrieť na tento problém.\n",
"\n",
"Vytvorte funkciu `create_ingredient()` v R, ktorá vráti dataframe s ingredienciami. Táto funkcia začne odstránením nepotrebného stĺpca a zoradí ingrediencie podľa ich počtu.\n",
"\n",
"Základná štruktúra funkcie v R je:\n",
"\n",
"`myFunction <- function(arglist){`\n",
"\n",
"**`...`**\n",
"\n",
"**`return`**`(value)`\n",
"\n",
"`}`\n",
"\n",
"Úhľadný úvod do funkcií v R nájdete [tu](https://skirmer.github.io/presentations/functions_with_r.html#1).\n",
"\n",
"Poďme na to! Využijeme [dplyr slovesá](https://dplyr.tidyverse.org/), ktoré sme sa učili v predchádzajúcich lekciách. Na zopakovanie:\n",
"\n",
"- `dplyr::select()`: pomáha vám vybrať, ktoré **stĺpce** chcete ponechať alebo vylúčiť.\n",
"\n",
"- `dplyr::pivot_longer()`: pomáha \"predĺžiť\" údaje, čím sa zvýši počet riadkov a zníži počet stĺpcov.\n",
"\n",
"- `dplyr::group_by()` a `dplyr::summarise()`: pomáha nájsť štatistické súhrny pre rôzne skupiny a usporiadať ich do prehľadnej tabuľky.\n",
"\n",
"- `dplyr::filter()`: vytvára podmnožinu údajov obsahujúcu iba riadky, ktoré spĺňajú vaše podmienky.\n",
"\n",
"- `dplyr::mutate()`: pomáha vytvárať alebo upravovať stĺpce.\n",
"\n",
"Pozrite si tento [*umelecky* ladený learnr tutoriál](https://allisonhorst.shinyapps.io/dplyr-learnr/#section-welcome) od Allison Horst, ktorý predstavuje niektoré užitočné funkcie na spracovanie údajov v dplyr *(súčasť 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": [
"Teraz môžeme použiť funkciu na získanie predstavy o desiatich najpopulárnejších ingredienciách podľa kuchyne. Poďme si to vyskúšať s `thai_df`.\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": [
"V predchádzajúcej časti sme použili `geom_col()`, pozrime sa, ako môžete použiť aj `geom_bar` na vytvorenie stĺpcových grafov. Použite `?geom_bar` na ďalšie čítanie.\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": [],
"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": [
"Čo tak čínska kuchyňa?\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": [],
"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": [
"Z vizualizácií dát môžeme teraz vynechať najbežnejšie ingrediencie, ktoré spôsobujú zmätok medzi odlišnými kuchyňami, pomocou `dplyr::select()`.\n",
"\n",
"Každý miluje ryžu, cesnak a zázvor!\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": [
"## Predspracovanie údajov pomocou receptov 👩‍🍳👨‍🍳 - Riešenie nevyvážených údajov ⚖️\n",
"\n",
"<p >\n",
" <img src=\"../../images/recipes.png\"\n",
" width=\"600\"/>\n",
" <figcaption>Ilustrácia od @allison_horst</figcaption>\n",
"\n",
"Keďže táto lekcia je o kuchyniach, musíme dať `recepty` do kontextu.\n",
"\n",
"Tidymodels poskytuje ďalší šikovný balík: `recipes` - balík na predspracovanie údajov.\n"
],
"metadata": {
"id": "kkFd-JxdIaL6"
}
},
{
"cell_type": "markdown",
"source": [
"Pozrime sa znova na rozdelenie našich kuchýň.\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": [
"Ako vidíte, počet kuchýň je dosť nerovnomerne rozdelený. Kórejské kuchyne sú takmer 3-krát početnejšie ako thajské kuchyne. Nevyvážené údaje často negatívne ovplyvňujú výkon modelu. Zamyslite sa nad binárnou klasifikáciou. Ak väčšina vašich údajov patrí do jednej triedy, model strojového učenia bude túto triedu predpovedať častejšie, jednoducho preto, že má k dispozícii viac údajov. Vyváženie údajov odstraňuje akúkoľvek skreslenosť a pomáha eliminovať túto nerovnováhu. Mnohé modely dosahujú najlepšie výsledky, keď je počet pozorovaní rovnaký, a preto majú tendenciu zápasiť s nevyváženými údajmi.\n",
"\n",
"Existujú dva hlavné spôsoby, ako sa vysporiadať s nevyváženými dátovými súbormi:\n",
"\n",
"- pridanie pozorovaní do minoritnej triedy: `Over-sampling`, napr. pomocou algoritmu SMOTE\n",
"\n",
"- odstránenie pozorovaní z majoritnej triedy: `Under-sampling`\n",
"\n",
"Teraz si ukážeme, ako pracovať s nevyváženými dátovými súbormi pomocou `receptu`. Recept si môžete predstaviť ako plán, ktorý popisuje, aké kroky by sa mali aplikovať na dátový súbor, aby bol pripravený na analýzu údajov.\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": [
"Poďme si rozobrať naše kroky predspracovania.\n",
"\n",
"- Volanie funkcie `recipe()` s formulou určuje *úlohy* premenných pomocou údajov `df_select` ako referencie. Napríklad stĺpec `cuisine` bol priradený úlohe `outcome`, zatiaľ čo ostatné stĺpce boli priradené úlohe `predictor`.\n",
"\n",
"- [`step_smote(cuisine)`](https://themis.tidymodels.org/reference/step_smote.html) vytvára *špecifikáciu* kroku receptu, ktorý synteticky generuje nové príklady minoritnej triedy pomocou najbližších susedov týchto prípadov.\n",
"\n",
"Ak by sme teraz chceli vidieť predspracované údaje, museli by sme [**`prep()`**](https://recipes.tidymodels.org/reference/prep.html) a [**`bake()`**](https://recipes.tidymodels.org/reference/bake.html) náš recept.\n",
"\n",
"`prep()`: odhaduje potrebné parametre z tréningovej množiny, ktoré môžu byť neskôr aplikované na iné množiny údajov.\n",
"\n",
"`bake()`: vezme pripravený recept a aplikuje operácie na akúkoľvek množinu údajov.\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": [
"Poďme teraz skontrolovať rozdelenie našich kuchýň a porovnať ich s nevyváženými údajmi.\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": [
"Mňam! Dáta sú pekné, čisté, vyvážené a veľmi chutné 😋!\n",
"\n",
"> Zvyčajne sa recept používa ako predspracovateľ pre modelovanie, kde definuje, aké kroky by sa mali aplikovať na dátovú sadu, aby bola pripravená na modelovanie. V takom prípade sa typicky používa `workflow()` (ako sme už videli v našich predchádzajúcich lekciách) namiesto manuálneho odhadovania receptu.\n",
">\n",
"> Preto zvyčajne nepotrebujete **`prep()`** a **`bake()`** recepty, keď používate tidymodels, ale sú to užitočné funkcie, ktoré môžete mať vo svojej výbave na potvrdenie, že recepty robia to, čo očakávate, ako v našom prípade.\n",
">\n",
"> Keď **`bake()`** predspracovaný recept s **`new_data = NULL`**, dostanete späť dáta, ktoré ste poskytli pri definovaní receptu, ale už prešli krokmi predspracovania.\n",
"\n",
"Teraz si uložíme kópiu týchto dát na použitie v budúcich lekciách:\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": [
"Tento nový CSV súbor sa teraz nachádza v hlavnom priečinku s dátami.\n",
"\n",
"**🚀Výzva**\n",
"\n",
"Tento učebný plán obsahuje niekoľko zaujímavých datasetov. Prezrite si priečinky `data` a zistite, či niektoré obsahujú datasety vhodné na binárnu alebo viactriednu klasifikáciu. Aké otázky by ste mohli položiť tomuto datasetu?\n",
"\n",
"## [**Kvíz po prednáške**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/20/)\n",
"\n",
"## **Prehľad a samostatné štúdium**\n",
"\n",
"- Pozrite si [balík themis](https://github.com/tidymodels/themis). Aké ďalšie techniky by sme mohli použiť na riešenie nevyvážených dát?\n",
"\n",
"- Referenčná stránka [Tidy models](https://www.tidymodels.org/start/).\n",
"\n",
"- H. Wickham a G. Grolemund, [*R for Data Science: Vizualizácia, modelovanie, transformácia, úprava a import dát*](https://r4ds.had.co.nz/).\n",
"\n",
"#### ĎAKUJEME:\n",
"\n",
"[`Allison Horst`](https://twitter.com/allison_horst/) 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",
"\n",
"[Cassie Breviu](https://www.twitter.com/cassieview) a [Jen Looper](https://www.twitter.com/jenlooper) za vytvorenie pôvodnej verzie tohto modulu v Pythone ♥️\n",
"\n",
"<p >\n",
" <img src=\"../../images/r_learners_sm.jpeg\"\n",
" width=\"600\"/>\n",
" <figcaption>Ilustrácia od @allison_horst</figcaption>\n"
],
"metadata": {
"id": "WQs5621pMGwf"
}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Upozornenie**: \nTento dokument bol preložený pomocou služby AI prekladu [Co-op Translator](https://github.com/Azure/co-op-translator). Hoci sa snažíme o presnosť, prosím, berte na vedomie, že automatizované preklady môžu obsahovať chyby alebo nepresnosti. Pôvodný dokument v jeho rodnom jazyku by mal byť považovaný za autoritatívny zdroj. Pre kritické informácie sa odporúča profesionálny ľudský preklad. Nie sme zodpovední za akékoľvek nedorozumenia alebo nesprávne interpretácie vyplývajúce z použitia tohto prekladu.\n"
]
}
]
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,39 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": 3
},
"orig_nbformat": 2,
"coopTranslator": {
"original_hash": "68829b06b4dcd512d3327849191f4d7f",
"translation_date": "2025-09-06T14:32:28+00:00",
"source_file": "4-Classification/2-Classifiers-1/notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"source": [],
"cell_type": "markdown",
"metadata": {}
},
{
"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"
]
}
]
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,279 @@
{
"cells": [
{
"source": [],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Unnamed: 0 cuisine almond angelica anise anise_seed apple \\\n",
"0 0 indian 0 0 0 0 0 \n",
"1 1 indian 1 0 0 0 0 \n",
"2 2 indian 0 0 0 0 0 \n",
"3 3 indian 0 0 0 0 0 \n",
"4 4 indian 0 0 0 0 0 \n",
"\n",
" apple_brandy apricot armagnac ... whiskey white_bread white_wine \\\n",
"0 0 0 0 ... 0 0 0 \n",
"1 0 0 0 ... 0 0 0 \n",
"2 0 0 0 ... 0 0 0 \n",
"3 0 0 0 ... 0 0 0 \n",
"4 0 0 0 ... 0 0 0 \n",
"\n",
" whole_grain_wheat_flour wine wood yam yeast yogurt zucchini \n",
"0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 1 0 \n",
"\n",
"[5 rows x 382 columns]"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>Unnamed: 0</th>\n <th>cuisine</th>\n <th>almond</th>\n <th>angelica</th>\n <th>anise</th>\n <th>anise_seed</th>\n <th>apple</th>\n <th>apple_brandy</th>\n <th>apricot</th>\n <th>armagnac</th>\n <th>...</th>\n <th>whiskey</th>\n <th>white_bread</th>\n <th>white_wine</th>\n <th>whole_grain_wheat_flour</th>\n <th>wine</th>\n <th>wood</th>\n <th>yam</th>\n <th>yeast</th>\n <th>yogurt</th>\n <th>zucchini</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>indian</td>\n <td>1</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>2</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>3</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>4</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>1</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 382 columns</p>\n</div>"
},
"metadata": {},
"execution_count": 1
}
],
"source": [
"import pandas as pd\n",
"cuisines_df = pd.read_csv(\"../../data/cleaned_cuisines.csv\")\n",
"cuisines_df.head()"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.linear_model import LogisticRegression\n",
"from sklearn.model_selection import train_test_split, cross_val_score\n",
"from sklearn.metrics import accuracy_score,precision_score,confusion_matrix,classification_report, precision_recall_curve\n",
"from sklearn.svm import SVC\n",
"import numpy as np"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"0 indian\n",
"1 indian\n",
"2 indian\n",
"3 indian\n",
"4 indian\n",
"Name: cuisine, dtype: object"
]
},
"metadata": {},
"execution_count": 3
}
],
"source": [
"cuisines_label_df = cuisines_df['cuisine']\n",
"cuisines_label_df.head()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" almond angelica anise anise_seed apple apple_brandy apricot \\\n",
"0 0 0 0 0 0 0 0 \n",
"1 1 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 0 \n",
"\n",
" armagnac artemisia artichoke ... whiskey white_bread white_wine \\\n",
"0 0 0 0 ... 0 0 0 \n",
"1 0 0 0 ... 0 0 0 \n",
"2 0 0 0 ... 0 0 0 \n",
"3 0 0 0 ... 0 0 0 \n",
"4 0 0 0 ... 0 0 0 \n",
"\n",
" whole_grain_wheat_flour wine wood yam yeast yogurt zucchini \n",
"0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 1 0 \n",
"\n",
"[5 rows x 380 columns]"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>almond</th>\n <th>angelica</th>\n <th>anise</th>\n <th>anise_seed</th>\n <th>apple</th>\n <th>apple_brandy</th>\n <th>apricot</th>\n <th>armagnac</th>\n <th>artemisia</th>\n <th>artichoke</th>\n <th>...</th>\n <th>whiskey</th>\n <th>white_bread</th>\n <th>white_wine</th>\n <th>whole_grain_wheat_flour</th>\n <th>wine</th>\n <th>wood</th>\n <th>yam</th>\n <th>yeast</th>\n <th>yogurt</th>\n <th>zucchini</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>1</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 380 columns</p>\n</div>"
},
"metadata": {},
"execution_count": 4
}
],
"source": [
"cuisines_feature_df = cuisines_df.drop(['Unnamed: 0', 'cuisine'], axis=1)\n",
"cuisines_feature_df.head()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"X_train, X_test, y_train, y_test = train_test_split(cuisines_feature_df, cuisines_label_df, test_size=0.3)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Accuracy is 0.8181818181818182\n"
]
}
],
"source": [
"lr = LogisticRegression(multi_class='ovr',solver='liblinear')\n",
"model = lr.fit(X_train, np.ravel(y_train))\n",
"\n",
"accuracy = model.score(X_test, y_test)\n",
"print (\"Accuracy is {}\".format(accuracy))"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"ingredients: Index(['artemisia', 'black_pepper', 'mushroom', 'shiitake', 'soy_sauce',\n 'vegetable_oil'],\n dtype='object')\ncuisine: korean\n"
]
}
],
"source": [
"# test an item\n",
"print(f'ingredients: {X_test.iloc[50][X_test.iloc[50]!=0].keys()}')\n",
"print(f'cuisine: {y_test.iloc[50]}')"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" 0\n",
"korean 0.392231\n",
"chinese 0.372872\n",
"japanese 0.218825\n",
"thai 0.013427\n",
"indian 0.002645"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>0</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>korean</th>\n <td>0.392231</td>\n </tr>\n <tr>\n <th>chinese</th>\n <td>0.372872</td>\n </tr>\n <tr>\n <th>japanese</th>\n <td>0.218825</td>\n </tr>\n <tr>\n <th>thai</th>\n <td>0.013427</td>\n </tr>\n <tr>\n <th>indian</th>\n <td>0.002645</td>\n </tr>\n </tbody>\n</table>\n</div>"
},
"metadata": {},
"execution_count": 8
}
],
"source": [
"#rehsape to 2d array and transpose\n",
"test= X_test.iloc[50].values.reshape(-1, 1).T\n",
"# predict with score\n",
"proba = model.predict_proba(test)\n",
"classes = model.classes_\n",
"# create df with classes and scores\n",
"resultdf = pd.DataFrame(data=proba, columns=classes)\n",
"\n",
"# create df to show results\n",
"topPrediction = resultdf.T.sort_values(by=[0], ascending = [False])\n",
"topPrediction.head()"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
" precision recall f1-score support\n\n chinese 0.75 0.73 0.74 223\n indian 0.93 0.88 0.90 255\n japanese 0.78 0.78 0.78 253\n korean 0.87 0.86 0.86 236\n thai 0.76 0.84 0.80 232\n\n accuracy 0.82 1199\n macro avg 0.82 0.82 0.82 1199\nweighted avg 0.82 0.82 0.82 1199\n\n"
]
}
],
"source": [
"y_pred = model.predict(X_test)\r\n",
"print(classification_report(y_test,y_pred))"
]
},
{
"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 žiadne nedorozumenia alebo nesprávne interpretácie vyplývajúce z použitia tohto prekladu.\n"
]
}
],
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
}
},
"coopTranslator": {
"original_hash": "9408506dd864f2b6e334c62f80c0cfcc",
"translation_date": "2025-09-06T14:32:57+00:00",
"source_file": "4-Classification/2-Classifiers-1/solution/notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

@ -0,0 +1,163 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": []
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Unnamed: 0 cuisine almond angelica anise anise_seed apple \\\n",
"0 0 indian 0 0 0 0 0 \n",
"1 1 indian 1 0 0 0 0 \n",
"2 2 indian 0 0 0 0 0 \n",
"3 3 indian 0 0 0 0 0 \n",
"4 4 indian 0 0 0 0 0 \n",
"\n",
" apple_brandy apricot armagnac ... whiskey white_bread white_wine \\\n",
"0 0 0 0 ... 0 0 0 \n",
"1 0 0 0 ... 0 0 0 \n",
"2 0 0 0 ... 0 0 0 \n",
"3 0 0 0 ... 0 0 0 \n",
"4 0 0 0 ... 0 0 0 \n",
"\n",
" whole_grain_wheat_flour wine wood yam yeast yogurt zucchini \n",
"0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 1 0 \n",
"\n",
"[5 rows x 382 columns]"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>Unnamed: 0</th>\n <th>cuisine</th>\n <th>almond</th>\n <th>angelica</th>\n <th>anise</th>\n <th>anise_seed</th>\n <th>apple</th>\n <th>apple_brandy</th>\n <th>apricot</th>\n <th>armagnac</th>\n <th>...</th>\n <th>whiskey</th>\n <th>white_bread</th>\n <th>white_wine</th>\n <th>whole_grain_wheat_flour</th>\n <th>wine</th>\n <th>wood</th>\n <th>yam</th>\n <th>yeast</th>\n <th>yogurt</th>\n <th>zucchini</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>indian</td>\n <td>1</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>2</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>3</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>4</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>1</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 382 columns</p>\n</div>"
},
"metadata": {},
"execution_count": 9
}
],
"source": [
"import pandas as pd\n",
"cuisines_df = pd.read_csv(\"../data/cleaned_cuisines.csv\")\n",
"cuisines_df.head()"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"0 indian\n",
"1 indian\n",
"2 indian\n",
"3 indian\n",
"4 indian\n",
"Name: cuisine, dtype: object"
]
},
"metadata": {},
"execution_count": 10
}
],
"source": [
"cuisines_label_df = cuisines_df['cuisine']\n",
"cuisines_label_df.head()"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" almond angelica anise anise_seed apple apple_brandy apricot \\\n",
"0 0 0 0 0 0 0 0 \n",
"1 1 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 0 \n",
"\n",
" armagnac artemisia artichoke ... whiskey white_bread white_wine \\\n",
"0 0 0 0 ... 0 0 0 \n",
"1 0 0 0 ... 0 0 0 \n",
"2 0 0 0 ... 0 0 0 \n",
"3 0 0 0 ... 0 0 0 \n",
"4 0 0 0 ... 0 0 0 \n",
"\n",
" whole_grain_wheat_flour wine wood yam yeast yogurt zucchini \n",
"0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 1 0 \n",
"\n",
"[5 rows x 380 columns]"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>almond</th>\n <th>angelica</th>\n <th>anise</th>\n <th>anise_seed</th>\n <th>apple</th>\n <th>apple_brandy</th>\n <th>apricot</th>\n <th>armagnac</th>\n <th>artemisia</th>\n <th>artichoke</th>\n <th>...</th>\n <th>whiskey</th>\n <th>white_bread</th>\n <th>white_wine</th>\n <th>whole_grain_wheat_flour</th>\n <th>wine</th>\n <th>wood</th>\n <th>yam</th>\n <th>yeast</th>\n <th>yogurt</th>\n <th>zucchini</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>1</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 380 columns</p>\n</div>"
},
"metadata": {},
"execution_count": 11
}
],
"source": [
"cuisines_feature_df = cuisines_df.drop(['Unnamed: 0', 'cuisine'], axis=1)\n",
"cuisines_feature_df.head()"
]
},
{
"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). Hoci 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 odporúčame 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"
]
}
],
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
}
},
"coopTranslator": {
"original_hash": "15a83277036572e0773229b5f21c1e12",
"translation_date": "2025-09-06T14:42:11+00:00",
"source_file": "4-Classification/3-Classifiers-2/notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

@ -0,0 +1,648 @@
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "lesson_12-R.ipynb",
"provenance": [],
"collapsed_sections": []
},
"kernelspec": {
"name": "ir",
"display_name": "R"
},
"language_info": {
"name": "R"
},
"coopTranslator": {
"original_hash": "fab50046ca413a38939d579f8432274f",
"translation_date": "2025-09-06T14:44:10+00:00",
"source_file": "4-Classification/3-Classifiers-2/solution/R/lesson_12-R.ipynb",
"language_code": "sk"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "jsFutf_ygqSx"
},
"source": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "HD54bEefgtNO"
},
"source": [
"## Klasifikátory kuchýň 2\n",
"\n",
"V tejto druhej lekcii o klasifikácii sa pozrieme na `ďalšie spôsoby`, ako klasifikovať kategóriálne údaje. Tiež sa oboznámime s dôsledkami výberu jedného klasifikátora oproti inému.\n",
"\n",
"### [**Kvíz pred prednáškou**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/23/)\n",
"\n",
"### **Predpoklady**\n",
"\n",
"Predpokladáme, že ste dokončili predchádzajúce lekcie, pretože budeme nadväzovať na niektoré koncepty, ktoré sme sa už naučili.\n",
"\n",
"Na túto lekciu 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/) určený na modelovanie a strojové učenie.\n",
"\n",
"- `themis`: [balík themis](https://themis.tidymodels.org/) poskytuje dodatočné kroky pre recepty na riešenie nevyvážených údajov.\n",
"\n",
"Môžete ich nainštalovať pomocou:\n",
"\n",
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"kernlab\", \"themis\", \"ranger\", \"xgboost\", \"kknn\"))`\n",
"\n",
"Prípadne, nasledujúci skript skontroluje, či máte nainštalované potrebné balíky na dokončenie tohto modulu, a v prípade, že chýbajú, ich nainštaluje za vás.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "vZ57IuUxgyQt"
},
"source": [
"suppressWarnings(if (!require(\"pacman\"))install.packages(\"pacman\"))\n",
"\n",
"pacman::p_load(tidyverse, tidymodels, themis, kernlab, ranger, xgboost, kknn)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "z22M-pj4g07x"
},
"source": [
"## **1. Mapa klasifikácie**\n",
"\n",
"V našej [predchádzajúcej lekcii](https://github.com/microsoft/ML-For-Beginners/tree/main/4-Classification/2-Classifiers-1) sme sa snažili odpovedať na otázku: ako si vybrať medzi viacerými modelmi? Do veľkej miery to závisí od charakteristík údajov a typu problému, ktorý chceme vyriešiť (napríklad klasifikácia alebo regresia?).\n",
"\n",
"Predtým sme sa naučili o rôznych možnostiach, ktoré máte pri klasifikácii údajov, pomocou prehľadovej tabuľky od Microsoftu. Pythonovský rámec pre strojové učenie, Scikit-learn, ponúka podobnú, ale podrobnejšiu prehľadovú tabuľku, ktorá vám môže ďalej pomôcť zúžiť výber vašich odhadovačov (iný výraz pre klasifikátory):\n",
"\n",
"<p >\n",
" <img src=\"../../images/map.png\"\n",
" width=\"700\"/>\n",
" <figcaption></figcaption>\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "u1i3xRIVg7vG"
},
"source": [
"> Tip: [navštívte túto mapu online](https://scikit-learn.org/stable/tutorial/machine_learning_map/) a kliknite na cestu, aby ste si prečítali dokumentáciu.\n",
">\n",
"> [Referenčná stránka Tidymodels](https://www.tidymodels.org/find/parsnip/#models) tiež poskytuje vynikajúcu dokumentáciu o rôznych typoch modelov.\n",
"\n",
"### **Plán** 🗺️\n",
"\n",
"Táto mapa je veľmi užitočná, ak máte jasné pochopenie svojich údajov, pretože sa môžete „prejsť“ po jej cestách k rozhodnutiu:\n",
"\n",
"- Máme viac ako 50 vzoriek\n",
"\n",
"- Chceme predpovedať kategóriu\n",
"\n",
"- Máme označené údaje\n",
"\n",
"- Máme menej ako 100K vzoriek\n",
"\n",
"- ✨ Môžeme si vybrať Linear SVC\n",
"\n",
"- Ak to nefunguje, keďže máme numerické údaje\n",
"\n",
" - Môžeme skúsiť ✨ KNeighbors Classifier\n",
"\n",
" - Ak to nefunguje, skúste ✨ SVC a ✨ Ensemble Classifiers\n",
"\n",
"Toto je veľmi užitočná cesta, ktorú sa oplatí nasledovať. Teraz sa do toho pustíme pomocou [tidymodels](https://www.tidymodels.org/) frameworku na modelovanie: konzistentnej a flexibilnej kolekcie balíkov v R, vyvinutej na podporu správnej štatistickej praxe 😊.\n",
"\n",
"## 2. Rozdelenie údajov a riešenie nevyváženého dátového súboru.\n",
"\n",
"Z našich predchádzajúcich lekcií sme sa naučili, že existuje súbor spoločných ingrediencií naprieč našimi kuchyňami. Tiež sme si všimli, že rozdelenie počtu kuchýň bolo dosť nerovnomerné.\n",
"\n",
"S týmto sa vysporiadame takto:\n",
"\n",
"- Odstránime najbežnejšie ingrediencie, ktoré spôsobujú zmätok medzi odlišnými kuchyňami, pomocou `dplyr::select()`.\n",
"\n",
"- Použijeme `recipe`, ktorý predspracuje údaje, aby boli pripravené na modelovanie, aplikovaním algoritmu `over-sampling`.\n",
"\n",
"Toto sme už prešli v predchádzajúcej lekcii, takže to bude hračka 🥳!\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "6tj_rN00hClA"
},
"source": [
"# Load the core Tidyverse and Tidymodels packages\n",
"library(tidyverse)\n",
"library(tidymodels)\n",
"\n",
"# Load the original cuisines data\n",
"df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/4-Classification/data/cuisines.csv\")\n",
"\n",
"# Drop id column, rice, garlic and ginger from our original data set\n",
"df_select <- df %>% \n",
" select(-c(1, rice, garlic, ginger)) %>%\n",
" # Encode cuisine column as categorical\n",
" mutate(cuisine = factor(cuisine))\n",
"\n",
"\n",
"# Create data split specification\n",
"set.seed(2056)\n",
"cuisines_split <- initial_split(data = df_select,\n",
" strata = cuisine,\n",
" prop = 0.7)\n",
"\n",
"# Extract the data in each split\n",
"cuisines_train <- training(cuisines_split)\n",
"cuisines_test <- testing(cuisines_split)\n",
"\n",
"# Display distribution of cuisines in the training set\n",
"cuisines_train %>% \n",
" count(cuisine) %>% \n",
" arrange(desc(n))"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "zFin5yw3hHb1"
},
"source": [
"### Riešenie nevyvážených údajov\n",
"\n",
"Nevyvážené údaje často negatívne ovplyvňujú výkon modelu. Mnohé modely dosahujú najlepšie výsledky, keď je počet pozorovaní rovnaký, a preto majú tendenciu zápasiť s nevyváženými údajmi.\n",
"\n",
"Existujú dva hlavné spôsoby, ako riešiť nevyvážené dátové súbory:\n",
"\n",
"- pridanie pozorovaní do minoritnej triedy: `Over-sampling`, napríklad pomocou algoritmu SMOTE, ktorý synteticky generuje nové príklady minoritnej triedy na základe najbližších susedov týchto prípadov.\n",
"\n",
"- odstránenie pozorovaní z majoritnej triedy: `Under-sampling`\n",
"\n",
"V našej predchádzajúcej lekcii sme ukázali, ako riešiť nevyvážené dátové súbory pomocou `recipe`. Recipe si môžete predstaviť ako plán, ktorý popisuje, aké kroky by sa mali aplikovať na dátový súbor, aby bol pripravený na analýzu údajov. V našom prípade chceme dosiahnuť rovnomerné rozdelenie počtu našich kuchýň pre náš `training set`. Poďme na to.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "cRzTnHolhLWd"
},
"source": [
"# Load themis package for dealing with imbalanced data\n",
"library(themis)\n",
"\n",
"# Create a recipe for preprocessing training data\n",
"cuisines_recipe <- recipe(cuisine ~ ., data = cuisines_train) %>%\n",
" step_smote(cuisine) \n",
"\n",
"# Print recipe\n",
"cuisines_recipe"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "KxOQ2ORhhO81"
},
"source": [
"Teraz sme pripravení trénovať modely 👩‍💻👨‍💻!\n",
"\n",
"## 3. Nad rámec multinomických regresných modelov\n",
"\n",
"V našej predchádzajúcej lekcii sme sa zaoberali multinomickými regresnými modelmi. Poďme preskúmať niektoré flexibilnejšie modely pre klasifikáciu.\n",
"\n",
"### Support Vector Machines.\n",
"\n",
"V kontexte klasifikácie je `Support Vector Machines` technika strojového učenia, ktorá sa snaží nájsť *hyperrovinu*, ktorá \"najlepšie\" oddeľuje triedy. Pozrime sa na jednoduchý príklad:\n",
"\n",
"<p >\n",
" <img src=\"../../images/svm.png\"\n",
" width=\"300\"/>\n",
" <figcaption>https://commons.wikimedia.org/w/index.php?curid=22877598</figcaption>\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "C4Wsd0vZhXYu"
},
"source": [
"H1~ neoddeľuje triedy. H2~ ich oddeľuje, ale iba s malým okrajom. H3~ ich oddeľuje s maximálnym okrajom.\n",
"\n",
"#### Lineárny Support Vector Classifier\n",
"\n",
"Support-Vector clustering (SVC) je súčasťou rodiny techník strojového učenia Support-Vector machines. V SVC je hyperplocha vybraná tak, aby správne oddelila `väčšinu` tréningových pozorovaní, ale `môže nesprávne klasifikovať` niektoré pozorovania. Tým, že umožníme niektorým bodom byť na nesprávnej strane, SVM sa stáva odolnejším voči odľahlým hodnotám, a tým lepšie generalizuje na nové dáta. Parameter, ktorý reguluje toto porušenie, sa nazýva `cost` a má predvolenú hodnotu 1 (pozri `help(\"svm_poly\")`).\n",
"\n",
"Vytvorme lineárny SVC nastavením `degree = 1` v polynomiálnom SVM modeli.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "vJpp6nuChlBz"
},
"source": [
"# Make a linear SVC specification\n",
"svc_linear_spec <- svm_poly(degree = 1) %>% \n",
" set_engine(\"kernlab\") %>% \n",
" set_mode(\"classification\")\n",
"\n",
"# Bundle specification and recipe into a worklow\n",
"svc_linear_wf <- workflow() %>% \n",
" add_recipe(cuisines_recipe) %>% \n",
" add_model(svc_linear_spec)\n",
"\n",
"# Print out workflow\n",
"svc_linear_wf"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "rDs8cWNkhoqu"
},
"source": [
"Teraz, keď sme zachytili kroky predspracovania a špecifikáciu modelu do *workflow*, môžeme pokračovať a natrénovať lineárny SVC a zároveň vyhodnotiť výsledky. Pre metriky výkonu vytvorme súbor metrík, ktorý bude hodnotiť: `presnosť`, `citlivosť`, `pozitívnu prediktívnu hodnotu` a `F mieru`.\n",
"\n",
"> `augment()` pridá stĺpec/stĺpce s predikciami k daným údajom.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "81wiqcwuhrnq"
},
"source": [
"# Train a linear SVC model\n",
"svc_linear_fit <- svc_linear_wf %>% \n",
" fit(data = cuisines_train)\n",
"\n",
"# Create a metric set\n",
"eval_metrics <- metric_set(ppv, sens, accuracy, f_meas)\n",
"\n",
"\n",
"# Make predictions and Evaluate model performance\n",
"svc_linear_fit %>% \n",
" augment(new_data = cuisines_test) %>% \n",
" eval_metrics(truth = cuisine, estimate = .pred_class)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "0UFQvHf-huo3"
},
"source": [
"#### Support Vector Machine\n",
"\n",
"Support vector machine (SVM) je rozšírením klasifikátora podporných vektorov, ktoré umožňuje zohľadniť nelineárnu hranicu medzi triedami. V podstate SVM využívajú *kernel trick* na rozšírenie priestoru vlastností, aby sa prispôsobili nelineárnym vzťahom medzi triedami. Jednou z populárnych a mimoriadne flexibilných funkcií jadra, ktorú SVM využívajú, je *Radial basis function.* Pozrime sa, ako bude fungovať na našich údajoch.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "-KX4S8mzhzmp"
},
"source": [
"set.seed(2056)\n",
"\n",
"# Make an RBF SVM specification\n",
"svm_rbf_spec <- svm_rbf() %>% \n",
" set_engine(\"kernlab\") %>% \n",
" set_mode(\"classification\")\n",
"\n",
"# Bundle specification and recipe into a worklow\n",
"svm_rbf_wf <- workflow() %>% \n",
" add_recipe(cuisines_recipe) %>% \n",
" add_model(svm_rbf_spec)\n",
"\n",
"\n",
"# Train an RBF model\n",
"svm_rbf_fit <- svm_rbf_wf %>% \n",
" fit(data = cuisines_train)\n",
"\n",
"\n",
"# Make predictions and Evaluate model performance\n",
"svm_rbf_fit %>% \n",
" augment(new_data = cuisines_test) %>% \n",
" eval_metrics(truth = cuisine, estimate = .pred_class)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "QBFSa7WSh4HQ"
},
"source": [
"Oveľa lepšie 🤩!\n",
"\n",
"> ✅ Pozrite si:\n",
">\n",
"> - [*Support Vector Machines*](https://bradleyboehmke.github.io/HOML/svm.html), Hands-on Machine Learning with R\n",
">\n",
"> - [*Support Vector Machines*](https://www.statlearning.com/), An Introduction to Statistical Learning with Applications in R\n",
">\n",
"> pre ďalšie čítanie.\n",
"\n",
"### Klasifikátory najbližšieho suseda\n",
"\n",
"Algoritmus *K*-najbližšieho suseda (KNN) predpovedá každé pozorovanie na základe jeho *podobnosti* s ostatnými pozorovaniami.\n",
"\n",
"Poďme ho aplikovať na naše dáta.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "k4BxxBcdh9Ka"
},
"source": [
"# Make a KNN specification\n",
"knn_spec <- nearest_neighbor() %>% \n",
" set_engine(\"kknn\") %>% \n",
" set_mode(\"classification\")\n",
"\n",
"# Bundle recipe and model specification into a workflow\n",
"knn_wf <- workflow() %>% \n",
" add_recipe(cuisines_recipe) %>% \n",
" add_model(knn_spec)\n",
"\n",
"# Train a boosted tree model\n",
"knn_wf_fit <- knn_wf %>% \n",
" fit(data = cuisines_train)\n",
"\n",
"\n",
"# Make predictions and Evaluate model performance\n",
"knn_wf_fit %>% \n",
" augment(new_data = cuisines_test) %>% \n",
" eval_metrics(truth = cuisine, estimate = .pred_class)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "HaegQseriAcj"
},
"source": [
"Zdá sa, že tento model nefunguje až tak dobre. Pravdepodobne zmena argumentov modelu (pozrite si `help(\"nearest_neighbor\")`) zlepší jeho výkon. Určite to vyskúšajte.\n",
"\n",
"> ✅ Pozrite si:\n",
">\n",
"> - [Hands-on Machine Learning with R](https://bradleyboehmke.github.io/HOML/)\n",
">\n",
"> - [An Introduction to Statistical Learning with Applications in R](https://www.statlearning.com/)\n",
">\n",
"> aby ste sa dozvedeli viac o klasifikátoroch *K*-Najbližších Susedov.\n",
"\n",
"### Ensemble klasifikátory\n",
"\n",
"Ensemble algoritmy fungujú tak, že kombinujú viacero základných odhadov, aby vytvorili optimálny model, buď:\n",
"\n",
"`bagging`: aplikáciou *priemerovacej funkcie* na kolekciu základných modelov\n",
"\n",
"`boosting`: vytváraním sekvencie modelov, ktoré na seba nadväzujú, aby zlepšili prediktívny výkon.\n",
"\n",
"Začnime tým, že vyskúšame model Random Forest, ktorý vytvára veľkú kolekciu rozhodovacích stromov a potom aplikuje priemerovaciu funkciu na vytvorenie lepšieho celkového modelu.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "49DPoVs6iK1M"
},
"source": [
"# Make a random forest specification\n",
"rf_spec <- rand_forest() %>% \n",
" set_engine(\"ranger\") %>% \n",
" set_mode(\"classification\")\n",
"\n",
"# Bundle recipe and model specification into a workflow\n",
"rf_wf <- workflow() %>% \n",
" add_recipe(cuisines_recipe) %>% \n",
" add_model(rf_spec)\n",
"\n",
"# Train a random forest model\n",
"rf_wf_fit <- rf_wf %>% \n",
" fit(data = cuisines_train)\n",
"\n",
"\n",
"# Make predictions and Evaluate model performance\n",
"rf_wf_fit %>% \n",
" augment(new_data = cuisines_test) %>% \n",
" eval_metrics(truth = cuisine, estimate = .pred_class)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "RGVYwC_aiUWc"
},
"source": [
"Dobrá práca 👏!\n",
"\n",
"Poďme tiež experimentovať s modelom Boosted Tree.\n",
"\n",
"Boosted Tree definuje ensemble metódu, ktorá vytvára sériu sekvenčných rozhodovacích stromov, kde každý strom závisí od výsledkov predchádzajúcich stromov v snahe postupne znižovať chybu. Zameriava sa na váhy nesprávne klasifikovaných položiek a upravuje prispôsobenie pre ďalší klasifikátor, aby ich opravil.\n",
"\n",
"Existujú rôzne spôsoby, ako tento model prispôsobiť (pozri `help(\"boost_tree\")`). V tomto príklade prispôsobíme Boosted stromy pomocou enginu `xgboost`.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "Py1YWo-micWs"
},
"source": [
"# Make a boosted tree specification\n",
"boost_spec <- boost_tree(trees = 200) %>% \n",
" set_engine(\"xgboost\") %>% \n",
" set_mode(\"classification\")\n",
"\n",
"# Bundle recipe and model specification into a workflow\n",
"boost_wf <- workflow() %>% \n",
" add_recipe(cuisines_recipe) %>% \n",
" add_model(boost_spec)\n",
"\n",
"# Train a boosted tree model\n",
"boost_wf_fit <- boost_wf %>% \n",
" fit(data = cuisines_train)\n",
"\n",
"\n",
"# Make predictions and Evaluate model performance\n",
"boost_wf_fit %>% \n",
" augment(new_data = cuisines_test) %>% \n",
" eval_metrics(truth = cuisine, estimate = .pred_class)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "zNQnbuejigZM"
},
"source": [
"> ✅ Pozrite si:\n",
">\n",
"> - [Machine Learning for Social Scientists](https://cimentadaj.github.io/ml_socsci/tree-based-methods.html#random-forests)\n",
">\n",
"> - [Hands-on Machine Learning with R](https://bradleyboehmke.github.io/HOML/)\n",
">\n",
"> - [An Introduction to Statistical Learning with Applications in R](https://www.statlearning.com/)\n",
">\n",
"> - <https://algotech.netlify.app/blog/xgboost/> - Skúma model AdaBoost, ktorý je dobrou alternatívou k xgboost.\n",
">\n",
"> pre viac informácií o Ensemble klasifikátoroch.\n",
"\n",
"## 4. Extra - porovnanie viacerých modelov\n",
"\n",
"V tomto cvičení sme vytvorili pomerne veľké množstvo modelov 🙌. Môže byť únavné alebo náročné vytvárať množstvo workflowov z rôznych sád predspracovania a/alebo špecifikácií modelov a potom jeden po druhom vypočítavať metriky výkonnosti.\n",
"\n",
"Pozrime sa, či to môžeme vyriešiť vytvorením funkcie, ktorá aplikuje zoznam workflowov na tréningovú množinu a následne vráti metriky výkonnosti na základe testovacej množiny. Použijeme `map()` a `map_dfr()` z balíka [purrr](https://purrr.tidyverse.org/) na aplikáciu funkcií na každý prvok zoznamu.\n",
"\n",
"> Funkcie [`map()`](https://purrr.tidyverse.org/reference/map.html) vám umožňujú nahradiť mnoho for-cyklov kódom, ktorý je stručnejší a ľahšie čitateľný. Najlepším miestom na učenie sa o funkciách [`map()`](https://purrr.tidyverse.org/reference/map.html) je [kapitola o iterácii](http://r4ds.had.co.nz/iteration.html) v knihe R for Data Science.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "Qzb7LyZnimd2"
},
"source": [
"set.seed(2056)\n",
"\n",
"# Create a metric set\n",
"eval_metrics <- metric_set(ppv, sens, accuracy, f_meas)\n",
"\n",
"# Define a function that returns performance metrics\n",
"compare_models <- function(workflow_list, train_set, test_set){\n",
" \n",
" suppressWarnings(\n",
" # Fit each model to the train_set\n",
" map(workflow_list, fit, data = train_set) %>% \n",
" # Make predictions on the test set\n",
" map_dfr(augment, new_data = test_set, .id = \"model\") %>%\n",
" # Select desired columns\n",
" select(model, cuisine, .pred_class) %>% \n",
" # Evaluate model performance\n",
" group_by(model) %>% \n",
" eval_metrics(truth = cuisine, estimate = .pred_class) %>% \n",
" ungroup()\n",
" )\n",
" \n",
"} # End of function"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "Fwa712sNisDA"
},
"source": []
},
{
"cell_type": "code",
"metadata": {
"id": "3i4VJOi2iu-a"
},
"source": [
"# Make a list of workflows\n",
"workflow_list <- list(\n",
" \"svc\" = svc_linear_wf,\n",
" \"svm\" = svm_rbf_wf,\n",
" \"knn\" = knn_wf,\n",
" \"random_forest\" = rf_wf,\n",
" \"xgboost\" = boost_wf)\n",
"\n",
"# Call the function\n",
"set.seed(2056)\n",
"perf_metrics <- compare_models(workflow_list = workflow_list, train_set = cuisines_train, test_set = cuisines_test)\n",
"\n",
"# Print out performance metrics\n",
"perf_metrics %>% \n",
" group_by(.metric) %>% \n",
" arrange(desc(.estimate)) %>% \n",
" slice_head(n=7)\n",
"\n",
"# Compare accuracy\n",
"perf_metrics %>% \n",
" filter(.metric == \"accuracy\") %>% \n",
" arrange(desc(.estimate))\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "KuWK_lEli4nW"
},
"source": [
"[**workflowset**](https://workflowsets.tidymodels.org/) balík umožňuje používateľom vytvárať a jednoducho prispôsobovať veľké množstvo modelov, ale je primárne navrhnutý na prácu s technikami resamplingu, ako je `krížová validácia`, ktorú si ešte len preberieme.\n",
"\n",
"## **🚀Výzva**\n",
"\n",
"Každá z týchto techník má veľké množstvo parametrov, ktoré môžete upravovať, napríklad `cost` v SVM, `neighbors` v KNN, `mtry` (náhodne vybrané prediktory) v Random Forest.\n",
"\n",
"Preskúmajte predvolené parametre každého z nich a zamyslite sa nad tým, čo by úprava týchto parametrov znamenala pre kvalitu modelu.\n",
"\n",
"Ak chcete zistiť viac o konkrétnom modeli a jeho parametroch, použite: `help(\"model\")`, napr. `help(\"rand_forest\")`.\n",
"\n",
"> V praxi zvyčajne *odhadujeme* *najlepšie hodnoty* týchto parametrov trénovaním mnohých modelov na `simulovanom dátovom súbore` a meraním, ako dobre tieto modely fungujú. Tento proces sa nazýva **ladenie**.\n",
"\n",
"### [**Kvíz po prednáške**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/24/)\n",
"\n",
"### **Prehľad a samostatné štúdium**\n",
"\n",
"V týchto lekciách je veľa odborných výrazov, preto si nájdite chvíľu na preštudovanie [tohto zoznamu](https://docs.microsoft.com/dotnet/machine-learning/resources/glossary?WT.mc_id=academic-77952-leestott) užitočnej terminológie!\n",
"\n",
"#### POĎAKOVANIE:\n",
"\n",
"[`Allison Horst`](https://twitter.com/allison_horst/) za vytvorenie úžasných ilustrácií, ktoré robia R prístupnejším a pútavejší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",
"\n",
"[Cassie Breviu](https://www.twitter.com/cassieview) a [Jen Looper](https://www.twitter.com/jenlooper) za vytvorenie pôvodnej verzie tohto modulu v Pythone ♥️\n",
"\n",
"Šťastné učenie,\n",
"\n",
"[Eric](https://twitter.com/ericntay), Zlatý študentský ambasádor Microsoft Learn.\n",
"\n",
"<p >\n",
" <img src=\"../../images/r_learners_sm.jpeg\"\n",
" width=\"569\"/>\n",
" <figcaption>Ilustrácia od @allison_horst</figcaption>\n"
]
},
{
"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"
]
}
]
}

@ -0,0 +1,302 @@
{
"cells": [
{
"source": [],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Unnamed: 0 cuisine almond angelica anise anise_seed apple \\\n",
"0 0 indian 0 0 0 0 0 \n",
"1 1 indian 1 0 0 0 0 \n",
"2 2 indian 0 0 0 0 0 \n",
"3 3 indian 0 0 0 0 0 \n",
"4 4 indian 0 0 0 0 0 \n",
"\n",
" apple_brandy apricot armagnac ... whiskey white_bread white_wine \\\n",
"0 0 0 0 ... 0 0 0 \n",
"1 0 0 0 ... 0 0 0 \n",
"2 0 0 0 ... 0 0 0 \n",
"3 0 0 0 ... 0 0 0 \n",
"4 0 0 0 ... 0 0 0 \n",
"\n",
" whole_grain_wheat_flour wine wood yam yeast yogurt zucchini \n",
"0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 1 0 \n",
"\n",
"[5 rows x 382 columns]"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>Unnamed: 0</th>\n <th>cuisine</th>\n <th>almond</th>\n <th>angelica</th>\n <th>anise</th>\n <th>anise_seed</th>\n <th>apple</th>\n <th>apple_brandy</th>\n <th>apricot</th>\n <th>armagnac</th>\n <th>...</th>\n <th>whiskey</th>\n <th>white_bread</th>\n <th>white_wine</th>\n <th>whole_grain_wheat_flour</th>\n <th>wine</th>\n <th>wood</th>\n <th>yam</th>\n <th>yeast</th>\n <th>yogurt</th>\n <th>zucchini</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>indian</td>\n <td>1</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>2</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>3</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>4</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>1</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 382 columns</p>\n</div>"
},
"metadata": {},
"execution_count": 1
}
],
"source": [
"import pandas as pd\n",
"cuisines_df = pd.read_csv(\"../../data/cleaned_cuisines.csv\")\n",
"cuisines_df.head()"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"0 indian\n",
"1 indian\n",
"2 indian\n",
"3 indian\n",
"4 indian\n",
"Name: cuisine, dtype: object"
]
},
"metadata": {},
"execution_count": 2
}
],
"source": [
"cuisines_label_df = cuisines_df['cuisine']\n",
"cuisines_label_df.head()"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" almond angelica anise anise_seed apple apple_brandy apricot \\\n",
"0 0 0 0 0 0 0 0 \n",
"1 1 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 0 \n",
"\n",
" armagnac artemisia artichoke ... whiskey white_bread white_wine \\\n",
"0 0 0 0 ... 0 0 0 \n",
"1 0 0 0 ... 0 0 0 \n",
"2 0 0 0 ... 0 0 0 \n",
"3 0 0 0 ... 0 0 0 \n",
"4 0 0 0 ... 0 0 0 \n",
"\n",
" whole_grain_wheat_flour wine wood yam yeast yogurt zucchini \n",
"0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 1 0 \n",
"\n",
"[5 rows x 380 columns]"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>almond</th>\n <th>angelica</th>\n <th>anise</th>\n <th>anise_seed</th>\n <th>apple</th>\n <th>apple_brandy</th>\n <th>apricot</th>\n <th>armagnac</th>\n <th>artemisia</th>\n <th>artichoke</th>\n <th>...</th>\n <th>whiskey</th>\n <th>white_bread</th>\n <th>white_wine</th>\n <th>whole_grain_wheat_flour</th>\n <th>wine</th>\n <th>wood</th>\n <th>yam</th>\n <th>yeast</th>\n <th>yogurt</th>\n <th>zucchini</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>1</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 380 columns</p>\n</div>"
},
"metadata": {},
"execution_count": 3
}
],
"source": [
"cuisines_feature_df = cuisines_df.drop(['Unnamed: 0', 'cuisine'], axis=1)\n",
"cuisines_feature_df.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Vyskúšajte rôzne klasifikátory\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.neighbors import KNeighborsClassifier\n",
"from sklearn.linear_model import LogisticRegression\n",
"from sklearn.svm import SVC\n",
"from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier\n",
"from sklearn.model_selection import train_test_split, cross_val_score\n",
"from sklearn.metrics import accuracy_score,precision_score,confusion_matrix,classification_report, precision_recall_curve\n",
"import numpy as np"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"X_train, X_test, y_train, y_test = train_test_split(cuisines_feature_df, cuisines_label_df, test_size=0.3)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"\n",
"C = 10\n",
"# Create different classifiers.\n",
"classifiers = {\n",
" 'Linear SVC': SVC(kernel='linear', C=C, probability=True,random_state=0),\n",
" 'KNN classifier': KNeighborsClassifier(C),\n",
" 'SVC': SVC(),\n",
" 'RFST': RandomForestClassifier(n_estimators=100),\n",
" 'ADA': AdaBoostClassifier(n_estimators=100)\n",
" \n",
"}\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Accuracy (train) for Linear SVC: 76.4% \n",
" precision recall f1-score support\n",
"\n",
" chinese 0.64 0.66 0.65 242\n",
" indian 0.91 0.86 0.89 236\n",
" japanese 0.72 0.73 0.73 245\n",
" korean 0.83 0.75 0.79 234\n",
" thai 0.75 0.82 0.78 242\n",
"\n",
" accuracy 0.76 1199\n",
" macro avg 0.77 0.76 0.77 1199\n",
"weighted avg 0.77 0.76 0.77 1199\n",
"\n",
"Accuracy (train) for KNN classifier: 70.7% \n",
" precision recall f1-score support\n",
"\n",
" chinese 0.65 0.63 0.64 242\n",
" indian 0.84 0.81 0.82 236\n",
" japanese 0.60 0.81 0.69 245\n",
" korean 0.89 0.53 0.67 234\n",
" thai 0.69 0.75 0.72 242\n",
"\n",
" accuracy 0.71 1199\n",
" macro avg 0.73 0.71 0.71 1199\n",
"weighted avg 0.73 0.71 0.71 1199\n",
"\n",
"Accuracy (train) for SVC: 80.1% \n",
" precision recall f1-score support\n",
"\n",
" chinese 0.71 0.69 0.70 242\n",
" indian 0.92 0.92 0.92 236\n",
" japanese 0.77 0.78 0.77 245\n",
" korean 0.87 0.77 0.82 234\n",
" thai 0.75 0.86 0.80 242\n",
"\n",
" accuracy 0.80 1199\n",
" macro avg 0.80 0.80 0.80 1199\n",
"weighted avg 0.80 0.80 0.80 1199\n",
"\n",
"Accuracy (train) for RFST: 82.8% \n",
" precision recall f1-score support\n",
"\n",
" chinese 0.80 0.75 0.77 242\n",
" indian 0.90 0.91 0.90 236\n",
" japanese 0.82 0.78 0.80 245\n",
" korean 0.85 0.82 0.83 234\n",
" thai 0.78 0.89 0.83 242\n",
"\n",
" accuracy 0.83 1199\n",
" macro avg 0.83 0.83 0.83 1199\n",
"weighted avg 0.83 0.83 0.83 1199\n",
"\n",
"Accuracy (train) for ADA: 71.1% \n",
" precision recall f1-score support\n",
"\n",
" chinese 0.60 0.57 0.58 242\n",
" indian 0.87 0.84 0.86 236\n",
" japanese 0.71 0.60 0.65 245\n",
" korean 0.68 0.78 0.72 234\n",
" thai 0.70 0.78 0.74 242\n",
"\n",
" accuracy 0.71 1199\n",
" macro avg 0.71 0.71 0.71 1199\n",
"weighted avg 0.71 0.71 0.71 1199\n",
"\n"
]
}
],
"source": [
"n_classifiers = len(classifiers)\n",
"\n",
"for index, (name, classifier) in enumerate(classifiers.items()):\n",
" classifier.fit(X_train, np.ravel(y_train))\n",
"\n",
" y_pred = classifier.predict(X_test)\n",
" accuracy = accuracy_score(y_test, y_pred)\n",
" print(\"Accuracy (train) for %s: %0.1f%% \" % (name, accuracy * 100))\n",
" print(classification_report(y_test,y_pred))"
]
},
{
"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"
]
}
],
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
}
},
"coopTranslator": {
"original_hash": "7ea2b714669c823a596d986ba2d5739f",
"translation_date": "2025-09-06T14:42:38+00:00",
"source_file": "4-Classification/3-Classifiers-2/solution/notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

@ -0,0 +1,39 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": 3
},
"orig_nbformat": 4,
"coopTranslator": {
"original_hash": "2f3e0d9e9ac5c301558fb8bf733ac0cb",
"translation_date": "2025-09-06T14:41:22+00:00",
"source_file": "4-Classification/4-Applied/notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"source": [],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Upozornenie**: \nTento dokument bol preložený pomocou služby AI prekladu [Co-op Translator](https://github.com/Azure/co-op-translator). Hoci sa snažíme o presnosť, prosím, berte na vedomie, že automatizované preklady môžu obsahovať chyby alebo nepresnosti. Pôvodný dokument v jeho rodnom jazyku by mal byť považovaný za autoritatívny zdroj. Pre kritické informácie sa odporúča profesionálny ľudský preklad. Nie sme zodpovední za žiadne nedorozumenia alebo nesprávne interpretácie vyplývajúce z použitia tohto prekladu.\n"
]
}
]
}

@ -0,0 +1,290 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"orig_nbformat": 2,
"kernelspec": {
"name": "python3",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
}
},
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
},
"coopTranslator": {
"original_hash": "49325d6dd12a3628fc64fa7ccb1a80ff",
"translation_date": "2025-09-06T14:41:47+00:00",
"source_file": "4-Classification/4-Applied/solution/notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"source": [],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Requirement already satisfied: skl2onnx in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (1.8.0)\n",
"Requirement already satisfied: protobuf in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from skl2onnx) (3.8.0)\n",
"Requirement already satisfied: numpy>=1.15 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from skl2onnx) (1.19.2)\n",
"Requirement already satisfied: onnx>=1.2.1 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from skl2onnx) (1.9.0)\n",
"Requirement already satisfied: six in /Users/jenlooper/Library/Python/3.7/lib/python/site-packages (from skl2onnx) (1.12.0)\n",
"Requirement already satisfied: onnxconverter-common<1.9,>=1.6.1 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from skl2onnx) (1.8.1)\n",
"Requirement already satisfied: scikit-learn>=0.19 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from skl2onnx) (0.24.2)\n",
"Requirement already satisfied: scipy>=1.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from skl2onnx) (1.4.1)\n",
"Requirement already satisfied: setuptools in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from protobuf->skl2onnx) (45.1.0)\n",
"Requirement already satisfied: typing-extensions>=3.6.2.1 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from onnx>=1.2.1->skl2onnx) (3.10.0.0)\n",
"Requirement already satisfied: threadpoolctl>=2.0.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from scikit-learn>=0.19->skl2onnx) (2.1.0)\n",
"Requirement already satisfied: joblib>=0.11 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from scikit-learn>=0.19->skl2onnx) (0.16.0)\n",
"\u001b[33mWARNING: You are using pip version 20.2.3; however, version 21.1.2 is available.\n",
"You should consider upgrading via the '/Library/Frameworks/Python.framework/Versions/3.7/bin/python3.7 -m pip install --upgrade pip' command.\u001b[0m\n",
"Note: you may need to restart the kernel to use updated packages.\n"
]
}
],
"source": [
"!pip install skl2onnx"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd \n"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Unnamed: 0 cuisine almond angelica anise anise_seed apple \\\n",
"0 0 indian 0 0 0 0 0 \n",
"1 1 indian 1 0 0 0 0 \n",
"2 2 indian 0 0 0 0 0 \n",
"3 3 indian 0 0 0 0 0 \n",
"4 4 indian 0 0 0 0 0 \n",
"\n",
" apple_brandy apricot armagnac ... whiskey white_bread white_wine \\\n",
"0 0 0 0 ... 0 0 0 \n",
"1 0 0 0 ... 0 0 0 \n",
"2 0 0 0 ... 0 0 0 \n",
"3 0 0 0 ... 0 0 0 \n",
"4 0 0 0 ... 0 0 0 \n",
"\n",
" whole_grain_wheat_flour wine wood yam yeast yogurt zucchini \n",
"0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 1 0 \n",
"\n",
"[5 rows x 382 columns]"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>Unnamed: 0</th>\n <th>cuisine</th>\n <th>almond</th>\n <th>angelica</th>\n <th>anise</th>\n <th>anise_seed</th>\n <th>apple</th>\n <th>apple_brandy</th>\n <th>apricot</th>\n <th>armagnac</th>\n <th>...</th>\n <th>whiskey</th>\n <th>white_bread</th>\n <th>white_wine</th>\n <th>whole_grain_wheat_flour</th>\n <th>wine</th>\n <th>wood</th>\n <th>yam</th>\n <th>yeast</th>\n <th>yogurt</th>\n <th>zucchini</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>indian</td>\n <td>1</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>2</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>3</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>4</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>1</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 382 columns</p>\n</div>"
},
"metadata": {},
"execution_count": 60
}
],
"source": [
"data = pd.read_csv('../../data/cleaned_cuisines.csv')\n",
"data.head()"
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" almond angelica anise anise_seed apple apple_brandy apricot \\\n",
"0 0 0 0 0 0 0 0 \n",
"1 1 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 0 \n",
"\n",
" armagnac artemisia artichoke ... whiskey white_bread white_wine \\\n",
"0 0 0 0 ... 0 0 0 \n",
"1 0 0 0 ... 0 0 0 \n",
"2 0 0 0 ... 0 0 0 \n",
"3 0 0 0 ... 0 0 0 \n",
"4 0 0 0 ... 0 0 0 \n",
"\n",
" whole_grain_wheat_flour wine wood yam yeast yogurt zucchini \n",
"0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 1 0 \n",
"\n",
"[5 rows x 380 columns]"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>almond</th>\n <th>angelica</th>\n <th>anise</th>\n <th>anise_seed</th>\n <th>apple</th>\n <th>apple_brandy</th>\n <th>apricot</th>\n <th>armagnac</th>\n <th>artemisia</th>\n <th>artichoke</th>\n <th>...</th>\n <th>whiskey</th>\n <th>white_bread</th>\n <th>white_wine</th>\n <th>whole_grain_wheat_flour</th>\n <th>wine</th>\n <th>wood</th>\n <th>yam</th>\n <th>yeast</th>\n <th>yogurt</th>\n <th>zucchini</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>1</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 380 columns</p>\n</div>"
},
"metadata": {},
"execution_count": 61
}
],
"source": [
"X = data.iloc[:,2:]\n",
"X.head()"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" cuisine\n",
"0 indian\n",
"1 indian\n",
"2 indian\n",
"3 indian\n",
"4 indian"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>cuisine</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>indian</td>\n </tr>\n <tr>\n <th>1</th>\n <td>indian</td>\n </tr>\n <tr>\n <th>2</th>\n <td>indian</td>\n </tr>\n <tr>\n <th>3</th>\n <td>indian</td>\n </tr>\n <tr>\n <th>4</th>\n <td>indian</td>\n </tr>\n </tbody>\n</table>\n</div>"
},
"metadata": {},
"execution_count": 62
}
],
"source": [
"y = data[['cuisine']]\n",
"y.head()"
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.model_selection import train_test_split\n",
"from sklearn.svm import SVC\n",
"from sklearn.model_selection import cross_val_score\n",
"from sklearn.metrics import accuracy_score,precision_score,confusion_matrix,classification_report"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [],
"source": [
"X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.3)"
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"SVC(C=10, kernel='linear', probability=True, random_state=0)"
]
},
"metadata": {},
"execution_count": 65
}
],
"source": [
"model = SVC(kernel='linear', C=10, probability=True,random_state=0)\n",
"model.fit(X_train,y_train.values.ravel())\n"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [],
"source": [
"y_pred = model.predict(X_test)"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
" precision recall f1-score support\n\n chinese 0.72 0.70 0.71 236\n indian 0.91 0.88 0.89 243\n japanese 0.80 0.75 0.77 240\n korean 0.80 0.81 0.81 230\n thai 0.76 0.85 0.80 250\n\n accuracy 0.80 1199\n macro avg 0.80 0.80 0.80 1199\nweighted avg 0.80 0.80 0.80 1199\n\n"
]
}
],
"source": [
"print(classification_report(y_test,y_pred))"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [],
"source": [
"from skl2onnx import convert_sklearn\n",
"from skl2onnx.common.data_types import FloatTensorType\n",
"\n",
"initial_type = [('float_input', FloatTensorType([None, 380]))]\n",
"options = {id(model): {'nocl': True, 'zipmap': False}}\n",
"onx = convert_sklearn(model, initial_types=initial_type, options=options)\n",
"with open(\"./model.onnx\", \"wb\") as f:\n",
" f.write(onx.SerializeToString())\n",
"\n",
"\n"
]
},
{
"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). Hoci 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 záväzný zdroj. Pre dôležité informácie odporúčame 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"
]
}
]
}

@ -0,0 +1,50 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.3"
},
"orig_nbformat": 2,
"kernelspec": {
"name": "python383jvsc74a57bd0e134e05457d34029b6460cd73bbf1ed73f339b5b6d98c95be70b69eba114fe95",
"display_name": "Python 3.8.3 64-bit (conda)"
},
"coopTranslator": {
"original_hash": "40e0707e96b3e1899a912776006264f9",
"translation_date": "2025-09-06T14:07:53+00:00",
"source_file": "5-Clustering/1-Visualize/notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"source": [],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"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 odporúčame 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"
]
}
]
}

@ -0,0 +1,499 @@
{
"cells": [
{
"cell_type": "markdown",
"source": [
"## **Nigerijská hudba zozbieraná zo Spotify - analýza**\n",
"\n",
"Clustering je typ [neučenej metódy](https://wikipedia.org/wiki/Unsupervised_learning), ktorá predpokladá, že dataset nie je označený alebo že jeho vstupy nie sú spojené s preddefinovanými výstupmi. Používa rôzne algoritmy na triedenie neoznačených dát a poskytuje skupiny podľa vzorov, ktoré rozpozná v dátach.\n",
"\n",
"[**Kvíz pred prednáškou**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/27/)\n",
"\n",
"### **Úvod**\n",
"\n",
"[Clustering](https://link.springer.com/referenceworkentry/10.1007%2F978-0-387-30164-8_124) je veľmi užitočný na prieskum dát. Pozrime sa, či nám môže pomôcť objaviť trendy a vzory v tom, ako nigérijské publikum konzumuje hudbu.\n",
"\n",
"> ✅ Zamyslite sa na chvíľu nad využitím clusteringu. V reálnom živote clustering nastáva vždy, keď máte kopu bielizne a potrebujete roztriediť oblečenie členov rodiny 🧦👕👖🩲. V dátovej vede clustering nastáva pri analýze preferencií používateľov alebo pri určovaní charakteristík akéhokoľvek neoznačeného datasetu. Clustering pomáha urobiť poriadok v chaose, ako napríklad v zásuvke na ponožky.\n",
"\n",
"V profesionálnom prostredí sa clustering môže použiť na určenie vecí, ako je segmentácia trhu, napríklad na zistenie, ktoré vekové skupiny kupujú aké produkty. Ďalším využitím by mohlo byť odhaľovanie anomálií, napríklad na detekciu podvodov v datasete transakcií kreditných kariet. Alebo by ste mohli použiť clustering na identifikáciu nádorov v dávke medicínskych skenov.\n",
"\n",
"✅ Zamyslite sa na chvíľu nad tým, ako ste sa mohli stretnúť s clusteringom „v divočine“, napríklad v bankovníctve, e-commerce alebo podnikateľskom prostredí.\n",
"\n",
"> 🎓 Zaujímavé je, že analýza klastrov vznikla v oblasti antropológie a psychológie v 30. rokoch 20. storočia. Dokážete si predstaviť, ako mohla byť použitá?\n",
"\n",
"Alternatívne by ste ju mohli použiť na zoskupovanie výsledkov vyhľadávania napríklad podľa nákupných odkazov, obrázkov alebo recenzií. Clustering je užitočný, keď máte veľký dataset, ktorý chcete zmenšiť a na ktorom chcete vykonať podrobnejšiu analýzu, takže táto technika môže byť použitá na získanie informácií o dátach pred vytvorením iných modelov.\n",
"\n",
"✅ Keď sú vaše dáta organizované v klastroch, priradíte im identifikátor klastru. Táto technika môže byť užitočná pri zachovaní súkromia datasetu; namiesto toho môžete odkazovať na dátový bod podľa jeho identifikátora klastru, namiesto odhaľovania identifikovateľných údajov. Dokážete si predstaviť ďalšie dôvody, prečo by ste odkazovali na identifikátor klastru namiesto iných prvkov klastru na jeho identifikáciu?\n",
"\n",
"### Začíname s clusteringom\n",
"\n",
"> 🎓 Spôsob, akým vytvárame klastre, má veľa spoločného s tým, ako zhromažďujeme dátové body do skupín. Poďme si rozobrať niektoré pojmy:\n",
">\n",
"> 🎓 ['Transduktívny' vs. 'induktívny'](https://wikipedia.org/wiki/Transduction_(machine_learning))\n",
">\n",
"> Transduktívna inferencia je odvodená z pozorovaných tréningových prípadov, ktoré sa mapujú na konkrétne testovacie prípady. Induktívna inferencia je odvodená z tréningových prípadov, ktoré sa mapujú na všeobecné pravidlá, ktoré sa až potom aplikujú na testovacie prípady.\n",
">\n",
"> Príklad: Predstavte si, že máte dataset, ktorý je len čiastočne označený. Niektoré veci sú „platne“, niektoré „CD“ a niektoré sú prázdne. Vašou úlohou je poskytnúť označenia pre prázdne miesta. Ak si zvolíte induktívny prístup, trénovali by ste model hľadajúci „platne“ a „CD“ a aplikovali tieto označenia na neoznačené dáta. Tento prístup bude mať problém klasifikovať veci, ktoré sú vlastne „kazety“. Transduktívny prístup na druhej strane efektívnejšie spracováva tieto neznáme dáta, pretože pracuje na zoskupovaní podobných položiek a potom aplikuje označenie na skupinu. V tomto prípade by klastre mohli odrážať „okrúhle hudobné veci“ a „štvorcové hudobné veci“.\n",
">\n",
"> 🎓 ['Nerovinná' vs. 'rovinná' geometria](https://datascience.stackexchange.com/questions/52260/terminology-flat-geometry-in-the-context-of-clustering)\n",
">\n",
"> Odvodené z matematickej terminológie, nerovinná vs. rovinná geometria sa týka merania vzdialeností medzi bodmi buď „rovinnými“ ([Euklidovskými](https://wikipedia.org/wiki/Euclidean_geometry)) alebo „nerovinnými“ (ne-Euklidovskými) geometrickými metódami.\n",
">\n",
"> „Rovinná“ v tomto kontexte odkazuje na Euklidovskú geometriu (časti ktorej sa učia ako „plánová“ geometria) a nerovinná odkazuje na ne-Euklidovskú geometriu. Čo má geometria spoločné s machine learningom? No, ako dve oblasti zakorenené v matematike, musí existovať spoločný spôsob merania vzdialeností medzi bodmi v klastroch, a to sa dá urobiť „rovinným“ alebo „nerovinným“ spôsobom, v závislosti od povahy dát. [Euklidovské vzdialenosti](https://wikipedia.org/wiki/Euclidean_distance) sa merajú ako dĺžka úsečky medzi dvoma bodmi. [Ne-Euklidovské vzdialenosti](https://wikipedia.org/wiki/Non-Euclidean_geometry) sa merajú pozdĺž krivky. Ak vaše dáta, vizualizované, neexistujú na rovine, možno budete potrebovať špecializovaný algoritmus na ich spracovanie.\n",
"\n",
"<p >\n",
" <img src=\"../../images/flat-nonflat.png\"\n",
" width=\"600\"/>\n",
" <figcaption>Infografika od Dasani Madipalli</figcaption>\n",
"\n",
"\n",
"\n",
"> 🎓 ['Vzdialenosti'](https://web.stanford.edu/class/cs345a/slides/12-clustering.pdf)\n",
">\n",
"> Klastre sú definované ich maticou vzdialeností, napr. vzdialenosťami medzi bodmi. Táto vzdialenosť sa dá merať niekoľkými spôsobmi. Euklidovské klastre sú definované priemerom hodnôt bodov a obsahujú „centroid“ alebo stredový bod. Vzdialenosti sa teda merajú podľa vzdialenosti od tohto centroidu. Ne-Euklidovské vzdialenosti odkazujú na „clustroidy“, bod najbližší k ostatným bodom. Clustroidy môžu byť definované rôznymi spôsobmi.\n",
">\n",
"> 🎓 ['Obmedzené'](https://wikipedia.org/wiki/Constrained_clustering)\n",
">\n",
"> [Obmedzený clustering](https://web.cs.ucdavis.edu/~davidson/Publications/ICDMTutorial.pdf) zavádza „semi-supervised“ učenie do tejto neučenej metódy. Vzťahy medzi bodmi sú označené ako „nemôže byť prepojené“ alebo „musí byť prepojené“, takže na dataset sú aplikované určité pravidlá.\n",
">\n",
"> Príklad: Ak je algoritmus voľne aplikovaný na dávku neoznačených alebo čiastočne označených dát, klastre, ktoré vytvorí, môžu byť nekvalitné. V príklade vyššie by klastre mohli zoskupovať „okrúhle hudobné veci“, „štvorcové hudobné veci“, „trojuholníkové veci“ a „sušienky“. Ak by boli dané určité obmedzenia alebo pravidlá („položka musí byť vyrobená z plastu“, „položka musí byť schopná produkovať hudbu“), mohlo by to pomôcť „obmedziť“ algoritmus na lepšie rozhodnutia.\n",
">\n",
"> 🎓 'Hustota'\n",
">\n",
"> Dáta, ktoré sú „šumové“, sa považujú za „husté“. Vzdialenosti medzi bodmi v každom z jeho klastrov môžu byť pri skúmaní viac alebo menej husté, alebo „preplnené“, a preto tieto dáta potrebujú byť analyzované vhodnou metódou clusteringu. [Tento článok](https://www.kdnuggets.com/2020/02/understanding-density-based-clustering.html) demonštruje rozdiel medzi použitím K-Means clusteringu a HDBSCAN algoritmov na preskúmanie šumového datasetu s nerovnomernou hustotou klastrov.\n",
"\n",
"Prehĺbte svoje pochopenie techník clusteringu v tomto [učebnom module](https://docs.microsoft.com/learn/modules/train-evaluate-cluster-models?WT.mc_id=academic-77952-leestott)\n",
"\n",
"### **Algoritmy clusteringu**\n",
"\n",
"Existuje viac ako 100 algoritmov clusteringu a ich použitie závisí od povahy dát. Poďme si prejsť niektoré hlavné:\n",
"\n",
"- **Hierarchický clustering**. Ak je objekt klasifikovaný podľa jeho blízkosti k blízkemu objektu, namiesto vzdialeného, klastre sa tvoria na základe vzdialenosti členov od ostatných objektov. Hierarchický clustering sa vyznačuje opakovaným spájaním dvoch klastrov.\n",
"\n",
"<p >\n",
" <img src=\"../../images/hierarchical.png\"\n",
" width=\"600\"/>\n",
" <figcaption>Infografika od Dasani Madipalli</figcaption>\n",
"\n",
"\n",
"\n",
"- **Centroid clustering**. Tento populárny algoritmus vyžaduje výber „k“, alebo počet klastrov, ktoré sa majú vytvoriť, po ktorom algoritmus určí stredový bod klastru a zhromaždí dáta okolo tohto bodu. [K-means clustering](https://wikipedia.org/wiki/K-means_clustering) je populárna verzia centroid clusteringu, ktorá rozdeľuje dataset na preddefinované K skupiny. Stred je určený najbližším priemerom, odtiaľ názov. Štvorcová vzdialenosť od klastru je minimalizovaná.\n",
"\n",
"<p >\n",
" <img src=\"../../images/centroid.png\"\n",
" width=\"600\"/>\n",
" <figcaption>Infografika od Dasani Madipalli</figcaption>\n",
"\n",
"\n",
"\n",
"- **Clustering založený na distribúcii**. Založený na štatistickom modelovaní, clustering založený na distribúcii sa sústreďuje na určenie pravdepodobnosti, že dátový bod patrí do klastru, a priradenie ho podľa toho. Metódy Gaussovskej zmesi patria do tohto typu.\n",
"\n",
"- **Clustering založený na hustote**. Dátové body sú priradené do klastrov na základe ich hustoty, alebo ich zoskupenia okolo seba. Dátové body vzdialené od skupiny sú považované za odľahlé alebo šumové. DBSCAN, Mean-shift a OPTICS patria do tohto typu clusteringu.\n",
"\n",
"- **Clustering založený na mriežke**. Pre multidimenzionálne datasety sa vytvorí mriežka a dáta sa rozdelia medzi bunky mriežky, čím sa vytvoria klastre.\n",
"\n",
"Najlepší spôsob, ako sa naučiť o clusteringu, je vyskúšať si ho sami, a presne to urobíte v tomto cvičení.\n",
"\n",
"Budeme potrebovať niektoré balíčky na dokončenie tohto modulu. Môžete ich nainštalovať pomocou: `install.packages(c('tidyverse', 'tidymodels', 'DataExplorer', 'summarytools', 'plotly', 'paletteer', 'corrplot', 'patchwork'))`\n",
"\n",
"Alternatívne, skript nižšie skontroluje, či máte balíčky potrebné na dokončenie tohto modulu, a nainštaluje ich za vás, ak niektoré chýbajú.\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": [
"## Cvičenie - zoskupte svoje údaje\n",
"\n",
"Zoskupovanie ako technika je výrazne podporené správnou vizualizáciou, takže začnime vizualizáciou našich hudobných údajov. Toto cvičenie nám pomôže rozhodnúť, ktorý z metód zoskupovania by sme mali najefektívnejšie použiť vzhľadom na povahu týchto údajov.\n",
"\n",
"Začnime hneď tým, že importujeme údaje.\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": [
"Niekedy môžeme chcieť získať trochu viac informácií o našich údajoch. Môžeme sa pozrieť na `údaje` a `ich štruktúru` pomocou funkcie [*glimpse()*](https://pillar.r-lib.org/reference/glimpse.html):\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": [
"Dobrá práca!💪\n",
"\n",
"Môžeme si všimnúť, že `glimpse()` vám poskytne celkový počet riadkov (pozorovaní) a stĺpcov (premenných), potom prvé záznamy každej premennej v riadku za názvom premennej. Okrem toho sa *dátový typ* premennej zobrazí hneď za názvom premennej vo vnútri `< >`.\n",
"\n",
"`DataExplorer::introduce()` dokáže túto informáciu prehľadne zhrnúť:\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": [
"Skvelé! Práve sme zistili, že naše údaje nemajú žiadne chýbajúce hodnoty.\n",
"\n",
"Keď už sme pri tom, môžeme preskúmať bežné štatistiky centrálnej tendencie (napr. [priemer](https://en.wikipedia.org/wiki/Arithmetic_mean) a [medián](https://en.wikipedia.org/wiki/Median)) a miery rozptylu (napr. [štandardná odchýlka](https://en.wikipedia.org/wiki/Standard_deviation)) pomocou `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": [
"Pozrime sa na všeobecné hodnoty údajov. Všimnite si, že popularita môže byť `0`, čo znamená piesne, ktoré nemajú žiadne hodnotenie. Tieto údaje čoskoro odstránime.\n",
"\n",
"> 🤔 Ak pracujeme s klastrovaním, nesupervidovanou metódou, ktorá nevyžaduje označené údaje, prečo zobrazujeme tieto údaje s označeniami? Počas fázy skúmania údajov sú užitočné, ale pre fungovanie algoritmov klastrovania nie sú nevyhnutné.\n",
"\n",
"### 1. Preskúmajte populárne žánre\n",
"\n",
"Poďme zistiť najpopulárnejšie žánre 🎶 tým, že spočítame, koľkokrát sa vyskytujú.\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": [
"To dopadlo dobre! Hovorí sa, že obrázok má hodnotu tisíc riadkov dátového rámca (vlastne to nikto nikdy nehovorí 😅). Ale chápete, čo tým myslím, však?\n",
"\n",
"Jedným zo spôsobov, ako vizualizovať kategóriálne údaje (znakové alebo faktorové premenné), je použitie stĺpcových grafov. Poďme vytvoriť stĺpcový graf pre top 10 žánrov:\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": [
"Teraz je oveľa jednoduchšie identifikovať, že máme `chýbajúce` žánre 🧐!\n",
"\n",
"> Dobrá vizualizácia vám ukáže veci, ktoré ste neočakávali, alebo vyvolá nové otázky o údajoch - Hadley Wickham a Garrett Grolemund, [R For Data Science](https://r4ds.had.co.nz/introduction.html)\n",
"\n",
"Poznámka: Keď je najvyšší žáner označený ako `Chýbajúci`, znamená to, že ho Spotify neklasifikoval, takže sa ho zbavme.\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": [
"Z krátkeho prieskumu údajov sme zistili, že tri najpopulárnejšie žánre dominujú tomuto datasetu. Zamerajme sa na `afro dancehall`, `afropop` a `nigerian pop`, a navyše filtrujme dataset tak, aby sme odstránili všetko s hodnotou popularity 0 (čo znamená, že nebolo klasifikované s popularitou v datasete a môže byť považované za šum pre naše účely):\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": [
"Pozrime sa, či existuje nejaký zjavný lineárny vzťah medzi číselnými premennými v našej dátovej sade. Tento vzťah je kvantifikovaný matematicky pomocou [korelačnej štatistiky](https://en.wikipedia.org/wiki/Correlation).\n",
"\n",
"Korelačná štatistika je hodnota medzi -1 a 1, ktorá naznačuje silu vzťahu. Hodnoty nad 0 indikujú *pozitívnu* koreláciu (vysoké hodnoty jednej premennej majú tendenciu zhodovať sa s vysokými hodnotami druhej), zatiaľ čo hodnoty pod 0 indikujú *negatívnu* koreláciu (vysoké hodnoty jednej premennej majú tendenciu zhodovať sa s nízkymi hodnotami druhej).\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": [
"Údaje nie sú silne korelované, okrem `energy` a `loudness`, čo dáva zmysel, keďže hlasná hudba je zvyčajne dosť energická. `Popularity` má súvislosť s `release date`, čo tiež dáva zmysel, pretože novšie skladby sú pravdepodobne populárnejšie. Zdá sa, že dĺžka a energia majú tiež určitú koreláciu.\n",
"\n",
"Bude zaujímavé zistiť, čo dokáže algoritmus zhlukovania urobiť s týmito údajmi!\n",
"\n",
"> 🎓 Upozorňujeme, že korelácia neznamená kauzalitu! Máme dôkaz o korelácii, ale žiadny dôkaz o kauzalite. [Zábavná webová stránka](https://tylervigen.com/spurious-correlations) obsahuje niekoľko vizuálov, ktoré tento bod zdôrazňujú.\n",
"\n",
"### 2. Preskúmajte distribúciu údajov\n",
"\n",
"Položme si niekoľko jemnejších otázok. Sú žánre výrazne odlišné v ich vnímaní tanečnosti na základe ich popularity? Preskúmajme distribúciu údajov našich troch najpopulárnejších žánrov z hľadiska popularity a tanečnosti pozdĺž danej osi x a y pomocou [hustotných grafov](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": [
"Vidíme, že existujú sústredené kruhy, ktoré sa zhodujú, bez ohľadu na žáner. Môže to byť tak, že nigerijské chute sa zbiehajú na určitej úrovni tanečnosti pre tento žáner?\n",
"\n",
"Vo všeobecnosti sa tri žánre zhodujú, pokiaľ ide o ich popularitu a tanečnosť. Určenie klastrov v týchto voľne zarovnaných údajoch bude výzvou. Pozrime sa, či nám rozptylový graf môže v tomto pomôcť.\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": [
"Rozptylový graf rovnakých osí ukazuje podobný vzor konvergencie.\n",
"\n",
"Vo všeobecnosti môžete pri zhlukovaní použiť rozptylové grafy na zobrazenie zhlukov údajov, takže zvládnutie tohto typu vizualizácie je veľmi užitočné. V ďalšej lekcii použijeme tieto filtrované údaje a metódu k-means na objavenie skupín v týchto údajoch, ktoré sa zaujímavo prekrývajú.\n",
"\n",
"## **🚀 Výzva**\n",
"\n",
"V rámci prípravy na ďalšiu lekciu vytvorte graf o rôznych algoritmoch zhlukovania, ktoré môžete objaviť a použiť v produkčnom prostredí. Aké typy problémov sa zhlukovanie snaží riešiť?\n",
"\n",
"## [**Kvíz po prednáške**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/28/)\n",
"\n",
"## **Prehľad a samostatné štúdium**\n",
"\n",
"Predtým, než použijete algoritmy zhlukovania, ako sme sa naučili, je dobré pochopiť povahu vášho datasetu. Prečítajte si viac na túto tému [tu](https://www.kdnuggets.com/2019/10/right-clustering-algorithm.html).\n",
"\n",
"Prehĺbte si svoje znalosti o technikách zhlukovania:\n",
"\n",
"- [Trénovanie a hodnotenie modelov zhlukovania pomocou Tidymodels a priateľov](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",
"## **Úloha**\n",
"\n",
"[Preskúmajte ďalšie vizualizácie pre zhlukovanie](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/assignment.md)\n",
"\n",
"## POĎAKOVANIE:\n",
"\n",
"[Jen Looper](https://www.twitter.com/jenlooper) za vytvorenie pôvodnej verzie tohto modulu v Pythone ♥️\n",
"\n",
"[`Dasani Madipalli`](https://twitter.com/dasani_decoded) za vytvorenie úžasných ilustrácií, ktoré robia koncepty strojového učenia zrozumiteľnejšími a ľahšie pochopiteľnými.\n",
"\n",
"Šťastné učenie,\n",
"\n",
"[Eric](https://twitter.com/ericntay), Gold Microsoft Learn Student Ambassador.\n"
],
"metadata": {}
},
{
"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"
]
}
],
"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-06T14:11:16+00:00",
"source_file": "5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 1
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,642 @@
{
"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-06T14:24:20+00:00",
"source_file": "5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb",
"language_code": "sk"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "GULATlQXLXyR"
},
"source": [
"## Preskúmajte K-Means zhlukovanie pomocou R a princípov Tidy dát.\n",
"\n",
"### [**Kvíz pred prednáškou**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/29/)\n",
"\n",
"V tejto lekcii sa naučíte, ako vytvárať zhluky pomocou balíka Tidymodels a ďalších balíkov v ekosystéme R (nazveme ich priatelia 🧑‍🤝‍🧑) a datasetu nigérijskej hudby, ktorý ste importovali skôr. Pokryjeme základy K-Means pre zhlukovanie. Majte na pamäti, že ako ste sa naučili v predchádzajúcej lekcii, existuje mnoho spôsobov, ako pracovať so zhlukmi, a metóda, ktorú použijete, závisí od vašich dát. Skúsime K-Means, pretože je to najbežnejšia technika zhlukovania. Poďme na to!\n",
"\n",
"Pojmy, o ktorých sa dozviete:\n",
"\n",
"- Silhouette skórovanie\n",
"\n",
"- Metóda lakťa\n",
"\n",
"- Inercia\n",
"\n",
"- Variancia\n",
"\n",
"### **Úvod**\n",
"\n",
"[K-Means zhlukovanie](https://wikipedia.org/wiki/K-means_clustering) je metóda odvodená z oblasti spracovania signálov. Používa sa na rozdelenie a rozčlenenie skupín dát do `k zhlukov` na základe podobností ich vlastností.\n",
"\n",
"Zhluky môžu byť vizualizované ako [Voronoi diagramy](https://wikipedia.org/wiki/Voronoi_diagram), ktoré zahŕňajú bod (alebo 'semienko') a jeho zodpovedajúcu oblasť.\n",
"\n",
"<p >\n",
" <img src=\"../../images/voronoi.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Infografika od Jen Looper</figcaption>\n",
"\n",
"\n",
"K-Means zhlukovanie má nasledujúce kroky:\n",
"\n",
"1. Data scientist začne tým, že špecifikuje požadovaný počet zhlukov, ktoré sa majú vytvoriť.\n",
"\n",
"2. Následne algoritmus náhodne vyberie K pozorovaní z datasetu, ktoré budú slúžiť ako počiatočné centrá zhlukov (t.j. centroidy).\n",
"\n",
"3. Potom sa každé zvyšné pozorovanie priradí k najbližšiemu centroidu.\n",
"\n",
"4. Následne sa vypočíta nový priemer každého zhluku a centroid sa presunie na tento priemer.\n",
"\n",
"5. Teraz, keď boli centrá prepočítané, každé pozorovanie sa opäť skontroluje, či by nemohlo byť bližšie k inému zhluku. Všetky objekty sa znovu priradia pomocou aktualizovaných priemerov zhlukov. Kroky priraďovania zhlukov a aktualizácie centroidov sa iteratívne opakujú, kým sa priradenia zhlukov prestanú meniť (t.j. keď sa dosiahne konvergencia). Typicky algoritmus končí, keď každá nová iterácia vedie k zanedbateľnému pohybu centroidov a zhluky sa stanú statickými.\n",
"\n",
"<div>\n",
"\n",
"> Upozorňujeme, že kvôli náhodnosti počiatočných k pozorovaní použitých ako východiskové centroidy môžeme získať mierne odlišné výsledky pri každom použití postupu. Z tohto dôvodu väčšina algoritmov používa niekoľko *náhodných začiatkov* a vyberie iteráciu s najnižším WCSS. Preto sa dôrazne odporúča vždy spustiť K-Means s viacerými hodnotami *nstart*, aby sa predišlo *nežiaducemu lokálnemu optimu.*\n",
"\n",
"</div>\n",
"\n",
"Táto krátka animácia využívajúca [ilustrácie](https://github.com/allisonhorst/stats-illustrations) od Allison Horst vysvetľuje proces zhlukovania:\n",
"\n",
"<p >\n",
" <img src=\"../../images/kmeans.gif\"\n",
" width=\"550\"/>\n",
" <figcaption>Ilustrácia od @allison_horst</figcaption>\n",
"\n",
"\n",
"\n",
"Základná otázka, ktorá pri zhlukovaní vyvstáva, je táto: ako viete, na koľko zhlukov rozdeliť vaše dáta? Jednou z nevýhod použitia K-Means je skutočnosť, že budete musieť určiť `k`, teda počet `centroidov`. Našťastie `metóda lakťa` pomáha odhadnúť dobrú východiskovú hodnotu pre `k`. Vyskúšate si to o chvíľu.\n",
"\n",
"### \n",
"\n",
"**Predpoklady**\n",
"\n",
"Nadviažeme presne tam, kde sme skončili v [predchádzajúcej lekcii](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb), kde sme analyzovali dataset, vytvorili množstvo vizualizácií a filtrovali dataset na pozorovania, ktoré nás zaujímajú. Určite si ju pozrite!\n",
"\n",
"Budeme potrebovať niekoľko balíkov na dokončenie tohto modulu. Môžete si ich nainštalovať pomocou: `install.packages(c('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork'))`\n",
"\n",
"Alternatívne, nasledujúci skript skontroluje, či máte balíky potrebné na dokončenie tohto modulu, a nainštaluje ich za vás, ak niektoré chýbajú.\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": [
"Poďme na to!\n",
"\n",
"## 1. Tanec s dátami: Zúžme to na 3 najpopulárnejšie hudobné žánre\n",
"\n",
"Toto je zhrnutie toho, čo sme robili v predchádzajúcej lekcii. Poďme si trochu pohrať s dátami!\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": [
"🤩 To išlo skvele!\n",
"\n",
"## 2. Viac prieskumu údajov.\n",
"\n",
"Aké čisté sú tieto údaje? Poďme skontrolovať odľahlé hodnoty pomocou boxplotov. Zameriame sa na číselné stĺpce s menším počtom odľahlých hodnôt (aj keď by ste mohli odľahlé hodnoty vyčistiť). Boxploty môžu ukázať rozsah údajov a pomôžu pri výbere stĺpcov na použitie. Upozorňujeme, že boxploty neukazujú rozptyl, čo je dôležitý prvok pre dobré zoskupiteľné údaje. Pre ďalšie čítanie si pozrite [túto diskusiu](https://stats.stackexchange.com/questions/91536/deduce-variance-from-boxplot).\n",
"\n",
"[Boxploty](https://en.wikipedia.org/wiki/Box_plot) sa používajú na grafické znázornenie distribúcie `číselných` údajov, takže začnime *výberom* všetkých číselných stĺpcov spolu s populárnymi hudobnými žánrami.\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": [
"Pozrite sa, ako výberový pomocník `where` uľahčuje tento proces 💁. Preskúmajte ďalšie podobné funkcie [tu](https://tidyselect.r-lib.org/).\n",
"\n",
"Keďže budeme vytvárať boxplot pre každú číselnú vlastnosť a chceme sa vyhnúť používaniu slučiek, preformátujme naše údaje do *dlhšieho* formátu, ktorý nám umožní využiť `facets` - podgrafy, z ktorých každý zobrazuje jednu podmnožinu údajov.\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": [
"Oveľa dlhšie! Teraz je čas na nejaké `ggplots`! Aký `geom` použijeme?\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": [
"Jednoduché-gg!\n",
"\n",
"Teraz môžeme vidieť, že tieto údaje sú trochu šumivé: pri pozorovaní jednotlivých stĺpcov ako boxplotov môžete vidieť odľahlé hodnoty. Mohli by ste prejsť dataset a odstrániť tieto odľahlé hodnoty, ale to by údaje dosť zredukovalo.\n",
"\n",
"Zatiaľ si vyberme, ktoré stĺpce použijeme na náš klastrovací cvičenie. Vyberme si číselné stĺpce s podobnými rozsahmi. Mohli by sme zakódovať `artist_top_genre` ako číselnú hodnotu, ale zatiaľ ho vynecháme.\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. Výpočet k-means zoskupovania v R\n",
"\n",
"K-means môžeme vypočítať v R pomocou zabudovanej funkcie `kmeans`, pozrite si `help(\"kmeans()\")`. Funkcia `kmeans()` prijíma dátový rámec so všetkými číselnými stĺpcami ako svoj hlavný argument.\n",
"\n",
"Prvým krokom pri používaní k-means zoskupovania je určiť počet klastrov (k), ktoré budú vytvorené vo finálnom riešení. Vieme, že v dátovom súbore sme identifikovali 3 hudobné žánre, takže skúsme 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": [
"Objekt kmeans obsahuje niekoľko informácií, ktoré sú dobre vysvetlené v `help(\"kmeans()\")`. Momentálne sa zamerajme na niekoľko z nich. Vidíme, že údaje boli rozdelené do 3 klastrov s veľkosťami 65, 110, 111. Výstup tiež obsahuje centrá klastrov (priemery) pre 3 skupiny naprieč 5 premennými.\n",
"\n",
"Vektor klastrovania je priradenie klastrov pre každé pozorovanie. Použime funkciu `augment`, aby sme pridali priradenie klastrov do pôvodného súboru údajov.\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": [
"Perfektné, práve sme rozdelili náš dátový súbor do 3 skupín. Takže, aké dobré je naše zhlukovanie 🤷? Pozrime sa na `Silhouette skóre`.\n",
"\n",
"### **Silhouette skóre**\n",
"\n",
"[Silhouette analýza](https://en.wikipedia.org/wiki/Silhouette_(clustering)) môže byť použitá na štúdium vzdialenosti medzi výslednými zhlukmi. Toto skóre sa pohybuje od -1 do 1, pričom skóre blízke 1 znamená, že zhluk je hustý a dobre oddelený od ostatných zhlukov. Hodnota blízka 0 predstavuje prekrývajúce sa zhluky so vzorkami veľmi blízko rozhodovacej hranice susedných zhlukov. [zdroj](https://dzone.com/articles/kmeans-silhouette-score-explained-with-python-exam).\n",
"\n",
"Metóda priemerného silhouette skóre vypočíta priemerné silhouette skóre pozorovaní pre rôzne hodnoty *k*. Vysoké priemerné silhouette skóre naznačuje dobré zhlukovanie.\n",
"\n",
"Funkcia `silhouette` v balíku cluster sa používa na výpočet priemernej šírky silhouette.\n",
"\n",
"> Silhouette môže byť vypočítané s akoukoľvek [vzdialenosťou](https://en.wikipedia.org/wiki/Distance \"Distance\"), ako napríklad [Euklidovská vzdialenosť](https://en.wikipedia.org/wiki/Euclidean_distance \"Euclidean distance\") alebo [Manhattanská vzdialenosť](https://en.wikipedia.org/wiki/Manhattan_distance \"Manhattan distance\"), o ktorých sme hovorili v [predchádzajúcej lekcii](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": [
"Náš skóre je **0,549**, teda presne v strede. To naznačuje, že naše údaje nie sú obzvlášť vhodné pre tento typ zoskupovania. Pozrime sa, či môžeme tento predpoklad vizuálne potvrdiť. Balík [factoextra](https://rpkgs.datanovia.com/factoextra/index.html) poskytuje funkcie (`fviz_cluster()`) na vizualizáciu zoskupovania.\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": [
"Prekrývanie klastrov naznačuje, že naše údaje nie sú obzvlášť vhodné pre tento typ klastrovania, ale poďme pokračovať.\n",
"\n",
"## 4. Určenie optimálneho počtu klastrov\n",
"\n",
"Základná otázka, ktorá často vyvstáva pri K-Means klastrovaní, je táto - bez známych triednych označení, ako zistíte, na koľko klastrov rozdeliť vaše údaje?\n",
"\n",
"Jedným zo spôsobov, ako to môžeme zistiť, je použiť vzorku údajov na `vytvorenie série modelov klastrovania` s narastajúcim počtom klastrov (napr. od 1 do 10) a vyhodnotiť metriky klastrovania, ako je **Silhouette skóre.**\n",
"\n",
"Určme optimálny počet klastrov výpočtom algoritmu klastrovania pre rôzne hodnoty *k* a vyhodnotením **Súčtu štvorcov v rámci klastrov** (WCSS). Celkový súčet štvorcov v rámci klastrov (WCSS) meria kompaktnosť klastrovania a chceme, aby bol čo najmenší, pričom nižšie hodnoty znamenajú, že dátové body sú bližšie.\n",
"\n",
"Preskúmajme vplyv rôznych volieb `k`, od 1 do 10, na toto klastrovanie.\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": [
"Teraz, keď máme celkový súčet štvorcov v rámci klastrov (tot.withinss) pre každý algoritmus zhlukovania s centrom *k*, použijeme [metódu lakťa](https://en.wikipedia.org/wiki/Elbow_method_(clustering)) na nájdenie optimálneho počtu klastrov. Táto metóda spočíva v zobrazení WCSS ako funkcie počtu klastrov a výbere [lakťa krivky](https://en.wikipedia.org/wiki/Elbow_of_the_curve \"Elbow of the curve\") ako počtu klastrov, ktoré sa majú použiť.\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": [
"Graf ukazuje výrazné zníženie WCSS (teda väčšiu *súdržnosť*) pri zvýšení počtu klastrov z jedného na dva, a ďalšie výrazné zníženie z dvoch na tri klastre. Potom je zníženie menej výrazné, čo vedie k vytvoreniu `laktu` 💪 na grafe približne pri troch klastroch. Toto je dobrý indikátor, že existujú dva až tri rozumne dobre oddelené klastre dátových bodov.\n",
"\n",
"Teraz môžeme pokračovať a extrahovať model klastrovania, kde `k = 3`:\n",
"\n",
"> `pull()`: používa sa na extrakciu jedného stĺpca\n",
">\n",
"> `pluck()`: používa sa na indexovanie dátových štruktúr, ako sú zoznamy\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": [
"Skvelé! Poďme si vizualizovať získané klastre. Máte záujem o interaktivitu pomocou `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": [
"Možno by sme očakávali, že každý klaster (reprezentovaný rôznymi farbami) bude mať odlišné žánre (reprezentované rôznymi tvarmi).\n",
"\n",
"Pozrime sa na presnosť modelu.\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": [
"Presnosť tohto modelu nie je zlá, ale ani výborná. Môže to byť spôsobené tým, že dáta nie sú vhodné pre K-Means Clustering. Tieto dáta sú príliš nevyvážené, málo korelované a medzi hodnotami stĺpcov je príliš veľká variabilita na to, aby sa dali dobre zoskupiť. V skutočnosti sú vytvorené klastre pravdepodobne silne ovplyvnené alebo skreslené tromi kategóriami žánrov, ktoré sme definovali vyššie.\n",
"\n",
"Napriek tomu to bol celkom poučný proces!\n",
"\n",
"V dokumentácii Scikit-learn môžete vidieť, že model ako tento, s klastrami, ktoré nie sú veľmi dobre ohraničené, má problém s „variabilitou“:\n",
"\n",
"<p >\n",
" <img src=\"../../images/problems.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Infografika zo Scikit-learn</figcaption>\n",
"\n",
"\n",
"\n",
"## **Variabilita**\n",
"\n",
"Variabilita je definovaná ako „priemer štvorcových rozdielov od priemeru“ [zdroj](https://www.mathsisfun.com/data/standard-deviation.html). V kontexte tohto problému zoskupovania sa vzťahuje na dáta, pri ktorých hodnoty v našej dátovej sade majú tendenciu odchýliť sa príliš od priemeru.\n",
"\n",
"✅ Toto je skvelý moment na zamyslenie sa nad všetkými spôsobmi, ako by ste mohli tento problém napraviť. Upraviť dáta trochu viac? Použiť iné stĺpce? Použiť iný algoritmus? Tip: Skúste [škálovať svoje dáta](https://www.mygreatlearning.com/blog/learning-data-science-with-k-means-clustering/) na ich normalizáciu a otestujte iné stĺpce.\n",
"\n",
"> Skúste tento '[kalkulátor variability](https://www.calculatorsoup.com/calculators/statistics/variance-calculator.php)', aby ste lepšie pochopili tento koncept.\n",
"\n",
"------------------------------------------------------------------------\n",
"\n",
"## **🚀Výzva**\n",
"\n",
"Strávte nejaký čas s týmto notebookom a upravujte parametre. Dokážete zlepšiť presnosť modelu tým, že dáta viac vyčistíte (napríklad odstránením odľahlých hodnôt)? Môžete použiť váhy na pridanie väčšej váhy určitým vzorkám dát. Čo ešte môžete urobiť, aby ste vytvorili lepšie klastre?\n",
"\n",
"Tip: Skúste škálovať svoje dáta. V notebooku je komentovaný kód, ktorý pridáva štandardné škálovanie, aby sa stĺpce dát viac podobali z hľadiska rozsahu. Zistíte, že zatiaľ čo skóre siluety klesá, „zlom“ v grafe lakťa sa vyhladzuje. Je to preto, že ponechanie dát neškálovaných umožňuje dátam s menšou variabilitou niesť väčšiu váhu. Prečítajte si o tomto probléme viac [tu](https://stats.stackexchange.com/questions/21222/are-mean-normalization-and-feature-scaling-needed-for-k-means-clustering/21226#21226).\n",
"\n",
"## [**Kvíz po prednáške**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/30/)\n",
"\n",
"## **Recenzia a samostatné štúdium**\n",
"\n",
"- Pozrite si simulátor K-Means [ako tento](https://user.ceng.metu.edu.tr/~akifakkus/courses/ceng574/k-means/). Tento nástroj môžete použiť na vizualizáciu vzorových dátových bodov a určenie ich centroidov. Môžete upraviť náhodnosť dát, počet klastrov a počet centroidov. Pomáha vám to získať predstavu o tom, ako sa dáta môžu zoskupovať?\n",
"\n",
"- Pozrite si tiež [tento materiál o K-Means](https://stanford.edu/~cpiech/cs221/handouts/kmeans.html) zo Stanfordu.\n",
"\n",
"Chcete si vyskúšať svoje novo nadobudnuté zručnosti zoskupovania na dátových sadách, ktoré sa dobre hodia pre K-Means clustering? Pozrite si:\n",
"\n",
"- [Trénovanie a hodnotenie modelov zoskupovania](https://rpubs.com/eR_ic/clustering) pomocou Tidymodels a priateľov\n",
"\n",
"- [Analýza klastrov K-Means](https://uc-r.github.io/kmeans_clustering), UC Business Analytics R Programming Guide\n",
"\n",
"- [K-Means clustering s princípmi upravených dát](https://www.tidymodels.org/learn/statistics/k-means/)\n",
"\n",
"## **Úloha**\n",
"\n",
"[Skúste rôzne metódy zoskupovania](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/2-K-Means/assignment.md)\n",
"\n",
"## ĎAKUJEME:\n",
"\n",
"[Jen Looper](https://www.twitter.com/jenlooper) za vytvorenie pôvodnej verzie tohto modulu v Pythone ♥️\n",
"\n",
"[`Allison Horst`](https://twitter.com/allison_horst/) 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",
"\n",
"Šťastné učenie,\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>Ilustrácia od @allison_horst</figcaption>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Upozornenie**: \nTento dokument bol preložený pomocou služby AI prekladu [Co-op Translator](https://github.com/Azure/co-op-translator). Hoci sa snažíme o presnosť, prosím, berte na vedomie, že automatizované preklady môžu obsahovať chyby alebo nepresnosti. Pôvodný dokument v jeho rodnom jazyku by mal byť považovaný za autoritatívny zdroj. Pre kritické informácie sa odporúča profesionálny ľudský preklad. Nie sme zodpovední za akékoľvek nedorozumenia alebo nesprávne interpretácie vyplývajúce z použitia tohto prekladu.\n"
]
}
]
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,100 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": 3
},
"orig_nbformat": 4,
"coopTranslator": {
"original_hash": "27de2abc0235ebd22080fc8f1107454d",
"translation_date": "2025-09-06T15:22:04+00:00",
"source_file": "6-NLP/3-Translation-Sentiment/solution/notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from textblob import TextBlob\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# You should download the book text, clean it, and import it here\n",
"with open(\"pride.txt\", encoding=\"utf8\") as f:\n",
" file_contents = f.read()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"book_pride = TextBlob(file_contents)\n",
"positive_sentiment_sentences = []\n",
"negative_sentiment_sentences = []"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for sentence in book_pride.sentences:\n",
" if sentence.sentiment.polarity == 1:\n",
" positive_sentiment_sentences.append(sentence)\n",
" if sentence.sentiment.polarity == -1:\n",
" negative_sentiment_sentences.append(sentence)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"The \" + str(len(positive_sentiment_sentences)) + \" most positive sentences:\")\n",
"for sentence in positive_sentiment_sentences:\n",
" print(\"+ \" + str(sentence.replace(\"\\n\", \"\").replace(\" \", \" \")))\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"The \" + str(len(negative_sentiment_sentences)) + \" most negative sentences:\")\n",
"for sentence in negative_sentiment_sentences:\n",
" print(\"- \" + str(sentence.replace(\"\\n\", \"\").replace(\" \", \" \")))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Upozornenie**: \nTento dokument bol preložený pomocou služby AI prekladu [Co-op Translator](https://github.com/Azure/co-op-translator). Hoci sa snažíme o presnosť, prosím, berte na vedomie, že automatizované preklady môžu obsahovať chyby alebo nepresnosti. Pôvodný dokument v jeho rodnom jazyku by mal byť považovaný za autoritatívny zdroj. Pre kritické informácie sa odporúča profesionálny ľudský preklad. Nenesieme zodpovednosť za akékoľvek nedorozumenia alebo nesprávne interpretácie vyplývajúce z použitia tohto prekladu.\n"
]
}
]
}

@ -0,0 +1,174 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": 3
},
"orig_nbformat": 4,
"coopTranslator": {
"original_hash": "2d05e7db439376aa824f4b387f8324ca",
"translation_date": "2025-09-06T15:21:44+00:00",
"source_file": "6-NLP/4-Hotel-Reviews-1/solution/notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# EDA\n",
"import pandas as pd\n",
"import time"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def get_difference_review_avg(row):\n",
" return row[\"Average_Score\"] - row[\"Calc_Average_Score\"]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Load the hotel reviews from CSV\n",
"print(\"Loading data file now, this could take a while depending on file size\")\n",
"start = time.time()\n",
"df = pd.read_csv('../../data/Hotel_Reviews.csv')\n",
"end = time.time()\n",
"print(\"Loading took \" + str(round(end - start, 2)) + \" seconds\")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# What shape is the data (rows, columns)?\n",
"print(\"The shape of the data (rows, cols) is \" + str(df.shape))\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# value_counts() creates a Series object that has index and values\n",
"# in this case, the country and the frequency they occur in reviewer nationality\n",
"nationality_freq = df[\"Reviewer_Nationality\"].value_counts()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# What reviewer nationality is the most common in the dataset?\n",
"print(\"The highest frequency reviewer nationality is \" + str(nationality_freq.index[0]).strip() + \" with \" + str(nationality_freq[0]) + \" reviews.\")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# What is the top 10 most common nationalities and their frequencies?\n",
"print(\"The top 10 highest frequency reviewer nationalities are:\")\n",
"print(nationality_freq[0:10].to_string())\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# How many unique nationalities are there?\n",
"print(\"There are \" + str(nationality_freq.index.size) + \" unique nationalities in the dataset\")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# What was the most frequently reviewed hotel for the top 10 nationalities - print the hotel and number of reviews\n",
"for nat in nationality_freq[:10].index:\n",
" # First, extract all the rows that match the criteria into a new dataframe\n",
" nat_df = df[df[\"Reviewer_Nationality\"] == nat] \n",
" # Now get the hotel freq\n",
" freq = nat_df[\"Hotel_Name\"].value_counts()\n",
" print(\"The most reviewed hotel for \" + str(nat).strip() + \" was \" + str(freq.index[0]) + \" with \" + str(freq[0]) + \" reviews.\") \n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# How many reviews are there per hotel (frequency count of hotel) and do the results match the value in `Total_Number_of_Reviews`?\n",
"# First create a new dataframe based on the old one, removing the uneeded columns\n",
"hotel_freq_df = df.drop([\"Hotel_Address\", \"Additional_Number_of_Scoring\", \"Review_Date\", \"Average_Score\", \"Reviewer_Nationality\", \"Negative_Review\", \"Review_Total_Negative_Word_Counts\", \"Positive_Review\", \"Review_Total_Positive_Word_Counts\", \"Total_Number_of_Reviews_Reviewer_Has_Given\", \"Reviewer_Score\", \"Tags\", \"days_since_review\", \"lat\", \"lng\"], axis = 1)\n",
"# Group the rows by Hotel_Name, count them and put the result in a new column Total_Reviews_Found\n",
"hotel_freq_df['Total_Reviews_Found'] = hotel_freq_df.groupby('Hotel_Name').transform('count')\n",
"# Get rid of all the duplicated rows\n",
"hotel_freq_df = hotel_freq_df.drop_duplicates(subset = [\"Hotel_Name\"])\n",
"print()\n",
"print(hotel_freq_df.to_string())\n",
"print(str(hotel_freq_df.shape))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# While there is an `Average_Score` for each hotel according to the dataset, \n",
"# you can also calculate an average score (getting the average of all reviewer scores in the dataset for each hotel)\n",
"# Add a new column to your dataframe with the column header `Calc_Average_Score` that contains that calculated average. \n",
"df['Calc_Average_Score'] = round(df.groupby('Hotel_Name').Reviewer_Score.transform('mean'), 1)\n",
"# Add a new column with the difference between the two average scores\n",
"df[\"Average_Score_Difference\"] = df.apply(get_difference_review_avg, axis = 1)\n",
"# Create a df without all the duplicates of Hotel_Name (so only 1 row per hotel)\n",
"review_scores_df = df.drop_duplicates(subset = [\"Hotel_Name\"])\n",
"# Sort the dataframe to find the lowest and highest average score difference\n",
"review_scores_df = review_scores_df.sort_values(by=[\"Average_Score_Difference\"])\n",
"print(review_scores_df[[\"Average_Score_Difference\", \"Average_Score\", \"Calc_Average_Score\", \"Hotel_Name\"]])\n",
"# Do any hotels have the same (rounded to 1 decimal place) `Average_Score` and `Calc_Average_Score`?\n"
]
},
{
"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"
]
}
]
}

@ -0,0 +1,172 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"orig_nbformat": 4,
"kernelspec": {
"name": "python3",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
},
"coopTranslator": {
"original_hash": "033cb89c85500224b3c63fd04f49b4aa",
"translation_date": "2025-09-06T15:22:26+00:00",
"source_file": "6-NLP/5-Hotel-Reviews-2/solution/1-notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import time\n",
"import ast"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"def replace_address(row):\n",
" if \"Netherlands\" in row[\"Hotel_Address\"]:\n",
" return \"Amsterdam, Netherlands\"\n",
" elif \"Barcelona\" in row[\"Hotel_Address\"]:\n",
" return \"Barcelona, Spain\"\n",
" elif \"United Kingdom\" in row[\"Hotel_Address\"]:\n",
" return \"London, United Kingdom\"\n",
" elif \"Milan\" in row[\"Hotel_Address\"]: \n",
" return \"Milan, Italy\"\n",
" elif \"France\" in row[\"Hotel_Address\"]:\n",
" return \"Paris, France\"\n",
" elif \"Vienna\" in row[\"Hotel_Address\"]:\n",
" return \"Vienna, Austria\" \n",
" else:\n",
" return row.Hotel_Address\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# Load the hotel reviews from CSV\n",
"start = time.time()\n",
"df = pd.read_csv('../../data/Hotel_Reviews.csv')\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# dropping columns we will not use:\n",
"df.drop([\"lat\", \"lng\"], axis = 1, inplace=True)\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# Replace all the addresses with a shortened, more useful form\n",
"df[\"Hotel_Address\"] = df.apply(replace_address, axis = 1)\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"# Drop `Additional_Number_of_Scoring`\n",
"df.drop([\"Additional_Number_of_Scoring\"], axis = 1, inplace=True)\n",
"# Replace `Total_Number_of_Reviews` and `Average_Score` with our own calculated values\n",
"df.Total_Number_of_Reviews = df.groupby('Hotel_Name').transform('count')\n",
"df.Average_Score = round(df.groupby('Hotel_Name').Reviewer_Score.transform('mean'), 1)\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"# Process the Tags into new columns\n",
"# The file Hotel_Reviews_Tags.py, identifies the most important tags\n",
"# Leisure trip, Couple, Solo traveler, Business trip, Group combined with Travelers with friends, \n",
"# Family with young children, Family with older children, With a pet\n",
"df[\"Leisure_trip\"] = df.Tags.apply(lambda tag: 1 if \"Leisure trip\" in tag else 0)\n",
"df[\"Couple\"] = df.Tags.apply(lambda tag: 1 if \"Couple\" in tag else 0)\n",
"df[\"Solo_traveler\"] = df.Tags.apply(lambda tag: 1 if \"Solo traveler\" in tag else 0)\n",
"df[\"Business_trip\"] = df.Tags.apply(lambda tag: 1 if \"Business trip\" in tag else 0)\n",
"df[\"Group\"] = df.Tags.apply(lambda tag: 1 if \"Group\" in tag or \"Travelers with friends\" in tag else 0)\n",
"df[\"Family_with_young_children\"] = df.Tags.apply(lambda tag: 1 if \"Family with young children\" in tag else 0)\n",
"df[\"Family_with_older_children\"] = df.Tags.apply(lambda tag: 1 if \"Family with older children\" in tag else 0)\n",
"df[\"With_a_pet\"] = df.Tags.apply(lambda tag: 1 if \"With a pet\" in tag else 0)\n"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"# No longer need any of these columns\n",
"df.drop([\"Review_Date\", \"Review_Total_Negative_Word_Counts\", \"Review_Total_Positive_Word_Counts\", \"days_since_review\", \"Total_Number_of_Reviews_Reviewer_Has_Given\"], axis = 1, inplace=True)\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Saving results to Hotel_Reviews_Filtered.csv\n",
"Filtering took 23.74 seconds\n"
]
}
],
"source": [
"# Saving new data file with calculated columns\n",
"print(\"Saving results to Hotel_Reviews_Filtered.csv\")\n",
"df.to_csv(r'../../data/Hotel_Reviews_Filtered.csv', index = False)\n",
"end = time.time()\n",
"print(\"Filtering took \" + str(round(end - start, 2)) + \" seconds\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Upozornenie**: \nTento dokument bol preložený pomocou služby AI prekladu [Co-op Translator](https://github.com/Azure/co-op-translator). Aj keď sa snažíme o presnosť, prosím, berte na vedomie, že automatizované 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 kritické informácie sa odporúča profesionálny ľudský preklad. Nie sme zodpovední za žiadne nedorozumenia alebo nesprávne interpretácie vyplývajúce z použitia tohto prekladu.\n"
]
}
]
}

@ -0,0 +1,137 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"orig_nbformat": 4,
"kernelspec": {
"name": "python3",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
},
"coopTranslator": {
"original_hash": "341efc86325ec2a214f682f57a189dfd",
"translation_date": "2025-09-06T15:22:47+00:00",
"source_file": "6-NLP/5-Hotel-Reviews-2/solution/2-notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# Load the hotel reviews from CSV (you can )\n",
"import pandas as pd \n",
"\n",
"df = pd.read_csv('../../data/Hotel_Reviews_Filtered.csv')\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# We want to find the most useful tags to keep\n",
"# Remove opening and closing brackets\n",
"df.Tags = df.Tags.str.strip(\"[']\")\n",
"# remove all quotes too\n",
"df.Tags = df.Tags.str.replace(\" ', '\", \",\", regex = False)\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"# removing this to take advantage of the 'already a phrase' fact of the dataset \n",
"# Now split the strings into a list\n",
"tag_list_df = df.Tags.str.split(',', expand = True)\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"# Remove leading and trailing spaces\n",
"df[\"Tag_1\"] = tag_list_df[0].str.strip()\n",
"df[\"Tag_2\"] = tag_list_df[1].str.strip()\n",
"df[\"Tag_3\"] = tag_list_df[2].str.strip()\n",
"df[\"Tag_4\"] = tag_list_df[3].str.strip()\n",
"df[\"Tag_5\"] = tag_list_df[4].str.strip()\n",
"df[\"Tag_6\"] = tag_list_df[5].str.strip()\n"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"# Merge the 6 columns into one with melt\n",
"df_tags = df.melt(value_vars=[\"Tag_1\", \"Tag_2\", \"Tag_3\", \"Tag_4\", \"Tag_5\", \"Tag_6\"])\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"The shape of the tags with no filtering: (2514684, 2)\n",
" index count\n",
"0 Leisure trip 338423\n",
"1 Couple 205305\n",
"2 Solo traveler 89779\n",
"3 Business trip 68176\n",
"4 Group 51593\n",
"5 Family with young children 49318\n",
"6 Family with older children 21509\n",
"7 Travelers with friends 1610\n",
"8 With a pet 1078\n"
]
}
],
"source": [
"# Get the value counts\n",
"tag_vc = df_tags.value.value_counts()\n",
"# print(tag_vc)\n",
"print(\"The shape of the tags with no filtering:\", str(df_tags.shape))\n",
"# Drop rooms, suites, and length of stay, mobile device and anything with less count than a 1000\n",
"df_tags = df_tags[~df_tags.value.str.contains(\"Standard|room|Stayed|device|Beds|Suite|Studio|King|Superior|Double\", na=False, case=False)]\n",
"tag_vc = df_tags.value.value_counts().reset_index(name=\"count\").query(\"count > 1000\")\n",
"# Print the top 10 (there should only be 9 and we'll use these in the filtering section)\n",
"print(tag_vc[:10])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Upozornenie**: \nTento dokument bol preložený pomocou služby AI prekladu [Co-op Translator](https://github.com/Azure/co-op-translator). Hoci sa snažíme o presnosť, prosím, berte na vedomie, že automatizované preklady môžu obsahovať chyby alebo nepresnosti. Pôvodný dokument v jeho rodnom jazyku by mal byť považovaný za autoritatívny zdroj. Pre kritické informácie sa odporúča profesionálny ľudský preklad. Nenesieme zodpovednosť za akékoľvek nedorozumenia alebo nesprávne interpretácie vyplývajúce z použitia tohto prekladu.\n"
]
}
]
}

@ -0,0 +1,260 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"orig_nbformat": 4,
"kernelspec": {
"name": "python3",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
},
"coopTranslator": {
"original_hash": "705bf02633759f689abc37b19749a16d",
"translation_date": "2025-09-06T15:23:07+00:00",
"source_file": "6-NLP/5-Hotel-Reviews-2/solution/3-notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"[nltk_data] Downloading package vader_lexicon to\n[nltk_data] /Users/jenlooper/nltk_data...\n"
]
},
{
"output_type": "execute_result",
"data": {
"text/plain": [
"True"
]
},
"metadata": {},
"execution_count": 9
}
],
"source": [
"import time\n",
"import pandas as pd\n",
"import nltk as nltk\n",
"from nltk.corpus import stopwords\n",
"from nltk.sentiment.vader import SentimentIntensityAnalyzer\n",
"nltk.download('vader_lexicon')\n"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"vader_sentiment = SentimentIntensityAnalyzer()\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"# There are 3 possibilities of input for a review:\n",
"# It could be \"No Negative\", in which case, return 0\n",
"# It could be \"No Positive\", in which case, return 0\n",
"# It could be a review, in which case calculate the sentiment\n",
"def calc_sentiment(review): \n",
" if review == \"No Negative\" or review == \"No Positive\":\n",
" return 0\n",
" return vader_sentiment.polarity_scores(review)[\"compound\"] \n"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"# Load the hotel reviews from CSV\n",
"df = pd.read_csv(\"../../data/Hotel_Reviews_Filtered.csv\")\n"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"# Remove stop words - can be slow for a lot of text!\n",
"# Ryan Han (ryanxjhan on Kaggle) has a great post measuring performance of different stop words removal approaches\n",
"# https://www.kaggle.com/ryanxjhan/fast-stop-words-removal # using the approach that Ryan recommends\n",
"start = time.time()\n",
"cache = set(stopwords.words(\"english\"))\n",
"def remove_stopwords(review):\n",
" text = \" \".join([word for word in review.split() if word not in cache])\n",
" return text\n"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"# Remove the stop words from both columns\n",
"df.Negative_Review = df.Negative_Review.apply(remove_stopwords) \n",
"df.Positive_Review = df.Positive_Review.apply(remove_stopwords)\n"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Removing stop words took 5.77 seconds\n"
]
}
],
"source": [
"end = time.time()\n",
"print(\"Removing stop words took \" + str(round(end - start, 2)) + \" seconds\")\n"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Calculating sentiment columns for both positive and negative reviews\n",
"Calculating sentiment took 201.07 seconds\n"
]
}
],
"source": [
"# Add a negative sentiment and positive sentiment column\n",
"print(\"Calculating sentiment columns for both positive and negative reviews\")\n",
"start = time.time()\n",
"df[\"Negative_Sentiment\"] = df.Negative_Review.apply(calc_sentiment)\n",
"df[\"Positive_Sentiment\"] = df.Positive_Review.apply(calc_sentiment)\n",
"end = time.time()\n",
"print(\"Calculating sentiment took \" + str(round(end - start, 2)) + \" seconds\")\n"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
" Negative_Review Negative_Sentiment\n",
"186584 So bad experience memories I hotel The first n... -0.9920\n",
"129503 First charged twice room booked booking second... -0.9896\n",
"307286 The staff Had bad experience even booking Janu... -0.9889\n",
"452092 No WLAN room Incredibly rude restaurant staff ... -0.9884\n",
"201293 We usually traveling Paris 2 3 times year busi... -0.9873\n",
"... ... ...\n",
"26899 I would say however one night expensive even d... 0.9933\n",
"138365 Wifi terribly slow I speed test network upload... 0.9938\n",
"79215 I find anything hotel first I walked past hote... 0.9938\n",
"278506 The property great location There bakery next ... 0.9945\n",
"339189 Guys I like hotel I wish return next year Howe... 0.9948\n",
"\n",
"[515738 rows x 2 columns]\n",
" Positive_Review Positive_Sentiment\n",
"137893 Bathroom Shower We going stay twice hotel 2 ni... -0.9820\n",
"5839 I completely disappointed mad since reception ... -0.9780\n",
"64158 get everything extra internet parking breakfas... -0.9751\n",
"124178 I didnt like anythig Room small Asked upgrade ... -0.9721\n",
"489137 Very rude manager abusive staff reception Dirt... -0.9703\n",
"... ... ...\n",
"331570 Everything This recently renovated hotel class... 0.9984\n",
"322920 From moment stepped doors Guesthouse Hotel sta... 0.9985\n",
"293710 This place surprise expected good actually gre... 0.9985\n",
"417442 We celebrated wedding night Langham I commend ... 0.9985\n",
"132492 We arrived super cute boutique hotel area expl... 0.9987\n",
"\n",
"[515738 rows x 2 columns]\n"
]
}
],
"source": [
"df = df.sort_values(by=[\"Negative_Sentiment\"], ascending=True)\n",
"print(df[[\"Negative_Review\", \"Negative_Sentiment\"]])\n",
"df = df.sort_values(by=[\"Positive_Sentiment\"], ascending=True)\n",
"print(df[[\"Positive_Review\", \"Positive_Sentiment\"]])\n"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"# Reorder the columns (This is cosmetic, but to make it easier to explore the data later)\n",
"df = df.reindex([\"Hotel_Name\", \"Hotel_Address\", \"Total_Number_of_Reviews\", \"Average_Score\", \"Reviewer_Score\", \"Negative_Sentiment\", \"Positive_Sentiment\", \"Reviewer_Nationality\", \"Leisure_trip\", \"Couple\", \"Solo_traveler\", \"Business_trip\", \"Group\", \"Family_with_young_children\", \"Family_with_older_children\", \"With_a_pet\", \"Negative_Review\", \"Positive_Review\"], axis=1)\n"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Saving results to Hotel_Reviews_NLP.csv\n"
]
}
],
"source": [
"print(\"Saving results to Hotel_Reviews_NLP.csv\")\n",
"df.to_csv(r\"../../data/Hotel_Reviews_NLP.csv\", index = False)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Upozornenie**: \nTento dokument bol preložený pomocou služby AI prekladu [Co-op Translator](https://github.com/Azure/co-op-translator). Hoci sa snažíme o presnosť, prosím, berte na vedomie, že automatizované preklady môžu obsahovať chyby alebo nepresnosti. Pôvodný dokument v jeho rodnom jazyku by mal byť považovaný za autoritatívny zdroj. Pre kritické informácie sa odporúča profesionálny ľudský preklad. Nie sme zodpovední za akékoľvek nedorozumenia alebo nesprávne interpretácie vyplývajúce z použitia tohto prekladu.\n"
]
}
]
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,63 @@
{
"cells": [
{
"source": [
"# Nastavenie údajov\n",
"\n",
"V tomto notebooku ukážeme, ako:\n",
"\n",
"nastaviť časové rady údajov pre tento modul\n",
"vizualizovať údaje\n",
"Údaje v tomto príklade pochádzajú zo súťaže GEFCom2014 v predpovedaní1. Obsahujú 3 roky hodinových hodnôt spotreby elektrickej energie a teploty medzi rokmi 2012 a 2014.\n",
"\n",
"1Tao Hong, Pierre Pinson, Shu Fan, Hamidreza Zareipour, Alberto Troccoli a Rob J. Hyndman, \"Pravdepodobnostné predpovedanie energie: Globálna súťaž v predpovedaní energie 2014 a ďalej\", International Journal of Forecasting, zv.32, č.3, str. 896-913, júl-september, 2016.\n"
],
"cell_type": "markdown",
"metadata": {}
},
{
"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"
]
}
],
"metadata": {
"kernel_info": {
"name": "python3"
},
"kernelspec": {
"name": "python37364bit8d3b438fb5fc4430a93ac2cb74d693a7",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"nteract": {
"version": "nteract-front-end@1.0.0"
},
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
}
},
"coopTranslator": {
"original_hash": "5e2bbe594906dce3aaaa736d6dac6683",
"translation_date": "2025-09-06T14:02:08+00:00",
"source_file": "7-TimeSeries/1-Introduction/working/notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,59 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": 3
},
"orig_nbformat": 2,
"coopTranslator": {
"original_hash": "523ec472196307b3c4235337353c9ceb",
"translation_date": "2025-09-06T14:00:10+00:00",
"source_file": "7-TimeSeries/2-ARIMA/working/notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"source": [
"# Prognózovanie časových radov pomocou ARIMA\n",
"\n",
"V tomto zápisníku si ukážeme, ako:\n",
"- pripraviť údaje časových radov na trénovanie modelu ARIMA pre prognózovanie časových radov\n",
"- implementovať jednoduchý model ARIMA na predpovedanie nasledujúcich HORIZON krokov dopredu (od času *t+1* po *t+HORIZON*) v časovom rade\n",
"- vyhodnotiť model\n",
"\n",
"Údaje v tomto príklade pochádzajú zo súťaže GEFCom2014 v prognózovaní. Skladajú sa z 3 rokov hodinových hodnôt elektrického zaťaženia a teploty medzi rokmi 2012 a 2014. Úlohou je predpovedať budúce hodnoty elektrického zaťaženia. V tomto príklade ukážeme, ako predpovedať jeden časový krok dopredu, pričom použijeme iba historické údaje o zaťažení.\n",
"\n",
"Tao Hong, Pierre Pinson, Shu Fan, Hamidreza Zareipour, Alberto Troccoli a Rob J. Hyndman, \"Probabilistic energy forecasting: Global Energy Forecasting Competition 2014 and beyond\", International Journal of Forecasting, vol.32, no.3, str. 896-913, júl-september, 2016.\n"
],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"pip install statsmodels"
]
},
{
"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"
]
}
]
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,695 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "fv9OoQsMFk5A"
},
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"V tomto zápisníku ukážeme, ako:\n",
"\n",
"- pripraviť 2D časové rady na trénovanie modelu regresora SVM\n",
"- implementovať SVR pomocou RBF jadra\n",
"- vyhodnotiť model pomocou grafov a MAPE\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Importovanie modulov\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"sys.path.append('../../')"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"id": "M687KNlQFp0-"
},
"outputs": [],
"source": [
"import os\n",
"import warnings\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import pandas as pd\n",
"import datetime as dt\n",
"import math\n",
"\n",
"from sklearn.svm import SVR\n",
"from sklearn.preprocessing import MinMaxScaler\n",
"from common.utils import load_data, mape"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Cj-kfVdMGjWP"
},
"source": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "8fywSjC6GsRz"
},
"source": [
"### Načítať údaje\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 363
},
"id": "aBDkEB11Fumg",
"outputId": "99cf7987-0509-4b73-8cc2-75d7da0d2740"
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>load</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2012-01-01 00:00:00</th>\n",
" <td>2698.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 01:00:00</th>\n",
" <td>2558.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 02:00:00</th>\n",
" <td>2444.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 03:00:00</th>\n",
" <td>2402.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 04:00:00</th>\n",
" <td>2403.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" load\n",
"2012-01-01 00:00:00 2698.0\n",
"2012-01-01 01:00:00 2558.0\n",
"2012-01-01 02:00:00 2444.0\n",
"2012-01-01 03:00:00 2402.0\n",
"2012-01-01 04:00:00 2403.0"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"energy = load_data('../../data')[['load']]\n",
"energy.head(5)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "O0BWP13rGnh4"
},
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 486
},
"id": "hGaNPKu_Gidk",
"outputId": "7f89b326-9057-4f49-efbe-cb100ebdf76d"
},
"outputs": [],
"source": [
"energy.plot(y='load', subplots=True, figsize=(15, 8), fontsize=12)\n",
"plt.xlabel('timestamp', fontsize=12)\n",
"plt.ylabel('load', fontsize=12)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "IPuNor4eGwYY"
},
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ysvsNyONGt0Q"
},
"outputs": [],
"source": [
"train_start_dt = '2014-11-01 00:00:00'\n",
"test_start_dt = '2014-12-30 00:00:00'"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 548
},
"id": "SsfdLoPyGy9w",
"outputId": "d6d6c25b-b1f4-47e5-91d1-707e043237d7"
},
"outputs": [],
"source": [
"energy[(energy.index < test_start_dt) & (energy.index >= train_start_dt)][['load']].rename(columns={'load':'train'}) \\\n",
" .join(energy[test_start_dt:][['load']].rename(columns={'load':'test'}), how='outer') \\\n",
" .plot(y=['train', 'test'], figsize=(15, 8), fontsize=12)\n",
"plt.xlabel('timestamp', fontsize=12)\n",
"plt.ylabel('load', fontsize=12)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "XbFTqBw6G1Ch"
},
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Teraz musíte pripraviť údaje na trénovanie vykonaním filtrovania a škálovania vašich údajov.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "cYivRdQpHDj3",
"outputId": "a138f746-461c-4fd6-bfa6-0cee094c4aa1"
},
"outputs": [],
"source": [
"train = energy.copy()[(energy.index >= train_start_dt) & (energy.index < test_start_dt)][['load']]\n",
"test = energy.copy()[energy.index >= test_start_dt][['load']]\n",
"\n",
"print('Training data shape: ', train.shape)\n",
"print('Test data shape: ', test.shape)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Zmeňte údaje tak, aby boli v rozsahu (0, 1).\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 363
},
"id": "3DNntGQnZX8G",
"outputId": "210046bc-7a66-4ccd-d70d-aa4a7309949c"
},
"outputs": [],
"source": [
"scaler = MinMaxScaler()\n",
"train['load'] = scaler.fit_transform(train)\n",
"train.head(5)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 206
},
"id": "26Yht-rzZexe",
"outputId": "20326077-a38a-4e78-cc5b-6fd7af95d301"
},
"outputs": [],
"source": [
"test['load'] = scaler.transform(test)\n",
"test.head(5)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "x0n6jqxOQ41Z"
},
"source": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "fdmxTZtOQ8xs"
},
"source": [
"Pre náš SVR transformujeme vstupné údaje do formy `[batch, timesteps]`. Takže preformátujeme existujúce `train_data` a `test_data` tak, aby existoval nový rozmer, ktorý sa vzťahuje na časové kroky. V našom príklade berieme `timesteps = 5`. Vstupy do modelu sú teda údaje za prvé 4 časové kroky a výstup budú údaje za 5. časový krok.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Rpju-Sc2HFm0"
},
"outputs": [],
"source": [
"# Converting to numpy arrays\n",
"\n",
"train_data = train.values\n",
"test_data = test.values"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Selecting the timesteps\n",
"\n",
"timesteps=None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "O-JrsrsVJhUQ",
"outputId": "c90dbe71-bacc-4ec4-b452-f82fe5aefaef"
},
"outputs": [],
"source": [
"# Converting data to 2D tensor\n",
"\n",
"train_data_timesteps=None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "exJD8AI7KE4g",
"outputId": "ce90260c-f327-427d-80f2-77307b5a6318"
},
"outputs": [],
"source": [
"# Converting test data to 2D tensor\n",
"\n",
"test_data_timesteps=None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "2u0R2sIsLuq5"
},
"outputs": [],
"source": [
"x_train, y_train = None\n",
"x_test, y_test = None\n",
"\n",
"print(x_train.shape, y_train.shape)\n",
"print(x_test.shape, y_test.shape)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "8wIPOtAGLZlh"
},
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "EhA403BEPEiD"
},
"outputs": [],
"source": [
"# Create model using RBF kernel\n",
"\n",
"model = None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "GS0UA3csMbqp",
"outputId": "d86b6f05-5742-4c1d-c2db-c40510bd4f0d"
},
"outputs": [],
"source": [
"# Fit model on training data"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Rz_x8S3UrlcF"
},
"source": [
"### Vytvoriť predikciu modelu\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "XR0gnt3MnuYS",
"outputId": "157e40ab-9a23-4b66-a885-0d52a24b2364"
},
"outputs": [],
"source": [
"# Making predictions\n",
"\n",
"y_train_pred = None\n",
"y_test_pred = None"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "_2epncg-SGzr"
},
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Scaling the predictions\n",
"\n",
"y_train_pred = scaler.inverse_transform(y_train_pred)\n",
"y_test_pred = scaler.inverse_transform(y_test_pred)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "xmm_YLXhq7gV",
"outputId": "18392f64-4029-49ac-c71a-a4e2411152a1"
},
"outputs": [],
"source": [
"# Scaling the original values\n",
"\n",
"y_train = scaler.inverse_transform(y_train)\n",
"y_test = scaler.inverse_transform(y_test)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "u3LBj93coHEi",
"outputId": "d4fd49e8-8c6e-4bb0-8ef9-ca0b26d725b4"
},
"outputs": [],
"source": [
"# Extract the timesteps for x-axis\n",
"\n",
"train_timestamps = None\n",
"test_timestamps = None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure(figsize=(25,6))\n",
"# plot original output\n",
"# plot predicted output\n",
"plt.legend(['Actual','Predicted'])\n",
"plt.xlabel('Timestamp')\n",
"plt.title(\"Training data prediction\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "LnhzcnYtXHCm",
"outputId": "f5f0d711-f18b-4788-ad21-d4470ea2c02b"
},
"outputs": [],
"source": [
"print('MAPE for training data: ', mape(y_train_pred, y_train)*100, '%')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 225
},
"id": "53Q02FoqQH4V",
"outputId": "53e2d59b-5075-4765-ad9e-aed56c966583"
},
"outputs": [],
"source": [
"plt.figure(figsize=(10,3))\n",
"# plot original output\n",
"# plot predicted output\n",
"plt.legend(['Actual','Predicted'])\n",
"plt.xlabel('Timestamp')\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "clOAUH-SXCJG",
"outputId": "a3aa85ff-126a-4a4a-cd9e-90b9cc465ef5"
},
"outputs": [],
"source": [
"print('MAPE for testing data: ', mape(y_test_pred, y_test)*100, '%')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "DHlKvVCId5ue"
},
"source": [
"## Predikcia celého súboru údajov\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "cOFJ45vreO0N",
"outputId": "35628e33-ecf9-4966-8036-f7ea86db6f16"
},
"outputs": [],
"source": [
"# Extracting load values as numpy array\n",
"data = None\n",
"\n",
"# Scaling\n",
"data = None\n",
"\n",
"# Transforming to 2D tensor as per model input requirement\n",
"data_timesteps=None\n",
"\n",
"# Selecting inputs and outputs from data\n",
"X, Y = None, None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ESSAdQgwexIi"
},
"outputs": [],
"source": [
"# Make model predictions\n",
"\n",
"# Inverse scale and reshape\n",
"Y_pred = None\n",
"Y = None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 328
},
"id": "M_qhihN0RVVX",
"outputId": "a89cb23e-1d35-437f-9d63-8b8907e12f80"
},
"outputs": [],
"source": [
"plt.figure(figsize=(30,8))\n",
"# plot original output\n",
"# plot predicted output\n",
"plt.legend(['Actual','Predicted'])\n",
"plt.xlabel('Timestamp')\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "AcN7pMYXVGTK",
"outputId": "7e1c2161-47ce-496c-9d86-7ad9ae0df770"
},
"outputs": [],
"source": [
"print('MAPE: ', mape(Y_pred, Y)*100, '%')"
]
},
{
"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"
]
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"collapsed_sections": [],
"name": "Recurrent_Neural_Networks.ipynb",
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.1"
},
"coopTranslator": {
"original_hash": "e86ce102239a14c44585623b9b924a74",
"translation_date": "2025-09-06T14:05:37+00:00",
"source_file": "7-TimeSeries/3-SVR/working/notebook.ipynb",
"language_code": "sk"
}
},
"nbformat": 4,
"nbformat_minor": 1
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

@ -0,0 +1,447 @@
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {
"colab": {
"name": "lesson_1-R.ipynb",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true
},
"kernelspec": {
"name": "ir",
"display_name": "R"
},
"language_info": {
"name": "R"
},
"coopTranslator": {
"original_hash": "c18d3bd0bd8ae3878597e89dcd1fa5c1",
"translation_date": "2025-09-06T13:41:25+00:00",
"source_file": "2-Regression/1-Tools/solution/R/lesson_1-R.ipynb",
"language_code": "sl"
}
},
"cells": [
{
"cell_type": "markdown",
"source": [],
"metadata": {
"id": "YJUHCXqK57yz"
}
},
{
"cell_type": "markdown",
"source": [
"## Uvod v regresijo - Lekcija 1\n",
"\n",
"#### Postavljanje v perspektivo\n",
"\n",
"✅ Obstaja veliko vrst regresijskih metod, izbira pa je odvisna od odgovora, ki ga iščete. Če želite napovedati verjetno višino osebe glede na njeno starost, bi uporabili `linearno regresijo`, saj iščete **številčno vrednost**. Če vas zanima, ali naj se določena vrsta kuhinje šteje za vegansko ali ne, iščete **dodelitev kategorije**, zato bi uporabili `logistično regresijo`. Več o logistični regresiji boste izvedeli kasneje. Razmislite o nekaterih vprašanjih, ki jih lahko zastavite podatkom, in o tem, katera od teh metod bi bila bolj primerna.\n",
"\n",
"V tem razdelku boste delali z [majhnim naborom podatkov o diabetesu](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html). Predstavljajte si, da želite preizkusiti zdravljenje za diabetične bolnike. Modeli strojnega učenja vam lahko pomagajo določiti, kateri bolniki bi se na zdravljenje bolje odzvali, glede na kombinacije spremenljivk. Tudi zelo osnovni regresijski model, ko je vizualiziran, lahko pokaže informacije o spremenljivkah, ki bi vam pomagale organizirati teoretične klinične preizkuse.\n",
"\n",
"Pa začnimo s to nalogo!\n",
"\n",
"<p >\n",
" <img src=\"../../images/encouRage.jpg\"\n",
" width=\"630\"/>\n",
" <figcaption>Umetniško delo @allison_horst</figcaption>\n",
"\n",
"<!--![Umetniško delo \\@allison_horst](../../../../../../2-Regression/1-Tools/images/encouRage.jpg)<br>Umetniško delo @allison_horst-->\n"
],
"metadata": {
"id": "LWNNzfqd6feZ"
}
},
{
"cell_type": "markdown",
"source": [
"## 1. Nalaganje našega nabora orodij\n",
"\n",
"Za to nalogo bomo potrebovali naslednje pakete:\n",
"\n",
"- `tidyverse`: [tidyverse](https://www.tidyverse.org/) je [zbirka paketov za R](https://www.tidyverse.org/packages), zasnovana za hitrejše, enostavnejše in bolj zabavno podatkovno znanost!\n",
"\n",
"- `tidymodels`: [tidymodels](https://www.tidymodels.org/) je [zbirka paketov](https://www.tidymodels.org/packages/) za modeliranje in strojno učenje.\n",
"\n",
"Namestite jih lahko z ukazom:\n",
"\n",
"`install.packages(c(\"tidyverse\", \"tidymodels\"))`\n",
"\n",
"Spodnji skript preveri, ali imate nameščene pakete, potrebne za dokončanje tega modula, in jih po potrebi namesti.\n"
],
"metadata": {
"id": "FIo2YhO26wI9"
}
},
{
"cell_type": "code",
"execution_count": 2,
"source": [
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\n",
"pacman::p_load(tidyverse, tidymodels)"
],
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"Loading required package: pacman\n",
"\n"
]
}
],
"metadata": {
"id": "cIA9fz9v7Dss",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "2df7073b-86b2-4b32-cb86-0da605a0dc11"
}
},
{
"cell_type": "markdown",
"source": [
"Zdaj naložimo te odlične pakete in jih naredimo dostopne v naši trenutni R seji. (To je zgolj za ponazoritev, `pacman::p_load()` je to že naredil namesto vas)\n"
],
"metadata": {
"id": "gpO_P_6f9WUG"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# load the core Tidyverse packages\r\n",
"library(tidyverse)\r\n",
"\r\n",
"# load the core Tidymodels packages\r\n",
"library(tidymodels)\r\n"
],
"outputs": [],
"metadata": {
"id": "NLMycgG-9ezO"
}
},
{
"cell_type": "markdown",
"source": [
"## 2. Dataset o diabetesu\n",
"\n",
"V tej vaji bomo uporabili svoje regresijske veščine za napovedovanje na podlagi podatkov o diabetesu. [Dataset o diabetesu](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt) vključuje `442 vzorce` podatkov o diabetesu, z 10 spremenljivkami napovedovalnih značilnosti: `starost`, `spol`, `indeks telesne mase`, `povprečni krvni tlak` in `šest meritev krvnega seruma`, ter izhodno spremenljivko `y`: kvantitativno merilo napredovanja bolezni eno leto po začetnem stanju.\n",
"\n",
"|Število opazovanj|442|\n",
"|-----------------|:---|\n",
"|Število napovedovalcev|Prvih 10 stolpcev je numeričnih napovedovalnih|\n",
"|Izhodna tarča|Stolpec 11 je kvantitativno merilo napredovanja bolezni eno leto po začetnem stanju|\n",
"|Informacije o napovedovalcih|- starost v letih\n",
"||- spol\n",
"||- bmi indeks telesne mase\n",
"||- bp povprečni krvni tlak\n",
"||- s1 tc, skupni serumski holesterol\n",
"||- s2 ldl, lipoproteini nizke gostote\n",
"||- s3 hdl, lipoproteini visoke gostote\n",
"||- s4 tch, skupni holesterol / HDL\n",
"||- s5 ltg, verjetno logaritem ravni serumskih trigliceridov\n",
"||- s6 glu, raven krvnega sladkorja|\n",
"\n",
"> 🎓 Zapomnite si, to je nadzorovano učenje, zato potrebujemo ciljno spremenljivko 'y'.\n",
"\n",
"Preden lahko manipulirate s podatki v R-ju, jih morate uvoziti v pomnilnik R-ja ali vzpostaviti povezavo do podatkov, ki jih R lahko uporablja za dostop do podatkov na daljavo.\n",
"\n",
"> Paket [readr](https://readr.tidyverse.org/), ki je del Tidyverse, ponuja hiter in prijazen način za branje pravokotnih podatkov v R.\n",
"\n",
"Zdaj naložimo dataset o diabetesu, ki je na voljo na tem URL-ju: <https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html>\n",
"\n",
"Prav tako bomo izvedli osnovni pregled podatkov z uporabo `glimpse()` in prikazali prvih 5 vrstic z uporabo `slice()`.\n",
"\n",
"Preden nadaljujemo, naj predstavimo nekaj, kar boste pogosto srečali v kodi R 🥁🥁: operator cevi `%>%`\n",
"\n",
"Operator cevi (`%>%`) izvaja operacije v logičnem zaporedju tako, da objekt posreduje naprej v funkcijo ali izraz klica. Operator cevi si lahko predstavljate kot \"in nato\" v vaši kodi.\n"
],
"metadata": {
"id": "KM6iXLH996Cl"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Import the data set\r\n",
"diabetes <- read_table2(file = \"https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt\")\r\n",
"\r\n",
"\r\n",
"# Get a glimpse and dimensions of the data\r\n",
"glimpse(diabetes)\r\n",
"\r\n",
"\r\n",
"# Select the first 5 rows of the data\r\n",
"diabetes %>% \r\n",
" slice(1:5)"
],
"outputs": [],
"metadata": {
"id": "Z1geAMhM-bSP"
}
},
{
"cell_type": "markdown",
"source": [
"`glimpse()` nam pokaže, da ima ta podatkovni niz 442 vrstic in 11 stolpcev, pri čemer so vsi stolpci tipa podatkov `double`.\n",
"\n",
"<br>\n",
"\n",
"> `glimpse()` in `slice()` sta funkciji v knjižnici [`dplyr`](https://dplyr.tidyverse.org/). Dplyr, ki je del Tidyverse, je slovnica za manipulacijo podatkov, ki ponuja dosleden nabor glagolov za reševanje najpogostejših izzivov pri obdelavi podatkov.\n",
"\n",
"<br>\n",
"\n",
"Zdaj, ko imamo podatke, se osredotočimo na eno značilnost (`bmi`), ki jo bomo uporabili za to vajo. To zahteva, da izberemo želene stolpce. Kako to storimo?\n",
"\n",
"[`dplyr::select()`](https://dplyr.tidyverse.org/reference/select.html) nam omogoča, da *izberemo* (in po želji preimenujemo) stolpce v podatkovnem okviru.\n"
],
"metadata": {
"id": "UwjVT1Hz-c3Z"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Select predictor feature `bmi` and outcome `y`\r\n",
"diabetes_select <- diabetes %>% \r\n",
" select(c(bmi, y))\r\n",
"\r\n",
"# Print the first 5 rows\r\n",
"diabetes_select %>% \r\n",
" slice(1:10)"
],
"outputs": [],
"metadata": {
"id": "RDY1oAKI-m80"
}
},
{
"cell_type": "markdown",
"source": [
"## 3. Podatki za učenje in testiranje\n",
"\n",
"Pri nadzorovanem učenju je običajna praksa, da podatke *razdelimo* na dva podsklopa; (običajno večji) sklop, s katerim treniramo model, in manjši \"rezervni\" sklop, s katerim preverimo, kako se je model odrezal.\n",
"\n",
"Zdaj, ko imamo podatke pripravljene, lahko preverimo, ali nam stroj lahko pomaga določiti logično razdelitev med številkami v tem naboru podatkov. Uporabimo lahko paket [rsample](https://tidymodels.github.io/rsample/), ki je del okvira Tidymodels, za ustvarjanje objekta, ki vsebuje informacije o *načinu* razdelitve podatkov, nato pa še dve funkciji rsample za pridobitev ustvarjenih učnih in testnih sklopov:\n"
],
"metadata": {
"id": "SDk668xK-tc3"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"set.seed(2056)\r\n",
"# Split 67% of the data for training and the rest for tesing\r\n",
"diabetes_split <- diabetes_select %>% \r\n",
" initial_split(prop = 0.67)\r\n",
"\r\n",
"# Extract the resulting train and test sets\r\n",
"diabetes_train <- training(diabetes_split)\r\n",
"diabetes_test <- testing(diabetes_split)\r\n",
"\r\n",
"# Print the first 3 rows of the training set\r\n",
"diabetes_train %>% \r\n",
" slice(1:10)"
],
"outputs": [],
"metadata": {
"id": "EqtHx129-1h-"
}
},
{
"cell_type": "markdown",
"source": [
"## 4. Učite model linearne regresije s Tidymodels\n",
"\n",
"Zdaj smo pripravljeni, da naučimo naš model!\n",
"\n",
"V Tidymodels modele določite z uporabo `parsnip()` tako, da določite tri koncepte:\n",
"\n",
"- **Tip** modela razlikuje med modeli, kot so linearna regresija, logistična regresija, modeli odločitvenih dreves in podobno.\n",
"\n",
"- **Način** modela vključuje pogoste možnosti, kot sta regresija in klasifikacija; nekateri tipi modelov podpirajo oba načina, medtem ko imajo drugi le en način.\n",
"\n",
"- **Pogon** modela je računsko orodje, ki bo uporabljeno za prilagoditev modela. Pogosto so to R paketi, kot sta **`\"lm\"`** ali **`\"ranger\"`**.\n",
"\n",
"Te informacije o modeliranju so zajete v specifikaciji modela, zato jo ustvarimo!\n"
],
"metadata": {
"id": "sBOS-XhB-6v7"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Build a linear model specification\r\n",
"lm_spec <- \r\n",
" # Type\r\n",
" linear_reg() %>% \r\n",
" # Engine\r\n",
" set_engine(\"lm\") %>% \r\n",
" # Mode\r\n",
" set_mode(\"regression\")\r\n",
"\r\n",
"\r\n",
"# Print the model specification\r\n",
"lm_spec"
],
"outputs": [],
"metadata": {
"id": "20OwEw20--t3"
}
},
{
"cell_type": "markdown",
"source": [
"Ko je model *določen*, ga je mogoče `oceniti` ali `usposobiti` z uporabo funkcije [`fit()`](https://parsnip.tidymodels.org/reference/fit.html), običajno z uporabo formule in nekaterih podatkov.\n",
"\n",
"`y ~ .` pomeni, da bomo prilagodili `y` kot napovedano količino/cilj, ki ga pojasnjujejo vsi napovedniki/lastnosti, tj. `.` (v tem primeru imamo samo en napovednik: `bmi`).\n"
],
"metadata": {
"id": "_oDHs89k_CJj"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Build a linear model specification\r\n",
"lm_spec <- linear_reg() %>% \r\n",
" set_engine(\"lm\") %>%\r\n",
" set_mode(\"regression\")\r\n",
"\r\n",
"\r\n",
"# Train a linear regression model\r\n",
"lm_mod <- lm_spec %>% \r\n",
" fit(y ~ ., data = diabetes_train)\r\n",
"\r\n",
"# Print the model\r\n",
"lm_mod"
],
"outputs": [],
"metadata": {
"id": "YlsHqd-q_GJQ"
}
},
{
"cell_type": "markdown",
"source": [
"Iz modelnega izhoda lahko vidimo koeficiente, pridobljene med učenjem. Ti predstavljajo koeficiente premice najboljše prileganja, ki nam daje najnižjo skupno napako med dejansko in napovedano spremenljivko.\n",
"<br>\n",
"\n",
"## 5. Napovedovanje na testnem naboru\n",
"\n",
"Zdaj, ko smo izurili model, ga lahko uporabimo za napovedovanje napredovanja bolezni y za testni nabor podatkov z uporabo [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html). To bo uporabljeno za risanje premice med skupinami podatkov.\n"
],
"metadata": {
"id": "kGZ22RQj_Olu"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Make predictions for the test set\r\n",
"predictions <- lm_mod %>% \r\n",
" predict(new_data = diabetes_test)\r\n",
"\r\n",
"# Print out some of the predictions\r\n",
"predictions %>% \r\n",
" slice(1:5)"
],
"outputs": [],
"metadata": {
"id": "nXHbY7M2_aao"
}
},
{
"cell_type": "markdown",
"source": [
"Juhu! 💃🕺 Pravkar smo izurili model in ga uporabili za napovedovanje!\n",
"\n",
"Pri napovedovanju je konvencija tidymodels vedno ustvariti tibble/podatkovni okvir z rezultati in standardiziranimi imeni stolpcev. To omogoča enostavno združevanje izvirnih podatkov in napovedi v uporabni obliki za nadaljnje operacije, kot je risanje grafov.\n",
"\n",
"`dplyr::bind_cols()` učinkovito združi več podatkovnih okvirjev po stolpcih.\n"
],
"metadata": {
"id": "R_JstwUY_bIs"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Combine the predictions and the original test set\r\n",
"results <- diabetes_test %>% \r\n",
" bind_cols(predictions)\r\n",
"\r\n",
"\r\n",
"results %>% \r\n",
" slice(1:5)"
],
"outputs": [],
"metadata": {
"id": "RybsMJR7_iI8"
}
},
{
"cell_type": "markdown",
"source": [
"## 6. Prikaz rezultatov modeliranja\n",
"\n",
"Zdaj je čas, da to vidimo vizualno 📈. Ustvarili bomo razpršen diagram vseh vrednosti `y` in `bmi` iz testnega nabora, nato pa uporabili napovedi za risanje črte na najbolj ustreznem mestu med skupinami podatkov modela.\n",
"\n",
"R ima več sistemov za izdelavo grafov, vendar je `ggplot2` eden najbolj elegantnih in najbolj vsestranskih. Omogoča vam sestavljanje grafov z **združevanjem neodvisnih komponent**.\n"
],
"metadata": {
"id": "XJbYbMZW_n_s"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Set a theme for the plot\r\n",
"theme_set(theme_light())\r\n",
"# Create a scatter plot\r\n",
"results %>% \r\n",
" ggplot(aes(x = bmi)) +\r\n",
" # Add a scatter plot\r\n",
" geom_point(aes(y = y), size = 1.6) +\r\n",
" # Add a line plot\r\n",
" geom_line(aes(y = .pred), color = \"blue\", size = 1.5)"
],
"outputs": [],
"metadata": {
"id": "R9tYp3VW_sTn"
}
},
{
"cell_type": "markdown",
"source": [
"✅ Malo razmislite, kaj se tukaj dogaja. Ravna črta poteka skozi številne majhne točke podatkov, vendar kaj točno počne? Ali vidite, kako bi morali biti sposobni uporabiti to črto za napovedovanje, kje bi se nova, nevidena podatkovna točka morala uvrstiti glede na y-os grafa? Poskusite z besedami opisati praktično uporabo tega modela.\n",
"\n",
"Čestitke, zgradili ste svoj prvi model linearne regresije, z njim ustvarili napoved in jo prikazali na grafu!\n"
],
"metadata": {
"id": "zrPtHIxx_tNI"
}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da se zavedate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
]
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,46 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.3-final"
},
"orig_nbformat": 2,
"kernelspec": {
"name": "python3",
"display_name": "Python 3",
"language": "python"
},
"coopTranslator": {
"original_hash": "1b2ab303ac6c604a34c6ca7a49077fc7",
"translation_date": "2025-09-06T13:45:51+00:00",
"source_file": "2-Regression/2-Data/notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
]
}

@ -0,0 +1,684 @@
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {
"colab": {
"name": "lesson_2-R.ipynb",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true
},
"kernelspec": {
"name": "ir",
"display_name": "R"
},
"language_info": {
"name": "R"
},
"coopTranslator": {
"original_hash": "f3c335f9940cfd76528b3ef918b9b342",
"translation_date": "2025-09-06T13:49:10+00:00",
"source_file": "2-Regression/2-Data/solution/R/lesson_2-R.ipynb",
"language_code": "sl"
}
},
"cells": [
{
"cell_type": "markdown",
"source": [
"# Zgradite regresijski model: priprava in vizualizacija podatkov\n",
"\n",
"## **Linearna regresija za buče - Lekcija 2**\n",
"#### Uvod\n",
"\n",
"Zdaj, ko imate na voljo orodja, ki jih potrebujete za začetek gradnje modelov strojnega učenja z Tidymodels in Tidyverse, ste pripravljeni začeti postavljati vprašanja o svojih podatkih. Ko delate s podatki in uporabljate rešitve strojnega učenja, je zelo pomembno, da znate postaviti prava vprašanja, da pravilno izkoristite potencial svojega nabora podatkov.\n",
"\n",
"V tej lekciji boste spoznali:\n",
"\n",
"- Kako pripraviti podatke za gradnjo modela.\n",
"\n",
"- Kako uporabiti `ggplot2` za vizualizacijo podatkov.\n",
"\n",
"Vprašanje, na katerega želite dobiti odgovor, bo določilo, katere vrste algoritmov strojnega učenja boste uporabili. Kakovost odgovora, ki ga dobite, pa bo močno odvisna od narave vaših podatkov.\n",
"\n",
"Poglejmo to skozi praktično vajo.\n",
"\n",
"\n",
"<p >\n",
" <img src=\"../../images/unruly_data.jpg\"\n",
" width=\"700\"/>\n",
" <figcaption>Umetniško delo @allison_horst</figcaption>\n",
"\n",
"\n",
"<!--![Umetniško delo \\@allison_horst](../../../../../../2-Regression/2-Data/images/unruly_data.jpg)<br>Umetniško delo \\@allison_horst-->\n"
],
"metadata": {
"id": "Pg5aexcOPqAZ"
}
},
{
"cell_type": "markdown",
"source": [
"## 1. Uvoz podatkov o bučah in priklic Tidyverse\n",
"\n",
"Za obdelavo te lekcije bomo potrebovali naslednje pakete:\n",
"\n",
"- `tidyverse`: [tidyverse](https://www.tidyverse.org/) je [zbirka paketov za R](https://www.tidyverse.org/packages), zasnovana za hitrejše, enostavnejše in bolj zabavno podatkovno znanost!\n",
"\n",
"Namestite jih lahko z ukazom:\n",
"\n",
"`install.packages(c(\"tidyverse\"))`\n",
"\n",
"Spodnji skript preveri, ali imate nameščene pakete, potrebne za dokončanje tega modula, in jih namesti, če kateri manjka.\n"
],
"metadata": {
"id": "dc5WhyVdXAjR"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\n",
"pacman::p_load(tidyverse)"
],
"outputs": [],
"metadata": {
"id": "GqPYUZgfXOBt"
}
},
{
"cell_type": "markdown",
"source": [
"Zdaj zaženimo nekaj paketov in naložimo [podatke](https://github.com/microsoft/ML-For-Beginners/blob/main/2-Regression/data/US-pumpkins.csv), ki so na voljo za to lekcijo!\n"
],
"metadata": {
"id": "kvjDTPDSXRr2"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Load the core Tidyverse packages\n",
"library(tidyverse)\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 =50)"
],
"outputs": [],
"metadata": {
"id": "VMri-t2zXqgD"
}
},
{
"cell_type": "markdown",
"source": [
"Hitro `glimpse()` takoj pokaže, da so prisotne prazne vrednosti ter mešanica nizov (`chr`) in numeričnih podatkov (`dbl`). `Date` je tipa znak, poleg tega pa je tu še nenavadni stolpec z imenom `Package`, kjer so podatki mešanica med `sacks`, `bins` in drugimi vrednostmi. Podatki so, pravzaprav, precej zmedeni 😤.\n",
"\n",
"Pravzaprav ni ravno pogosto, da bi dobili podatkovni niz, ki je popolnoma pripravljen za uporabo pri ustvarjanju modela strojnega učenja kar takoj. A brez skrbi, v tej lekciji se boste naučili, kako pripraviti surov podatkovni niz z uporabo standardnih knjižnic v R 🧑‍🔧. Prav tako se boste naučili različnih tehnik za vizualizacijo podatkov.📈📊\n",
"<br>\n",
"\n",
"> Osvežitev: Operator cevi (`%>%`) izvaja operacije v logičnem zaporedju tako, da objekt posreduje naprej v funkcijo ali izraz klica. Operator cevi si lahko predstavljate kot \"in potem\" v vaši kodi.\n"
],
"metadata": {
"id": "REWcIv9yX29v"
}
},
{
"cell_type": "markdown",
"source": [
"## 2. Preverjanje manjkajočih podatkov\n",
"\n",
"Ena najpogostejših težav, s katerimi se soočajo podatkovni znanstveniki, so nepopolni ali manjkajoči podatki. R predstavlja manjkajoče ali neznane vrednosti s posebnim označevalcem: `NA` (Not Available).\n",
"\n",
"Kako torej ugotovimo, da podatkovni okvir vsebuje manjkajoče vrednosti?\n",
"<br>\n",
"- Eden od preprostih načinov je uporaba osnovne R funkcije `anyNA`, ki vrne logične vrednosti `TRUE` ali `FALSE`.\n"
],
"metadata": {
"id": "Zxfb3AM5YbUe"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" anyNA()"
],
"outputs": [],
"metadata": {
"id": "G--DQutAYltj"
}
},
{
"cell_type": "markdown",
"source": [
"Odlično, zdi se, da manjkajo nekateri podatki! To je dobro izhodišče.\n",
"\n",
"- Druga možnost bi bila uporaba funkcije `is.na()`, ki pokaže, kateri posamezni elementi stolpcev manjkajo, z logično vrednostjo `TRUE`.\n"
],
"metadata": {
"id": "mU-7-SB6YokF"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" is.na() %>% \n",
" head(n = 7)"
],
"outputs": [],
"metadata": {
"id": "W-DxDOR4YxSW"
}
},
{
"cell_type": "markdown",
"source": [
"V redu, naloga je opravljena, vendar bi bilo z veliko podatkovno tabelo, kot je ta, neučinkovito in praktično nemogoče pregledati vse vrstice in stolpce posamično😴.\n",
"\n",
"- Bolj intuitiven način bi bil izračunati vsoto manjkajočih vrednosti za vsak stolpec:\n"
],
"metadata": {
"id": "xUWxipKYY0o7"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" is.na() %>% \n",
" colSums()"
],
"outputs": [],
"metadata": {
"id": "ZRBWV6P9ZArL"
}
},
{
"cell_type": "markdown",
"source": [
"Veliko bolje! Manjkajo podatki, vendar morda to ne bo pomembno za nalogo. Poglejmo, kaj bo prinesla nadaljnja analiza.\n",
"\n",
"> Poleg odličnih paketov in funkcij ima R zelo dobro dokumentacijo. Na primer, uporabite `help(colSums)` ali `?colSums`, da izveste več o funkciji.\n"
],
"metadata": {
"id": "9gv-crB6ZD1Y"
}
},
{
"cell_type": "markdown",
"source": [
"## 3. Dplyr: Slovnica za manipulacijo podatkov\n",
"\n",
"<p >\n",
" <img src=\"../../images/dplyr_wrangling.png\"\n",
" width=\"569\"/>\n",
" <figcaption>Ilustracija avtorice @allison_horst</figcaption>\n",
"\n",
"\n",
"<!--![Ilustracija avtorice \\@allison_horst](../../../../../../2-Regression/2-Data/images/dplyr_wrangling.png)<br/>Ilustracija avtorice \\@allison_horst-->\n"
],
"metadata": {
"id": "o4jLY5-VZO2C"
}
},
{
"cell_type": "markdown",
"source": [
"[`dplyr`](https://dplyr.tidyverse.org/), paket v Tidyverse, je slovnica za obdelavo podatkov, ki ponuja dosleden nabor glagolov, s katerimi lahko rešite najpogostejše izzive pri obdelavi podatkov. V tem razdelku bomo raziskali nekatere glagole dplyr!\n"
],
"metadata": {
"id": "i5o33MQBZWWw"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::select()\n",
"\n",
"`select()` je funkcija v paketu `dplyr`, ki vam pomaga izbrati stolpce za ohranitev ali izključitev.\n",
"\n",
"Da bo vaš podatkovni okvir lažji za delo, odstranite več njegovih stolpcev z uporabo `select()` in obdržite samo tiste stolpce, ki jih potrebujete.\n",
"\n",
"Na primer, v tej vaji bo naša analiza vključevala stolpce `Package`, `Low Price`, `High Price` in `Date`. Izberimo te stolpce.\n"
],
"metadata": {
"id": "x3VGMAGBZiUr"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Select desired columns\n",
"pumpkins <- pumpkins %>% \n",
" select(Package, `Low Price`, `High Price`, Date)\n",
"\n",
"\n",
"# Print data set\n",
"pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "F_FgxQnVZnM0"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::mutate()\n",
"\n",
"`mutate()` je funkcija v paketu `dplyr`, ki vam omogoča ustvarjanje ali spreminjanje stolpcev, pri čemer obstoječi stolpci ostanejo nespremenjeni.\n",
"\n",
"Splošna struktura funkcije mutate je:\n",
"\n",
"`data %>% mutate(new_column_name = what_it_contains)`\n",
"\n",
"Poglejmo, kako deluje `mutate`, z uporabo stolpca `Date` in izvedbo naslednjih operacij:\n",
"\n",
"1. Pretvorba datumov (trenutno tipa znak) v format meseca (to so ameriški datumi, zato je format `MM/DD/YYYY`).\n",
"\n",
"2. Izvleček meseca iz datumov v nov stolpec.\n",
"\n",
"V jeziku R paket [lubridate](https://lubridate.tidyverse.org/) olajša delo s podatki tipa Datum-čas. Zato uporabimo `dplyr::mutate()`, `lubridate::mdy()`, `lubridate::month()` in preverimo, kako doseči zgoraj navedene cilje. Stolpec Date lahko odstranimo, saj ga v nadaljnjih operacijah ne bomo več potrebovali.\n"
],
"metadata": {
"id": "2KKo0Ed9Z1VB"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Load lubridate\n",
"library(lubridate)\n",
"\n",
"pumpkins <- pumpkins %>% \n",
" # Convert the Date column to a date object\n",
" mutate(Date = mdy(Date)) %>% \n",
" # Extract month from Date\n",
" mutate(Month = month(Date)) %>% \n",
" # Drop Date column\n",
" select(-Date)\n",
"\n",
"# View the first few rows\n",
"pumpkins %>% \n",
" slice_head(n = 7)"
],
"outputs": [],
"metadata": {
"id": "5joszIVSZ6xe"
}
},
{
"cell_type": "markdown",
"source": [
"Juhu! 🤩\n",
"\n",
"Zdaj ustvarimo nov stolpec `Price`, ki predstavlja povprečno ceno buče. Nato izračunajmo povprečje stolpcev `Low Price` in `High Price`, da zapolnimo novi stolpec Price. \n",
"<br>\n"
],
"metadata": {
"id": "nIgLjNMCZ-6Y"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Create a new column Price\n",
"pumpkins <- pumpkins %>% \n",
" mutate(Price = (`Low Price` + `High Price`)/2)\n",
"\n",
"# View the first few rows of the data\n",
"pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "Zo0BsqqtaJw2"
}
},
{
"cell_type": "markdown",
"source": [
"Ja!💪\n",
"\n",
"\"Počakaj malo!\", boš rekel po hitrem pregledu celotnega nabora podatkov z `View(pumpkins)`, \"Tukaj je nekaj nenavadnega!\"🤔\n",
"\n",
"Če pogledaš stolpec `Package`, so buče prodane v različnih konfiguracijah. Nekatere so prodane v merah `1 1/9 bushel`, nekatere v merah `1/2 bushel`, nekatere na bučo, nekatere na funt, in nekatere v velikih škatlah z različnimi širinami.\n",
"\n",
"Preverimo to:\n"
],
"metadata": {
"id": "p77WZr-9aQAR"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Verify the distinct observations in Package column\n",
"pumpkins %>% \n",
" distinct(Package)"
],
"outputs": [],
"metadata": {
"id": "XISGfh0IaUy6"
}
},
{
"cell_type": "markdown",
"source": [
"Neverjetno!👏\n",
"\n",
"Buče je očitno zelo težko dosledno tehtati, zato jih filtrirajmo tako, da izberemo samo buče z nizom *bushel* v stolpcu `Package` in jih shranimo v nov podatkovni okvir `new_pumpkins`.\n"
],
"metadata": {
"id": "7sMjiVujaZxY"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::filter() in stringr::str_detect()\n",
"\n",
"[`dplyr::filter()`](https://dplyr.tidyverse.org/reference/filter.html): ustvari podmnožico podatkov, ki vsebuje **vrstice**, ki ustrezajo vašim pogojem, v tem primeru buče z nizom *bushel* v stolpcu `Package`.\n",
"\n",
"[stringr::str_detect()](https://stringr.tidyverse.org/reference/str_detect.html): zazna prisotnost ali odsotnost vzorca v nizu.\n",
"\n",
"Paket [`stringr`](https://github.com/tidyverse/stringr) ponuja enostavne funkcije za pogoste operacije z nizi.\n"
],
"metadata": {
"id": "L8Qfcs92ageF"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Retain only pumpkins with \"bushel\"\n",
"new_pumpkins <- pumpkins %>% \n",
" filter(str_detect(Package, \"bushel\"))\n",
"\n",
"# Get the dimensions of the new data\n",
"dim(new_pumpkins)\n",
"\n",
"# View a few rows of the new data\n",
"new_pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "hy_SGYREampd"
}
},
{
"cell_type": "markdown",
"source": [
"Vidite, da smo zožili izbor na približno 415 vrstic podatkov, ki vsebujejo buče po koših.🤩\n"
],
"metadata": {
"id": "VrDwF031avlR"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::case_when()\n",
"\n",
"**Ampak počakajte! Še nekaj je treba narediti**\n",
"\n",
"Ste opazili, da se količina košev razlikuje po vrsticah? Potrebno je normalizirati cene, da bodo prikazane na koš, ne pa na 1 1/9 ali 1/2 koša. Čas je za nekaj matematike, da to standardiziramo.\n",
"\n",
"Uporabili bomo funkcijo [`case_when()`](https://dplyr.tidyverse.org/reference/case_when.html), da *spremenimo* stolpec Price glede na določene pogoje. `case_when` omogoča vektorizacijo več `if_else()` stavkov.\n"
],
"metadata": {
"id": "mLpw2jH4a0tx"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Convert the price if the Package contains fractional bushel values\n",
"new_pumpkins <- new_pumpkins %>% \n",
" mutate(Price = case_when(\n",
" str_detect(Package, \"1 1/9\") ~ Price/(1 + 1/9),\n",
" str_detect(Package, \"1/2\") ~ Price/(1/2),\n",
" TRUE ~ Price))\n",
"\n",
"# View the first few rows of the data\n",
"new_pumpkins %>% \n",
" slice_head(n = 30)"
],
"outputs": [],
"metadata": {
"id": "P68kLVQmbM6I"
}
},
{
"cell_type": "markdown",
"source": [
"Zdaj lahko analiziramo ceno na enoto glede na njihovo meritev v bušlnih. Vsa ta študija o bušlnih buč pa kaže, kako zelo `pomembno` je `razumeti naravo svojih podatkov`!\n",
"\n",
"> ✅ Po navedbah [The Spruce Eats](https://www.thespruceeats.com/how-much-is-a-bushel-1389308) teža bušlja zavisi od vrste pridelka, saj gre za meritev prostornine. \"Bušelj paradižnikov, na primer, naj bi tehtal 56 funtov... Listi in zelenjava zavzamejo več prostora z manjšo težo, zato bušelj špinače tehta le 20 funtov.\" Vse skupaj je precej zapleteno! Ne ukvarjajmo se s pretvorbo iz bušljev v funte, ampak raje določimo ceno po bušlju. Vsa ta študija o bušlnih buč pa kaže, kako zelo pomembno je razumeti naravo svojih podatkov!\n",
">\n",
"> ✅ Ste opazili, da so buče, prodane po pol bušlja, zelo drage? Ali lahko ugotovite, zakaj? Namig: majhne buče so precej dražje od velikih, verjetno zato, ker jih je v bušlju veliko več, glede na neizkoriščen prostor, ki ga zavzame ena velika votla buča za pito.\n"
],
"metadata": {
"id": "pS2GNPagbSdb"
}
},
{
"cell_type": "markdown",
"source": [
"Pomembno pravilo: \n",
"1. NE dodajajte '''markdown ali kakršnih koli drugih oznak okoli prevoda \n",
"2. Poskrbite, da prevod ne bo zvenel preveč dobesedno \n",
"3. Prevedite tudi komentarje \n",
"4. Ta datoteka je napisana v obliki Markdown - ne obravnavajte je kot XML ali HTML \n",
"5. Ne prevajajte: \n",
" - [!NOTE], [!WARNING], [!TIP], [!IMPORTANT], [!CAUTION] \n",
" - Imen spremenljivk, funkcij, razredov \n",
" - Oznak, kot so @@INLINE_CODE_x@@ ali @@CODE_BLOCK_x@@ \n",
" - URL-jev ali poti \n",
"6. Ohranite vso izvirno oblikovanje Markdown nespremenjeno \n",
"7. Vrni SAMO prevedeno vsebino brez dodatnih oznak ali oblikovanja \n",
"\n",
"Zdaj pa, za čisto avanturo 💁‍♀️, premaknimo stolpec Month na prvo mesto, torej `pred` stolpec `Package`. \n",
"\n",
"Za spremembo položajev stolpcev se uporablja `dplyr::relocate()`. \n"
],
"metadata": {
"id": "qql1SowfbdnP"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Create a new data frame new_pumpkins\n",
"new_pumpkins <- new_pumpkins %>% \n",
" relocate(Month, .before = Package)\n",
"\n",
"new_pumpkins %>% \n",
" slice_head(n = 7)"
],
"outputs": [],
"metadata": {
"id": "JJ1x6kw8bixF"
}
},
{
"cell_type": "markdown",
"source": [
"Odlično delo!👌 Zdaj imate čist in urejen nabor podatkov, na katerem lahko zgradite svoj novi regresijski model! \n",
"<br>\n"
],
"metadata": {
"id": "y8TJ0Za_bn5Y"
}
},
{
"cell_type": "markdown",
"source": [
"## 4. Vizualizacija podatkov z ggplot2\n",
"\n",
"<p >\n",
" <img src=\"../../images/data-visualization.png\"\n",
" width=\"600\"/>\n",
" <figcaption>Infografika avtorja Dasani Madipalli</figcaption>\n",
"\n",
"\n",
"<!--![Infografika avtorja Dasani Madipalli](../../../../../../2-Regression/2-Data/images/data-visualization.png){width=\"600\"}-->\n",
"\n",
"Obstaja *modri* rek, ki pravi:\n",
"\n",
"> \"Preprost graf je analitiku podatkov prinesel več informacij kot katerakoli druga naprava.\" --- John Tukey\n",
"\n",
"Del vloge podatkovnega znanstvenika je prikazati kakovost in naravo podatkov, s katerimi dela. To pogosto dosežejo z ustvarjanjem zanimivih vizualizacij, kot so grafi, diagrami in prikazi, ki pokažejo različne vidike podatkov. Na ta način lahko vizualno prikažejo odnose in vrzeli, ki jih je sicer težko odkriti.\n",
"\n",
"Vizualizacije lahko pomagajo tudi pri določanju najbolj primerne tehnike strojnega učenja za podatke. Na primer, razpršen diagram, ki sledi črti, nakazuje, da so podatki primerni za nalogo linearne regresije.\n",
"\n",
"R ponuja več sistemov za izdelavo grafov, vendar je [`ggplot2`](https://ggplot2.tidyverse.org/index.html) eden najbolj elegantnih in vsestranskih. `ggplot2` omogoča sestavljanje grafov z **združevanjem neodvisnih komponent**.\n",
"\n",
"Začnimo s preprostim razpršenim diagramom za stolpca Price in Month.\n",
"\n",
"V tem primeru bomo začeli z [`ggplot()`](https://ggplot2.tidyverse.org/reference/ggplot.html), podali podatkovni niz in estetsko preslikavo (z [`aes()`](https://ggplot2.tidyverse.org/reference/aes.html)), nato pa dodali sloje (kot je [`geom_point()`](https://ggplot2.tidyverse.org/reference/geom_point.html)) za razpršene diagrame.\n"
],
"metadata": {
"id": "mYSH6-EtbvNa"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Set a theme for the plots\n",
"theme_set(theme_light())\n",
"\n",
"# Create a scatter plot\n",
"p <- ggplot(data = new_pumpkins, aes(x = Price, y = Month))\n",
"p + geom_point()"
],
"outputs": [],
"metadata": {
"id": "g2YjnGeOcLo4"
}
},
{
"cell_type": "markdown",
"source": [
"Je to uporaben graf 🤷? Ali te kaj na njem preseneča?\n",
"\n",
"Ni posebej uporaben, saj zgolj prikazuje tvoje podatke kot razpored točk v določenem mesecu.\n",
"<br>\n"
],
"metadata": {
"id": "Ml7SDCLQcPvE"
}
},
{
"cell_type": "markdown",
"source": [
"### **Kako naredimo podatke uporabne?**\n",
"\n",
"Da bi prikazali koristne podatke na grafikonih, je običajno potrebno podatke nekako združiti. Na primer, v našem primeru bi iskanje povprečne cene buč za vsak mesec omogočilo boljši vpogled v osnovne vzorce v naših podatkih. To nas pripelje do še ene hitre predstavitve **dplyr**:\n",
"\n",
"#### `dplyr::group_by() %>% summarize()`\n",
"\n",
"Združeno agregiranje v R lahko enostavno izvedemo z\n",
"\n",
"`dplyr::group_by() %>% summarize()`\n",
"\n",
"- `dplyr::group_by()` spremeni enoto analize iz celotnega nabora podatkov na posamezne skupine, kot so na primer meseci.\n",
"\n",
"- `dplyr::summarize()` ustvari nov podatkovni okvir z enim stolpcem za vsako spremenljivko skupine in enim stolpcem za vsako statistiko povzetka, ki ste jo določili.\n",
"\n",
"Na primer, lahko uporabimo `dplyr::group_by() %>% summarize()` za združevanje buč v skupine na podlagi stolpca **Month** in nato izračunamo **povprečno ceno** za vsak mesec.\n"
],
"metadata": {
"id": "jMakvJZIcVkh"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Find the average price of pumpkins per month\r\n",
"new_pumpkins %>%\r\n",
" group_by(Month) %>% \r\n",
" summarise(mean_price = mean(Price))"
],
"outputs": [],
"metadata": {
"id": "6kVSUa2Bcilf"
}
},
{
"cell_type": "markdown",
"source": [
"Jedrnato!✨\n",
"\n",
"Kategorijske značilnosti, kot so meseci, so bolje prikazane z uporabo stolpčnega diagrama 📊. Plasti, ki so odgovorne za stolpčne diagrame, so `geom_bar()` in `geom_col()`. Preverite `?geom_bar` za več informacij.\n",
"\n",
"Pa ga ustvarimo!\n"
],
"metadata": {
"id": "Kds48GUBcj3W"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Find the average price of pumpkins per month then plot a bar chart\r\n",
"new_pumpkins %>%\r\n",
" group_by(Month) %>% \r\n",
" summarise(mean_price = mean(Price)) %>% \r\n",
" ggplot(aes(x = Month, y = mean_price)) +\r\n",
" geom_col(fill = \"midnightblue\", alpha = 0.7) +\r\n",
" ylab(\"Pumpkin Price\")"
],
"outputs": [],
"metadata": {
"id": "VNbU1S3BcrxO"
}
},
{
"cell_type": "markdown",
"source": [
"🤩🤩 To je bolj uporabna vizualizacija podatkov! Zdi se, da kaže, da so najvišje cene buč v septembru in oktobru. Ali to ustreza vašim pričakovanjem? Zakaj ali zakaj ne?\n",
"\n",
"Čestitke za zaključek druge lekcije 👏! Pripravili ste svoje podatke za gradnjo modela in nato odkrili več vpogledov z uporabo vizualizacij!\n"
],
"metadata": {
"id": "zDm0VOzzcuzR"
}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
]
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,128 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Cene buč\n",
"\n",
"Naložite potrebne knjižnice in podatkovni niz. Pretvorite podatke v podatkovni okvir, ki vsebuje podnabor podatkov:\n",
"\n",
"- Pridobite samo buče, ki so ocenjene po ceni na koš\n",
"- Pretvorite datum v mesec\n",
"- Izračunajte ceno kot povprečje med najvišjo in najnižjo ceno\n",
"- Pretvorite ceno, da odraža ceno glede na količino v košu\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"from datetime import datetime\n",
"\n",
"pumpkins = pd.read_csv('../data/US-pumpkins.csv')\n",
"\n",
"pumpkins.head()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"pumpkins = pumpkins[pumpkins['Package'].str.contains('bushel', case=True, regex=True)]\n",
"\n",
"columns_to_select = ['Package', 'Variety', 'City Name', 'Low Price', 'High Price', 'Date']\n",
"pumpkins = pumpkins.loc[:, columns_to_select]\n",
"\n",
"price = (pumpkins['Low Price'] + pumpkins['High Price']) / 2\n",
"\n",
"month = pd.DatetimeIndex(pumpkins['Date']).month\n",
"day_of_year = pd.to_datetime(pumpkins['Date']).apply(lambda dt: (dt-datetime(dt.year,1,1)).days)\n",
"\n",
"new_pumpkins = pd.DataFrame(\n",
" {'Month': month, \n",
" 'DayOfYear' : day_of_year, \n",
" 'Variety': pumpkins['Variety'], \n",
" 'City': pumpkins['City Name'], \n",
" 'Package': pumpkins['Package'], \n",
" 'Low Price': pumpkins['Low Price'],\n",
" 'High Price': pumpkins['High Price'], \n",
" 'Price': price})\n",
"\n",
"new_pumpkins.loc[new_pumpkins['Package'].str.contains('1 1/9'), 'Price'] = price/1.1\n",
"new_pumpkins.loc[new_pumpkins['Package'].str.contains('1/2'), 'Price'] = price*2\n",
"\n",
"new_pumpkins.head()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Osnovni raztreseni diagram nas opominja, da imamo podatke o mesecih samo od avgusta do decembra. Verjetno potrebujemo več podatkov, da bi lahko sklepali na linearen način.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"plt.scatter('Month','Price',data=new_pumpkins)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"\n",
"plt.scatter('DayOfYear','Price',data=new_pumpkins)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.3-final"
},
"orig_nbformat": 2,
"coopTranslator": {
"original_hash": "b032d371c75279373507f003439a577e",
"translation_date": "2025-09-06T13:08:38+00:00",
"source_file": "2-Regression/3-Linear/notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,269 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Sorte buč in barva\n",
"\n",
"Naložite potrebne knjižnice in podatkovni niz. Podatke pretvorite v podatkovni okvir, ki vsebuje podmnožico podatkov:\n",
"\n",
"Poglejmo razmerje med barvo in sorto.\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>City Name</th>\n",
" <th>Type</th>\n",
" <th>Package</th>\n",
" <th>Variety</th>\n",
" <th>Sub Variety</th>\n",
" <th>Grade</th>\n",
" <th>Date</th>\n",
" <th>Low Price</th>\n",
" <th>High Price</th>\n",
" <th>Mostly Low</th>\n",
" <th>...</th>\n",
" <th>Unit of Sale</th>\n",
" <th>Quality</th>\n",
" <th>Condition</th>\n",
" <th>Appearance</th>\n",
" <th>Storage</th>\n",
" <th>Crop</th>\n",
" <th>Repack</th>\n",
" <th>Trans Mode</th>\n",
" <th>Unnamed: 24</th>\n",
" <th>Unnamed: 25</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>BALTIMORE</td>\n",
" <td>NaN</td>\n",
" <td>24 inch bins</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>4/29/17</td>\n",
" <td>270.0</td>\n",
" <td>280.0</td>\n",
" <td>270.0</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>E</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>BALTIMORE</td>\n",
" <td>NaN</td>\n",
" <td>24 inch bins</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>5/6/17</td>\n",
" <td>270.0</td>\n",
" <td>280.0</td>\n",
" <td>270.0</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>E</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>BALTIMORE</td>\n",
" <td>NaN</td>\n",
" <td>24 inch bins</td>\n",
" <td>HOWDEN TYPE</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>9/24/16</td>\n",
" <td>160.0</td>\n",
" <td>160.0</td>\n",
" <td>160.0</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>N</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>BALTIMORE</td>\n",
" <td>NaN</td>\n",
" <td>24 inch bins</td>\n",
" <td>HOWDEN TYPE</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>9/24/16</td>\n",
" <td>160.0</td>\n",
" <td>160.0</td>\n",
" <td>160.0</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>N</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>BALTIMORE</td>\n",
" <td>NaN</td>\n",
" <td>24 inch bins</td>\n",
" <td>HOWDEN TYPE</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>11/5/16</td>\n",
" <td>90.0</td>\n",
" <td>100.0</td>\n",
" <td>90.0</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>N</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5 rows × 26 columns</p>\n",
"</div>"
],
"text/plain": [
" City Name Type Package Variety Sub Variety Grade Date \\\n",
"0 BALTIMORE NaN 24 inch bins NaN NaN NaN 4/29/17 \n",
"1 BALTIMORE NaN 24 inch bins NaN NaN NaN 5/6/17 \n",
"2 BALTIMORE NaN 24 inch bins HOWDEN TYPE NaN NaN 9/24/16 \n",
"3 BALTIMORE NaN 24 inch bins HOWDEN TYPE NaN NaN 9/24/16 \n",
"4 BALTIMORE NaN 24 inch bins HOWDEN TYPE NaN NaN 11/5/16 \n",
"\n",
" Low Price High Price Mostly Low ... Unit of Sale Quality Condition \\\n",
"0 270.0 280.0 270.0 ... NaN NaN NaN \n",
"1 270.0 280.0 270.0 ... NaN NaN NaN \n",
"2 160.0 160.0 160.0 ... NaN NaN NaN \n",
"3 160.0 160.0 160.0 ... NaN NaN NaN \n",
"4 90.0 100.0 90.0 ... NaN NaN NaN \n",
"\n",
" Appearance Storage Crop Repack Trans Mode Unnamed: 24 Unnamed: 25 \n",
"0 NaN NaN NaN E NaN NaN NaN \n",
"1 NaN NaN NaN E NaN NaN NaN \n",
"2 NaN NaN NaN N NaN NaN NaN \n",
"3 NaN NaN NaN N NaN NaN NaN \n",
"4 NaN NaN NaN N NaN NaN NaN \n",
"\n",
"[5 rows x 26 columns]"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"\n",
"full_pumpkins = pd.read_csv('../data/US-pumpkins.csv')\n",
"\n",
"full_pumpkins.head()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da se zavedate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.1"
},
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
}
},
"orig_nbformat": 2,
"coopTranslator": {
"original_hash": "dee08c2b49057b0de8b6752c4dbca368",
"translation_date": "2025-09-06T13:26:26+00:00",
"source_file": "2-Regression/4-Logistic/notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

@ -0,0 +1,685 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Ustvarite model logistične regresije - Lekcija 4\n",
"\n",
"![Infografika: Logistična vs. linearna regresija](../../../../../../2-Regression/4-Logistic/images/linear-vs-logistic.png)\n",
"\n",
"#### **[Predhodni kviz](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/15/)**\n",
"\n",
"#### Uvod\n",
"\n",
"V tej zadnji lekciji o regresiji, eni izmed osnovnih *klasičnih* tehnik strojnega učenja, si bomo ogledali logistično regresijo. To tehniko bi uporabili za odkrivanje vzorcev za napovedovanje binarnih kategorij. Ali je ta sladkarija čokolada ali ne? Ali je ta bolezen nalezljiva ali ne? Ali bo ta stranka izbrala ta izdelek ali ne?\n",
"\n",
"V tej lekciji boste spoznali:\n",
"\n",
"- Tehnike za logistično regresijo\n",
"\n",
"✅ Poglobite svoje razumevanje dela s to vrsto regresije v tem [učnem modulu](https://learn.microsoft.com/training/modules/introduction-classification-models/?WT.mc_id=academic-77952-leestott)\n",
"\n",
"## Predpogoji\n",
"\n",
"Ker smo že delali s podatki o bučah, smo zdaj dovolj seznanjeni z njimi, da ugotovimo, da obstaja ena binarna kategorija, s katero lahko delamo: `Barva`.\n",
"\n",
"Zgradimo model logistične regresije, da napovemo, glede na nekatere spremenljivke, *kakšne barve bo določena buča verjetno* (oranžna 🎃 ali bela 👻).\n",
"\n",
"> Zakaj govorimo o binarni klasifikaciji v lekciji, ki se ukvarja z regresijo? Izključno zaradi jezikovne priročnosti, saj je logistična regresija [pravzaprav metoda klasifikacije](https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression), čeprav temelji na linearni metodi. Več o drugih načinih klasifikacije podatkov boste izvedeli v naslednji skupini lekcij.\n",
"\n",
"Za to lekcijo bomo potrebovali naslednje pakete:\n",
"\n",
"- `tidyverse`: [Tidyverse](https://www.tidyverse.org/) je [zbirka paketov za R](https://www.tidyverse.org/packages), zasnovana za hitrejše, lažje in bolj zabavno delo z podatki!\n",
"\n",
"- `tidymodels`: [Tidymodels](https://www.tidymodels.org/) je okvir [zbirke paketov](https://www.tidymodels.org/packages/) za modeliranje in strojno učenje.\n",
"\n",
"- `janitor`: Paket [janitor](https://github.com/sfirke/janitor) ponuja preprosta orodja za pregledovanje in čiščenje umazanih podatkov.\n",
"\n",
"- `ggbeeswarm`: Paket [ggbeeswarm](https://github.com/eclarke/ggbeeswarm) omogoča ustvarjanje grafov v slogu \"beeswarm\" z uporabo ggplot2.\n",
"\n",
"Namestite jih lahko z ukazom:\n",
"\n",
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"janitor\", \"ggbeeswarm\"))`\n",
"\n",
"Alternativno, spodnji skript preveri, ali imate potrebne pakete za dokončanje tega modula, in jih namesti, če manjkajo.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"suppressWarnings(if (!require(\"pacman\"))install.packages(\"pacman\"))\n",
"\n",
"pacman::p_load(tidyverse, tidymodels, janitor, ggbeeswarm)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## **Določite vprašanje**\n",
"\n",
"Za naše namene bomo to izrazili kot binarno: 'Bela' ali 'Ne bela'. V našem naboru podatkov obstaja tudi kategorija 'črtasta', vendar je primerov te kategorije malo, zato je ne bomo uporabili. Kategorija tako ali tako izgine, ko odstranimo ničelne vrednosti iz nabora podatkov.\n",
"\n",
"> 🎃 Zabavno dejstvo: bele buče včasih imenujemo 'duhove' buče. Niso zelo enostavne za rezljanje, zato niso tako priljubljene kot oranžne, vendar so videti kul! Tako bi lahko naše vprašanje preoblikovali tudi kot: 'Duh' ali 'Ne duh'. 👻\n",
"\n",
"## **O logistični regresiji**\n",
"\n",
"Logistična regresija se od linearne regresije, o kateri ste se že učili, razlikuje v nekaj pomembnih vidikih.\n",
"\n",
"#### **Binarna klasifikacija**\n",
"\n",
"Logistična regresija ne ponuja enakih funkcij kot linearna regresija. Prva ponuja napoved o `binarni kategoriji` (\"oranžna ali ne oranžna\"), medtem ko je druga sposobna napovedovati `neprekinjene vrednosti`, na primer glede na izvor buče in čas žetve, *koliko se bo njena cena zvišala*.\n",
"\n",
"![Infografika avtorja Dasani Madipalli](../../../../../../2-Regression/4-Logistic/images/pumpkin-classifier.png)\n",
"\n",
"### Druge klasifikacije\n",
"\n",
"Obstajajo tudi druge vrste logistične regresije, vključno z multinomno in ordinalno:\n",
"\n",
"- **Multinomna**, ki vključuje več kot eno kategorijo - \"Oranžna, Bela in Črtasta\".\n",
"\n",
"- **Ordinalna**, ki vključuje urejene kategorije, uporabna, če želimo logično urediti naše rezultate, na primer naše buče, ki so razvrščene po končnem številu velikosti (mini,sm,med,lg,xl,xxl).\n",
"\n",
"![Multinomna vs ordinalna regresija](../../../../../../2-Regression/4-Logistic/images/multinomial-vs-ordinal.png)\n",
"\n",
"#### **Spremenljivke NI NUJNO, da so povezane**\n",
"\n",
"Se spomnite, kako je linearna regresija bolje delovala z bolj povezanimi spremenljivkami? Logistična regresija je nasprotje - spremenljivke ni nujno, da se ujemajo. To ustreza tem podatkom, ki imajo nekoliko šibke korelacije.\n",
"\n",
"#### **Potrebujete veliko čistih podatkov**\n",
"\n",
"Logistična regresija bo dala natančnejše rezultate, če uporabite več podatkov; naš majhen nabor podatkov ni optimalen za to nalogo, zato imejte to v mislih.\n",
"\n",
"✅ Razmislite o vrstah podatkov, ki bi bile primerne za logistično regresijo.\n",
"\n",
"## Naloga - uredite podatke\n",
"\n",
"Najprej nekoliko očistite podatke, odstranite ničelne vrednosti in izberite le nekatere stolpce:\n",
"\n",
"1. Dodajte naslednjo kodo:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Load the core tidyverse packages\n",
"library(tidyverse)\n",
"\n",
"# Import the data and clean column names\n",
"pumpkins <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/2-Regression/data/US-pumpkins.csv\") %>% \n",
" clean_names()\n",
"\n",
"# Select desired columns\n",
"pumpkins_select <- pumpkins %>% \n",
" select(c(city_name, package, variety, origin, item_size, color)) \n",
"\n",
"# Drop rows containing missing values and encode color as factor (category)\n",
"pumpkins_select <- pumpkins_select %>% \n",
" drop_na() %>% \n",
" mutate(color = factor(color))\n",
"\n",
"# View the first few rows\n",
"pumpkins_select %>% \n",
" slice_head(n = 5)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Vedno lahko pogledate svoj novi podatkovni okvir z uporabo funkcije [*glimpse()*](https://pillar.r-lib.org/reference/glimpse.html), kot je prikazano spodaj:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"pumpkins_select %>% \n",
" glimpse()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Potrdimo, da bomo dejansko reševali problem binarne klasifikacije:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Subset distinct observations in outcome column\n",
"pumpkins_select %>% \n",
" distinct(color)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Vizualizacija - kategorni graf\n",
"Do sedaj ste znova naložili podatke o bučah in jih očistili, da ste ohranili podatkovni niz, ki vsebuje nekaj spremenljivk, vključno z Barvo. Vizualizirajmo podatkovni okvir v zvezku z uporabo knjižnice ggplot.\n",
"\n",
"Knjižnica ggplot ponuja nekaj odličnih načinov za vizualizacijo vaših podatkov. Na primer, lahko primerjate porazdelitve podatkov za vsako Sorto in Barvo v kategorni graf.\n",
"\n",
"1. Ustvarite takšen graf z uporabo funkcije geombar, pri čemer uporabite naše podatke o bučah in določite barvno preslikavo za vsako kategorijo buč (oranžna ali bela):\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "python"
}
},
"outputs": [],
"source": [
"# Specify colors for each value of the hue variable\n",
"palette <- c(ORANGE = \"orange\", WHITE = \"wheat\")\n",
"\n",
"# Create the bar plot\n",
"ggplot(pumpkins_select, aes(y = variety, fill = color)) +\n",
" geom_bar(position = \"dodge\") +\n",
" scale_fill_manual(values = palette) +\n",
" labs(y = \"Variety\", fill = \"Color\") +\n",
" theme_minimal()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Z opazovanjem podatkov lahko vidite, kako so podatki o barvi povezani z vrsto.\n",
"\n",
"✅ Glede na ta kategorni graf, katere zanimive raziskave si lahko predstavljate?\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Predobdelava podatkov: kodiranje značilnosti\n",
"\n",
"Naš nabor podatkov o bučah vsebuje nize kot vrednosti za vse stolpce. Delo s kategorialnimi podatki je za ljudi intuitivno, za računalnike pa ne. Algoritmi strojnega učenja delujejo dobro s številkami. Zato je kodiranje zelo pomemben korak v fazi predobdelave podatkov, saj nam omogoča, da kategorialne podatke pretvorimo v številske, ne da bi pri tem izgubili informacije. Dobro kodiranje vodi do gradnje dobrega modela.\n",
"\n",
"Za kodiranje značilnosti obstajata dve glavni vrsti kodirnikov:\n",
"\n",
"1. **Ordinalni kodirnik**: Ta je primeren za ordinalne spremenljivke, torej kategorialne spremenljivke, kjer podatki sledijo logičnemu vrstnemu redu, kot je stolpec `item_size` v našem naboru podatkov. Ustvari preslikavo, kjer je vsaka kategorija predstavljena s številko, ki ustreza vrstnemu redu kategorije v stolpcu.\n",
"\n",
"2. **Kategorialni kodirnik**: Ta je primeren za nominalne spremenljivke, torej kategorialne spremenljivke, kjer podatki ne sledijo logičnemu vrstnemu redu, kot so vse značilnosti, ki niso `item_size` v našem naboru podatkov. Gre za kodiranje \"ena-vroča\" (one-hot encoding), kar pomeni, da je vsaka kategorija predstavljena z binarnim stolpcem: kodirana spremenljivka je enaka 1, če buča pripada tej sorti, in 0 sicer.\n",
"\n",
"Tidymodels ponuja še eno uporabno knjižnico: [recipes](https://recipes.tidymodels.org/) - knjižnico za predobdelavo podatkov. Določili bomo `recipe`, ki opredeljuje, da je treba vse stolpce napovedovalcev zakodirati v nabor celih števil, nato pa ga `prep`-irati, da ocenimo potrebne količine in statistike za posamezne operacije, in na koncu `bake`, da uporabimo izračune na novih podatkih.\n",
"\n",
"> Običajno se recipes uporablja kot predprocesor za modeliranje, kjer določa, kateri koraki naj se uporabijo na naboru podatkov, da ga pripravimo za modeliranje. V tem primeru je **zelo priporočljivo**, da uporabite `workflow()` namesto ročnega ocenjevanja recepta z uporabo prep in bake. Vse to bomo videli v kratkem.\n",
">\n",
"> Zaenkrat pa uporabljamo recipes + prep + bake, da določimo, kateri koraki naj se uporabijo na naboru podatkov, da ga pripravimo za analizo podatkov, in nato izvlečemo predobdelane podatke z uporabljenimi koraki.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Preprocess and extract data to allow some data analysis\n",
"baked_pumpkins <- recipe(color ~ ., data = pumpkins_select) %>%\n",
" # Define ordering for item_size column\n",
" step_mutate(item_size = ordered(item_size, levels = c('sml', 'med', 'med-lge', 'lge', 'xlge', 'jbo', 'exjbo'))) %>%\n",
" # Convert factors to numbers using the order defined above (Ordinal encoding)\n",
" step_integer(item_size, zero_based = F) %>%\n",
" # Encode all other predictors using one hot encoding\n",
" step_dummy(all_nominal(), -all_outcomes(), one_hot = TRUE) %>%\n",
" prep(data = pumpkin_select) %>%\n",
" bake(new_data = NULL)\n",
"\n",
"# Display the first few rows of preprocessed data\n",
"baked_pumpkins %>% \n",
" slice_head(n = 5)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"✅ Kakšne so prednosti uporabe ordinalnega kodirnika za stolpec Velikost artikla?\n",
"\n",
"### Analizirajte odnose med spremenljivkami\n",
"\n",
"Zdaj, ko smo predhodno obdelali naše podatke, lahko analiziramo odnose med značilnostmi in oznako, da dobimo predstavo o tem, kako dobro bo model lahko napovedal oznako glede na značilnosti. Najboljši način za izvedbo takšne analize je vizualizacija podatkov. \n",
"Ponovno bomo uporabili funkcijo ggplot geom_boxplot_, da vizualiziramo odnose med Velikostjo artikla, Sorto in Barvo v kategorijskem grafu. Za boljšo vizualizacijo podatkov bomo uporabili kodiran stolpec Velikost artikla in nekodiran stolpec Sorta.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Define the color palette\n",
"palette <- c(ORANGE = \"orange\", WHITE = \"wheat\")\n",
"\n",
"# We need the encoded Item Size column to use it as the x-axis values in the plot\n",
"pumpkins_select_plot<-pumpkins_select\n",
"pumpkins_select_plot$item_size <- baked_pumpkins$item_size\n",
"\n",
"# Create the grouped box plot\n",
"ggplot(pumpkins_select_plot, aes(x = `item_size`, y = color, fill = color)) +\n",
" geom_boxplot() +\n",
" facet_grid(variety ~ ., scales = \"free_x\") +\n",
" scale_fill_manual(values = palette) +\n",
" labs(x = \"Item Size\", y = \"\") +\n",
" theme_minimal() +\n",
" theme(strip.text = element_text(size = 12)) +\n",
" theme(axis.text.x = element_text(size = 10)) +\n",
" theme(axis.title.x = element_text(size = 12)) +\n",
" theme(axis.title.y = element_blank()) +\n",
" theme(legend.position = \"bottom\") +\n",
" guides(fill = guide_legend(title = \"Color\")) +\n",
" theme(panel.spacing = unit(0.5, \"lines\"))+\n",
" theme(strip.text.y = element_text(size = 4, hjust = 0)) \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Uporaba swarm plota\n",
"\n",
"Ker je Barva binarna kategorija (Bela ali Ne), zahteva 'poseben pristop [k vizualizaciji](https://github.com/rstudio/cheatsheets/blob/main/data-visualization.pdf)'.\n",
"\n",
"Poskusite uporabiti `swarm plot`, da prikažete porazdelitev barve glede na velikost predmeta.\n",
"\n",
"Uporabili bomo [paket ggbeeswarm](https://github.com/eclarke/ggbeeswarm), ki ponuja metode za ustvarjanje grafov v slogu beeswarm z uporabo ggplot2. Beeswarm grafi so način prikaza točk, ki bi se sicer prekrivale, tako da so razporejene ena poleg druge.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Create beeswarm plots of color and item_size\n",
"baked_pumpkins %>% \n",
" mutate(color = factor(color)) %>% \n",
" ggplot(mapping = aes(x = color, y = item_size, color = color)) +\n",
" geom_quasirandom() +\n",
" scale_color_brewer(palette = \"Dark2\", direction = -1) +\n",
" theme(legend.position = \"none\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Zdaj, ko imamo predstavo o razmerju med binarnimi kategorijami barve in večjo skupino velikosti, raziščimo logistično regresijo za določitev verjetne barve določene buče.\n",
"\n",
"## Ustvarite svoj model\n",
"\n",
"Izberite spremenljivke, ki jih želite uporabiti v svojem klasifikacijskem modelu, in razdelite podatke na učne in testne sklope. [rsample](https://rsample.tidymodels.org/), paket v Tidymodels, zagotavlja infrastrukturo za učinkovito razdeljevanje podatkov in ponovno vzorčenje:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Split data into 80% for training and 20% for testing\n",
"set.seed(2056)\n",
"pumpkins_split <- pumpkins_select %>% \n",
" initial_split(prop = 0.8)\n",
"\n",
"# Extract the data in each split\n",
"pumpkins_train <- training(pumpkins_split)\n",
"pumpkins_test <- testing(pumpkins_split)\n",
"\n",
"# Print out the first 5 rows of the training set\n",
"pumpkins_train %>% \n",
" slice_head(n = 5)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"🙌 Zdaj smo pripravljeni, da model naučimo tako, da prilagodimo učne značilnosti učni oznaki (barvi).\n",
"\n",
"Začeli bomo z ustvarjanjem recepta, ki določa korake predobdelave, ki jih je treba izvesti na naših podatkih, da jih pripravimo za modeliranje, tj. kodiranje kategornih spremenljivk v niz celih števil. Tako kot `baked_pumpkins`, ustvarimo `pumpkins_recipe`, vendar ga ne `prep` in `bake`, saj bo vključen v delovni tok, kar boste videli v le nekaj korakih.\n",
"\n",
"Obstaja kar nekaj načinov za določitev logistične regresije v Tidymodels. Oglejte si `?logistic_reg()`. Za zdaj bomo določili model logistične regresije prek privzetega pogona `stats::glm()`.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Create a recipe that specifies preprocessing steps for modelling\n",
"pumpkins_recipe <- recipe(color ~ ., data = pumpkins_train) %>% \n",
" step_mutate(item_size = ordered(item_size, levels = c('sml', 'med', 'med-lge', 'lge', 'xlge', 'jbo', 'exjbo'))) %>%\n",
" step_integer(item_size, zero_based = F) %>% \n",
" step_dummy(all_nominal(), -all_outcomes(), one_hot = TRUE)\n",
"\n",
"# Create a logistic model specification\n",
"log_reg <- logistic_reg() %>% \n",
" set_engine(\"glm\") %>% \n",
" set_mode(\"classification\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Zdaj, ko imamo recept in specifikacijo modela, moramo najti način, kako ju združiti v objekt, ki bo najprej predobdelal podatke (v ozadju uporabil funkciji prep + bake), nato prilagodil model na predobdelane podatke in omogočil tudi morebitne aktivnosti po obdelavi.\n",
"\n",
"V Tidymodels se ta priročen objekt imenuje [`workflow`](https://workflows.tidymodels.org/) in priročno združuje vaše komponente modeliranja.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Bundle modelling components in a workflow\n",
"log_reg_wf <- workflow() %>% \n",
" add_recipe(pumpkins_recipe) %>% \n",
" add_model(log_reg)\n",
"\n",
"# Print out the workflow\n",
"log_reg_wf\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ko je potek dela *določen*, lahko model `usposobimo` z uporabo funkcije [`fit()`](https://tidymodels.github.io/parsnip/reference/fit.html). Potek dela bo ocenil recept in predhodno obdelal podatke pred usposabljanjem, zato tega ne bo treba ročno narediti z uporabo funkcij prep in bake.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Train the model\n",
"wf_fit <- log_reg_wf %>% \n",
" fit(data = pumpkins_train)\n",
"\n",
"# Print the trained workflow\n",
"wf_fit\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Model izpiše koeficiente, pridobljene med usposabljanjem.\n",
"\n",
"Zdaj, ko smo model usposobili z uporabo učnih podatkov, lahko naredimo napovedi na testnih podatkih z uporabo [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html). Začnimo z uporabo modela za napovedovanje oznak za naš testni niz in verjetnosti za vsako oznako. Ko je verjetnost večja od 0.5, je napovedan razred `WHITE`, sicer `ORANGE`.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Make predictions for color and corresponding probabilities\n",
"results <- pumpkins_test %>% select(color) %>% \n",
" bind_cols(wf_fit %>% \n",
" predict(new_data = pumpkins_test)) %>%\n",
" bind_cols(wf_fit %>%\n",
" predict(new_data = pumpkins_test, type = \"prob\"))\n",
"\n",
"# Compare predictions\n",
"results %>% \n",
" slice_head(n = 10)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Zelo lepo! To ponuja nekaj več vpogleda v delovanje logistične regresije.\n",
"\n",
"### Boljše razumevanje prek matrike zmede\n",
"\n",
"Primerjanje vsake napovedi z ustrezno \"resnično vrednostjo\" ni zelo učinkovit način za določanje, kako dobro model napoveduje. Na srečo ima Tidymodels še nekaj trikov v rokavu: [`yardstick`](https://yardstick.tidymodels.org/) - paket, ki se uporablja za merjenje učinkovitosti modelov z uporabo metrik uspešnosti.\n",
"\n",
"Ena od metrik uspešnosti, povezanih s klasifikacijskimi problemi, je [`matrika zmede`](https://wikipedia.org/wiki/Confusion_matrix). Matrika zmede opisuje, kako dobro klasifikacijski model deluje. Matrika zmede prikazuje, koliko primerov v vsakem razredu je model pravilno klasificiral. V našem primeru bo pokazala, koliko oranžnih buč je bilo klasificiranih kot oranžne in koliko belih buč kot bele; matrika zmede prav tako prikazuje, koliko jih je bilo klasificiranih v **napačne** kategorije.\n",
"\n",
"Funkcija [**`conf_mat()`**](https://tidymodels.github.io/yardstick/reference/conf_mat.html) iz paketa yardstick izračuna to križno tabelo opazovanih in napovedanih razredov.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Confusion matrix for prediction results\n",
"conf_mat(data = results, truth = color, estimate = .pred_class)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Poglejmo, kako interpretirati matriko zmede. Naš model mora razvrstiti buče v dve binarni kategoriji, kategorijo `bela` in kategorijo `ne-bela`.\n",
"\n",
"- Če vaš model napove, da je buča bela, in ta v resnici spada v kategorijo 'bela', temu pravimo `prava pozitivna napoved` (true positive), kar je prikazano s številom v zgornjem levem kotu.\n",
"\n",
"- Če vaš model napove, da buča ni bela, in ta v resnici spada v kategorijo 'bela', temu pravimo `napačna negativna napoved` (false negative), kar je prikazano s številom v spodnjem levem kotu.\n",
"\n",
"- Če vaš model napove, da je buča bela, in ta v resnici spada v kategorijo 'ne-bela', temu pravimo `napačna pozitivna napoved` (false positive), kar je prikazano s številom v zgornjem desnem kotu.\n",
"\n",
"- Če vaš model napove, da buča ni bela, in ta v resnici spada v kategorijo 'ne-bela', temu pravimo `prava negativna napoved` (true negative), kar je prikazano s številom v spodnjem desnem kotu.\n",
"\n",
"| Resnica |\n",
"|:-------:|\n",
"\n",
"| | | |\n",
"|---------------|--------|-------|\n",
"| **Napovedano** | BELA | ORANŽNA |\n",
"| BELA | TP | FP |\n",
"| ORANŽNA | FN | TN |\n",
"\n",
"Kot ste morda uganili, je zaželeno imeti večje število pravih pozitivnih in pravih negativnih napovedi ter manjše število napačnih pozitivnih in napačnih negativnih napovedi, saj to pomeni, da model deluje bolje.\n",
"\n",
"Matrika zmede je koristna, saj omogoča izračun drugih metrik, ki nam pomagajo bolje oceniti uspešnost klasifikacijskega modela. Poglejmo si nekatere od njih:\n",
"\n",
"🎓 Natančnost (Precision): `TP/(TP + FP)` je definirana kot delež napovedanih pozitivnih primerov, ki so dejansko pozitivni. Imenujemo jo tudi [pozitivna napovedna vrednost](https://en.wikipedia.org/wiki/Positive_predictive_value \"Positive predictive value\").\n",
"\n",
"🎓 Priklic (Recall): `TP/(TP + FN)` je definiran kot delež pozitivnih rezultatov glede na število vzorcev, ki so dejansko pozitivni. Imenujemo ga tudi `občutljivost` (sensitivity).\n",
"\n",
"🎓 Specifičnost (Specificity): `TN/(TN + FP)` je definirana kot delež negativnih rezultatov glede na število vzorcev, ki so dejansko negativni.\n",
"\n",
"🎓 Točnost (Accuracy): `TP + TN/(TP + TN + FP + FN)` je odstotek oznak, ki so bile pravilno napovedane za vzorec.\n",
"\n",
"🎓 F-metrika (F Measure): Tehtano povprečje natančnosti in priklica, kjer je najboljša vrednost 1, najslabša pa 0.\n",
"\n",
"Izračunajmo te metrike!\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Combine metric functions and calculate them all at once\n",
"eval_metrics <- metric_set(ppv, recall, spec, f_meas, accuracy)\n",
"eval_metrics(data = results, truth = color, estimate = .pred_class)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Vizualizirajmo ROC krivuljo tega modela\n",
"\n",
"Naredimo še eno vizualizacijo, da si ogledamo tako imenovano [`ROC krivuljo`](https://en.wikipedia.org/wiki/Receiver_operating_characteristic):\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Make a roc_curve\n",
"results %>% \n",
" roc_curve(color, .pred_ORANGE) %>% \n",
" autoplot()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"ROC krivulje se pogosto uporabljajo za prikaz rezultatov klasifikatorja glede na njegove prave in lažne pozitivne zadetke. ROC krivulje običajno prikazujejo `True Positive Rate`/občutljivost na Y osi in `False Positive Rate`/1-specifičnost na X osi. Zato sta strmina krivulje in prostor med sredinsko črto ter krivuljo pomembna: želite krivuljo, ki se hitro dvigne in preseže črto. V našem primeru se začne z lažnimi pozitivnimi zadetki, nato pa se črta pravilno dvigne in preseže.\n",
"\n",
"Na koncu uporabimo `yardstick::roc_auc()` za izračun dejanskega območja pod krivuljo (Area Under the Curve). Eden od načinov interpretacije AUC je kot verjetnost, da model naključno pozitivni primer razvrsti višje kot naključno negativni primer.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Calculate area under curve\n",
"results %>% \n",
" roc_auc(color, .pred_ORANGE)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Rezultat je približno `0.975`. Ker se AUC giblje med 0 in 1, si želite visok rezultat, saj bo model, ki je 100 % natančen v svojih napovedih, imel AUC vrednost 1; v tem primeru je model *kar dober*.\n",
"\n",
"V prihodnjih lekcijah o klasifikacijah boste spoznali, kako izboljšati rezultate svojega modela (na primer obravnavanje neuravnoteženih podatkov v tem primeru).\n",
"\n",
"## 🚀Izziv\n",
"\n",
"Logistična regresija ponuja še veliko več! Najboljši način za učenje je eksperimentiranje. Poiščite podatkovni niz, ki je primeren za tovrstno analizo, in zgradite model z njim. Kaj ste se naučili? namig: poskusite [Kaggle](https://www.kaggle.com/search?q=logistic+regression+datasets) za zanimive podatkovne nize.\n",
"\n",
"## Pregled in samostojno učenje\n",
"\n",
"Preberite prvih nekaj strani [tega dokumenta iz Stanforda](https://web.stanford.edu/~jurafsky/slp3/5.pdf) o praktični uporabi logistične regresije. Razmislite o nalogah, ki so bolj primerne za eno ali drugo vrsto regresijskih nalog, ki smo jih preučevali do zdaj. Kaj bi delovalo najbolje?\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da se zavedate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
],
"metadata": {
"anaconda-cloud": "",
"kernelspec": {
"display_name": "R",
"langauge": "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": "feaf125f481a89c468fa115bf2aed580",
"translation_date": "2025-09-06T13:31:00+00:00",
"source_file": "2-Regression/4-Logistic/solution/R/lesson_4-R.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 1
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,267 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"orig_nbformat": 2,
"kernelspec": {
"name": "python37364bit8d3b438fb5fc4430a93ac2cb74d693a7",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
}
},
"coopTranslator": {
"original_hash": "5fa2e8f4584c78250ca9729b46562ceb",
"translation_date": "2025-09-06T14:32:05+00:00",
"source_file": "3-Web-App/1-Web-App/solution/notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"source": [],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" datetime city state country shape \\\n",
"0 10/10/1949 20:30 san marcos tx us cylinder \n",
"1 10/10/1949 21:00 lackland afb tx NaN light \n",
"2 10/10/1955 17:00 chester (uk/england) NaN gb circle \n",
"3 10/10/1956 21:00 edna tx us circle \n",
"4 10/10/1960 20:00 kaneohe hi us light \n",
"\n",
" duration (seconds) duration (hours/min) \\\n",
"0 2700.0 45 minutes \n",
"1 7200.0 1-2 hrs \n",
"2 20.0 20 seconds \n",
"3 20.0 1/2 hour \n",
"4 900.0 15 minutes \n",
"\n",
" comments date posted latitude \\\n",
"0 This event took place in early fall around 194... 4/27/2004 29.883056 \n",
"1 1949 Lackland AFB&#44 TX. Lights racing acros... 12/16/2005 29.384210 \n",
"2 Green/Orange circular disc over Chester&#44 En... 1/21/2008 53.200000 \n",
"3 My older brother and twin sister were leaving ... 1/17/2004 28.978333 \n",
"4 AS a Marine 1st Lt. flying an FJ4B fighter/att... 1/22/2004 21.418056 \n",
"\n",
" longitude \n",
"0 -97.941111 \n",
"1 -98.581082 \n",
"2 -2.916667 \n",
"3 -96.645833 \n",
"4 -157.803611 "
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>datetime</th>\n <th>city</th>\n <th>state</th>\n <th>country</th>\n <th>shape</th>\n <th>duration (seconds)</th>\n <th>duration (hours/min)</th>\n <th>comments</th>\n <th>date posted</th>\n <th>latitude</th>\n <th>longitude</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>10/10/1949 20:30</td>\n <td>san marcos</td>\n <td>tx</td>\n <td>us</td>\n <td>cylinder</td>\n <td>2700.0</td>\n <td>45 minutes</td>\n <td>This event took place in early fall around 194...</td>\n <td>4/27/2004</td>\n <td>29.883056</td>\n <td>-97.941111</td>\n </tr>\n <tr>\n <th>1</th>\n <td>10/10/1949 21:00</td>\n <td>lackland afb</td>\n <td>tx</td>\n <td>NaN</td>\n <td>light</td>\n <td>7200.0</td>\n <td>1-2 hrs</td>\n <td>1949 Lackland AFB&amp;#44 TX. Lights racing acros...</td>\n <td>12/16/2005</td>\n <td>29.384210</td>\n <td>-98.581082</td>\n </tr>\n <tr>\n <th>2</th>\n <td>10/10/1955 17:00</td>\n <td>chester (uk/england)</td>\n <td>NaN</td>\n <td>gb</td>\n <td>circle</td>\n <td>20.0</td>\n <td>20 seconds</td>\n <td>Green/Orange circular disc over Chester&amp;#44 En...</td>\n <td>1/21/2008</td>\n <td>53.200000</td>\n <td>-2.916667</td>\n </tr>\n <tr>\n <th>3</th>\n <td>10/10/1956 21:00</td>\n <td>edna</td>\n <td>tx</td>\n <td>us</td>\n <td>circle</td>\n <td>20.0</td>\n <td>1/2 hour</td>\n <td>My older brother and twin sister were leaving ...</td>\n <td>1/17/2004</td>\n <td>28.978333</td>\n <td>-96.645833</td>\n </tr>\n <tr>\n <th>4</th>\n <td>10/10/1960 20:00</td>\n <td>kaneohe</td>\n <td>hi</td>\n <td>us</td>\n <td>light</td>\n <td>900.0</td>\n <td>15 minutes</td>\n <td>AS a Marine 1st Lt. flying an FJ4B fighter/att...</td>\n <td>1/22/2004</td>\n <td>21.418056</td>\n <td>-157.803611</td>\n </tr>\n </tbody>\n</table>\n</div>"
},
"metadata": {},
"execution_count": 23
}
],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"\n",
"ufos = pd.read_csv('../data/ufos.csv')\n",
"ufos.head()\n"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"array(['us', nan, 'gb', 'ca', 'au', 'de'], dtype=object)"
]
},
"metadata": {},
"execution_count": 24
}
],
"source": [
"\n",
"ufos = pd.DataFrame({'Seconds': ufos['duration (seconds)'], 'Country': ufos['country'],'Latitude': ufos['latitude'],'Longitude': ufos['longitude']})\n",
"\n",
"ufos.Country.unique()\n",
"\n",
"# 0 au, 1 ca, 2 de, 3 gb, 4 us"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"<class 'pandas.core.frame.DataFrame'>\nInt64Index: 25863 entries, 2 to 80330\nData columns (total 4 columns):\n # Column Non-Null Count Dtype \n--- ------ -------------- ----- \n 0 Seconds 25863 non-null float64\n 1 Country 25863 non-null object \n 2 Latitude 25863 non-null float64\n 3 Longitude 25863 non-null float64\ndtypes: float64(3), object(1)\nmemory usage: 1010.3+ KB\n"
]
}
],
"source": [
"ufos.dropna(inplace=True)\n",
"\n",
"ufos = ufos[(ufos['Seconds'] >= 1) & (ufos['Seconds'] <= 60)]\n",
"\n",
"ufos.info()"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Seconds Country Latitude Longitude\n",
"2 20.0 3 53.200000 -2.916667\n",
"3 20.0 4 28.978333 -96.645833\n",
"14 30.0 4 35.823889 -80.253611\n",
"23 60.0 4 45.582778 -122.352222\n",
"24 3.0 3 51.783333 -0.783333"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>Seconds</th>\n <th>Country</th>\n <th>Latitude</th>\n <th>Longitude</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>2</th>\n <td>20.0</td>\n <td>3</td>\n <td>53.200000</td>\n <td>-2.916667</td>\n </tr>\n <tr>\n <th>3</th>\n <td>20.0</td>\n <td>4</td>\n <td>28.978333</td>\n <td>-96.645833</td>\n </tr>\n <tr>\n <th>14</th>\n <td>30.0</td>\n <td>4</td>\n <td>35.823889</td>\n <td>-80.253611</td>\n </tr>\n <tr>\n <th>23</th>\n <td>60.0</td>\n <td>4</td>\n <td>45.582778</td>\n <td>-122.352222</td>\n </tr>\n <tr>\n <th>24</th>\n <td>3.0</td>\n <td>3</td>\n <td>51.783333</td>\n <td>-0.783333</td>\n </tr>\n </tbody>\n</table>\n</div>"
},
"metadata": {},
"execution_count": 26
}
],
"source": [
"from sklearn.preprocessing import LabelEncoder\n",
"\n",
"ufos['Country'] = LabelEncoder().fit_transform(ufos['Country'])\n",
"\n",
"ufos.head()"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.model_selection import train_test_split\n",
"\n",
"Selected_features = ['Seconds','Latitude','Longitude']\n",
"\n",
"X = ufos[Selected_features]\n",
"y = ufos['Country']\n",
"\n",
"\n",
"X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)\n"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n",
" FutureWarning)\n",
"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:469: FutureWarning: Default multi_class will be changed to 'auto' in 0.22. Specify the multi_class option to silence this warning.\n",
" \"this warning.\", FutureWarning)\n",
" precision recall f1-score support\n",
"\n",
" 0 1.00 1.00 1.00 41\n",
" 1 1.00 0.02 0.05 250\n",
" 2 0.00 0.00 0.00 8\n",
" 3 0.94 1.00 0.97 131\n",
" 4 0.95 1.00 0.97 4743\n",
"\n",
" accuracy 0.95 5173\n",
" macro avg 0.78 0.60 0.60 5173\n",
"weighted avg 0.95 0.95 0.93 5173\n",
"\n",
"Predicted labels: [4 4 4 ... 3 4 4]\n",
"Accuracy: 0.9512855209742895\n",
"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/metrics/classification.py:1437: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples.\n",
" 'precision', 'predicted', average, warn_for)\n"
]
}
],
"source": [
"from sklearn.model_selection import train_test_split\n",
"from sklearn.metrics import accuracy_score, classification_report \n",
"from sklearn.linear_model import LogisticRegression\n",
"model = LogisticRegression()\n",
"model.fit(X_train, y_train)\n",
"predictions = model.predict(X_test)\n",
"\n",
"print(classification_report(y_test, predictions))\n",
"print('Predicted labels: ', predictions)\n",
"print('Accuracy: ', accuracy_score(y_test, predictions))\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"[3]\n"
]
}
],
"source": [
"import pickle\n",
"model_filename = 'ufo-model.pkl'\n",
"pickle.dump(model, open(model_filename,'wb'))\n",
"\n",
"model = pickle.load(open('ufo-model.pkl','rb'))\n",
"print(model.predict([[50,44,-12]]))\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da se zavedate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
]
}

@ -0,0 +1,39 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": 3
},
"orig_nbformat": 2,
"coopTranslator": {
"original_hash": "d544ef384b7ba73757d830a72372a7f2",
"translation_date": "2025-09-06T14:50:43+00:00",
"source_file": "4-Classification/1-Introduction/notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"source": [],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas opozarjamo, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
]
}

@ -0,0 +1,724 @@
{
"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-06T14:55:33+00:00",
"source_file": "4-Classification/1-Introduction/solution/R/lesson_10-R.ipynb",
"language_code": "sl"
}
},
"cells": [
{
"cell_type": "markdown",
"source": [
"# Zgradite klasifikacijski model: Slastne azijske in indijske kuhinje\n"
],
"metadata": {
"id": "ItETB4tSFprR"
}
},
{
"cell_type": "markdown",
"source": [
"## Uvod v klasifikacijo: Čiščenje, priprava in vizualizacija podatkov\n",
"\n",
"V teh štirih lekcijah boste raziskovali temeljni vidik klasičnega strojnega učenja - *klasifikacijo*. Preučili bomo uporabo različnih algoritmov za klasifikacijo na podatkovnem naboru o vseh čudovitih kuhinjah Azije in Indije. Upam, da ste lačni!\n",
"\n",
"<p >\n",
" <img src=\"../../images/pinch.png\"\n",
" width=\"600\"/>\n",
" <figcaption>Proslavite panazijske kuhinje v teh lekcijah! Slika: Jen Looper</figcaption>\n",
"\n",
"<!--![Proslavite panazijske kuhinje v teh lekcijah! Slika: Jen Looper](../../../../../../4-Classification/1-Introduction/solution/R/images/pinch.png)-->\n",
"\n",
"Klasifikacija je oblika [nadzorovanega učenja](https://wikipedia.org/wiki/Supervised_learning), ki ima veliko skupnega s tehnikami regresije. Pri klasifikaciji trenirate model, da napove, v katero `kategorijo` spada določen element. Če je strojno učenje namenjeno napovedovanju vrednosti ali imen stvari z uporabo podatkovnih nizov, potem klasifikacija običajno spada v dve skupini: *binarna klasifikacija* in *večrazredna klasifikacija*.\n",
"\n",
"Zapomnite si:\n",
"\n",
"- **Linearna regresija** vam je pomagala napovedati odnose med spremenljivkami in narediti natančne napovedi, kje bi nov podatkovni element padel v odnosu do te črte. Na primer, lahko bi napovedali numerične vrednosti, kot je *kakšna bo cena buče septembra v primerjavi z decembrom*.\n",
"\n",
"- **Logistična regresija** vam je pomagala odkriti \"binarne kategorije\": pri tej cenovni točki, *ali je buča oranžna ali ne-oranžna*?\n",
"\n",
"Klasifikacija uporablja različne algoritme za določanje drugih načinov določanja oznake ali razreda podatkovne točke. Delajmo s temi podatki o kuhinjah, da vidimo, ali lahko z opazovanjem skupine sestavin določimo izvorno kuhinjo.\n",
"\n",
"### [**Predlekcijski kviz**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/19/)\n",
"\n",
"### **Uvod**\n",
"\n",
"Klasifikacija je ena temeljnih dejavnosti raziskovalca strojnega učenja in podatkovnega znanstvenika. Od osnovne klasifikacije binarne vrednosti (\"ali je ta e-pošta spam ali ne?\") do kompleksne klasifikacije slik in segmentacije z uporabo računalniškega vida, je vedno koristno, da lahko podatke razvrstimo v razrede in zastavimo vprašanja o njih.\n",
"\n",
"Če proces opišemo na bolj znanstven način, vaša metoda klasifikacije ustvari napovedni model, ki vam omogoča mapiranje odnosa med vhodnimi spremenljivkami in izhodnimi spremenljivkami.\n",
"\n",
"<p >\n",
" <img src=\"../../images/binary-multiclass.png\"\n",
" width=\"600\"/>\n",
" <figcaption>Binarni vs. večrazredni problemi, ki jih algoritmi za klasifikacijo obravnavajo. Infografika: Jen Looper</figcaption>\n",
"\n",
"Preden začnemo s procesom čiščenja podatkov, njihove vizualizacije in priprave za naloge strojnega učenja, se naučimo nekaj o različnih načinih, kako lahko strojno učenje uporabimo za klasifikacijo podatkov.\n",
"\n",
"Izpeljana iz [statistike](https://wikipedia.org/wiki/Statistical_classification), klasifikacija z uporabo klasičnega strojnega učenja uporablja značilnosti, kot so `kadilec`, `teža` in `starost`, za določanje *verjetnosti razvoja X bolezni*. Kot tehnika nadzorovanega učenja, podobna regresijskim vajam, ki ste jih izvajali prej, so vaši podatki označeni, algoritmi strojnega učenja pa te oznake uporabljajo za klasifikacijo in napovedovanje razredov (ali 'značilnosti') podatkovnega niza ter njihovo dodelitev skupini ali izidu.\n",
"\n",
"✅ Vzemite trenutek in si zamislite podatkovni niz o kuhinjah. Kaj bi lahko odgovoril večrazredni model? Kaj bi lahko odgovoril binarni model? Kaj če bi želeli ugotoviti, ali določena kuhinja verjetno uporablja piskavico? Kaj če bi želeli videti, ali bi lahko iz vrečke zvezdastega janeža, artičok, cvetače in hrena pripravili tipično indijsko jed?\n",
"\n",
"### **Pozdravljeni 'klasifikator'**\n",
"\n",
"Vprašanje, ki ga želimo zastaviti o tem podatkovnem naboru kuhinj, je pravzaprav **večrazredno vprašanje**, saj imamo na voljo več potencialnih nacionalnih kuhinj. Glede na skupino sestavin, v katerega od teh razredov bodo podatki ustrezali?\n",
"\n",
"Tidymodels ponuja več različnih algoritmov za klasifikacijo podatkov, odvisno od vrste problema, ki ga želite rešiti. V naslednjih dveh lekcijah se boste naučili o nekaterih od teh algoritmov.\n",
"\n",
"#### **Predpogoj**\n",
"\n",
"Za to lekcijo bomo potrebovali naslednje pakete za čiščenje, pripravo in vizualizacijo naših podatkov:\n",
"\n",
"- `tidyverse`: [tidyverse](https://www.tidyverse.org/) je [zbirka paketov za R](https://www.tidyverse.org/packages), zasnovana za hitrejše, lažje in bolj zabavno podatkovno znanost!\n",
"\n",
"- `tidymodels`: [tidymodels](https://www.tidymodels.org/) je okvir [zbirke paketov](https://www.tidymodels.org/packages/) za modeliranje in strojno učenje.\n",
"\n",
"- `DataExplorer`: Paket [DataExplorer](https://cran.r-project.org/web/packages/DataExplorer/vignettes/dataexplorer-intro.html) je namenjen poenostavitvi in avtomatizaciji procesa EDA ter generiranju poročil.\n",
"\n",
"- `themis`: Paket [themis](https://themis.tidymodels.org/) ponuja dodatne korake receptov za obravnavo neuravnoteženih podatkov.\n",
"\n",
"Namestite jih lahko z:\n",
"\n",
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"DataExplorer\", \"here\"))`\n",
"\n",
"Alternativno, spodnji skript preveri, ali imate pakete, potrebne za dokončanje tega modula, in jih namesti, če manjkajo.\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": [
"Kasneje bomo naložili te odlične pakete in jih naredili dostopne v naši trenutni R seji. (To je zgolj za ponazoritev, `pacman::p_load()` je to že naredil namesto vas)\n"
],
"metadata": {
"id": "YkKAxOJvGD4C"
}
},
{
"cell_type": "markdown",
"source": [
"## Vaja - očistite in uravnotežite svoje podatke\n",
"\n",
"Prva naloga, preden začnete s tem projektom, je očistiti in **uravnotežiti** svoje podatke za boljše rezultate.\n",
"\n",
"Spoznajmo podatke! 🕵️\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": [
"Zanimivo! Po videzu sodeč je prvi stolpec nekakšen stolpec `id`. Poglejmo si malo več informacij o podatkih.\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": [
"Iz izpisa lahko takoj vidimo, da imamo `2448` vrstic in `385` stolpcev ter `0` manjkajočih vrednosti. Imamo tudi 1 diskretni stolpec, *cuisine*.\n",
"\n",
"## Naloga - spoznavanje kuhinj\n",
"\n",
"Zdaj delo postaja bolj zanimivo. Odkrijmo porazdelitev podatkov glede na kuhinjo.\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": [
"Obstaja končno število kuhinj, vendar je porazdelitev podatkov neenakomerna. To lahko popravite! Preden to storite, raziščite še malo več.\n",
"\n",
"Nato dodelimo vsako kuhinjo v njen lasten tibble in ugotovimo, koliko podatkov je na voljo (vrstice, stolpci) za posamezno kuhinjo.\n",
"\n",
"> [Tibble](https://tibble.tidyverse.org/) je sodoben podatkovni okvir.\n",
"\n",
"<p >\n",
" <img src=\"../../images/dplyr_filter.jpg\"\n",
" width=\"600\"/>\n",
" <figcaption>Umetniško delo @allison_horst</figcaption>\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": [
"## **Vaja - Odkrijte glavne sestavine po kuhinji z uporabo dplyr**\n",
"\n",
"Zdaj lahko podrobneje raziščete podatke in ugotovite, katere so značilne sestavine za posamezno kuhinjo. Odstraniti morate ponavljajoče se podatke, ki povzročajo zmedo med kuhinjami, zato se lotimo tega problema.\n",
"\n",
"Ustvarite funkcijo `create_ingredient()` v R, ki vrne podatkovni okvir sestavin. Ta funkcija bo začela z odstranitvijo neuporabnega stolpca in razvrstila sestavine glede na njihovo število.\n",
"\n",
"Osnovna struktura funkcije v R je:\n",
"\n",
"`myFunction <- function(arglist){`\n",
"\n",
"**`...`**\n",
"\n",
"**`return`**`(value)`\n",
"\n",
"`}`\n",
"\n",
"Uvod v funkcije v R najdete [tukaj](https://skirmer.github.io/presentations/functions_with_r.html#1).\n",
"\n",
"Pojdimo naravnost k stvari! Uporabili bomo [dplyr glagole](https://dplyr.tidyverse.org/), ki smo jih spoznali v prejšnjih lekcijah. Za osvežitev spomina:\n",
"\n",
"- `dplyr::select()`: vam pomaga izbrati, katere **stolpce** obdržati ali izključiti.\n",
"\n",
"- `dplyr::pivot_longer()`: vam pomaga \"podaljšati\" podatke, s čimer povečate število vrstic in zmanjšate število stolpcev.\n",
"\n",
"- `dplyr::group_by()` in `dplyr::summarise()`: vam pomagata najti povzetke statistike za različne skupine in jih predstaviti v pregledni tabeli.\n",
"\n",
"- `dplyr::filter()`: ustvari podmnožico podatkov, ki vsebuje samo vrstice, ki ustrezajo vašim pogojem.\n",
"\n",
"- `dplyr::mutate()`: vam pomaga ustvariti ali spremeniti stolpce.\n",
"\n",
"Oglejte si ta [*umetniško* obarvan učni vodič](https://allisonhorst.shinyapps.io/dplyr-learnr/#section-welcome) avtorice Allison Horst, ki predstavlja nekaj uporabnih funkcij za obdelavo podatkov v dplyr *(del 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": [
"Zdaj lahko uporabimo funkcijo, da dobimo vpogled v deset najbolj priljubljenih sestavin po kuhinji. Preizkusimo jo s `thai_df`.\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": [
"V prejšnjem razdelku smo uporabili `geom_col()`, poglejmo, kako lahko uporabite tudi `geom_bar` za ustvarjanje stolpčnih grafikonov. Uporabite `?geom_bar` za nadaljnje branje.\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": [
"Naredimo enako za japonske podatke\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": [
"Kaj pa kitajska kuhinja?\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": [
"Na koncu narišite korejske sestavine.\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": [
"Iz vizualizacij podatkov lahko zdaj odstranimo najpogostejše sestavine, ki povzročajo zmedo med različnimi kuhinjami, z uporabo `dplyr::select()`.\n",
"\n",
"Vsi obožujemo riž, česen in ingver!\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": [
"## Predobdelava podatkov z recepti 👩‍🍳👨‍🍳 - Obvladovanje neuravnoteženih podatkov ⚖️\n",
"\n",
"<p >\n",
" <img src=\"../../images/recipes.png\"\n",
" width=\"600\"/>\n",
" <figcaption>Umetniško delo @allison_horst</figcaption>\n",
"\n",
"Ker je ta lekcija o kulinariki, moramo postaviti `recepte` v kontekst.\n",
"\n",
"Tidymodels ponuja še en odličen paket: `recipes` - paket za predobdelavo podatkov.\n"
],
"metadata": {
"id": "kkFd-JxdIaL6"
}
},
{
"cell_type": "markdown",
"source": [
"Poglejmo si ponovno porazdelitev naših kuhinj.\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": [
"Kot lahko vidite, je število kuhinj precej neenakomerno porazdeljeno. Korejske kuhinje so skoraj trikrat bolj številčne kot tajske kuhinje. Neuravnoteženi podatki pogosto negativno vplivajo na delovanje modela. Pomislite na binarno klasifikacijo. Če večina vaših podatkov pripada enemu razredu, bo model strojnega učenja pogosteje napovedoval ta razred, preprosto zato, ker je zanj na voljo več podatkov. Uravnoteženje podatkov odpravlja to neuravnoteženost in pomaga odstraniti pristranskost. Veliko modelov najbolje deluje, ko je število opazovanj enako, zato se pogosto soočajo s težavami pri delu z neuravnoteženimi podatki.\n",
"\n",
"Obstajata dva glavna načina za obravnavo neuravnoteženih podatkovnih nizov:\n",
"\n",
"- dodajanje opazovanj v manjšinski razred: `Over-sampling`, npr. uporaba algoritma SMOTE\n",
"\n",
"- odstranjevanje opazovanj iz večinskega razreda: `Under-sampling`\n",
"\n",
"Zdaj bomo prikazali, kako obravnavati neuravnotežene podatkovne nize z uporabo `recipe`. Recipe lahko razumemo kot načrt, ki opisuje, katere korake je treba uporabiti na podatkovnem nizu, da ga pripravimo za analizo podatkov.\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": [
"Razčlenimo naše korake predobdelave.\n",
"\n",
"- Klic funkcije `recipe()` s formulo pove receptu *vloge* spremenljivk, pri čemer uporablja podatke `df_select` kot referenco. Na primer, stolpec `cuisine` je bil dodeljen vlogi `outcome`, medtem ko so ostali stolpci dodeljeni vlogi `predictor`.\n",
"\n",
"- [`step_smote(cuisine)`](https://themis.tidymodels.org/reference/step_smote.html) ustvari *specifikacijo* koraka recepta, ki sintetično generira nove primere manjšinske skupine z uporabo najbližjih sosedov teh primerov.\n",
"\n",
"Če bi želeli videti predobdelane podatke, bi morali [**`prep()`**](https://recipes.tidymodels.org/reference/prep.html) in [**`bake()`**](https://recipes.tidymodels.org/reference/bake.html) uporabiti na našem receptu.\n",
"\n",
"`prep()`: oceni potrebne parametre iz učnega nabora, ki jih je mogoče kasneje uporabiti na drugih podatkovnih nizih.\n",
"\n",
"`bake()`: uporabi pripravljen recept in operacije na katerem koli podatkovnem nizu.\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": [
"Zdaj preverimo porazdelitev naših kuhinj in jih primerjajmo z neuravnoteženimi podatki.\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": [
"Mmm! Podatki so lepi in čisti, uravnoteženi in zelo okusni 😋!\n",
"\n",
"> Običajno se recept uporablja kot predprocesor za modeliranje, kjer določa, katere korake je treba uporabiti na podatkovnem naboru, da ga pripravimo za modeliranje. V tem primeru se običajno uporablja `workflow()` (kot smo že videli v prejšnjih lekcijah) namesto ročnega ocenjevanja recepta.\n",
">\n",
"> Zato običajno ni treba uporabljati **`prep()`** in **`bake()`** receptov, ko uporabljate tidymodels, vendar so to koristne funkcije, ki jih imate v svojem orodju za preverjanje, ali recepti delujejo, kot pričakujete, kot v našem primeru.\n",
">\n",
"> Ko z **`new_data = NULL`** **`bake()`** pripravljen recept, dobite nazaj podatke, ki ste jih podali pri definiranju recepta, vendar so že prestali korake predprocesiranja.\n",
"\n",
"Zdaj shranimo kopijo teh podatkov za uporabo v prihodnjih lekcijah:\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": [
"Ta svež CSV je zdaj na voljo v korenski mapi podatkov.\n",
"\n",
"**🚀Izziv**\n",
"\n",
"Ta učni načrt vsebuje več zanimivih podatkovnih zbirk. Prebrskajte mape `data` in preverite, ali katera vsebuje podatkovne zbirke, ki bi bile primerne za binarno ali večrazredno klasifikacijo? Kakšna vprašanja bi zastavili tej podatkovni zbirki?\n",
"\n",
"## [**Kvizi po predavanju**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/20/)\n",
"\n",
"## **Pregled & Samostojno učenje**\n",
"\n",
"- Oglejte si [paket themis](https://github.com/tidymodels/themis). Katere druge tehnike bi lahko uporabili za obravnavo neuravnoteženih podatkov?\n",
"\n",
"- Referenčna spletna stran za Tidy models [tukaj](https://www.tidymodels.org/start/).\n",
"\n",
"- H. Wickham in G. Grolemund, [*R za podatkovno znanost: Vizualizacija, modeliranje, transformacija, urejanje in uvoz podatkov*](https://r4ds.had.co.nz/).\n",
"\n",
"#### HVALA:\n",
"\n",
"[`Allison Horst`](https://twitter.com/allison_horst/) za ustvarjanje čudovitih ilustracij, ki naredijo R bolj prijazen in privlačen. Več ilustracij najdete v njeni [galeriji](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) in [Jen Looper](https://www.twitter.com/jenlooper) za ustvarjanje izvirne Python različice tega modula ♥️\n",
"\n",
"<p >\n",
" <img src=\"../../images/r_learners_sm.jpeg\"\n",
" width=\"600\"/>\n",
" <figcaption>Umetniško delo @allison_horst</figcaption>\n"
],
"metadata": {
"id": "WQs5621pMGwf"
}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
]
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,41 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": 3
},
"orig_nbformat": 2,
"coopTranslator": {
"original_hash": "68829b06b4dcd512d3327849191f4d7f",
"translation_date": "2025-09-06T14:32:32+00:00",
"source_file": "4-Classification/2-Classifiers-1/notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"source": [
"# Izdelava modelov za klasifikacijo\n"
],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
]
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,281 @@
{
"cells": [
{
"source": [
"# Ustvari modele za klasifikacijo\n"
],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Unnamed: 0 cuisine almond angelica anise anise_seed apple \\\n",
"0 0 indian 0 0 0 0 0 \n",
"1 1 indian 1 0 0 0 0 \n",
"2 2 indian 0 0 0 0 0 \n",
"3 3 indian 0 0 0 0 0 \n",
"4 4 indian 0 0 0 0 0 \n",
"\n",
" apple_brandy apricot armagnac ... whiskey white_bread white_wine \\\n",
"0 0 0 0 ... 0 0 0 \n",
"1 0 0 0 ... 0 0 0 \n",
"2 0 0 0 ... 0 0 0 \n",
"3 0 0 0 ... 0 0 0 \n",
"4 0 0 0 ... 0 0 0 \n",
"\n",
" whole_grain_wheat_flour wine wood yam yeast yogurt zucchini \n",
"0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 1 0 \n",
"\n",
"[5 rows x 382 columns]"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>Unnamed: 0</th>\n <th>cuisine</th>\n <th>almond</th>\n <th>angelica</th>\n <th>anise</th>\n <th>anise_seed</th>\n <th>apple</th>\n <th>apple_brandy</th>\n <th>apricot</th>\n <th>armagnac</th>\n <th>...</th>\n <th>whiskey</th>\n <th>white_bread</th>\n <th>white_wine</th>\n <th>whole_grain_wheat_flour</th>\n <th>wine</th>\n <th>wood</th>\n <th>yam</th>\n <th>yeast</th>\n <th>yogurt</th>\n <th>zucchini</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>indian</td>\n <td>1</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>2</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>3</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>4</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>1</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 382 columns</p>\n</div>"
},
"metadata": {},
"execution_count": 1
}
],
"source": [
"import pandas as pd\n",
"cuisines_df = pd.read_csv(\"../../data/cleaned_cuisines.csv\")\n",
"cuisines_df.head()"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.linear_model import LogisticRegression\n",
"from sklearn.model_selection import train_test_split, cross_val_score\n",
"from sklearn.metrics import accuracy_score,precision_score,confusion_matrix,classification_report, precision_recall_curve\n",
"from sklearn.svm import SVC\n",
"import numpy as np"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"0 indian\n",
"1 indian\n",
"2 indian\n",
"3 indian\n",
"4 indian\n",
"Name: cuisine, dtype: object"
]
},
"metadata": {},
"execution_count": 3
}
],
"source": [
"cuisines_label_df = cuisines_df['cuisine']\n",
"cuisines_label_df.head()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" almond angelica anise anise_seed apple apple_brandy apricot \\\n",
"0 0 0 0 0 0 0 0 \n",
"1 1 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 0 \n",
"\n",
" armagnac artemisia artichoke ... whiskey white_bread white_wine \\\n",
"0 0 0 0 ... 0 0 0 \n",
"1 0 0 0 ... 0 0 0 \n",
"2 0 0 0 ... 0 0 0 \n",
"3 0 0 0 ... 0 0 0 \n",
"4 0 0 0 ... 0 0 0 \n",
"\n",
" whole_grain_wheat_flour wine wood yam yeast yogurt zucchini \n",
"0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 1 0 \n",
"\n",
"[5 rows x 380 columns]"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>almond</th>\n <th>angelica</th>\n <th>anise</th>\n <th>anise_seed</th>\n <th>apple</th>\n <th>apple_brandy</th>\n <th>apricot</th>\n <th>armagnac</th>\n <th>artemisia</th>\n <th>artichoke</th>\n <th>...</th>\n <th>whiskey</th>\n <th>white_bread</th>\n <th>white_wine</th>\n <th>whole_grain_wheat_flour</th>\n <th>wine</th>\n <th>wood</th>\n <th>yam</th>\n <th>yeast</th>\n <th>yogurt</th>\n <th>zucchini</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>1</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 380 columns</p>\n</div>"
},
"metadata": {},
"execution_count": 4
}
],
"source": [
"cuisines_feature_df = cuisines_df.drop(['Unnamed: 0', 'cuisine'], axis=1)\n",
"cuisines_feature_df.head()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"X_train, X_test, y_train, y_test = train_test_split(cuisines_feature_df, cuisines_label_df, test_size=0.3)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Accuracy is 0.8181818181818182\n"
]
}
],
"source": [
"lr = LogisticRegression(multi_class='ovr',solver='liblinear')\n",
"model = lr.fit(X_train, np.ravel(y_train))\n",
"\n",
"accuracy = model.score(X_test, y_test)\n",
"print (\"Accuracy is {}\".format(accuracy))"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"ingredients: Index(['artemisia', 'black_pepper', 'mushroom', 'shiitake', 'soy_sauce',\n 'vegetable_oil'],\n dtype='object')\ncuisine: korean\n"
]
}
],
"source": [
"# test an item\n",
"print(f'ingredients: {X_test.iloc[50][X_test.iloc[50]!=0].keys()}')\n",
"print(f'cuisine: {y_test.iloc[50]}')"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" 0\n",
"korean 0.392231\n",
"chinese 0.372872\n",
"japanese 0.218825\n",
"thai 0.013427\n",
"indian 0.002645"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>0</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>korean</th>\n <td>0.392231</td>\n </tr>\n <tr>\n <th>chinese</th>\n <td>0.372872</td>\n </tr>\n <tr>\n <th>japanese</th>\n <td>0.218825</td>\n </tr>\n <tr>\n <th>thai</th>\n <td>0.013427</td>\n </tr>\n <tr>\n <th>indian</th>\n <td>0.002645</td>\n </tr>\n </tbody>\n</table>\n</div>"
},
"metadata": {},
"execution_count": 8
}
],
"source": [
"#rehsape to 2d array and transpose\n",
"test= X_test.iloc[50].values.reshape(-1, 1).T\n",
"# predict with score\n",
"proba = model.predict_proba(test)\n",
"classes = model.classes_\n",
"# create df with classes and scores\n",
"resultdf = pd.DataFrame(data=proba, columns=classes)\n",
"\n",
"# create df to show results\n",
"topPrediction = resultdf.T.sort_values(by=[0], ascending = [False])\n",
"topPrediction.head()"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
" precision recall f1-score support\n\n chinese 0.75 0.73 0.74 223\n indian 0.93 0.88 0.90 255\n japanese 0.78 0.78 0.78 253\n korean 0.87 0.86 0.86 236\n thai 0.76 0.84 0.80 232\n\n accuracy 0.82 1199\n macro avg 0.82 0.82 0.82 1199\nweighted avg 0.82 0.82 0.82 1199\n\n"
]
}
],
"source": [
"y_pred = model.predict(X_test)\r\n",
"print(classification_report(y_test,y_pred))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
],
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
}
},
"coopTranslator": {
"original_hash": "9408506dd864f2b6e334c62f80c0cfcc",
"translation_date": "2025-09-06T14:33:00+00:00",
"source_file": "4-Classification/2-Classifiers-1/solution/notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

@ -0,0 +1,165 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Ustvari Model za Klasifikacijo\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Unnamed: 0 cuisine almond angelica anise anise_seed apple \\\n",
"0 0 indian 0 0 0 0 0 \n",
"1 1 indian 1 0 0 0 0 \n",
"2 2 indian 0 0 0 0 0 \n",
"3 3 indian 0 0 0 0 0 \n",
"4 4 indian 0 0 0 0 0 \n",
"\n",
" apple_brandy apricot armagnac ... whiskey white_bread white_wine \\\n",
"0 0 0 0 ... 0 0 0 \n",
"1 0 0 0 ... 0 0 0 \n",
"2 0 0 0 ... 0 0 0 \n",
"3 0 0 0 ... 0 0 0 \n",
"4 0 0 0 ... 0 0 0 \n",
"\n",
" whole_grain_wheat_flour wine wood yam yeast yogurt zucchini \n",
"0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 1 0 \n",
"\n",
"[5 rows x 382 columns]"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>Unnamed: 0</th>\n <th>cuisine</th>\n <th>almond</th>\n <th>angelica</th>\n <th>anise</th>\n <th>anise_seed</th>\n <th>apple</th>\n <th>apple_brandy</th>\n <th>apricot</th>\n <th>armagnac</th>\n <th>...</th>\n <th>whiskey</th>\n <th>white_bread</th>\n <th>white_wine</th>\n <th>whole_grain_wheat_flour</th>\n <th>wine</th>\n <th>wood</th>\n <th>yam</th>\n <th>yeast</th>\n <th>yogurt</th>\n <th>zucchini</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>indian</td>\n <td>1</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>2</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>3</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>4</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>1</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 382 columns</p>\n</div>"
},
"metadata": {},
"execution_count": 9
}
],
"source": [
"import pandas as pd\n",
"cuisines_df = pd.read_csv(\"../data/cleaned_cuisines.csv\")\n",
"cuisines_df.head()"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"0 indian\n",
"1 indian\n",
"2 indian\n",
"3 indian\n",
"4 indian\n",
"Name: cuisine, dtype: object"
]
},
"metadata": {},
"execution_count": 10
}
],
"source": [
"cuisines_label_df = cuisines_df['cuisine']\n",
"cuisines_label_df.head()"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" almond angelica anise anise_seed apple apple_brandy apricot \\\n",
"0 0 0 0 0 0 0 0 \n",
"1 1 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 0 \n",
"\n",
" armagnac artemisia artichoke ... whiskey white_bread white_wine \\\n",
"0 0 0 0 ... 0 0 0 \n",
"1 0 0 0 ... 0 0 0 \n",
"2 0 0 0 ... 0 0 0 \n",
"3 0 0 0 ... 0 0 0 \n",
"4 0 0 0 ... 0 0 0 \n",
"\n",
" whole_grain_wheat_flour wine wood yam yeast yogurt zucchini \n",
"0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 1 0 \n",
"\n",
"[5 rows x 380 columns]"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>almond</th>\n <th>angelica</th>\n <th>anise</th>\n <th>anise_seed</th>\n <th>apple</th>\n <th>apple_brandy</th>\n <th>apricot</th>\n <th>armagnac</th>\n <th>artemisia</th>\n <th>artichoke</th>\n <th>...</th>\n <th>whiskey</th>\n <th>white_bread</th>\n <th>white_wine</th>\n <th>whole_grain_wheat_flour</th>\n <th>wine</th>\n <th>wood</th>\n <th>yam</th>\n <th>yeast</th>\n <th>yogurt</th>\n <th>zucchini</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>1</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 380 columns</p>\n</div>"
},
"metadata": {},
"execution_count": 11
}
],
"source": [
"cuisines_feature_df = cuisines_df.drop(['Unnamed: 0', 'cuisine'], axis=1)\n",
"cuisines_feature_df.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
],
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
}
},
"coopTranslator": {
"original_hash": "15a83277036572e0773229b5f21c1e12",
"translation_date": "2025-09-06T14:42:15+00:00",
"source_file": "4-Classification/3-Classifiers-2/notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

@ -0,0 +1,647 @@
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "lesson_12-R.ipynb",
"provenance": [],
"collapsed_sections": []
},
"kernelspec": {
"name": "ir",
"display_name": "R"
},
"language_info": {
"name": "R"
},
"coopTranslator": {
"original_hash": "fab50046ca413a38939d579f8432274f",
"translation_date": "2025-09-06T14:45:06+00:00",
"source_file": "4-Classification/3-Classifiers-2/solution/R/lesson_12-R.ipynb",
"language_code": "sl"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "jsFutf_ygqSx"
},
"source": [
"# Zgradite klasifikacijski model: Slastne azijske in indijske kuhinje\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "HD54bEefgtNO"
},
"source": [
"## Razvrščevalniki kuhinj 2\n",
"\n",
"V tej drugi lekciji o razvrščanju bomo raziskali `več načinov` za razvrščanje kategorijskih podatkov. Prav tako se bomo naučili o posledicah izbire enega razvrščevalnika namesto drugega.\n",
"\n",
"### [**Predhodni kviz**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/23/)\n",
"\n",
"### **Predpogoji**\n",
"\n",
"Predvidevamo, da ste zaključili prejšnje lekcije, saj bomo nadaljevali z nekaterimi koncepti, ki smo jih že obravnavali.\n",
"\n",
"Za to lekcijo bomo potrebovali naslednje pakete:\n",
"\n",
"- `tidyverse`: [tidyverse](https://www.tidyverse.org/) je [zbirka paketov za R](https://www.tidyverse.org/packages), zasnovana za hitrejše, enostavnejše in bolj zabavno podatkovno znanost!\n",
"\n",
"- `tidymodels`: [tidymodels](https://www.tidymodels.org/) je okvir [zbirke paketov](https://www.tidymodels.org/packages/) za modeliranje in strojno učenje.\n",
"\n",
"- `themis`: [paket themis](https://themis.tidymodels.org/) ponuja dodatne korake receptov za obravnavo neuravnoteženih podatkov.\n",
"\n",
"Pakete lahko namestite z naslednjim ukazom:\n",
"\n",
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"kernlab\", \"themis\", \"ranger\", \"xgboost\", \"kknn\"))`\n",
"\n",
"Alternativno, spodnji skript preveri, ali imate nameščene potrebne pakete za dokončanje tega modula, in jih namesti, če manjkajo.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "vZ57IuUxgyQt"
},
"source": [
"suppressWarnings(if (!require(\"pacman\"))install.packages(\"pacman\"))\n",
"\n",
"pacman::p_load(tidyverse, tidymodels, themis, kernlab, ranger, xgboost, kknn)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "z22M-pj4g07x"
},
"source": [
"## **1. Zemljevid klasifikacije**\n",
"\n",
"V naši [prejšnji lekciji](https://github.com/microsoft/ML-For-Beginners/tree/main/4-Classification/2-Classifiers-1) smo poskušali odgovoriti na vprašanje: kako izbrati med več modeli? V veliki meri je to odvisno od značilnosti podatkov in vrste problema, ki ga želimo rešiti (na primer klasifikacija ali regresija?).\n",
"\n",
"Prej smo se naučili o različnih možnostih, ki jih imate pri klasifikaciji podatkov, z uporabo Microsoftovega pripomočka. Pythonov okvir za strojno učenje, Scikit-learn, ponuja podoben, vendar bolj podroben pripomoček, ki vam lahko dodatno pomaga zožiti izbiro vaših ocenjevalnikov (drugi izraz za klasifikatorje):\n",
"\n",
"<p >\n",
" <img src=\"../../images/map.png\"\n",
" width=\"700\"/>\n",
" <figcaption></figcaption>\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "u1i3xRIVg7vG"
},
"source": [
"> Nasvet: [obiščite ta zemljevid na spletu](https://scikit-learn.org/stable/tutorial/machine_learning_map/) in kliknite po poti, da preberete dokumentacijo.\n",
">\n",
"> [Referenčna stran Tidymodels](https://www.tidymodels.org/find/parsnip/#models) prav tako ponuja odlično dokumentacijo o različnih vrstah modelov.\n",
"\n",
"### **Načrt** 🗺️\n",
"\n",
"Ta zemljevid je zelo koristen, ko imate jasno predstavo o svojih podatkih, saj lahko 'hodite' po njegovih poteh do odločitve:\n",
"\n",
"- Imamo \\>50 vzorcev\n",
"\n",
"- Želimo napovedati kategorijo\n",
"\n",
"- Imamo označene podatke\n",
"\n",
"- Imamo manj kot 100K vzorcev\n",
"\n",
"- ✨ Lahko izberemo Linear SVC\n",
"\n",
"- Če to ne deluje, ker imamo numerične podatke\n",
"\n",
" - Lahko poskusimo ✨ KNeighbors Classifier\n",
"\n",
" - Če to ne deluje, poskusite ✨ SVC in ✨ Ensemble Classifiers\n",
"\n",
"To je zelo koristna pot, ki ji lahko sledite. Zdaj pa se lotimo dela z uporabo [tidymodels](https://www.tidymodels.org/) okvira za modeliranje: dosledne in prilagodljive zbirke paketov za R, razvitih za spodbujanje dobre statistične prakse 😊.\n",
"\n",
"## 2. Razdelite podatke in obravnavajte neuravnotežen nabor podatkov.\n",
"\n",
"Iz naših prejšnjih lekcij smo se naučili, da obstaja niz skupnih sestavin med našimi kuhinjami. Prav tako je bila precej neenakomerna porazdelitev števila kuhinj.\n",
"\n",
"To bomo obravnavali tako, da:\n",
"\n",
"- Odstranimo najpogostejše sestavine, ki povzročajo zmedo med različnimi kuhinjami, z uporabo `dplyr::select()`.\n",
"\n",
"- Uporabimo `recipe`, ki predhodno obdela podatke, da jih pripravi za modeliranje z uporabo algoritma za `over-sampling`.\n",
"\n",
"To smo že obravnavali v prejšnji lekciji, zato bo to enostavno 🥳!\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "6tj_rN00hClA"
},
"source": [
"# Load the core Tidyverse and Tidymodels packages\n",
"library(tidyverse)\n",
"library(tidymodels)\n",
"\n",
"# Load the original cuisines data\n",
"df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/4-Classification/data/cuisines.csv\")\n",
"\n",
"# Drop id column, rice, garlic and ginger from our original data set\n",
"df_select <- df %>% \n",
" select(-c(1, rice, garlic, ginger)) %>%\n",
" # Encode cuisine column as categorical\n",
" mutate(cuisine = factor(cuisine))\n",
"\n",
"\n",
"# Create data split specification\n",
"set.seed(2056)\n",
"cuisines_split <- initial_split(data = df_select,\n",
" strata = cuisine,\n",
" prop = 0.7)\n",
"\n",
"# Extract the data in each split\n",
"cuisines_train <- training(cuisines_split)\n",
"cuisines_test <- testing(cuisines_split)\n",
"\n",
"# Display distribution of cuisines in the training set\n",
"cuisines_train %>% \n",
" count(cuisine) %>% \n",
" arrange(desc(n))"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "zFin5yw3hHb1"
},
"source": [
"### Obdelava neuravnoteženih podatkov\n",
"\n",
"Neuravnoteženi podatki pogosto negativno vplivajo na delovanje modela. Veliko modelov deluje najbolje, ko je število opazovanj enako, zato imajo težave z neuravnoteženimi podatki.\n",
"\n",
"Obstajata predvsem dva načina za obravnavo neuravnoteženih podatkovnih nizov:\n",
"\n",
"- dodajanje opazovanj v manjšinsko skupino: `Prevzorčenje` (ang. Over-sampling), npr. z uporabo algoritma SMOTE, ki sintetično ustvari nove primere manjšinske skupine z uporabo najbližjih sosedov teh primerov.\n",
"\n",
"- odstranjevanje opazovanj iz večinske skupine: `Podvzorčenje` (ang. Under-sampling)\n",
"\n",
"V prejšnji lekciji smo prikazali, kako obravnavati neuravnotežene podatkovne nize z uporabo `recepta`. Recept si lahko predstavljamo kot načrt, ki opisuje, kateri koraki naj se uporabijo na podatkovnem nizu, da bo pripravljen za analizo podatkov. V našem primeru želimo doseči enakomerno porazdelitev števila naših kulinarik v `učnem naboru`. Pa začnimo!\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "cRzTnHolhLWd"
},
"source": [
"# Load themis package for dealing with imbalanced data\n",
"library(themis)\n",
"\n",
"# Create a recipe for preprocessing training data\n",
"cuisines_recipe <- recipe(cuisine ~ ., data = cuisines_train) %>%\n",
" step_smote(cuisine) \n",
"\n",
"# Print recipe\n",
"cuisines_recipe"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "KxOQ2ORhhO81"
},
"source": [
"Zdaj smo pripravljeni na treniranje modelov 👩‍💻👨‍💻!\n",
"\n",
"## 3. Onkraj multinomnih regresijskih modelov\n",
"\n",
"V prejšnji lekciji smo obravnavali multinomne regresijske modele. Raziskali bomo nekaj bolj prilagodljivih modelov za klasifikacijo.\n",
"\n",
"### Podporni vektorski stroji\n",
"\n",
"V kontekstu klasifikacije so `Podporni vektorski stroji` tehnika strojnega učenja, ki poskuša najti *hiperploskev*, ki \"najbolje\" ločuje razrede. Poglejmo preprost primer:\n",
"\n",
"<p >\n",
" <img src=\"../../images/svm.png\"\n",
" width=\"300\"/>\n",
" <figcaption>https://commons.wikimedia.org/w/index.php?curid=22877598</figcaption>\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "C4Wsd0vZhXYu"
},
"source": [
"H1~ ne ločuje razredov. H2~ jih ločuje, vendar le z majhno razdaljo. H3~ jih ločuje z največjo razdaljo.\n",
"\n",
"#### Linearni klasifikator podpornih vektorjev\n",
"\n",
"Podporni vektorski razvrščanje (SVC) je del družine tehnik strojnega učenja, imenovanih podporni vektorski stroji. Pri SVC je hiperploskev izbrana tako, da pravilno loči `večino` opazovanj v učnem naboru, vendar `lahko napačno razvrsti` nekaj opazovanj. Z dovoljenjem, da so nekateri podatkovni točki na napačni strani, postane SVM bolj odporen na odstopanja, kar omogoča boljšo posplošitev na nove podatke. Parameter, ki uravnava to kršitev, se imenuje `cost` in ima privzeto vrednost 1 (glej `help(\"svm_poly\")`).\n",
"\n",
"Ustvarimo linearni SVC tako, da nastavimo `degree = 1` v polinomskem modelu SVM.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "vJpp6nuChlBz"
},
"source": [
"# Make a linear SVC specification\n",
"svc_linear_spec <- svm_poly(degree = 1) %>% \n",
" set_engine(\"kernlab\") %>% \n",
" set_mode(\"classification\")\n",
"\n",
"# Bundle specification and recipe into a worklow\n",
"svc_linear_wf <- workflow() %>% \n",
" add_recipe(cuisines_recipe) %>% \n",
" add_model(svc_linear_spec)\n",
"\n",
"# Print out workflow\n",
"svc_linear_wf"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "rDs8cWNkhoqu"
},
"source": [
"Zdaj, ko smo zajeli korake predobdelave in specifikacijo modela v *workflow*, lahko nadaljujemo s treniranjem linearnega SVC in hkrati ocenimo rezultate. Za merjenje učinkovitosti ustvarimo nabor metrik, ki bo ocenjeval: `natančnost`, `občutljivost`, `pozitivno napovedno vrednost` in `F-mero`.\n",
"\n",
"> `augment()` bo dodal stolpec(-ce) za napovedi k danim podatkom.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "81wiqcwuhrnq"
},
"source": [
"# Train a linear SVC model\n",
"svc_linear_fit <- svc_linear_wf %>% \n",
" fit(data = cuisines_train)\n",
"\n",
"# Create a metric set\n",
"eval_metrics <- metric_set(ppv, sens, accuracy, f_meas)\n",
"\n",
"\n",
"# Make predictions and Evaluate model performance\n",
"svc_linear_fit %>% \n",
" augment(new_data = cuisines_test) %>% \n",
" eval_metrics(truth = cuisine, estimate = .pred_class)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "0UFQvHf-huo3"
},
"source": [
"#### Podporni vektorski stroj\n",
"\n",
"Podporni vektorski stroj (SVM) je razširitev podpornega vektorskega klasifikatorja, ki omogoča uporabo nelinearne meje med razredi. V bistvu SVM-ji uporabljajo *trik s kernelom*, da razširijo prostor značilnosti in se prilagodijo nelinearnim odnosom med razredi. Ena izmed priljubljenih in izjemno prilagodljivih funkcij jedra, ki jih uporabljajo SVM-ji, je *funkcija radialne baze.* Poglejmo, kako se bo obnesla na naših podatkih.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "-KX4S8mzhzmp"
},
"source": [
"set.seed(2056)\n",
"\n",
"# Make an RBF SVM specification\n",
"svm_rbf_spec <- svm_rbf() %>% \n",
" set_engine(\"kernlab\") %>% \n",
" set_mode(\"classification\")\n",
"\n",
"# Bundle specification and recipe into a worklow\n",
"svm_rbf_wf <- workflow() %>% \n",
" add_recipe(cuisines_recipe) %>% \n",
" add_model(svm_rbf_spec)\n",
"\n",
"\n",
"# Train an RBF model\n",
"svm_rbf_fit <- svm_rbf_wf %>% \n",
" fit(data = cuisines_train)\n",
"\n",
"\n",
"# Make predictions and Evaluate model performance\n",
"svm_rbf_fit %>% \n",
" augment(new_data = cuisines_test) %>% \n",
" eval_metrics(truth = cuisine, estimate = .pred_class)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "QBFSa7WSh4HQ"
},
"source": [
"Veliko bolje 🤩!\n",
"\n",
"> ✅ Prosimo, poglejte:\n",
">\n",
"> - [*Support Vector Machines*](https://bradleyboehmke.github.io/HOML/svm.html), Hands-on Machine Learning with R\n",
">\n",
"> - [*Support Vector Machines*](https://www.statlearning.com/), An Introduction to Statistical Learning with Applications in R\n",
">\n",
"> za dodatno branje.\n",
"\n",
"### Razvrščevalniki najbližjih sosedov\n",
"\n",
"Algoritem *K*-najbližjih sosedov (KNN) je metoda, pri kateri se vsaka opazovana vrednost napove na podlagi njene *podobnosti* z drugimi opazovanji.\n",
"\n",
"Poglejmo, kako ga lahko uporabimo na naših podatkih.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "k4BxxBcdh9Ka"
},
"source": [
"# Make a KNN specification\n",
"knn_spec <- nearest_neighbor() %>% \n",
" set_engine(\"kknn\") %>% \n",
" set_mode(\"classification\")\n",
"\n",
"# Bundle recipe and model specification into a workflow\n",
"knn_wf <- workflow() %>% \n",
" add_recipe(cuisines_recipe) %>% \n",
" add_model(knn_spec)\n",
"\n",
"# Train a boosted tree model\n",
"knn_wf_fit <- knn_wf %>% \n",
" fit(data = cuisines_train)\n",
"\n",
"\n",
"# Make predictions and Evaluate model performance\n",
"knn_wf_fit %>% \n",
" augment(new_data = cuisines_test) %>% \n",
" eval_metrics(truth = cuisine, estimate = .pred_class)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "HaegQseriAcj"
},
"source": [
"Zdi se, da ta model ne deluje najbolje. Verjetno bo izboljšanje delovanja modela mogoče z spremembo argumentov modela (glejte `help(\"nearest_neighbor\")`). Vsekakor poskusite to možnost.\n",
"\n",
"> ✅ Prosimo, poglejte:\n",
">\n",
"> - [Hands-on Machine Learning with R](https://bradleyboehmke.github.io/HOML/)\n",
">\n",
"> - [An Introduction to Statistical Learning with Applications in R](https://www.statlearning.com/)\n",
">\n",
"> za več informacij o klasifikatorjih *K*-Najbližjih Sosedov.\n",
"\n",
"### Ensemble klasifikatorji\n",
"\n",
"Ensemble algoritmi delujejo tako, da kombinirajo več osnovnih ocenjevalnikov za izdelavo optimalnega modela bodisi z:\n",
"\n",
"`bagging`: uporabo *povprečne funkcije* na zbirki osnovnih modelov\n",
"\n",
"`boosting`: gradnjo zaporedja modelov, ki se medsebojno nadgrajujejo za izboljšanje napovedne zmogljivosti.\n",
"\n",
"Začnimo z uporabo modela Random Forest, ki gradi veliko zbirko odločitvenih dreves in nato uporabi povprečno funkcijo za boljši celotni model.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "49DPoVs6iK1M"
},
"source": [
"# Make a random forest specification\n",
"rf_spec <- rand_forest() %>% \n",
" set_engine(\"ranger\") %>% \n",
" set_mode(\"classification\")\n",
"\n",
"# Bundle recipe and model specification into a workflow\n",
"rf_wf <- workflow() %>% \n",
" add_recipe(cuisines_recipe) %>% \n",
" add_model(rf_spec)\n",
"\n",
"# Train a random forest model\n",
"rf_wf_fit <- rf_wf %>% \n",
" fit(data = cuisines_train)\n",
"\n",
"\n",
"# Make predictions and Evaluate model performance\n",
"rf_wf_fit %>% \n",
" augment(new_data = cuisines_test) %>% \n",
" eval_metrics(truth = cuisine, estimate = .pred_class)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "RGVYwC_aiUWc"
},
"source": [
"Odlično delo 👏!\n",
"\n",
"Poskusimo tudi z modelom Boosted Tree.\n",
"\n",
"Boosted Tree opredeljuje metodo ansambla, ki ustvari serijo zaporednih odločitvenih dreves, kjer vsako drevo temelji na rezultatih prejšnjih dreves, da postopoma zmanjša napako. Osredotoča se na uteži napačno razvrščenih elementov in prilagodi prileganje za naslednji klasifikator, da jih popravi.\n",
"\n",
"Obstajajo različni načini za prileganje tega modela (glejte `help(\"boost_tree\")`). V tem primeru bomo prilegali Boosted drevesa prek pogona `xgboost`.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "Py1YWo-micWs"
},
"source": [
"# Make a boosted tree specification\n",
"boost_spec <- boost_tree(trees = 200) %>% \n",
" set_engine(\"xgboost\") %>% \n",
" set_mode(\"classification\")\n",
"\n",
"# Bundle recipe and model specification into a workflow\n",
"boost_wf <- workflow() %>% \n",
" add_recipe(cuisines_recipe) %>% \n",
" add_model(boost_spec)\n",
"\n",
"# Train a boosted tree model\n",
"boost_wf_fit <- boost_wf %>% \n",
" fit(data = cuisines_train)\n",
"\n",
"\n",
"# Make predictions and Evaluate model performance\n",
"boost_wf_fit %>% \n",
" augment(new_data = cuisines_test) %>% \n",
" eval_metrics(truth = cuisine, estimate = .pred_class)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "zNQnbuejigZM"
},
"source": [
"✅ Prosimo, da si ogledate:\n",
"\n",
"- [Strojno učenje za družboslovce](https://cimentadaj.github.io/ml_socsci/tree-based-methods.html#random-forests)\n",
"- [Praktično strojno učenje z R](https://bradleyboehmke.github.io/HOML/)\n",
"- [Uvod v statistično učenje z aplikacijami v R](https://www.statlearning.com/)\n",
"- <https://algotech.netlify.app/blog/xgboost/> - Raziskuje model AdaBoost, ki je dobra alternativa xgboost.\n",
"\n",
"za več informacij o Ensemble klasifikatorjih.\n",
"\n",
"## 4. Dodatno - primerjava več modelov\n",
"\n",
"V tem laboratoriju smo prilagodili kar nekaj modelov 🙌. Ustvarjanje številnih delovnih tokov iz različnih naborov predprocesorjev in/ali specifikacij modelov ter nato izračunavanje metrik zmogljivosti enega za drugim lahko postane zamudno ali naporno.\n",
"\n",
"Poglejmo, ali lahko to rešimo z ustvarjanjem funkcije, ki prilagodi seznam delovnih tokov na učnem naboru podatkov in nato vrne metrike zmogljivosti na podlagi testnega nabora. Uporabili bomo `map()` in `map_dfr()` iz paketa [purrr](https://purrr.tidyverse.org/), da funkcije uporabimo na vsakem elementu seznama.\n",
"\n",
"> Funkcije [`map()`](https://purrr.tidyverse.org/reference/map.html) vam omogočajo, da nadomestite številne for zanke s kodo, ki je bolj jedrnata in lažja za branje. Najboljše mesto za učenje o funkcijah [`map()`](https://purrr.tidyverse.org/reference/map.html) je [poglavje o iteraciji](http://r4ds.had.co.nz/iteration.html) v R za podatkovno znanost.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "Qzb7LyZnimd2"
},
"source": [
"set.seed(2056)\n",
"\n",
"# Create a metric set\n",
"eval_metrics <- metric_set(ppv, sens, accuracy, f_meas)\n",
"\n",
"# Define a function that returns performance metrics\n",
"compare_models <- function(workflow_list, train_set, test_set){\n",
" \n",
" suppressWarnings(\n",
" # Fit each model to the train_set\n",
" map(workflow_list, fit, data = train_set) %>% \n",
" # Make predictions on the test set\n",
" map_dfr(augment, new_data = test_set, .id = \"model\") %>%\n",
" # Select desired columns\n",
" select(model, cuisine, .pred_class) %>% \n",
" # Evaluate model performance\n",
" group_by(model) %>% \n",
" eval_metrics(truth = cuisine, estimate = .pred_class) %>% \n",
" ungroup()\n",
" )\n",
" \n",
"} # End of function"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "Fwa712sNisDA"
},
"source": []
},
{
"cell_type": "code",
"metadata": {
"id": "3i4VJOi2iu-a"
},
"source": [
"# Make a list of workflows\n",
"workflow_list <- list(\n",
" \"svc\" = svc_linear_wf,\n",
" \"svm\" = svm_rbf_wf,\n",
" \"knn\" = knn_wf,\n",
" \"random_forest\" = rf_wf,\n",
" \"xgboost\" = boost_wf)\n",
"\n",
"# Call the function\n",
"set.seed(2056)\n",
"perf_metrics <- compare_models(workflow_list = workflow_list, train_set = cuisines_train, test_set = cuisines_test)\n",
"\n",
"# Print out performance metrics\n",
"perf_metrics %>% \n",
" group_by(.metric) %>% \n",
" arrange(desc(.estimate)) %>% \n",
" slice_head(n=7)\n",
"\n",
"# Compare accuracy\n",
"perf_metrics %>% \n",
" filter(.metric == \"accuracy\") %>% \n",
" arrange(desc(.estimate))\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "KuWK_lEli4nW"
},
"source": [
"[**workflowset**](https://workflowsets.tidymodels.org/) paket omogoča uporabnikom, da ustvarijo in enostavno prilegajo veliko število modelov, vendar je večinoma zasnovan za delo s tehnikami ponovnega vzorčenja, kot je `križno preverjanje`, pristop, ki ga bomo še obravnavali.\n",
"\n",
"## **🚀Izziv**\n",
"\n",
"Vsaka od teh tehnik ima veliko število parametrov, ki jih lahko prilagodite, na primer `cost` pri SVM, `neighbors` pri KNN, `mtry` (naključno izbrani prediktorji) pri Random Forest.\n",
"\n",
"Raziskujte privzete parametre za vsako od teh tehnik in razmislite, kaj bi prilagajanje teh parametrov pomenilo za kakovost modela.\n",
"\n",
"Če želite izvedeti več o določenem modelu in njegovih parametrih, uporabite: `help(\"model\")`, npr. `help(\"rand_forest\")`.\n",
"\n",
"> V praksi običajno *ocenimo* *najboljše vrednosti* teh parametrov tako, da treniramo veliko modelov na `simuliranem naboru podatkov` in merimo, kako dobro se vsi ti modeli obnesejo. Ta proces imenujemo **uglaševanje**.\n",
"\n",
"### [**Kvizi po predavanju**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/24/)\n",
"\n",
"### **Pregled in samostojno učenje**\n",
"\n",
"V teh lekcijah je veliko strokovnih izrazov, zato si vzemite trenutek za pregled [tega seznama](https://docs.microsoft.com/dotnet/machine-learning/resources/glossary?WT.mc_id=academic-77952-leestott) uporabne terminologije!\n",
"\n",
"#### HVALA:\n",
"\n",
"[`Allison Horst`](https://twitter.com/allison_horst/) za ustvarjanje neverjetnih ilustracij, ki naredijo R bolj prijazen in privlačen. Več ilustracij najdete v njeni [galeriji](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) in [Jen Looper](https://www.twitter.com/jenlooper) za ustvarjanje izvirne različice tega modula v Pythonu ♥️\n",
"\n",
"Veselo učenje,\n",
"\n",
"[Eric](https://twitter.com/ericntay), zlati Microsoft Learn študentski ambasador.\n",
"\n",
"<p >\n",
" <img src=\"../../images/r_learners_sm.jpeg\"\n",
" width=\"569\"/>\n",
" <figcaption>Ilustracija @allison_horst</figcaption>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
]
}

@ -0,0 +1,304 @@
{
"cells": [
{
"source": [
"# Zgradite več klasifikacijskih modelov\n"
],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Unnamed: 0 cuisine almond angelica anise anise_seed apple \\\n",
"0 0 indian 0 0 0 0 0 \n",
"1 1 indian 1 0 0 0 0 \n",
"2 2 indian 0 0 0 0 0 \n",
"3 3 indian 0 0 0 0 0 \n",
"4 4 indian 0 0 0 0 0 \n",
"\n",
" apple_brandy apricot armagnac ... whiskey white_bread white_wine \\\n",
"0 0 0 0 ... 0 0 0 \n",
"1 0 0 0 ... 0 0 0 \n",
"2 0 0 0 ... 0 0 0 \n",
"3 0 0 0 ... 0 0 0 \n",
"4 0 0 0 ... 0 0 0 \n",
"\n",
" whole_grain_wheat_flour wine wood yam yeast yogurt zucchini \n",
"0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 1 0 \n",
"\n",
"[5 rows x 382 columns]"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>Unnamed: 0</th>\n <th>cuisine</th>\n <th>almond</th>\n <th>angelica</th>\n <th>anise</th>\n <th>anise_seed</th>\n <th>apple</th>\n <th>apple_brandy</th>\n <th>apricot</th>\n <th>armagnac</th>\n <th>...</th>\n <th>whiskey</th>\n <th>white_bread</th>\n <th>white_wine</th>\n <th>whole_grain_wheat_flour</th>\n <th>wine</th>\n <th>wood</th>\n <th>yam</th>\n <th>yeast</th>\n <th>yogurt</th>\n <th>zucchini</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>indian</td>\n <td>1</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>2</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>3</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>4</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>1</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 382 columns</p>\n</div>"
},
"metadata": {},
"execution_count": 1
}
],
"source": [
"import pandas as pd\n",
"cuisines_df = pd.read_csv(\"../../data/cleaned_cuisines.csv\")\n",
"cuisines_df.head()"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"0 indian\n",
"1 indian\n",
"2 indian\n",
"3 indian\n",
"4 indian\n",
"Name: cuisine, dtype: object"
]
},
"metadata": {},
"execution_count": 2
}
],
"source": [
"cuisines_label_df = cuisines_df['cuisine']\n",
"cuisines_label_df.head()"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" almond angelica anise anise_seed apple apple_brandy apricot \\\n",
"0 0 0 0 0 0 0 0 \n",
"1 1 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 0 \n",
"\n",
" armagnac artemisia artichoke ... whiskey white_bread white_wine \\\n",
"0 0 0 0 ... 0 0 0 \n",
"1 0 0 0 ... 0 0 0 \n",
"2 0 0 0 ... 0 0 0 \n",
"3 0 0 0 ... 0 0 0 \n",
"4 0 0 0 ... 0 0 0 \n",
"\n",
" whole_grain_wheat_flour wine wood yam yeast yogurt zucchini \n",
"0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 1 0 \n",
"\n",
"[5 rows x 380 columns]"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>almond</th>\n <th>angelica</th>\n <th>anise</th>\n <th>anise_seed</th>\n <th>apple</th>\n <th>apple_brandy</th>\n <th>apricot</th>\n <th>armagnac</th>\n <th>artemisia</th>\n <th>artichoke</th>\n <th>...</th>\n <th>whiskey</th>\n <th>white_bread</th>\n <th>white_wine</th>\n <th>whole_grain_wheat_flour</th>\n <th>wine</th>\n <th>wood</th>\n <th>yam</th>\n <th>yeast</th>\n <th>yogurt</th>\n <th>zucchini</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>1</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 380 columns</p>\n</div>"
},
"metadata": {},
"execution_count": 3
}
],
"source": [
"cuisines_feature_df = cuisines_df.drop(['Unnamed: 0', 'cuisine'], axis=1)\n",
"cuisines_feature_df.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Poskusite različne klasifikatorje\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.neighbors import KNeighborsClassifier\n",
"from sklearn.linear_model import LogisticRegression\n",
"from sklearn.svm import SVC\n",
"from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier\n",
"from sklearn.model_selection import train_test_split, cross_val_score\n",
"from sklearn.metrics import accuracy_score,precision_score,confusion_matrix,classification_report, precision_recall_curve\n",
"import numpy as np"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"X_train, X_test, y_train, y_test = train_test_split(cuisines_feature_df, cuisines_label_df, test_size=0.3)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"\n",
"C = 10\n",
"# Create different classifiers.\n",
"classifiers = {\n",
" 'Linear SVC': SVC(kernel='linear', C=C, probability=True,random_state=0),\n",
" 'KNN classifier': KNeighborsClassifier(C),\n",
" 'SVC': SVC(),\n",
" 'RFST': RandomForestClassifier(n_estimators=100),\n",
" 'ADA': AdaBoostClassifier(n_estimators=100)\n",
" \n",
"}\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Accuracy (train) for Linear SVC: 76.4% \n",
" precision recall f1-score support\n",
"\n",
" chinese 0.64 0.66 0.65 242\n",
" indian 0.91 0.86 0.89 236\n",
" japanese 0.72 0.73 0.73 245\n",
" korean 0.83 0.75 0.79 234\n",
" thai 0.75 0.82 0.78 242\n",
"\n",
" accuracy 0.76 1199\n",
" macro avg 0.77 0.76 0.77 1199\n",
"weighted avg 0.77 0.76 0.77 1199\n",
"\n",
"Accuracy (train) for KNN classifier: 70.7% \n",
" precision recall f1-score support\n",
"\n",
" chinese 0.65 0.63 0.64 242\n",
" indian 0.84 0.81 0.82 236\n",
" japanese 0.60 0.81 0.69 245\n",
" korean 0.89 0.53 0.67 234\n",
" thai 0.69 0.75 0.72 242\n",
"\n",
" accuracy 0.71 1199\n",
" macro avg 0.73 0.71 0.71 1199\n",
"weighted avg 0.73 0.71 0.71 1199\n",
"\n",
"Accuracy (train) for SVC: 80.1% \n",
" precision recall f1-score support\n",
"\n",
" chinese 0.71 0.69 0.70 242\n",
" indian 0.92 0.92 0.92 236\n",
" japanese 0.77 0.78 0.77 245\n",
" korean 0.87 0.77 0.82 234\n",
" thai 0.75 0.86 0.80 242\n",
"\n",
" accuracy 0.80 1199\n",
" macro avg 0.80 0.80 0.80 1199\n",
"weighted avg 0.80 0.80 0.80 1199\n",
"\n",
"Accuracy (train) for RFST: 82.8% \n",
" precision recall f1-score support\n",
"\n",
" chinese 0.80 0.75 0.77 242\n",
" indian 0.90 0.91 0.90 236\n",
" japanese 0.82 0.78 0.80 245\n",
" korean 0.85 0.82 0.83 234\n",
" thai 0.78 0.89 0.83 242\n",
"\n",
" accuracy 0.83 1199\n",
" macro avg 0.83 0.83 0.83 1199\n",
"weighted avg 0.83 0.83 0.83 1199\n",
"\n",
"Accuracy (train) for ADA: 71.1% \n",
" precision recall f1-score support\n",
"\n",
" chinese 0.60 0.57 0.58 242\n",
" indian 0.87 0.84 0.86 236\n",
" japanese 0.71 0.60 0.65 245\n",
" korean 0.68 0.78 0.72 234\n",
" thai 0.70 0.78 0.74 242\n",
"\n",
" accuracy 0.71 1199\n",
" macro avg 0.71 0.71 0.71 1199\n",
"weighted avg 0.71 0.71 0.71 1199\n",
"\n"
]
}
],
"source": [
"n_classifiers = len(classifiers)\n",
"\n",
"for index, (name, classifier) in enumerate(classifiers.items()):\n",
" classifier.fit(X_train, np.ravel(y_train))\n",
"\n",
" y_pred = classifier.predict(X_test)\n",
" accuracy = accuracy_score(y_test, y_pred)\n",
" print(\"Accuracy (train) for %s: %0.1f%% \" % (name, accuracy * 100))\n",
" print(classification_report(y_test,y_pred))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
],
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
}
},
"coopTranslator": {
"original_hash": "7ea2b714669c823a596d986ba2d5739f",
"translation_date": "2025-09-06T14:42:43+00:00",
"source_file": "4-Classification/3-Classifiers-2/solution/notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

@ -0,0 +1,41 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": 3
},
"orig_nbformat": 4,
"coopTranslator": {
"original_hash": "2f3e0d9e9ac5c301558fb8bf733ac0cb",
"translation_date": "2025-09-06T14:41:26+00:00",
"source_file": "4-Classification/4-Applied/notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"source": [
"# Ustvari priporočilnik za kulinariko\n"
],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
]
}

@ -0,0 +1,292 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"orig_nbformat": 2,
"kernelspec": {
"name": "python3",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
}
},
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
},
"coopTranslator": {
"original_hash": "49325d6dd12a3628fc64fa7ccb1a80ff",
"translation_date": "2025-09-06T14:41:51+00:00",
"source_file": "4-Classification/4-Applied/solution/notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"source": [
"# Ustvari priporočilnik za kulinariko\n"
],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Requirement already satisfied: skl2onnx in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (1.8.0)\n",
"Requirement already satisfied: protobuf in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from skl2onnx) (3.8.0)\n",
"Requirement already satisfied: numpy>=1.15 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from skl2onnx) (1.19.2)\n",
"Requirement already satisfied: onnx>=1.2.1 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from skl2onnx) (1.9.0)\n",
"Requirement already satisfied: six in /Users/jenlooper/Library/Python/3.7/lib/python/site-packages (from skl2onnx) (1.12.0)\n",
"Requirement already satisfied: onnxconverter-common<1.9,>=1.6.1 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from skl2onnx) (1.8.1)\n",
"Requirement already satisfied: scikit-learn>=0.19 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from skl2onnx) (0.24.2)\n",
"Requirement already satisfied: scipy>=1.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from skl2onnx) (1.4.1)\n",
"Requirement already satisfied: setuptools in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from protobuf->skl2onnx) (45.1.0)\n",
"Requirement already satisfied: typing-extensions>=3.6.2.1 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from onnx>=1.2.1->skl2onnx) (3.10.0.0)\n",
"Requirement already satisfied: threadpoolctl>=2.0.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from scikit-learn>=0.19->skl2onnx) (2.1.0)\n",
"Requirement already satisfied: joblib>=0.11 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from scikit-learn>=0.19->skl2onnx) (0.16.0)\n",
"\u001b[33mWARNING: You are using pip version 20.2.3; however, version 21.1.2 is available.\n",
"You should consider upgrading via the '/Library/Frameworks/Python.framework/Versions/3.7/bin/python3.7 -m pip install --upgrade pip' command.\u001b[0m\n",
"Note: you may need to restart the kernel to use updated packages.\n"
]
}
],
"source": [
"!pip install skl2onnx"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd \n"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Unnamed: 0 cuisine almond angelica anise anise_seed apple \\\n",
"0 0 indian 0 0 0 0 0 \n",
"1 1 indian 1 0 0 0 0 \n",
"2 2 indian 0 0 0 0 0 \n",
"3 3 indian 0 0 0 0 0 \n",
"4 4 indian 0 0 0 0 0 \n",
"\n",
" apple_brandy apricot armagnac ... whiskey white_bread white_wine \\\n",
"0 0 0 0 ... 0 0 0 \n",
"1 0 0 0 ... 0 0 0 \n",
"2 0 0 0 ... 0 0 0 \n",
"3 0 0 0 ... 0 0 0 \n",
"4 0 0 0 ... 0 0 0 \n",
"\n",
" whole_grain_wheat_flour wine wood yam yeast yogurt zucchini \n",
"0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 1 0 \n",
"\n",
"[5 rows x 382 columns]"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>Unnamed: 0</th>\n <th>cuisine</th>\n <th>almond</th>\n <th>angelica</th>\n <th>anise</th>\n <th>anise_seed</th>\n <th>apple</th>\n <th>apple_brandy</th>\n <th>apricot</th>\n <th>armagnac</th>\n <th>...</th>\n <th>whiskey</th>\n <th>white_bread</th>\n <th>white_wine</th>\n <th>whole_grain_wheat_flour</th>\n <th>wine</th>\n <th>wood</th>\n <th>yam</th>\n <th>yeast</th>\n <th>yogurt</th>\n <th>zucchini</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>indian</td>\n <td>1</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>2</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>3</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>4</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>1</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 382 columns</p>\n</div>"
},
"metadata": {},
"execution_count": 60
}
],
"source": [
"data = pd.read_csv('../../data/cleaned_cuisines.csv')\n",
"data.head()"
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" almond angelica anise anise_seed apple apple_brandy apricot \\\n",
"0 0 0 0 0 0 0 0 \n",
"1 1 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 0 \n",
"\n",
" armagnac artemisia artichoke ... whiskey white_bread white_wine \\\n",
"0 0 0 0 ... 0 0 0 \n",
"1 0 0 0 ... 0 0 0 \n",
"2 0 0 0 ... 0 0 0 \n",
"3 0 0 0 ... 0 0 0 \n",
"4 0 0 0 ... 0 0 0 \n",
"\n",
" whole_grain_wheat_flour wine wood yam yeast yogurt zucchini \n",
"0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 1 0 \n",
"\n",
"[5 rows x 380 columns]"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>almond</th>\n <th>angelica</th>\n <th>anise</th>\n <th>anise_seed</th>\n <th>apple</th>\n <th>apple_brandy</th>\n <th>apricot</th>\n <th>armagnac</th>\n <th>artemisia</th>\n <th>artichoke</th>\n <th>...</th>\n <th>whiskey</th>\n <th>white_bread</th>\n <th>white_wine</th>\n <th>whole_grain_wheat_flour</th>\n <th>wine</th>\n <th>wood</th>\n <th>yam</th>\n <th>yeast</th>\n <th>yogurt</th>\n <th>zucchini</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>1</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 380 columns</p>\n</div>"
},
"metadata": {},
"execution_count": 61
}
],
"source": [
"X = data.iloc[:,2:]\n",
"X.head()"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" cuisine\n",
"0 indian\n",
"1 indian\n",
"2 indian\n",
"3 indian\n",
"4 indian"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>cuisine</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>indian</td>\n </tr>\n <tr>\n <th>1</th>\n <td>indian</td>\n </tr>\n <tr>\n <th>2</th>\n <td>indian</td>\n </tr>\n <tr>\n <th>3</th>\n <td>indian</td>\n </tr>\n <tr>\n <th>4</th>\n <td>indian</td>\n </tr>\n </tbody>\n</table>\n</div>"
},
"metadata": {},
"execution_count": 62
}
],
"source": [
"y = data[['cuisine']]\n",
"y.head()"
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.model_selection import train_test_split\n",
"from sklearn.svm import SVC\n",
"from sklearn.model_selection import cross_val_score\n",
"from sklearn.metrics import accuracy_score,precision_score,confusion_matrix,classification_report"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [],
"source": [
"X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.3)"
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"SVC(C=10, kernel='linear', probability=True, random_state=0)"
]
},
"metadata": {},
"execution_count": 65
}
],
"source": [
"model = SVC(kernel='linear', C=10, probability=True,random_state=0)\n",
"model.fit(X_train,y_train.values.ravel())\n"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [],
"source": [
"y_pred = model.predict(X_test)"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
" precision recall f1-score support\n\n chinese 0.72 0.70 0.71 236\n indian 0.91 0.88 0.89 243\n japanese 0.80 0.75 0.77 240\n korean 0.80 0.81 0.81 230\n thai 0.76 0.85 0.80 250\n\n accuracy 0.80 1199\n macro avg 0.80 0.80 0.80 1199\nweighted avg 0.80 0.80 0.80 1199\n\n"
]
}
],
"source": [
"print(classification_report(y_test,y_pred))"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [],
"source": [
"from skl2onnx import convert_sklearn\n",
"from skl2onnx.common.data_types import FloatTensorType\n",
"\n",
"initial_type = [('float_input', FloatTensorType([None, 380]))]\n",
"options = {id(model): {'nocl': True, 'zipmap': False}}\n",
"onx = convert_sklearn(model, initial_types=initial_type, options=options)\n",
"with open(\"./model.onnx\", \"wb\") as f:\n",
" f.write(onx.SerializeToString())\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
]
}

@ -0,0 +1,50 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.3"
},
"orig_nbformat": 2,
"kernelspec": {
"name": "python383jvsc74a57bd0e134e05457d34029b6460cd73bbf1ed73f339b5b6d98c95be70b69eba114fe95",
"display_name": "Python 3.8.3 64-bit (conda)"
},
"coopTranslator": {
"original_hash": "40e0707e96b3e1899a912776006264f9",
"translation_date": "2025-09-06T14:07:56+00:00",
"source_file": "5-Clustering/1-Visualize/notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"source": [],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da se zavedate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
]
}

@ -0,0 +1,488 @@
{
"cells": [
{
"cell_type": "markdown",
"source": [
"## **Nigerijska glasba pridobljena s Spotifyja - analiza**\n",
"\n",
"Grozdanje je vrsta [nenadzorovanega učenja](https://wikipedia.org/wiki/Unsupervised_learning), ki predpostavlja, da je podatkovni niz neoznačen ali da njegovi vnosi niso povezani z vnaprej določenimi izhodi. Uporablja različne algoritme za razvrščanje neoznačenih podatkov in zagotavljanje skupin glede na vzorce, ki jih zazna v podatkih.\n",
"\n",
"[**Predhodni kviz**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/27/)\n",
"\n",
"### **Uvod**\n",
"\n",
"[Grozdanje](https://link.springer.com/referenceworkentry/10.1007%2F978-0-387-30164-8_124) je zelo uporabno za raziskovanje podatkov. Poglejmo, ali lahko pomaga odkriti trende in vzorce v načinu, kako nigerijsko občinstvo posluša glasbo.\n",
"\n",
"> ✅ Vzemite si trenutek in razmislite o uporabi grozdanja. V vsakdanjem življenju se grozdanje zgodi, kadar imate kup perila in morate razvrstiti oblačila družinskih članov 🧦👕👖🩲. V podatkovni znanosti se grozdanje zgodi, ko poskušate analizirati uporabnikove preference ali določiti značilnosti katerega koli neoznačenega podatkovnega niza. Grozdanje na nek način pomaga ustvariti red iz kaosa, kot je predal za nogavice.\n",
"\n",
"V profesionalnem okolju se grozdanje lahko uporablja za določanje stvari, kot je segmentacija trga, na primer za ugotavljanje, katere starostne skupine kupujejo določene izdelke. Druga uporaba bi bila odkrivanje anomalij, morda za zaznavanje goljufij v podatkovnem nizu transakcij s kreditnimi karticami. Lahko pa uporabite grozdanje za določanje tumorjev v seriji medicinskih skenov.\n",
"\n",
"✅ Razmislite za trenutek, kako ste morda naleteli na grozdanje 'v naravi', v bančništvu, e-trgovini ali poslovnem okolju.\n",
"\n",
"> 🎓 Zanimivo je, da analiza grozdov izvira iz področij antropologije in psihologije v 1930-ih. Si lahko predstavljate, kako bi jo takrat uporabljali?\n",
"\n",
"Alternativno bi jo lahko uporabili za razvrščanje rezultatov iskanja - na primer po nakupovalnih povezavah, slikah ali ocenah. Grozdanje je uporabno, kadar imate velik podatkovni niz, ki ga želite zmanjšati in na katerem želite opraviti bolj podrobno analizo, zato se tehnika lahko uporablja za spoznavanje podatkov, preden se zgradijo drugi modeli.\n",
"\n",
"✅ Ko so vaši podatki organizirani v grozde, jim dodelite ID grozda, kar je lahko uporabno pri ohranjanju zasebnosti podatkovnega niza; namesto bolj razkrivajočih identifikacijskih podatkov lahko uporabite ID grozda za sklicevanje na podatkovno točko. Ali lahko pomislite na druge razloge, zakaj bi za identifikacijo raje uporabili ID grozda kot druge elemente grozda?\n",
"\n",
"### Začetek z grozdanjem\n",
"\n",
"> 🎓 Način, kako ustvarimo grozde, je močno povezan s tem, kako združimo podatkovne točke v skupine. Razčistimo nekaj terminologije:\n",
">\n",
"> 🎓 ['Transduktivno' vs. 'induktivno'](https://wikipedia.org/wiki/Transduction_(machine_learning))\n",
">\n",
"> Transduktivno sklepanje izhaja iz opazovanih primerov usposabljanja, ki se preslikajo na specifične testne primere. Induktivno sklepanje izhaja iz primerov usposabljanja, ki se preslikajo na splošna pravila, ki se nato uporabijo na testnih primerih.\n",
">\n",
"> Primer: Predstavljajte si, da imate podatkovni niz, ki je le delno označen. Nekatere stvari so 'plošče', nekatere 'CD-ji', nekatere pa so prazne. Vaša naloga je dodeliti oznake praznim. Če izberete induktivni pristop, bi usposobili model za iskanje 'plošč' in 'CD-jev' ter te oznake uporabili na neoznačenih podatkih. Ta pristop bo imel težave pri razvrščanju stvari, ki so dejansko 'kasete'. Transduktivni pristop pa bo to neznano podatkovno točko obravnaval bolj učinkovito, saj deluje tako, da združi podobne predmete in nato skupini dodeli oznako. V tem primeru bi grozdi lahko odražali 'okrogle glasbene stvari' in 'kvadratne glasbene stvari'.\n",
">\n",
"> 🎓 ['Neploskovna' vs. 'ploskovna' geometrija](https://datascience.stackexchange.com/questions/52260/terminology-flat-geometry-in-the-context-of-clustering)\n",
">\n",
"> Izpeljano iz matematične terminologije, neploskovna vs. ploskovna geometrija se nanaša na merjenje razdalj med točkami bodisi s 'ploskovnimi' ([Evklidskimi](https://wikipedia.org/wiki/Euclidean_geometry)) bodisi z neploskovnimi (neevklidskimi) geometrijskimi metodami.\n",
">\n",
"> 'Ploskovna' v tem kontekstu se nanaša na evklidsko geometrijo (deli katere se učijo kot 'ravninska' geometrija), medtem ko se neploskovna nanaša na neevklidsko geometrijo. Kaj ima geometrija skupnega z strojno učenje? Kot dve področji, ki temeljita na matematiki, mora obstajati skupen način za merjenje razdalj med točkami v grozdih, kar se lahko izvede na 'ploskovni' ali 'neploskovni' način, odvisno od narave podatkov. [Evklidske razdalje](https://wikipedia.org/wiki/Euclidean_distance) se merijo kot dolžina odseka med dvema točkama. [Neevklidske razdalje](https://wikipedia.org/wiki/Non-Euclidean_geometry) se merijo vzdolž krivulje. Če se vaši podatki, vizualizirani, ne nahajajo na ravnini, boste morda morali uporabiti specializiran algoritem za obdelavo.\n",
">\n",
"> 🎓 ['Razdalje'](https://web.stanford.edu/class/cs345a/slides/12-clustering.pdf)\n",
">\n",
"> Grozdi so opredeljeni z matriko razdalj, npr. razdaljami med točkami. Te razdalje je mogoče meriti na več načinov. Evklidski grozdi so opredeljeni z povprečjem vrednosti točk in vsebujejo 'centroid' ali osrednjo točko. Razdalje se tako merijo glede na razdaljo do tega centroida. Neevklidske razdalje se nanašajo na 'clustroid', točko, ki je najbližja drugim točkam. Clustroidi so lahko opredeljeni na različne načine.\n",
">\n",
"> 🎓 ['Omejeno'](https://wikipedia.org/wiki/Constrained_clustering)\n",
">\n",
"> [Omejeno grozdanje](https://web.cs.ucdavis.edu/~davidson/Publications/ICDMTutorial.pdf) uvaja 'polnadzorovano' učenje v to nenadzorovano metodo. Razmerja med točkami so označena kot 'ne smejo se povezati' ali 'morajo se povezati', tako da se na podatkovni niz uvedejo določena pravila.\n",
">\n",
"> Primer: Če je algoritem sproščen na serijo neoznačenih ali delno označenih podatkov, so lahko grozdi, ki jih ustvari, slabe kakovosti. V zgornjem primeru bi grozdi lahko združevali 'okrogle glasbene stvari', 'kvadratne glasbene stvari', 'trikotne stvari' in 'piškote'. Če se uvedejo določene omejitve ali pravila (\"predmet mora biti iz plastike\", \"predmet mora biti sposoben proizvajati glasbo\"), to lahko pomaga 'omejiti' algoritem, da sprejema boljše odločitve.\n",
">\n",
"> 🎓 'Gostota'\n",
">\n",
"> Podatki, ki so 'hrupni', se štejejo za 'goste'. Razdalje med točkami v vsakem od njegovih grozdov se lahko ob pregledu izkažejo za bolj ali manj goste ali 'natrpane', zato je treba te podatke analizirati z ustrezno metodo grozdanja. [Ta članek](https://www.kdnuggets.com/2020/02/understanding-density-based-clustering.html) prikazuje razliko med uporabo algoritmov K-Means grozdanja in HDBSCAN za raziskovanje hrupnega podatkovnega niza z neenakomerno gostoto grozdov.\n",
"\n",
"Poglobite svoje razumevanje tehnik grozdanja v tem [učnem modulu](https://docs.microsoft.com/learn/modules/train-evaluate-cluster-models?WT.mc_id=academic-77952-leestott)\n",
"\n",
"### **Algoritmi grozdanja**\n",
"\n",
"Obstaja več kot 100 algoritmov za grozdanje, njihova uporaba pa je odvisna od narave podatkov. Oglejmo si nekatere glavne:\n",
"\n",
"- **Hierarhično grozdanje**. Če je predmet razvrščen glede na svojo bližino bližnjemu predmetu, namesto bolj oddaljenemu, se grozdi oblikujejo na podlagi razdalje med člani. Hierarhično grozdanje je značilno po tem, da se dva grozda večkrat združita.\n",
"\n",
"<p >\n",
" <img src=\"../../images/hierarchical.png\"\n",
" width=\"600\"/>\n",
" <figcaption>Infografika: Dasani Madipalli</figcaption>\n",
"\n",
"- **Centroidno grozdanje**. Ta priljubljeni algoritem zahteva izbiro 'k', ali število grozdov, ki jih je treba oblikovati, nato pa algoritem določi osrednjo točko grozda in zbira podatke okoli te točke. [K-means grozdanje](https://wikipedia.org/wiki/K-means_clustering) je priljubljena različica centroidnega grozdanja, ki razdeli podatkovni niz v vnaprej določene K skupine. Center je določen z najbližjim povprečjem, od tod tudi ime. Kvadratna razdalja od grozda je minimizirana.\n",
"\n",
"<p >\n",
" <img src=\"../../images/centroid.png\"\n",
" width=\"600\"/>\n",
" <figcaption>Infografika: Dasani Madipalli</figcaption>\n",
"\n",
"- **Grozdanje na podlagi porazdelitve**. Temelji na statističnem modeliranju, grozdanje na podlagi porazdelitve se osredotoča na določanje verjetnosti, da podatkovna točka pripada grozdu, in ji ustrezno dodeli mesto. Metode Gaussove mešanice spadajo v to vrsto.\n",
"\n",
"- **Grozdanje na podlagi gostote**. Podatkovne točke so dodeljene grozdom glede na njihovo gostoto ali njihovo združevanje okoli drugih točk. Podatkovne točke, ki so daleč od skupine, se štejejo za odstopanja ali hrup. DBSCAN, Mean-shift in OPTICS spadajo v to vrsto grozdanja.\n",
"\n",
"- **Grozdanje na podlagi mreže**. Za večdimenzionalne podatkovne nize se ustvari mreža, podatki pa se razdelijo med celice mreže, s čimer se ustvarijo grozdi.\n",
"\n",
"Najboljši način za učenje o grozdanju je, da ga preizkusite sami, kar boste storili v tej vaji.\n",
"\n",
"Za dokončanje tega modula bomo potrebovali nekaj paketov. Namestite jih lahko z ukazom: `install.packages(c('tidyverse', 'tidymodels', 'DataExplorer', 'summarytools', 'plotly', 'paletteer', 'corrplot', 'patchwork'))`\n",
"\n",
"Alternativno spodnji skript preveri, ali imate potrebne pakete za dokončanje tega modula, in jih namesti, če manjkajo.\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": [
"## Naloga - razvrščanje podatkov v skupine\n",
"\n",
"Razvrščanje v skupine kot tehnika je močno podprto z ustrezno vizualizacijo, zato začnimo z vizualizacijo naših glasbenih podatkov. Ta naloga nam bo pomagala odločiti, katero metodo razvrščanja v skupine bi morali najučinkoviteje uporabiti glede na naravo teh podatkov.\n",
"\n",
"Začnimo z uvozom podatkov.\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": [
"Včasih si želimo pridobiti malo več informacij o naših podatkih. Podatke in njihovo strukturo si lahko ogledamo z uporabo funkcije [*glimpse()*](https://pillar.r-lib.org/reference/glimpse.html):\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": [
"Odlično delo!💪\n",
"\n",
"Opazimo lahko, da `glimpse()` prikaže skupno število vrstic (opazovanj) in stolpcev (spremenljivk), nato pa prvih nekaj vnosov vsake spremenljivke v vrstici za imenom spremenljivke. Poleg tega je *tip podatkov* spremenljivke prikazan takoj za imenom spremenljivke znotraj `< >`.\n",
"\n",
"`DataExplorer::introduce()` lahko to informacijo povzame na urejen način:\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": [
"Odlično! Pravkar smo ugotovili, da naši podatki nimajo manjkajočih vrednosti.\n",
"\n",
"Medtem lahko raziščemo pogoste statistike centralne tendence (npr. [povprečje](https://en.wikipedia.org/wiki/Arithmetic_mean) in [mediano](https://en.wikipedia.org/wiki/Median)) ter mere razpršenosti (npr. [standardni odklon](https://en.wikipedia.org/wiki/Standard_deviation)) z uporabo `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": [
"Poglejmo splošne vrednosti podatkov. Upoštevajte, da lahko priljubljenost znaša `0`, kar pomeni pesmi, ki nimajo uvrstitve. Te bomo kmalu odstranili.\n",
"\n",
"> 🤔 Če delamo s gručenjem, nenadzorovano metodo, ki ne zahteva označenih podatkov, zakaj prikazujemo te podatke z oznakami? V fazi raziskovanja podatkov so koristni, vendar niso nujni za delovanje algoritmov za gručenje.\n",
"\n",
"### 1. Raziskovanje priljubljenih žanrov\n",
"\n",
"Pojdimo naprej in ugotovimo najbolj priljubljene žanre 🎶 tako, da preštejemo, kolikokrat se pojavijo.\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": [
"To je šlo dobro! Pravijo, da slika pove več kot tisoč vrstic podatkovnega okvira (pravzaprav tega nihče nikoli ne reče 😅). Ampak razumete bistvo, kajne?\n",
"\n",
"Eden od načinov za vizualizacijo kategorijskih podatkov (znakovnih ali faktorskih spremenljivk) je uporaba stolpčnih grafov. Naredimo stolpčni graf za 10 najbolj priljubljenih žanrov:\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": [
"Zdaj je veliko lažje prepoznati, da imamo `manjkajoče` žanre 🧐!\n",
"\n",
"> Dobra vizualizacija vam bo pokazala stvari, ki jih niste pričakovali, ali pa sprožila nova vprašanja o podatkih - Hadley Wickham in Garrett Grolemund, [R For Data Science](https://r4ds.had.co.nz/introduction.html)\n",
"\n",
"Opomba: ko je glavni žanr opisan kot `Manjkajoč`, to pomeni, da ga Spotify ni klasificiral, zato ga odstranimo.\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": [
"Iz osnovnega raziskovanja podatkov ugotovimo, da tri najbolj priljubljene zvrsti prevladujejo v tem naboru podatkov. Osredotočimo se na `afro dancehall`, `afropop` in `nigerian pop`, poleg tega pa filtrirajmo nabor podatkov, da odstranimo vse, kar ima vrednost priljubljenosti 0 (kar pomeni, da ni bilo razvrščeno glede na priljubljenost v naboru podatkov in se lahko za naše namene šteje kot šum):\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": [
"Poglejmo, ali obstaja kakšna očitna linearna povezava med številskimi spremenljivkami v našem naboru podatkov. To povezavo matematično kvantificira [statistika korelacije](https://en.wikipedia.org/wiki/Correlation).\n",
"\n",
"Statistika korelacije je vrednost med -1 in 1, ki kaže na moč povezave. Vrednosti nad 0 kažejo na *pozitivno* korelacijo (visoke vrednosti ene spremenljivke običajno sovpadajo z visokimi vrednostmi druge), medtem ko vrednosti pod 0 kažejo na *negativno* korelacijo (visoke vrednosti ene spremenljivke običajno sovpadajo z nizkimi vrednostmi druge).\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": [
"Podatki niso močno povezani, razen med `energy` in `loudness`, kar je smiselno, saj je glasna glasba običajno precej energična. `Popularity` ima povezavo z `release date`, kar prav tako ni presenetljivo, saj so novejše pesmi verjetno bolj priljubljene. Dolžina in energija se zdita tudi povezani.\n",
"\n",
"Zanimivo bo videti, kaj lahko algoritem za razvrščanje naredi s temi podatki!\n",
"\n",
"> 🎓 Upoštevajte, da korelacija ne pomeni vzročne povezanosti! Imamo dokaz o korelaciji, vendar nimamo dokaza o vzročnosti. [Zabavna spletna stran](https://tylervigen.com/spurious-correlations) ponuja nekaj vizualizacij, ki poudarjajo to točko.\n",
"\n",
"### 2. Raziskovanje porazdelitve podatkov\n",
"\n",
"Postavimo si nekaj bolj subtilnih vprašanj. Ali se žanri bistveno razlikujejo v zaznavanju njihove plesnosti glede na njihovo priljubljenost? Preučimo porazdelitev podatkov naših treh najbolj priljubljenih žanrov glede priljubljenosti in plesnosti vzdolž določene osi x in y z uporabo [gostotnih grafov](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": [
"Vidimo, da so tu koncentrični krogi, ki se ujemajo, ne glede na žanr. Ali je mogoče, da se nigerijski okusi pri tem žanru zbližajo na določeni ravni plesnosti?\n",
"\n",
"Na splošno se trije žanri ujemajo glede na svojo priljubljenost in plesnost. Določanje skupkov v teh ohlapno poravnanih podatkih bo izziv. Poglejmo, ali lahko raztreseni diagram to podpre.\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": [
"Razpršeni diagram istih osi prikazuje podoben vzorec konvergence.\n",
"\n",
"Na splošno lahko za razvrščanje uporabite razpršene diagrame, da prikažete skupine podatkov, zato je obvladovanje te vrste vizualizacije zelo koristno. V naslednji lekciji bomo uporabili te filtrirane podatke in s k-means razvrščanjem odkrili skupine v teh podatkih, ki se na zanimive načine prekrivajo.\n",
"\n",
"## **🚀 Izziv**\n",
"\n",
"V pripravi na naslednjo lekcijo naredite diagram o različnih algoritmih za razvrščanje, ki jih morda odkrijete in uporabite v produkcijskem okolju. Kakšne vrste težav poskuša razvrščanje rešiti?\n",
"\n",
"## [**Kvizi po predavanju**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/28/)\n",
"\n",
"## **Pregled & Samostojno učenje**\n",
"\n",
"Preden uporabite algoritme za razvrščanje, kot smo se naučili, je dobro razumeti naravo vašega nabora podatkov. Več o tej temi preberite [tukaj](https://www.kdnuggets.com/2019/10/right-clustering-algorithm.html).\n",
"\n",
"Poglobite svoje razumevanje tehnik razvrščanja:\n",
"\n",
"- [Usposabljanje in ocenjevanje modelov za razvrščanje z uporabo Tidymodels in prijateljev](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",
"## **Naloga**\n",
"\n",
"[Raziskujte druge vizualizacije za razvrščanje](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/assignment.md)\n",
"\n",
"## HVALA:\n",
"\n",
"[Jen Looper](https://www.twitter.com/jenlooper) za ustvarjanje izvirne Python različice tega modula ♥️\n",
"\n",
"[`Dasani Madipalli`](https://twitter.com/dasani_decoded) za ustvarjanje neverjetnih ilustracij, ki omogočajo boljše razumevanje konceptov strojnega učenja in jih naredijo bolj dostopne.\n",
"\n",
"Veselo učenje,\n",
"\n",
"[Eric](https://twitter.com/ericntay), Gold Microsoft Learn Student Ambassador.\n"
],
"metadata": {}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\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-06T14:12:22+00:00",
"source_file": "5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 1
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,640 @@
{
"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-06T14:25:26+00:00",
"source_file": "5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb",
"language_code": "sl"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "GULATlQXLXyR"
},
"source": [
"## Raziskovanje gručenja K-Means z uporabo R in načel urejenih podatkov.\n",
"\n",
"### [**Predhodni kviz**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/29/)\n",
"\n",
"V tej lekciji se boste naučili, kako ustvariti gruče z uporabo paketa Tidymodels in drugih paketov v ekosistemu R (imenovali jih bomo prijatelji 🧑‍🤝‍🧑) ter nigerijskega glasbenega nabora podatkov, ki ste ga uvozili prej. Pokrili bomo osnove K-Means za gručenje. Upoštevajte, da, kot ste se naučili v prejšnji lekciji, obstaja veliko načinov za delo z gručenjem, metoda, ki jo uporabite, pa je odvisna od vaših podatkov. Poskusili bomo K-Means, saj je to najpogostejša tehnika gručenja. Začnimo!\n",
"\n",
"Pojmi, o katerih se boste učili:\n",
"\n",
"- Silhuetno ocenjevanje\n",
"\n",
"- Metoda komolca\n",
"\n",
"- Inercija\n",
"\n",
"- Varianca\n",
"\n",
"### **Uvod**\n",
"\n",
"[K-Means gručenje](https://wikipedia.org/wiki/K-means_clustering) je metoda, ki izhaja iz področja obdelave signalov. Uporablja se za razdelitev in razvrščanje skupin podatkov v `k gruče` na podlagi podobnosti njihovih značilnosti.\n",
"\n",
"Gruče je mogoče vizualizirati kot [Voronoijeve diagrame](https://wikipedia.org/wiki/Voronoi_diagram), ki vključujejo točko (ali 'seme') in njeno ustrezno regijo.\n",
"\n",
"<p >\n",
" <img src=\"../../images/voronoi.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Infografika avtorice Jen Looper</figcaption>\n",
"\n",
"\n",
"Postopek K-Means gručenja vključuje naslednje korake:\n",
"\n",
"1. Podatkovni znanstvenik najprej določi želeno število gruč, ki jih želi ustvariti.\n",
"\n",
"2. Nato algoritem naključno izbere K opazovanj iz nabora podatkov, ki služijo kot začetna središča gruč (tj. centroidi).\n",
"\n",
"3. Nato se vsako preostalo opazovanje dodeli najbližjemu centroidu.\n",
"\n",
"4. Nato se izračunajo nove povprečne vrednosti vsake grupe, centroid pa se premakne na povprečje.\n",
"\n",
"5. Ko so središča ponovno izračunana, se vsako opazovanje ponovno preveri, ali bi lahko bilo bližje drugi gruč. Vsa opazovanja se ponovno prerazporedijo z uporabo posodobljenih povprečnih vrednosti gruč. Koraki dodeljevanja gruč in posodabljanja centroidov se ponavljajo, dokler se dodelitve gruč ne prenehajo spreminjati (tj. ko je dosežena konvergenca). Algoritem se običajno ustavi, ko vsaka nova iteracija povzroči zanemarljivo premikanje centroidov in gruče postanejo statične.\n",
"\n",
"<div>\n",
"\n",
"> Upoštevajte, da zaradi naključnosti začetnih k opazovanj, ki se uporabljajo kot začetni centroidi, lahko dobimo nekoliko različne rezultate vsakič, ko uporabimo postopek. Zaradi tega večina algoritmov uporablja več *naključnih začetkov* in izbere iteracijo z najnižjim WCSS. Zato je močno priporočljivo, da K-Means vedno izvajate z več vrednostmi *nstart*, da se izognete *nezaželenemu lokalnemu optimumu.*\n",
"\n",
"</div>\n",
"\n",
"Ta kratka animacija z uporabo [ilustracij](https://github.com/allisonhorst/stats-illustrations) Allison Horst pojasnjuje postopek gručenja:\n",
"\n",
"<p >\n",
" <img src=\"../../images/kmeans.gif\"\n",
" width=\"550\"/>\n",
" <figcaption>Ilustracija avtorice @allison_horst</figcaption>\n",
"\n",
"\n",
"\n",
"Osnovno vprašanje, ki se pojavi pri gručenju, je naslednje: kako veste, na koliko gruč razdeliti svoje podatke? Ena od pomanjkljivosti uporabe K-Means je dejstvo, da morate določiti `k`, torej število `centroidov`. Na srečo metoda `komolca` pomaga oceniti dobro začetno vrednost za `k`. Kmalu jo boste preizkusili.\n",
"\n",
"### \n",
"\n",
"**Predpogoj**\n",
"\n",
"Nadaljevali bomo tam, kjer smo končali v [prejšnji lekciji](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb), kjer smo analizirali nabor podatkov, ustvarili veliko vizualizacij in filtrirali nabor podatkov na zanimiva opazovanja. Prepričajte se, da si jo ogledate!\n",
"\n",
"Za dokončanje tega modula bomo potrebovali nekaj paketov. Namestite jih lahko z ukazom: `install.packages(c('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork'))`\n",
"\n",
"Alternativno spodnji skript preveri, ali imate potrebne pakete za dokončanje tega modula, in jih namesti, če manjkajo.\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": [
"Začnimo!\n",
"\n",
"## 1. Ples s podatki: Omejimo se na 3 najbolj priljubljene glasbene zvrsti\n",
"\n",
"To je povzetek tega, kar smo naredili v prejšnji lekciji. Razčlenimo in analizirajmo nekaj podatkov!\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": [
"🤩 To je šlo odlično!\n",
"\n",
"## 2. Več raziskovanja podatkov.\n",
"\n",
"Kako čisti so ti podatki? Preverimo izstopajoče vrednosti z uporabo škatelnih diagramov. Osredotočili se bomo na številske stolpce z manj izstopajočimi vrednostmi (čeprav bi lahko odstranili izstopajoče vrednosti). Škatelni diagrami lahko pokažejo razpon podatkov in pomagajo pri izbiri, katere stolpce uporabiti. Upoštevajte, da škatelni diagrami ne prikazujejo variance, kar je pomemben element za dobro združljive podatke. Za več informacij si oglejte [to razpravo](https://stats.stackexchange.com/questions/91536/deduce-variance-from-boxplot).\n",
"\n",
"[Škatelni diagrami](https://en.wikipedia.org/wiki/Box_plot) se uporabljajo za grafično prikazovanje porazdelitve `številskih` podatkov, zato začnimo z *izbiro* vseh številskih stolpcev skupaj s priljubljenimi glasbenimi žanri.\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": [
"Opazite, kako funkcija za izbiro `where` to olajša 💁? Raziščite še druge podobne funkcije [tukaj](https://tidyselect.r-lib.org/).\n",
"\n",
"Ker bomo izdelali škatlaste diagrame za vsako številsko značilnost in se želimo izogniti uporabi zank, bomo preoblikovali naše podatke v *daljšo* obliko, ki nam bo omogočila uporabo `facets` - podgrafov, ki vsak prikazujejo en podnabor podatkov.\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": [
"Zdaj pa nekaj daljšega! Čas je za nekaj `ggplotov`! Kateri `geom` bomo uporabili?\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": [
"Zdaj lahko vidimo, da so ti podatki nekoliko hrupni: če opazujemo vsak stolpec kot škatelni diagram, lahko vidimo odstopajoče vrednosti. Lahko bi pregledali podatkovni niz in odstranili te odstopajoče vrednosti, vendar bi to podatke precej zmanjšalo.\n",
"\n",
"Zaenkrat izberimo, katere stolpce bomo uporabili za našo nalogo gručenja. Izberimo številske stolpce s podobnimi razponi. Stolpec `artist_top_genre` bi lahko kodirali kot številskega, vendar ga bomo za zdaj izpustili.\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. Izračun k-means gručenja v R\n",
"\n",
"K-means lahko izračunamo v R z vgrajeno funkcijo `kmeans`, glejte `help(\"kmeans()\")`. Funkcija `kmeans()` sprejme podatkovni okvir z vsemi številsko izraženimi stolpci kot svoj primarni argument.\n",
"\n",
"Prvi korak pri uporabi k-means gručenja je določitev števila gručenj (k), ki bodo ustvarjene v končni rešitvi. Vemo, da obstajajo 3 glasbeni žanri, ki smo jih izluščili iz nabora podatkov, zato poskusimo s 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 objekt vsebuje več informacij, ki so dobro razložene v `help(\"kmeans()\")`. Za zdaj se osredotočimo na nekaj ključnih točk. Vidimo, da so podatki razdeljeni v 3 skupine velikosti 65, 110, 111. Rezultat prav tako vsebuje središča skupin (povprečja) za 3 skupine glede na 5 spremenljivk.\n",
"\n",
"Vektor razvrščanja predstavlja dodelitev skupine za vsako opazovanje. Uporabimo funkcijo `augment`, da dodamo dodelitev skupine v originalni nabor podatkov.\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": [
"Odlično, pravkar smo razdelili naš nabor podatkov v 3 skupine. Kako dobra je torej naša razvrstitev 🤷? Poglejmo si `Silhouette score`.\n",
"\n",
"### **Silhouette score**\n",
"\n",
"[Silhouette analiza](https://en.wikipedia.org/wiki/Silhouette_(clustering)) se lahko uporabi za preučevanje razdalje med nastalimi grozdi. Ta ocena se giblje od -1 do 1, pri čemer vrednost blizu 1 pomeni, da je grozd gost in dobro ločen od drugih grozdov. Vrednost blizu 0 predstavlja prekrivajoče se grozde, kjer so vzorci zelo blizu odločitveni meji sosednjih grozdov. [vir](https://dzone.com/articles/kmeans-silhouette-score-explained-with-python-exam).\n",
"\n",
"Metoda povprečnega silhouette izračuna povprečno silhouette opazovanj za različne vrednosti *k*. Visoka povprečna silhouette ocena kaže na dobro razvrstitev.\n",
"\n",
"Funkcija `silhouette` v paketu za razvrščanje omogoča izračun povprečne širine silhouette.\n",
"\n",
"> Silhouette se lahko izračuna z uporabo katere koli [razdalje](https://en.wikipedia.org/wiki/Distance \"Distance\"), kot sta [Evklidska razdalja](https://en.wikipedia.org/wiki/Euclidean_distance \"Euclidean distance\") ali [Manhattanska razdalja](https://en.wikipedia.org/wiki/Manhattan_distance \"Manhattan distance\"), ki smo ju obravnavali v [prejšnji lekciji](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": [
"Naš rezultat je **.549**, kar pomeni, da smo nekje na sredini. To kaže, da naši podatki niso posebej primerni za tovrstno razvrščanje v skupine. Poglejmo, ali lahko to domnevo vizualno potrdimo. Paket [factoextra](https://rpkgs.datanovia.com/factoextra/index.html) ponuja funkcije (`fviz_cluster()`), ki omogočajo vizualizacijo razvrščanja v skupine.\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": [
"Prekrivanje med grozdi kaže, da naši podatki niso posebej primerni za to vrsto grozdenja, vendar nadaljujmo.\n",
"\n",
"## 4. Določanje optimalnega števila grozdov\n",
"\n",
"Osnovno vprašanje, ki se pogosto pojavi pri K-Means grozdenju, je naslednje - brez znanih oznak razredov, kako veste, na koliko grozdov razdeliti svoje podatke?\n",
"\n",
"Eden od načinov, kako to ugotoviti, je uporaba vzorca podatkov za `ustvarjanje serije modelov grozdenja` z naraščajočim številom grozdov (npr. od 1 do 10) in ocenjevanje metrik grozdenja, kot je **Silhouette score.**\n",
"\n",
"Določimo optimalno število grozdov tako, da izvedemo algoritem grozdenja za različne vrednosti *k* in ocenimo **vsoto kvadratov znotraj grozda** (WCSS). Skupna vsota kvadratov znotraj grozda (WCSS) meri kompaktnost grozdenja, pri čemer želimo, da je čim manjša, saj nižje vrednosti pomenijo, da so podatkovne točke bližje skupaj.\n",
"\n",
"Raziskujmo učinek različnih izbir `k`, od 1 do 10, na to grozdenje.\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": [
"Zdaj, ko imamo skupno vsoto kvadratov znotraj grozdov (tot.withinss) za vsak algoritem grozdenja s središčem *k*, uporabimo [metodo komolca](https://en.wikipedia.org/wiki/Elbow_method_(clustering)), da najdemo optimalno število grozdov. Metoda vključuje risanje WCSS kot funkcije števila grozdov in izbiro [komolca krivulje](https://en.wikipedia.org/wiki/Elbow_of_the_curve \"Elbow of the curve\") kot števila grozdov, ki jih uporabimo.\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": [
"Graf prikazuje veliko zmanjšanje WCSS (torej večjo *kompaktnost*), ko se število grozdov poveča z enega na dva, in nadaljnje opazno zmanjšanje z dveh na tri grozde. Po tem je zmanjšanje manj izrazito, kar povzroči `komolec` 💪 na grafu pri približno treh grozdih. To je dober pokazatelj, da obstajata dva do trije razmeroma dobro ločeni grozdi podatkovnih točk.\n",
"\n",
"Zdaj lahko nadaljujemo in izluščimo model grozdenja, kjer je `k = 3`:\n",
"\n",
"> `pull()`: uporablja se za izvlečenje ene same kolone\n",
">\n",
"> `pluck()`: uporablja se za indeksiranje podatkovnih struktur, kot so seznami\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": [
"Odlično! Poglejmo si pridobljene grozde. Vas zanima nekaj interaktivnosti z uporabo `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": [
"Morda bi pričakovali, da bo imel vsak grozd (predstavljen z različnimi barvami) različne žanre (predstavljene z različnimi oblikami).\n",
"\n",
"Poglejmo natančnost modela.\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": [
"Točnost tega modela ni slaba, vendar ni odlična. Morda podatki niso primerni za K-Means razvrščanje. Ti podatki so preveč neuravnoteženi, premalo povezani in med vrednostmi stolpcev je preveč variance, da bi jih lahko dobro razvrstili. Pravzaprav so skupine, ki se oblikujejo, verjetno močno vplivane ali izkrivljene zaradi treh kategorij žanrov, ki smo jih opredelili zgoraj.\n",
"\n",
"Kljub temu je bil to precej poučen proces!\n",
"\n",
"V dokumentaciji Scikit-learn lahko vidite, da ima model, kot je ta, pri katerem skupine niso dobro opredeljene, težavo z 'varianco':\n",
"\n",
"<p >\n",
" <img src=\"../../images/problems.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Infografika iz Scikit-learn</figcaption>\n",
"\n",
"\n",
"\n",
"## **Varianca**\n",
"\n",
"Varianca je opredeljena kot \"povprečje kvadratov razlik od povprečja\" [vir](https://www.mathsisfun.com/data/standard-deviation.html). V kontekstu te težave z razvrščanjem se nanaša na podatke, pri katerih se vrednosti našega nabora podatkov preveč oddaljujejo od povprečja.\n",
"\n",
"✅ To je odličen trenutek, da razmislite o vseh načinih, kako bi lahko odpravili to težavo. Bi lahko podatke še malo prilagodili? Uporabili različne stolpce? Uporabili drugačen algoritem? Namig: Poskusite [normalizirati podatke](https://www.mygreatlearning.com/blog/learning-data-science-with-k-means-clustering/) in preizkusiti druge stolpce.\n",
"\n",
"> Poskusite '[kalkulator variance](https://www.calculatorsoup.com/calculators/statistics/variance-calculator.php)', da bolje razumete koncept.\n",
"\n",
"------------------------------------------------------------------------\n",
"\n",
"## **🚀Izziv**\n",
"\n",
"Preživite nekaj časa s tem zvezkom in prilagodite parametre. Ali lahko izboljšate natančnost modela z dodatnim čiščenjem podatkov (na primer odstranjevanjem odstopanj)? Lahko uporabite uteži, da nekaterim vzorcem podatkov dodelite večjo težo. Kaj še lahko storite, da ustvarite boljše skupine?\n",
"\n",
"Namig: Poskusite normalizirati podatke. V zvezku je komentirana koda, ki dodaja standardno normalizacijo, da se stolpci podatkov bolj približajo drug drugemu glede na obseg. Ugotovili boste, da se medtem ko se silhuetni rezultat zniža, 'pregib' na grafu komolca zgladi. To je zato, ker nenormalizirani podatki omogočajo, da podatki z manjšo varianco nosijo večjo težo. Preberite več o tej težavi [tukaj](https://stats.stackexchange.com/questions/21222/are-mean-normalization-and-feature-scaling-needed-for-k-means-clustering/21226#21226).\n",
"\n",
"## [**Kvizi po predavanju**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/30/)\n",
"\n",
"## **Pregled in samostojno učenje**\n",
"\n",
"- Oglejte si simulator K-Means [kot je ta](https://user.ceng.metu.edu.tr/~akifakkus/courses/ceng574/k-means/). S tem orodjem lahko vizualizirate vzorčne podatkovne točke in določite njihove centroidne točke. Lahko urejate naključnost podatkov, število skupin in število centroidov. Ali vam to pomaga pridobiti idejo, kako se podatki lahko razvrstijo?\n",
"\n",
"- Prav tako si oglejte [ta priročnik o K-Means](https://stanford.edu/~cpiech/cs221/handouts/kmeans.html) iz Stanforda.\n",
"\n",
"Želite preizkusiti svoje novo pridobljene veščine razvrščanja na naborih podatkov, ki so primerni za K-Means razvrščanje? Oglejte si:\n",
"\n",
"- [Usposabljanje in ocenjevanje modelov razvrščanja](https://rpubs.com/eR_ic/clustering) z uporabo Tidymodels in podobnih orodij\n",
"\n",
"- [Analiza skupin K-Means](https://uc-r.github.io/kmeans_clustering), UC Business Analytics R Programming Guide\n",
"\n",
"- [K-Means razvrščanje z načeli urejenih podatkov](https://www.tidymodels.org/learn/statistics/k-means/)\n",
"\n",
"## **Naloga**\n",
"\n",
"[Preizkusite različne metode razvrščanja](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/2-K-Means/assignment.md)\n",
"\n",
"## HVALA:\n",
"\n",
"[Jen Looper](https://www.twitter.com/jenlooper) za ustvarjanje izvirne Python različice tega modula ♥️\n",
"\n",
"[`Allison Horst`](https://twitter.com/allison_horst/) za ustvarjanje čudovitih ilustracij, ki naredijo R bolj prijazen in privlačen. Več ilustracij najdete v njeni [galeriji](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n",
"\n",
"Veselo učenje,\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>Umetniško delo @allison_horst</figcaption>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
]
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,100 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": 3
},
"orig_nbformat": 4,
"coopTranslator": {
"original_hash": "27de2abc0235ebd22080fc8f1107454d",
"translation_date": "2025-09-06T15:22:07+00:00",
"source_file": "6-NLP/3-Translation-Sentiment/solution/notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from textblob import TextBlob\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# You should download the book text, clean it, and import it here\n",
"with open(\"pride.txt\", encoding=\"utf8\") as f:\n",
" file_contents = f.read()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"book_pride = TextBlob(file_contents)\n",
"positive_sentiment_sentences = []\n",
"negative_sentiment_sentences = []"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for sentence in book_pride.sentences:\n",
" if sentence.sentiment.polarity == 1:\n",
" positive_sentiment_sentences.append(sentence)\n",
" if sentence.sentiment.polarity == -1:\n",
" negative_sentiment_sentences.append(sentence)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"The \" + str(len(positive_sentiment_sentences)) + \" most positive sentences:\")\n",
"for sentence in positive_sentiment_sentences:\n",
" print(\"+ \" + str(sentence.replace(\"\\n\", \"\").replace(\" \", \" \")))\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"The \" + str(len(negative_sentiment_sentences)) + \" most negative sentences:\")\n",
"for sentence in negative_sentiment_sentences:\n",
" print(\"- \" + str(sentence.replace(\"\\n\", \"\").replace(\" \", \" \")))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za prevajanje z umetno inteligenco [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem maternem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo profesionalni človeški prevod. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki bi nastale zaradi uporabe tega prevoda.\n"
]
}
]
}

@ -0,0 +1,174 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": 3
},
"orig_nbformat": 4,
"coopTranslator": {
"original_hash": "2d05e7db439376aa824f4b387f8324ca",
"translation_date": "2025-09-06T15:21:47+00:00",
"source_file": "6-NLP/4-Hotel-Reviews-1/solution/notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# EDA\n",
"import pandas as pd\n",
"import time"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def get_difference_review_avg(row):\n",
" return row[\"Average_Score\"] - row[\"Calc_Average_Score\"]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Load the hotel reviews from CSV\n",
"print(\"Loading data file now, this could take a while depending on file size\")\n",
"start = time.time()\n",
"df = pd.read_csv('../../data/Hotel_Reviews.csv')\n",
"end = time.time()\n",
"print(\"Loading took \" + str(round(end - start, 2)) + \" seconds\")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# What shape is the data (rows, columns)?\n",
"print(\"The shape of the data (rows, cols) is \" + str(df.shape))\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# value_counts() creates a Series object that has index and values\n",
"# in this case, the country and the frequency they occur in reviewer nationality\n",
"nationality_freq = df[\"Reviewer_Nationality\"].value_counts()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# What reviewer nationality is the most common in the dataset?\n",
"print(\"The highest frequency reviewer nationality is \" + str(nationality_freq.index[0]).strip() + \" with \" + str(nationality_freq[0]) + \" reviews.\")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# What is the top 10 most common nationalities and their frequencies?\n",
"print(\"The top 10 highest frequency reviewer nationalities are:\")\n",
"print(nationality_freq[0:10].to_string())\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# How many unique nationalities are there?\n",
"print(\"There are \" + str(nationality_freq.index.size) + \" unique nationalities in the dataset\")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# What was the most frequently reviewed hotel for the top 10 nationalities - print the hotel and number of reviews\n",
"for nat in nationality_freq[:10].index:\n",
" # First, extract all the rows that match the criteria into a new dataframe\n",
" nat_df = df[df[\"Reviewer_Nationality\"] == nat] \n",
" # Now get the hotel freq\n",
" freq = nat_df[\"Hotel_Name\"].value_counts()\n",
" print(\"The most reviewed hotel for \" + str(nat).strip() + \" was \" + str(freq.index[0]) + \" with \" + str(freq[0]) + \" reviews.\") \n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# How many reviews are there per hotel (frequency count of hotel) and do the results match the value in `Total_Number_of_Reviews`?\n",
"# First create a new dataframe based on the old one, removing the uneeded columns\n",
"hotel_freq_df = df.drop([\"Hotel_Address\", \"Additional_Number_of_Scoring\", \"Review_Date\", \"Average_Score\", \"Reviewer_Nationality\", \"Negative_Review\", \"Review_Total_Negative_Word_Counts\", \"Positive_Review\", \"Review_Total_Positive_Word_Counts\", \"Total_Number_of_Reviews_Reviewer_Has_Given\", \"Reviewer_Score\", \"Tags\", \"days_since_review\", \"lat\", \"lng\"], axis = 1)\n",
"# Group the rows by Hotel_Name, count them and put the result in a new column Total_Reviews_Found\n",
"hotel_freq_df['Total_Reviews_Found'] = hotel_freq_df.groupby('Hotel_Name').transform('count')\n",
"# Get rid of all the duplicated rows\n",
"hotel_freq_df = hotel_freq_df.drop_duplicates(subset = [\"Hotel_Name\"])\n",
"print()\n",
"print(hotel_freq_df.to_string())\n",
"print(str(hotel_freq_df.shape))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# While there is an `Average_Score` for each hotel according to the dataset, \n",
"# you can also calculate an average score (getting the average of all reviewer scores in the dataset for each hotel)\n",
"# Add a new column to your dataframe with the column header `Calc_Average_Score` that contains that calculated average. \n",
"df['Calc_Average_Score'] = round(df.groupby('Hotel_Name').Reviewer_Score.transform('mean'), 1)\n",
"# Add a new column with the difference between the two average scores\n",
"df[\"Average_Score_Difference\"] = df.apply(get_difference_review_avg, axis = 1)\n",
"# Create a df without all the duplicates of Hotel_Name (so only 1 row per hotel)\n",
"review_scores_df = df.drop_duplicates(subset = [\"Hotel_Name\"])\n",
"# Sort the dataframe to find the lowest and highest average score difference\n",
"review_scores_df = review_scores_df.sort_values(by=[\"Average_Score_Difference\"])\n",
"print(review_scores_df[[\"Average_Score_Difference\", \"Average_Score\", \"Calc_Average_Score\", \"Hotel_Name\"]])\n",
"# Do any hotels have the same (rounded to 1 decimal place) `Average_Score` and `Calc_Average_Score`?\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za prevajanje z umetno inteligenco [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem maternem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo profesionalni človeški prevod. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki bi nastale zaradi uporabe tega prevoda.\n"
]
}
]
}

@ -0,0 +1,172 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"orig_nbformat": 4,
"kernelspec": {
"name": "python3",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
},
"coopTranslator": {
"original_hash": "033cb89c85500224b3c63fd04f49b4aa",
"translation_date": "2025-09-06T15:22:29+00:00",
"source_file": "6-NLP/5-Hotel-Reviews-2/solution/1-notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import time\n",
"import ast"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"def replace_address(row):\n",
" if \"Netherlands\" in row[\"Hotel_Address\"]:\n",
" return \"Amsterdam, Netherlands\"\n",
" elif \"Barcelona\" in row[\"Hotel_Address\"]:\n",
" return \"Barcelona, Spain\"\n",
" elif \"United Kingdom\" in row[\"Hotel_Address\"]:\n",
" return \"London, United Kingdom\"\n",
" elif \"Milan\" in row[\"Hotel_Address\"]: \n",
" return \"Milan, Italy\"\n",
" elif \"France\" in row[\"Hotel_Address\"]:\n",
" return \"Paris, France\"\n",
" elif \"Vienna\" in row[\"Hotel_Address\"]:\n",
" return \"Vienna, Austria\" \n",
" else:\n",
" return row.Hotel_Address\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# Load the hotel reviews from CSV\n",
"start = time.time()\n",
"df = pd.read_csv('../../data/Hotel_Reviews.csv')\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# dropping columns we will not use:\n",
"df.drop([\"lat\", \"lng\"], axis = 1, inplace=True)\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# Replace all the addresses with a shortened, more useful form\n",
"df[\"Hotel_Address\"] = df.apply(replace_address, axis = 1)\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"# Drop `Additional_Number_of_Scoring`\n",
"df.drop([\"Additional_Number_of_Scoring\"], axis = 1, inplace=True)\n",
"# Replace `Total_Number_of_Reviews` and `Average_Score` with our own calculated values\n",
"df.Total_Number_of_Reviews = df.groupby('Hotel_Name').transform('count')\n",
"df.Average_Score = round(df.groupby('Hotel_Name').Reviewer_Score.transform('mean'), 1)\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"# Process the Tags into new columns\n",
"# The file Hotel_Reviews_Tags.py, identifies the most important tags\n",
"# Leisure trip, Couple, Solo traveler, Business trip, Group combined with Travelers with friends, \n",
"# Family with young children, Family with older children, With a pet\n",
"df[\"Leisure_trip\"] = df.Tags.apply(lambda tag: 1 if \"Leisure trip\" in tag else 0)\n",
"df[\"Couple\"] = df.Tags.apply(lambda tag: 1 if \"Couple\" in tag else 0)\n",
"df[\"Solo_traveler\"] = df.Tags.apply(lambda tag: 1 if \"Solo traveler\" in tag else 0)\n",
"df[\"Business_trip\"] = df.Tags.apply(lambda tag: 1 if \"Business trip\" in tag else 0)\n",
"df[\"Group\"] = df.Tags.apply(lambda tag: 1 if \"Group\" in tag or \"Travelers with friends\" in tag else 0)\n",
"df[\"Family_with_young_children\"] = df.Tags.apply(lambda tag: 1 if \"Family with young children\" in tag else 0)\n",
"df[\"Family_with_older_children\"] = df.Tags.apply(lambda tag: 1 if \"Family with older children\" in tag else 0)\n",
"df[\"With_a_pet\"] = df.Tags.apply(lambda tag: 1 if \"With a pet\" in tag else 0)\n"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"# No longer need any of these columns\n",
"df.drop([\"Review_Date\", \"Review_Total_Negative_Word_Counts\", \"Review_Total_Positive_Word_Counts\", \"days_since_review\", \"Total_Number_of_Reviews_Reviewer_Has_Given\"], axis = 1, inplace=True)\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Saving results to Hotel_Reviews_Filtered.csv\n",
"Filtering took 23.74 seconds\n"
]
}
],
"source": [
"# Saving new data file with calculated columns\n",
"print(\"Saving results to Hotel_Reviews_Filtered.csv\")\n",
"df.to_csv(r'../../data/Hotel_Reviews_Filtered.csv', index = False)\n",
"end = time.time()\n",
"print(\"Filtering took \" + str(round(end - start, 2)) + \" seconds\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za prevajanje z umetno inteligenco [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem maternem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo profesionalni človeški prevod. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki bi nastale zaradi uporabe tega prevoda.\n"
]
}
]
}

@ -0,0 +1,137 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"orig_nbformat": 4,
"kernelspec": {
"name": "python3",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
},
"coopTranslator": {
"original_hash": "341efc86325ec2a214f682f57a189dfd",
"translation_date": "2025-09-06T15:22:50+00:00",
"source_file": "6-NLP/5-Hotel-Reviews-2/solution/2-notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# Load the hotel reviews from CSV (you can )\n",
"import pandas as pd \n",
"\n",
"df = pd.read_csv('../../data/Hotel_Reviews_Filtered.csv')\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# We want to find the most useful tags to keep\n",
"# Remove opening and closing brackets\n",
"df.Tags = df.Tags.str.strip(\"[']\")\n",
"# remove all quotes too\n",
"df.Tags = df.Tags.str.replace(\" ', '\", \",\", regex = False)\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"# removing this to take advantage of the 'already a phrase' fact of the dataset \n",
"# Now split the strings into a list\n",
"tag_list_df = df.Tags.str.split(',', expand = True)\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"# Remove leading and trailing spaces\n",
"df[\"Tag_1\"] = tag_list_df[0].str.strip()\n",
"df[\"Tag_2\"] = tag_list_df[1].str.strip()\n",
"df[\"Tag_3\"] = tag_list_df[2].str.strip()\n",
"df[\"Tag_4\"] = tag_list_df[3].str.strip()\n",
"df[\"Tag_5\"] = tag_list_df[4].str.strip()\n",
"df[\"Tag_6\"] = tag_list_df[5].str.strip()\n"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"# Merge the 6 columns into one with melt\n",
"df_tags = df.melt(value_vars=[\"Tag_1\", \"Tag_2\", \"Tag_3\", \"Tag_4\", \"Tag_5\", \"Tag_6\"])\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"The shape of the tags with no filtering: (2514684, 2)\n",
" index count\n",
"0 Leisure trip 338423\n",
"1 Couple 205305\n",
"2 Solo traveler 89779\n",
"3 Business trip 68176\n",
"4 Group 51593\n",
"5 Family with young children 49318\n",
"6 Family with older children 21509\n",
"7 Travelers with friends 1610\n",
"8 With a pet 1078\n"
]
}
],
"source": [
"# Get the value counts\n",
"tag_vc = df_tags.value.value_counts()\n",
"# print(tag_vc)\n",
"print(\"The shape of the tags with no filtering:\", str(df_tags.shape))\n",
"# Drop rooms, suites, and length of stay, mobile device and anything with less count than a 1000\n",
"df_tags = df_tags[~df_tags.value.str.contains(\"Standard|room|Stayed|device|Beds|Suite|Studio|King|Superior|Double\", na=False, case=False)]\n",
"tag_vc = df_tags.value.value_counts().reset_index(name=\"count\").query(\"count > 1000\")\n",
"# Print the top 10 (there should only be 9 and we'll use these in the filtering section)\n",
"print(tag_vc[:10])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za prevajanje z umetno inteligenco [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo profesionalni človeški prevod. Ne prevzemamo odgovornosti za morebitna napačna razumevanja ali napačne interpretacije, ki bi nastale zaradi uporabe tega prevoda.\n"
]
}
]
}

@ -0,0 +1,260 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"orig_nbformat": 4,
"kernelspec": {
"name": "python3",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
},
"coopTranslator": {
"original_hash": "705bf02633759f689abc37b19749a16d",
"translation_date": "2025-09-06T15:23:09+00:00",
"source_file": "6-NLP/5-Hotel-Reviews-2/solution/3-notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"[nltk_data] Downloading package vader_lexicon to\n[nltk_data] /Users/jenlooper/nltk_data...\n"
]
},
{
"output_type": "execute_result",
"data": {
"text/plain": [
"True"
]
},
"metadata": {},
"execution_count": 9
}
],
"source": [
"import time\n",
"import pandas as pd\n",
"import nltk as nltk\n",
"from nltk.corpus import stopwords\n",
"from nltk.sentiment.vader import SentimentIntensityAnalyzer\n",
"nltk.download('vader_lexicon')\n"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"vader_sentiment = SentimentIntensityAnalyzer()\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"# There are 3 possibilities of input for a review:\n",
"# It could be \"No Negative\", in which case, return 0\n",
"# It could be \"No Positive\", in which case, return 0\n",
"# It could be a review, in which case calculate the sentiment\n",
"def calc_sentiment(review): \n",
" if review == \"No Negative\" or review == \"No Positive\":\n",
" return 0\n",
" return vader_sentiment.polarity_scores(review)[\"compound\"] \n"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"# Load the hotel reviews from CSV\n",
"df = pd.read_csv(\"../../data/Hotel_Reviews_Filtered.csv\")\n"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"# Remove stop words - can be slow for a lot of text!\n",
"# Ryan Han (ryanxjhan on Kaggle) has a great post measuring performance of different stop words removal approaches\n",
"# https://www.kaggle.com/ryanxjhan/fast-stop-words-removal # using the approach that Ryan recommends\n",
"start = time.time()\n",
"cache = set(stopwords.words(\"english\"))\n",
"def remove_stopwords(review):\n",
" text = \" \".join([word for word in review.split() if word not in cache])\n",
" return text\n"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"# Remove the stop words from both columns\n",
"df.Negative_Review = df.Negative_Review.apply(remove_stopwords) \n",
"df.Positive_Review = df.Positive_Review.apply(remove_stopwords)\n"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Removing stop words took 5.77 seconds\n"
]
}
],
"source": [
"end = time.time()\n",
"print(\"Removing stop words took \" + str(round(end - start, 2)) + \" seconds\")\n"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Calculating sentiment columns for both positive and negative reviews\n",
"Calculating sentiment took 201.07 seconds\n"
]
}
],
"source": [
"# Add a negative sentiment and positive sentiment column\n",
"print(\"Calculating sentiment columns for both positive and negative reviews\")\n",
"start = time.time()\n",
"df[\"Negative_Sentiment\"] = df.Negative_Review.apply(calc_sentiment)\n",
"df[\"Positive_Sentiment\"] = df.Positive_Review.apply(calc_sentiment)\n",
"end = time.time()\n",
"print(\"Calculating sentiment took \" + str(round(end - start, 2)) + \" seconds\")\n"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
" Negative_Review Negative_Sentiment\n",
"186584 So bad experience memories I hotel The first n... -0.9920\n",
"129503 First charged twice room booked booking second... -0.9896\n",
"307286 The staff Had bad experience even booking Janu... -0.9889\n",
"452092 No WLAN room Incredibly rude restaurant staff ... -0.9884\n",
"201293 We usually traveling Paris 2 3 times year busi... -0.9873\n",
"... ... ...\n",
"26899 I would say however one night expensive even d... 0.9933\n",
"138365 Wifi terribly slow I speed test network upload... 0.9938\n",
"79215 I find anything hotel first I walked past hote... 0.9938\n",
"278506 The property great location There bakery next ... 0.9945\n",
"339189 Guys I like hotel I wish return next year Howe... 0.9948\n",
"\n",
"[515738 rows x 2 columns]\n",
" Positive_Review Positive_Sentiment\n",
"137893 Bathroom Shower We going stay twice hotel 2 ni... -0.9820\n",
"5839 I completely disappointed mad since reception ... -0.9780\n",
"64158 get everything extra internet parking breakfas... -0.9751\n",
"124178 I didnt like anythig Room small Asked upgrade ... -0.9721\n",
"489137 Very rude manager abusive staff reception Dirt... -0.9703\n",
"... ... ...\n",
"331570 Everything This recently renovated hotel class... 0.9984\n",
"322920 From moment stepped doors Guesthouse Hotel sta... 0.9985\n",
"293710 This place surprise expected good actually gre... 0.9985\n",
"417442 We celebrated wedding night Langham I commend ... 0.9985\n",
"132492 We arrived super cute boutique hotel area expl... 0.9987\n",
"\n",
"[515738 rows x 2 columns]\n"
]
}
],
"source": [
"df = df.sort_values(by=[\"Negative_Sentiment\"], ascending=True)\n",
"print(df[[\"Negative_Review\", \"Negative_Sentiment\"]])\n",
"df = df.sort_values(by=[\"Positive_Sentiment\"], ascending=True)\n",
"print(df[[\"Positive_Review\", \"Positive_Sentiment\"]])\n"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"# Reorder the columns (This is cosmetic, but to make it easier to explore the data later)\n",
"df = df.reindex([\"Hotel_Name\", \"Hotel_Address\", \"Total_Number_of_Reviews\", \"Average_Score\", \"Reviewer_Score\", \"Negative_Sentiment\", \"Positive_Sentiment\", \"Reviewer_Nationality\", \"Leisure_trip\", \"Couple\", \"Solo_traveler\", \"Business_trip\", \"Group\", \"Family_with_young_children\", \"Family_with_older_children\", \"With_a_pet\", \"Negative_Review\", \"Positive_Review\"], axis=1)\n"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Saving results to Hotel_Reviews_NLP.csv\n"
]
}
],
"source": [
"print(\"Saving results to Hotel_Reviews_NLP.csv\")\n",
"df.to_csv(r\"../../data/Hotel_Reviews_NLP.csv\", index = False)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za prevajanje z umetno inteligenco [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo profesionalni človeški prevod. Ne prevzemamo odgovornosti za morebitne nesporazume ali napačne razlage, ki bi nastale zaradi uporabe tega prevoda.\n"
]
}
]
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,63 @@
{
"cells": [
{
"source": [
"# Nastavitev podatkov\n",
"\n",
"V tem zvezku prikazujemo, kako:\n",
"\n",
"nastaviti podatke časovnih vrst za ta modul\n",
"vizualizirati podatke\n",
"Podatki v tem primeru so vzeti iz tekmovanja GEFCom2014 za napovedovanje. Vključujejo 3 leta urnih vrednosti porabe električne energije in temperature med letoma 2012 in 2014.\n",
"\n",
"1Tao Hong, Pierre Pinson, Shu Fan, Hamidreza Zareipour, Alberto Troccoli in Rob J. Hyndman, \"Probabilistično napovedovanje energije: Globalno tekmovanje za napovedovanje energije 2014 in naprej\", International Journal of Forecasting, vol.32, št.3, str. 896-913, julij-september, 2016.\n"
],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za prevajanje z umetno inteligenco [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem maternem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo profesionalni človeški prevod. Ne prevzemamo odgovornosti za morebitna napačna razumevanja ali napačne interpretacije, ki bi nastale zaradi uporabe tega prevoda.\n"
]
}
],
"metadata": {
"kernel_info": {
"name": "python3"
},
"kernelspec": {
"name": "python37364bit8d3b438fb5fc4430a93ac2cb74d693a7",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"nteract": {
"version": "nteract-front-end@1.0.0"
},
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
}
},
"coopTranslator": {
"original_hash": "5e2bbe594906dce3aaaa736d6dac6683",
"translation_date": "2025-09-06T14:02:14+00:00",
"source_file": "7-TimeSeries/1-Introduction/working/notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,59 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": 3
},
"orig_nbformat": 2,
"coopTranslator": {
"original_hash": "523ec472196307b3c4235337353c9ceb",
"translation_date": "2025-09-06T14:00:17+00:00",
"source_file": "7-TimeSeries/2-ARIMA/working/notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"source": [
"# Napovedovanje časovnih vrst z ARIMA\n",
"\n",
"V tem zvezku bomo prikazali, kako:\n",
"- pripraviti podatke časovnih vrst za učenje napovednega modela ARIMA,\n",
"- implementirati preprost model ARIMA za napovedovanje naslednjih korakov HORIZON (od časa *t+1* do *t+HORIZON*) v časovni vrsti,\n",
"- oceniti model.\n",
"\n",
"Podatki v tem primeru so vzeti iz tekmovanja za napovedovanje GEFCom2014. Sestavljeni so iz 3 let urnih vrednosti porabe električne energije in temperature med letoma 2012 in 2014. Naloga je napovedati prihodnje vrednosti porabe električne energije. V tem primeru pokažemo, kako napovedati eno časovno točko naprej, pri čemer uporabimo samo zgodovinske podatke o porabi.\n",
"\n",
"Tao Hong, Pierre Pinson, Shu Fan, Hamidreza Zareipour, Alberto Troccoli in Rob J. Hyndman, \"Probabilistic energy forecasting: Global Energy Forecasting Competition 2014 and beyond\", International Journal of Forecasting, vol.32, št.3, str. 896-913, julij-september, 2016.\n"
],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"pip install statsmodels"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
]
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,705 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "fv9OoQsMFk5A"
},
"source": [
"# Napovedovanje časovnih vrst z uporabo regresorja podpornih vektorjev\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"V tem zvezku bomo prikazali, kako:\n",
"\n",
"- pripraviti 2D časovne vrste podatkov za učenje modela SVM regresorja\n",
"- implementirati SVR z uporabo RBF jedra\n",
"- oceniti model s pomočjo grafov in MAPE\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Uvažanje modulov\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"sys.path.append('../../')"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"id": "M687KNlQFp0-"
},
"outputs": [],
"source": [
"import os\n",
"import warnings\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import pandas as pd\n",
"import datetime as dt\n",
"import math\n",
"\n",
"from sklearn.svm import SVR\n",
"from sklearn.preprocessing import MinMaxScaler\n",
"from common.utils import load_data, mape"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Cj-kfVdMGjWP"
},
"source": [
"## Priprava podatkov\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "8fywSjC6GsRz"
},
"source": [
"### Naloži podatke\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 363
},
"id": "aBDkEB11Fumg",
"outputId": "99cf7987-0509-4b73-8cc2-75d7da0d2740"
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>load</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2012-01-01 00:00:00</th>\n",
" <td>2698.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 01:00:00</th>\n",
" <td>2558.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 02:00:00</th>\n",
" <td>2444.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 03:00:00</th>\n",
" <td>2402.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 04:00:00</th>\n",
" <td>2403.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" load\n",
"2012-01-01 00:00:00 2698.0\n",
"2012-01-01 01:00:00 2558.0\n",
"2012-01-01 02:00:00 2444.0\n",
"2012-01-01 03:00:00 2402.0\n",
"2012-01-01 04:00:00 2403.0"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"energy = load_data('../../data')[['load']]\n",
"energy.head(5)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "O0BWP13rGnh4"
},
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 486
},
"id": "hGaNPKu_Gidk",
"outputId": "7f89b326-9057-4f49-efbe-cb100ebdf76d"
},
"outputs": [],
"source": [
"energy.plot(y='load', subplots=True, figsize=(15, 8), fontsize=12)\n",
"plt.xlabel('timestamp', fontsize=12)\n",
"plt.ylabel('load', fontsize=12)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "IPuNor4eGwYY"
},
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ysvsNyONGt0Q"
},
"outputs": [],
"source": [
"train_start_dt = '2014-11-01 00:00:00'\n",
"test_start_dt = '2014-12-30 00:00:00'"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 548
},
"id": "SsfdLoPyGy9w",
"outputId": "d6d6c25b-b1f4-47e5-91d1-707e043237d7"
},
"outputs": [],
"source": [
"energy[(energy.index < test_start_dt) & (energy.index >= train_start_dt)][['load']].rename(columns={'load':'train'}) \\\n",
" .join(energy[test_start_dt:][['load']].rename(columns={'load':'test'}), how='outer') \\\n",
" .plot(y=['train', 'test'], figsize=(15, 8), fontsize=12)\n",
"plt.xlabel('timestamp', fontsize=12)\n",
"plt.ylabel('load', fontsize=12)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "XbFTqBw6G1Ch"
},
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Zdaj morate pripraviti podatke za učenje z izvajanjem filtriranja in skaliranja vaših podatkov.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "cYivRdQpHDj3",
"outputId": "a138f746-461c-4fd6-bfa6-0cee094c4aa1"
},
"outputs": [],
"source": [
"train = energy.copy()[(energy.index >= train_start_dt) & (energy.index < test_start_dt)][['load']]\n",
"test = energy.copy()[energy.index >= test_start_dt][['load']]\n",
"\n",
"print('Training data shape: ', train.shape)\n",
"print('Test data shape: ', test.shape)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Prilagodite podatke, da bodo v razponu (0, 1).\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 363
},
"id": "3DNntGQnZX8G",
"outputId": "210046bc-7a66-4ccd-d70d-aa4a7309949c"
},
"outputs": [],
"source": [
"scaler = MinMaxScaler()\n",
"train['load'] = scaler.fit_transform(train)\n",
"train.head(5)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 206
},
"id": "26Yht-rzZexe",
"outputId": "20326077-a38a-4e78-cc5b-6fd7af95d301"
},
"outputs": [],
"source": [
"test['load'] = scaler.transform(test)\n",
"test.head(5)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "x0n6jqxOQ41Z"
},
"source": [
"### Ustvarjanje podatkov s časovnimi koraki\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "fdmxTZtOQ8xs"
},
"source": [
"Za naš SVR preoblikujemo vhodne podatke v obliko `[batch, timesteps]`. Tako preoblikujemo obstoječe `train_data` in `test_data`, da dodamo novo dimenzijo, ki se nanaša na časovne korake. V našem primeru vzamemo `timesteps = 5`. Tako so vhodi v model podatki za prve 4 časovne korake, izhod pa bodo podatki za 5. časovni korak.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Rpju-Sc2HFm0"
},
"outputs": [],
"source": [
"# Converting to numpy arrays\n",
"\n",
"train_data = train.values\n",
"test_data = test.values"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Selecting the timesteps\n",
"\n",
"timesteps=None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "O-JrsrsVJhUQ",
"outputId": "c90dbe71-bacc-4ec4-b452-f82fe5aefaef"
},
"outputs": [],
"source": [
"# Converting data to 2D tensor\n",
"\n",
"train_data_timesteps=None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "exJD8AI7KE4g",
"outputId": "ce90260c-f327-427d-80f2-77307b5a6318"
},
"outputs": [],
"source": [
"# Converting test data to 2D tensor\n",
"\n",
"test_data_timesteps=None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "2u0R2sIsLuq5"
},
"outputs": [],
"source": [
"x_train, y_train = None\n",
"x_test, y_test = None\n",
"\n",
"print(x_train.shape, y_train.shape)\n",
"print(x_test.shape, y_test.shape)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "8wIPOtAGLZlh"
},
"source": [
"## Ustvarjanje SVR modela\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "EhA403BEPEiD"
},
"outputs": [],
"source": [
"# Create model using RBF kernel\n",
"\n",
"model = None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "GS0UA3csMbqp",
"outputId": "d86b6f05-5742-4c1d-c2db-c40510bd4f0d"
},
"outputs": [],
"source": [
"# Fit model on training data"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Rz_x8S3UrlcF"
},
"source": [
"### Ustvari napoved modela\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "XR0gnt3MnuYS",
"outputId": "157e40ab-9a23-4b66-a885-0d52a24b2364"
},
"outputs": [],
"source": [
"# Making predictions\n",
"\n",
"y_train_pred = None\n",
"y_test_pred = None"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "_2epncg-SGzr"
},
"source": [
"## Analiza učinkovitosti modela\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Scaling the predictions\n",
"\n",
"y_train_pred = scaler.inverse_transform(y_train_pred)\n",
"y_test_pred = scaler.inverse_transform(y_test_pred)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "xmm_YLXhq7gV",
"outputId": "18392f64-4029-49ac-c71a-a4e2411152a1"
},
"outputs": [],
"source": [
"# Scaling the original values\n",
"\n",
"y_train = scaler.inverse_transform(y_train)\n",
"y_test = scaler.inverse_transform(y_test)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "u3LBj93coHEi",
"outputId": "d4fd49e8-8c6e-4bb0-8ef9-ca0b26d725b4"
},
"outputs": [],
"source": [
"# Extract the timesteps for x-axis\n",
"\n",
"train_timestamps = None\n",
"test_timestamps = None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure(figsize=(25,6))\n",
"# plot original output\n",
"# plot predicted output\n",
"plt.legend(['Actual','Predicted'])\n",
"plt.xlabel('Timestamp')\n",
"plt.title(\"Training data prediction\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "LnhzcnYtXHCm",
"outputId": "f5f0d711-f18b-4788-ad21-d4470ea2c02b"
},
"outputs": [],
"source": [
"print('MAPE for training data: ', mape(y_train_pred, y_train)*100, '%')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 225
},
"id": "53Q02FoqQH4V",
"outputId": "53e2d59b-5075-4765-ad9e-aed56c966583"
},
"outputs": [],
"source": [
"plt.figure(figsize=(10,3))\n",
"# plot original output\n",
"# plot predicted output\n",
"plt.legend(['Actual','Predicted'])\n",
"plt.xlabel('Timestamp')\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "clOAUH-SXCJG",
"outputId": "a3aa85ff-126a-4a4a-cd9e-90b9cc465ef5"
},
"outputs": [],
"source": [
"print('MAPE for testing data: ', mape(y_test_pred, y_test)*100, '%')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "DHlKvVCId5ue"
},
"source": [
"## Napoved celotnega nabora podatkov\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "cOFJ45vreO0N",
"outputId": "35628e33-ecf9-4966-8036-f7ea86db6f16"
},
"outputs": [],
"source": [
"# Extracting load values as numpy array\n",
"data = None\n",
"\n",
"# Scaling\n",
"data = None\n",
"\n",
"# Transforming to 2D tensor as per model input requirement\n",
"data_timesteps=None\n",
"\n",
"# Selecting inputs and outputs from data\n",
"X, Y = None, None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ESSAdQgwexIi"
},
"outputs": [],
"source": [
"# Make model predictions\n",
"\n",
"# Inverse scale and reshape\n",
"Y_pred = None\n",
"Y = None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 328
},
"id": "M_qhihN0RVVX",
"outputId": "a89cb23e-1d35-437f-9d63-8b8907e12f80"
},
"outputs": [],
"source": [
"plt.figure(figsize=(30,8))\n",
"# plot original output\n",
"# plot predicted output\n",
"plt.legend(['Actual','Predicted'])\n",
"plt.xlabel('Timestamp')\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "AcN7pMYXVGTK",
"outputId": "7e1c2161-47ce-496c-9d86-7ad9ae0df770"
},
"outputs": [],
"source": [
"print('MAPE: ', mape(Y_pred, Y)*100, '%')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Omejitev odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki izhajajo iz uporabe tega prevoda.\n"
]
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"collapsed_sections": [],
"name": "Recurrent_Neural_Networks.ipynb",
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.1"
},
"coopTranslator": {
"original_hash": "e86ce102239a14c44585623b9b924a74",
"translation_date": "2025-09-06T14:06:00+00:00",
"source_file": "7-TimeSeries/3-SVR/working/notebook.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 1
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save