parent
6a683a369d
commit
443c121c29
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
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 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 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 one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,450 @@
|
||||
{
|
||||
"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-04T07:03:52+00:00",
|
||||
"source_file": "2-Regression/1-Tools/solution/R/lesson_1-R.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [],
|
||||
"metadata": {
|
||||
"id": "YJUHCXqK57yz"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Úvod do regrese - Lekce 1\n",
|
||||
"\n",
|
||||
"#### Uvedení do kontextu\n",
|
||||
"\n",
|
||||
"✅ Existuje mnoho typů regresních metod a výběr té správné závisí na tom, jakou odpověď hledáte. Pokud chcete předpovědět pravděpodobnou výšku osoby určitého věku, použijete `lineární regresi`, protože hledáte **číselnou hodnotu**. Pokud vás zajímá, zda by určitý typ kuchyně měl být považován za veganský nebo ne, hledáte **přiřazení kategorie**, a proto byste použili `logistickou regresi`. O logistické regresi se dozvíte více později. Zamyslete se nad některými otázkami, které byste mohli klást datům, a nad tím, která z těchto metod by byla vhodnější.\n",
|
||||
"\n",
|
||||
"V této části budete pracovat s [malou datovou sadou o cukrovce](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html). Představte si, že byste chtěli otestovat léčbu pro pacienty s cukrovkou. Modely strojového učení by vám mohly pomoci určit, kteří pacienti by na léčbu reagovali lépe, na základě kombinací proměnných. I velmi základní regresní model, pokud je vizualizován, by mohl ukázat informace o proměnných, které by vám pomohly uspořádat vaše teoretické klinické studie.\n",
|
||||
"\n",
|
||||
"Tak tedy, pojďme se pustit do tohoto úkolu!\n",
|
||||
"\n",
|
||||
"<p >\n",
|
||||
" <img src=\"../../images/encouRage.jpg\"\n",
|
||||
" width=\"630\"/>\n",
|
||||
" <figcaption>Ilustrace od @allison_horst</figcaption>\n",
|
||||
"\n",
|
||||
"<!--<br>Ilustrace od @allison_horst-->\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "LWNNzfqd6feZ"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## 1. Načtení našeho nástrojového setu\n",
|
||||
"\n",
|
||||
"Pro tento úkol budeme potřebovat následující balíčky:\n",
|
||||
"\n",
|
||||
"- `tidyverse`: [tidyverse](https://www.tidyverse.org/) je [kolekce balíčků pro R](https://www.tidyverse.org/packages), která je navržena tak, aby byla práce s daty rychlejší, jednodušší a zábavnější!\n",
|
||||
"\n",
|
||||
"- `tidymodels`: [tidymodels](https://www.tidymodels.org/) je [kolekce balíčků](https://www.tidymodels.org/packages/) určená pro modelování a strojové učení.\n",
|
||||
"\n",
|
||||
"Můžete je nainstalovat pomocí:\n",
|
||||
"\n",
|
||||
"`install.packages(c(\"tidyverse\", \"tidymodels\"))`\n",
|
||||
"\n",
|
||||
"Níže uvedený skript zkontroluje, zda máte balíčky potřebné k dokončení tohoto modulu, a v případě, že některé chybí, je pro vás nainstaluje.\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": [
|
||||
"Nyní načtěme tyto skvělé balíčky a zpřístupněme je v naší aktuální relaci R. (Toto je pouze pro ilustraci, `pacman::p_load()` to již udělal za vás)\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. Datová sada o cukrovce\n",
|
||||
"\n",
|
||||
"V tomto cvičení si procvičíme naše dovednosti v regresi tím, že budeme provádět predikce na datové sadě o cukrovce. [Datová sada o cukrovce](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt) obsahuje `442 vzorků` dat týkajících se cukrovky, s 10 prediktivními proměnnými, jako jsou `věk`, `pohlaví`, `index tělesné hmotnosti`, `průměrný krevní tlak` a `šest měření krevního séra`, a také výstupní proměnnou `y`: kvantitativní míru progrese onemocnění jeden rok po výchozím stavu.\n",
|
||||
"\n",
|
||||
"|Počet pozorování|442|\n",
|
||||
"|----------------|:---|\n",
|
||||
"|Počet prediktorů|Prvních 10 sloupců jsou číselné prediktivní proměnné|\n",
|
||||
"|Výstup/Cíl|Sloupec 11 je kvantitativní míra progrese onemocnění jeden rok po výchozím stavu|\n",
|
||||
"|Informace o prediktorech|- věk v letech\n",
|
||||
"||- pohlaví\n",
|
||||
"||- bmi index tělesné hmotnosti\n",
|
||||
"||- bp průměrný krevní tlak\n",
|
||||
"||- s1 tc, celkový cholesterol v séru\n",
|
||||
"||- s2 ldl, lipoproteiny s nízkou hustotou\n",
|
||||
"||- s3 hdl, lipoproteiny s vysokou hustotou\n",
|
||||
"||- s4 tch, poměr celkového cholesterolu k HDL\n",
|
||||
"||- s5 ltg, pravděpodobně logaritmus hladiny triglyceridů v séru\n",
|
||||
"||- s6 glu, hladina cukru v krvi|\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"> 🎓 Pamatujte, že se jedná o učení s učitelem (supervised learning), a potřebujeme cílovou proměnnou 'y'.\n",
|
||||
"\n",
|
||||
"Než budete moci manipulovat s daty v R, musíte data načíst do paměti R nebo vytvořit připojení k datům, které R umožní přístup k datům vzdáleně.\n",
|
||||
"\n",
|
||||
"> Balíček [readr](https://readr.tidyverse.org/), který je součástí Tidyverse, poskytuje rychlý a uživatelsky přívětivý způsob, jak načíst obdélníková data do R.\n",
|
||||
"\n",
|
||||
"Nyní načtěme datovou sadu o cukrovce z tohoto zdrojového URL: <https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html>\n",
|
||||
"\n",
|
||||
"Také provedeme kontrolu našich dat pomocí funkce `glimpse()` a zobrazíme prvních 5 řádků pomocí funkce `slice()`.\n",
|
||||
"\n",
|
||||
"Než budeme pokračovat, představme si ještě něco, s čím se v kódu R často setkáte 🥁🥁: operátor pipe `%>%`\n",
|
||||
"\n",
|
||||
"Operátor pipe (`%>%`) provádí operace v logickém sledu tím, že předává objekt dál do funkce nebo výrazu. Můžete si operátor pipe představit jako výraz \"a pak\" ve vašem kódu.\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 tato data obsahují 442 řádků a 11 sloupců, přičemž všechny sloupce mají datový typ `double`.\n",
|
||||
"\n",
|
||||
"<br>\n",
|
||||
"\n",
|
||||
"> glimpse() a slice() jsou funkce v [`dplyr`](https://dplyr.tidyverse.org/). Dplyr, součást Tidyverse, je gramatika pro manipulaci s daty, která poskytuje konzistentní sadu sloves, jež vám pomohou vyřešit nejběžnější výzvy při práci s daty.\n",
|
||||
"\n",
|
||||
"<br>\n",
|
||||
"\n",
|
||||
"Teď, když máme data, zaměříme se na jednu vlastnost (`bmi`) jako cíl tohoto cvičení. To bude vyžadovat, abychom vybrali požadované sloupce. Jak to uděláme?\n",
|
||||
"\n",
|
||||
"[`dplyr::select()`](https://dplyr.tidyverse.org/reference/select.html) nám umožňuje *vybrat* (a případně přejmenovat) sloupce v datovém 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énovací a testovací data\n",
|
||||
"\n",
|
||||
"V řízeném učení je běžnou praxí *rozdělit* data na dvě podmnožiny; (obvykle větší) sadu, která slouží k trénování modelu, a menší „záložní“ sadu, která slouží k ověření, jak si model vedl.\n",
|
||||
"\n",
|
||||
"Nyní, když máme data připravena, můžeme zjistit, zda nám stroj dokáže pomoci určit logické rozdělení čísel v tomto datasetu. Můžeme použít balíček [rsample](https://tidymodels.github.io/rsample/), který je součástí frameworku Tidymodels, k vytvoření objektu, který obsahuje informace o *tom*, jak data rozdělit, a poté dvě další funkce rsample k extrakci vytvořených trénovacích a testovacích sad:\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. Trénování lineárního regresního modelu pomocí Tidymodels\n",
|
||||
"\n",
|
||||
"Teď jsme připraveni trénovat náš model!\n",
|
||||
"\n",
|
||||
"V Tidymodels specifikujete modely pomocí `parsnip()` tím, že určíte tři koncepty:\n",
|
||||
"\n",
|
||||
"- **Typ modelu** rozlišuje mezi modely, jako je lineární regrese, logistická regrese, modely rozhodovacích stromů a podobně.\n",
|
||||
"\n",
|
||||
"- **Režim modelu** zahrnuje běžné možnosti, jako je regrese a klasifikace; některé typy modelů podporují obě možnosti, zatímco jiné mají pouze jeden režim.\n",
|
||||
"\n",
|
||||
"- **Engine modelu** je výpočetní nástroj, který bude použit k nastavení modelu. Často se jedná o balíčky v R, jako například **`\"lm\"`** nebo **`\"ranger\"`**.\n",
|
||||
"\n",
|
||||
"Tyto informace o modelování jsou zachyceny ve specifikaci modelu, tak si jednu vytvořme!\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": [
|
||||
"Poté, co byl model *specifikován*, může být model `odhadnut` nebo `natrénován` pomocí funkce [`fit()`](https://parsnip.tidymodels.org/reference/fit.html), obvykle za použití vzorce a nějakých dat.\n",
|
||||
"\n",
|
||||
"`y ~ .` znamená, že budeme přizpůsobovat `y` jako předpovídanou hodnotu/cíl, vysvětlenou všemi prediktory/vlastnostmi, tj. `.` (v tomto případě máme pouze 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 výstupu modelu můžeme vidět koeficienty naučené během trénování. Tyto koeficienty představují parametry přímky nejlepšího přizpůsobení, která nám poskytuje nejnižší celkovou chybu mezi skutečnou a předpovězenou proměnnou.\n",
|
||||
"<br>\n",
|
||||
"\n",
|
||||
"## 5. Vytvoření předpovědí na testovací sadě\n",
|
||||
"\n",
|
||||
"Nyní, když jsme model natrénovali, můžeme jej použít k předpovědi vývoje onemocnění y pro testovací dataset pomocí [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html). To bude použito k vykreslení čáry mezi skupinami dat.\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ávě jsme natrénovali model a použili ho k vytvoření předpovědí!\n",
|
||||
"\n",
|
||||
"Při vytváření předpovědí je konvencí v tidymodels vždy vytvořit tibble/datový rámec s výsledky, který má standardizované názvy sloupců. To usnadňuje kombinaci původních dat a předpovědí do použitelného formátu pro následné operace, jako je například vytváření grafů.\n",
|
||||
"\n",
|
||||
"`dplyr::bind_cols()` efektivně spojuje více datových rámců podle sloupců.\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. Zobrazení výsledků modelování\n",
|
||||
"\n",
|
||||
"Teď je čas podívat se na to vizuálně 📈. Vytvoříme bodový graf všech hodnot `y` a `bmi` z testovací sady a poté použijeme predikce k nakreslení čáry na nejvhodnějším místě mezi skupinami dat modelu.\n",
|
||||
"\n",
|
||||
"R má několik systémů pro vytváření grafů, ale `ggplot2` je jedním z nejpůsobivějších a nejvšestrannějších. Umožňuje vám skládat grafy **kombinováním nezávislých 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": [
|
||||
"✅ Zamyslete se nad tím, co se zde děje. Přímka prochází mnoha malými body dat, ale co přesně dělá? Vidíte, jak byste měli být schopni použít tuto přímku k předpovědi, kam by měl nový, neviděný datový bod zapadnout ve vztahu k ose y grafu? Zkuste slovy popsat praktické využití tohoto modelu.\n",
|
||||
"\n",
|
||||
"Gratulujeme, vytvořili jste svůj první model lineární regrese, provedli předpověď a zobrazili ji v grafu!\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "zrPtHIxx_tNI"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n---\n\n**Prohlášení**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Nenese odpovědnost za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.\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-04T07:10:47+00:00",
|
||||
"source_file": "2-Regression/2-Data/notebook.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2,
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n---\n\n**Prohlášení**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,673 @@
|
||||
{
|
||||
"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-04T07:14:33+00:00",
|
||||
"source_file": "2-Regression/2-Data/solution/R/lesson_2-R.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"# Vytvoření regresního modelu: příprava a vizualizace dat\n",
|
||||
"\n",
|
||||
"## **Lineární regrese pro dýně - Lekce 2**\n",
|
||||
"#### Úvod\n",
|
||||
"\n",
|
||||
"Nyní, když máte k dispozici nástroje potřebné k zahájení budování modelů strojového učení pomocí Tidymodels a Tidyverse, jste připraveni začít klást otázky svým datům. Při práci s daty a aplikaci řešení strojového učení je velmi důležité vědět, jak položit správnou otázku, abyste mohli plně využít potenciál svého datasetu.\n",
|
||||
"\n",
|
||||
"V této lekci se naučíte:\n",
|
||||
"\n",
|
||||
"- Jak připravit data pro budování modelu.\n",
|
||||
"\n",
|
||||
"- Jak používat `ggplot2` pro vizualizaci dat.\n",
|
||||
"\n",
|
||||
"Otázka, na kterou potřebujete odpověď, určí, jaký typ algoritmů strojového učení budete používat. Kvalita odpovědi, kterou získáte, bude silně záviset na povaze vašich dat.\n",
|
||||
"\n",
|
||||
"Podívejme se na to prostřednictvím praktického cvičení.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"<p >\n",
|
||||
" <img src=\"../../images/unruly_data.jpg\"\n",
|
||||
" width=\"700\"/>\n",
|
||||
" <figcaption>Ilustrace od @allison_horst</figcaption>\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"<!--<br>Ilustrace od \\@allison_horst-->\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "Pg5aexcOPqAZ"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## 1. Importování dat o dýních a přivolání Tidyverse\n",
|
||||
"\n",
|
||||
"Budeme potřebovat následující balíčky, abychom mohli rozdělit a zpracovat tuto lekci:\n",
|
||||
"\n",
|
||||
"- `tidyverse`: [tidyverse](https://www.tidyverse.org/) je [sbírka balíčků pro R](https://www.tidyverse.org/packages), která je navržena tak, aby byla datová věda rychlejší, jednodušší a zábavnější!\n",
|
||||
"\n",
|
||||
"Můžete je nainstalovat pomocí:\n",
|
||||
"\n",
|
||||
"`install.packages(c(\"tidyverse\"))`\n",
|
||||
"\n",
|
||||
"Níže uvedený skript zkontroluje, zda máte balíčky potřebné k dokončení tohoto modulu, a v případě, že některé chybí, je pro vás nainstaluje.\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": [
|
||||
"Nyní spusťme některé balíčky a načtěme [data](https://github.com/microsoft/ML-For-Beginners/blob/main/2-Regression/data/US-pumpkins.csv) poskytnutá pro tuto lekci!\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": [
|
||||
"Rychlý `glimpse()` okamžitě ukazuje, že jsou zde prázdné hodnoty a směs řetězců (`chr`) a číselných dat (`dbl`). `Date` je typu znakového řetězce a je tu také zvláštní sloupec nazvaný `Package`, kde jsou data směsí mezi `sacks`, `bins` a dalšími hodnotami. Data jsou vlastně trochu chaotická 😤.\n",
|
||||
"\n",
|
||||
"Ve skutečnosti není příliš běžné dostat dataset, který je zcela připravený k použití pro vytvoření ML modelu hned na první pokus. Ale nezoufejte, v této lekci se naučíte, jak připravit surový dataset pomocí standardních knihoven v R 🧑🔧. Také se naučíte různé techniky vizualizace dat.📈📊\n",
|
||||
"<br>\n",
|
||||
"\n",
|
||||
"> Připomenutí: Operátor pipe (`%>%`) provádí operace v logickém sledu tím, že předává objekt dál do funkce nebo výrazu. Můžete si operátor pipe představit jako \"a potom\" ve vašem kódu.\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "REWcIv9yX29v"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## 2. Kontrola chybějících dat\n",
|
||||
"\n",
|
||||
"Jedním z nejčastějších problémů, se kterými se datoví vědci musí vypořádat, jsou neúplná nebo chybějící data. R reprezentuje chybějící nebo neznámé hodnoty pomocí speciálního sentinelového hodnoty: `NA` (Not Available).\n",
|
||||
"\n",
|
||||
"Jak tedy zjistíme, že datový rámec obsahuje chybějící hodnoty?\n",
|
||||
"<br>\n",
|
||||
"- Jedním z nejjednodušších způsobů je použití základní funkce R `anyNA`, která vrací logické objekty `TRUE` nebo `FALSE`.\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "Zxfb3AM5YbUe"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"source": [
|
||||
"pumpkins %>% \n",
|
||||
" anyNA()"
|
||||
],
|
||||
"outputs": [],
|
||||
"metadata": {
|
||||
"id": "G--DQutAYltj"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"Skvělé, zdá se, že některá data chybí! To je dobré místo, kde začít.\n",
|
||||
"\n",
|
||||
"- Dalším způsobem by bylo použít funkci `is.na()`, která označuje, které jednotlivé prvky sloupce chybí pomocí logické 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": [
|
||||
"Dobře, hotovo, ale s tak velkým datovým rámcem, jako je tento, by bylo neefektivní a prakticky nemožné zkontrolovat všechny řádky a sloupce jednotlivě😴.\n",
|
||||
"\n",
|
||||
"- Intuitivnější způsob by byl spočítat součet chybějících hodnot pro každý sloupec:\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": [
|
||||
"Mnohem lepší! Chybí některá data, ale možná to nebude mít vliv na daný úkol. Uvidíme, jaký další rozbor přinese.\n",
|
||||
"\n",
|
||||
"> Spolu s úžasnými balíčky a funkcemi má R velmi dobrou dokumentaci. Například použijte `help(colSums)` nebo `?colSums`, abyste se dozvěděli více o této funkci.\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "9gv-crB6ZD1Y"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## 3. Dplyr: Gramatika manipulace s daty\n",
|
||||
"\n",
|
||||
"<p >\n",
|
||||
" <img src=\"../../images/dplyr_wrangling.png\"\n",
|
||||
" width=\"569\"/>\n",
|
||||
" <figcaption>Ilustrace od @allison_horst</figcaption>\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"<!--<br/>Ilustrace od \\@allison_horst-->\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "o4jLY5-VZO2C"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"[`dplyr`](https://dplyr.tidyverse.org/), balíček v Tidyverse, je gramatikou manipulace s daty, která poskytuje konzistentní sadu sloves, jež vám pomohou vyřešit nejběžnější výzvy při manipulaci s daty. V této části se podíváme na některá slovesa z dplyr! \n",
|
||||
"<br>\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "i5o33MQBZWWw"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"#### dplyr::select()\n",
|
||||
"\n",
|
||||
"`select()` je funkce z balíčku `dplyr`, která vám pomáhá vybrat sloupce, které chcete zachovat nebo vyloučit.\n",
|
||||
"\n",
|
||||
"Abyste si usnadnili práci s datovým rámcem, odstraňte několik jeho sloupců pomocí `select()` a ponechte pouze ty, které potřebujete.\n",
|
||||
"\n",
|
||||
"Například v tomto cvičení bude naše analýza zahrnovat sloupce `Package`, `Low Price`, `High Price` a `Date`. Pojďme tyto sloupce vybrat.\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 funkce z balíčku `dplyr`, která vám umožňuje vytvářet nebo upravovat sloupce, přičemž zachovává stávající sloupce.\n",
|
||||
"\n",
|
||||
"Obecná struktura funkce mutate je:\n",
|
||||
"\n",
|
||||
"`data %>% mutate(new_column_name = what_it_contains)`\n",
|
||||
"\n",
|
||||
"Pojďme si vyzkoušet `mutate` na sloupci `Date` provedením následujících operací:\n",
|
||||
"\n",
|
||||
"1. Převést data (aktuálně typu znak) na formát měsíce (jedná se o americká data, takže formát je `MM/DD/YYYY`).\n",
|
||||
"\n",
|
||||
"2. Extrahovat měsíc z dat do nového sloupce.\n",
|
||||
"\n",
|
||||
"V R balíček [lubridate](https://lubridate.tidyverse.org/) usnadňuje práci s daty a časy. Takže použijeme `dplyr::mutate()`, `lubridate::mdy()`, `lubridate::month()` a podíváme se, jak dosáhnout výše uvedených cílů. Sloupec Date můžeme vynechat, protože ho v dalších operacích nebudeme potřebovat.\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",
|
||||
"Nyní vytvořme nový sloupec `Price`, který bude představovat průměrnou cenu dýně. Vezmeme průměr hodnot ze sloupců `Low Price` a `High Price` a použijeme jej k naplnění nového sloupce 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čkejte!“, řeknete po rychlém prohlédnutí celého datového souboru pomocí `View(pumpkins)`, „Tady je něco zvláštního!“🤔\n",
|
||||
"\n",
|
||||
"Pokud se podíváte na sloupec `Package`, dýně se prodávají v mnoha různých konfiguracích. Některé se prodávají v mírách `1 1/9 bushel`, některé v mírách `1/2 bushel`, některé na kus, některé na váhu, a některé ve velkých krabicích s různými šířkami.\n",
|
||||
"\n",
|
||||
"Pojďme si to ověřit:\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á se, že dýně je velmi těžké vážit konzistentně, takže je vyfiltrujeme tím, že vybereme pouze dýně, které obsahují řetězec *bushel* ve sloupci `Package`, a uložíme je do nového datového rámce `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áří podmnožinu dat obsahující pouze **řádky**, které splňují vaše podmínky, v tomto případě dýně s řetězcem *bushel* ve sloupci `Package`.\n",
|
||||
"\n",
|
||||
"[stringr::str_detect()](https://stringr.tidyverse.org/reference/str_detect.html): zjišťuje přítomnost nebo nepřítomnost vzoru v řetězci.\n",
|
||||
"\n",
|
||||
"Balíček [`stringr`](https://github.com/tidyverse/stringr) poskytuje jednoduché funkce pro běžné operace s řetězci.\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 vidět, že jsme zúžili výběr na přibližně 415 řádků dat obsahujících dýně po bušlech.🤩 \n",
|
||||
"<br>\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "VrDwF031avlR"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"#### dplyr::case_when()\n",
|
||||
"\n",
|
||||
"**Ale počkejte! Ještě je třeba něco udělat**\n",
|
||||
"\n",
|
||||
"Všimli jste si, že množství v bušlech se liší podle řádku? Je potřeba normalizovat ceny tak, aby ukazovaly cenu za bušel, a ne za 1 1/9 nebo 1/2 bušle. Je čas provést nějaké výpočty, abychom to standardizovali.\n",
|
||||
"\n",
|
||||
"Použijeme funkci [`case_when()`](https://dplyr.tidyverse.org/reference/case_when.html) k *úpravě* sloupce Price na základě určitých podmínek. `case_when` umožňuje vektorizovat více `if_else()` výroků.\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": [
|
||||
"Nyní můžeme analyzovat cenu za jednotku na základě jejich měření v bušlech. Celá tato studie bušlů dýní však ukazuje, jak velmi `důležité` je `pochopit povahu vašich dat`!\n",
|
||||
"\n",
|
||||
"> ✅ Podle [The Spruce Eats](https://www.thespruceeats.com/how-much-is-a-bushel-1389308) závisí váha bušle na typu produktu, protože jde o objemové měření. \"Bušl rajčat by například měl vážit 56 liber... Listy a zelené rostliny zabírají více prostoru s menší váhou, takže bušl špenátu váží pouze 20 liber.\" Je to všechno docela složité! Nezabývejme se převodem bušlů na libry a místo toho stanovme cenu podle bušle. Celá tato studie bušlů dýní však ukazuje, jak velmi důležité je pochopit povahu vašich dat!\n",
|
||||
">\n",
|
||||
"> ✅ Všimli jste si, že dýně prodávané na půl bušle jsou velmi drahé? Dokážete zjistit proč? Nápověda: malé dýně jsou mnohem dražší než velké, pravděpodobně proto, že jich je mnohem více na bušl, vzhledem k nevyužitému prostoru, který zabírá jedna velká dutá dýně na koláč.\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "pS2GNPagbSdb"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"Nyní nakonec, čistě pro dobrodružství 💁♀️, pojďme také přesunout sloupec Month na první pozici, tj. `před` sloupec `Package`.\n",
|
||||
"\n",
|
||||
"Funkce `dplyr::relocate()` se používá ke změně pozic sloupců.\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": [
|
||||
"Dobrá práce!👌 Nyní máte čistý a uspořádaný dataset, na kterém můžete postavit svůj nový regresní model! \n",
|
||||
"<br>\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "y8TJ0Za_bn5Y"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## 4. Vizualizace dat 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",
|
||||
"<!--{width=\"600\"}-->\n",
|
||||
"\n",
|
||||
"Existuje *moudré* rčení, které říká:\n",
|
||||
"\n",
|
||||
"> \"Jednoduchý graf přinesl analytikovi více informací než jakékoli jiné zařízení.\" --- John Tukey\n",
|
||||
"\n",
|
||||
"Součástí role datového vědce je ukázat kvalitu a povahu dat, se kterými pracuje. K tomu často vytváří zajímavé vizualizace, nebo grafy, diagramy a tabulky, které zobrazují různé aspekty dat. Tímto způsobem mohou vizuálně ukázat vztahy a mezery, které by jinak bylo obtížné odhalit.\n",
|
||||
"\n",
|
||||
"Vizualizace také mohou pomoci určit, která technika strojového učení je pro daná data nejvhodnější. Například bodový graf, který se zdá sledovat přímku, naznačuje, že data jsou vhodným kandidátem pro úlohu lineární regrese.\n",
|
||||
"\n",
|
||||
"R nabízí několik systémů pro tvorbu grafů, ale [`ggplot2`](https://ggplot2.tidyverse.org/index.html) je jedním z nejelegantnějších a nejvšestrannějších. `ggplot2` vám umožňuje skládat grafy **kombinováním nezávislých komponent**.\n",
|
||||
"\n",
|
||||
"Začněme jednoduchým bodovým grafem pro sloupce Price a Month.\n",
|
||||
"\n",
|
||||
"V tomto případě začneme s [`ggplot()`](https://ggplot2.tidyverse.org/reference/ggplot.html), dodáme dataset a estetické mapování (pomocí [`aes()`](https://ggplot2.tidyverse.org/reference/aes.html)) a poté přidáme vrstvy (jako [`geom_point()`](https://ggplot2.tidyverse.org/reference/geom_point.html)) pro 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 tento graf užitečný 🤷? Překvapilo vás na něm něco?\n",
|
||||
"\n",
|
||||
"Není příliš užitečný, protože pouze zobrazuje vaše data jako rozptyl bodů v daném měsíci. \n",
|
||||
"<br>\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "Ml7SDCLQcPvE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### **Jak to udělat užitečné?**\n",
|
||||
"\n",
|
||||
"Aby grafy zobrazovaly užitečná data, obvykle je potřeba data nějakým způsobem seskupit. Například v našem případě by nalezení průměrné ceny dýní za každý měsíc poskytlo více informací o základních vzorcích v našich datech. To nás přivádí k dalšímu rychlému přehledu **dplyr**:\n",
|
||||
"\n",
|
||||
"#### `dplyr::group_by() %>% summarize()`\n",
|
||||
"\n",
|
||||
"Seskupenou agregaci v R lze snadno vypočítat pomocí\n",
|
||||
"\n",
|
||||
"`dplyr::group_by() %>% summarize()`\n",
|
||||
"\n",
|
||||
"- `dplyr::group_by()` mění jednotku analýzy z celého datasetu na jednotlivé skupiny, například podle měsíců.\n",
|
||||
"\n",
|
||||
"- `dplyr::summarize()` vytváří nový datový rámec s jedním sloupcem pro každou seskupovací proměnnou a jedním sloupcem pro každou zadanou statistiku shrnutí.\n",
|
||||
"\n",
|
||||
"Například můžeme použít `dplyr::group_by() %>% summarize()` k seskupení dýní do skupin na základě sloupce **Month** a následně najít **průměrnou cenu** za každý měsíc.\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čně!✨\n",
|
||||
"\n",
|
||||
"Kategorie, jako jsou měsíce, se lépe zobrazují pomocí sloupcového grafu 📊. Vrstvy, které se používají pro sloupcové grafy, jsou `geom_bar()` a `geom_col()`. Podívejte se na `?geom_bar`, abyste zjistili více.\n",
|
||||
"\n",
|
||||
"Pojďme si jeden vytvořit!\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žitečnější vizualizace dat! Zdá se, že naznačuje, že nejvyšší cena za dýně se vyskytuje v září a říjnu. Odpovídá to vašemu očekávání? Proč ano nebo proč ne?\n",
|
||||
"\n",
|
||||
"Gratulujeme k dokončení druhé lekce 👏! Připravili jste svá data pro tvorbu modelu a poté odhalili další poznatky pomocí vizualizací!\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "zDm0VOzzcuzR"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n---\n\n**Prohlášení**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,128 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Ceny dýní\n",
|
||||
"\n",
|
||||
"Načtěte potřebné knihovny a dataset. Převést data na dataframe obsahující podmnožinu dat:\n",
|
||||
"\n",
|
||||
"- Získat pouze dýně oceněné podle množství na bušl\n",
|
||||
"- Převést datum na měsíc\n",
|
||||
"- Vypočítat cenu jako průměr vysokých a nízkých cen\n",
|
||||
"- Převést cenu tak, aby odrážela ocenění podle množství na bušl\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 připomíná, že máme údaje pouze od srpna do prosince. Pravděpodobně potřebujeme více dat, abychom mohli vyvodit závěry lineárním způsobem.\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**Prohlášení**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.\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-04T06:17:07+00:00",
|
||||
"source_file": "2-Regression/3-Linear/notebook.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -0,0 +1,686 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Vytvoření modelu logistické regrese - Lekce 4\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"#### **[Kvíz před lekcí](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/15/)**\n",
|
||||
"\n",
|
||||
"#### Úvod\n",
|
||||
"\n",
|
||||
"V této závěrečné lekci o regresi, jednom ze základních *klasických* technik strojového učení, se podíváme na logistickou regresi. Tuto techniku byste použili k objevování vzorců pro predikci binárních kategorií. Je tato cukrovinka čokoláda, nebo ne? Je tato nemoc nakažlivá, nebo ne? Vybere si tento zákazník tento produkt, nebo ne?\n",
|
||||
"\n",
|
||||
"V této lekci se naučíte:\n",
|
||||
"\n",
|
||||
"- Techniky logistické regrese\n",
|
||||
"\n",
|
||||
"✅ Prohlubte své znalosti práce s tímto typem regrese v tomto [výukovém modulu](https://learn.microsoft.com/training/modules/introduction-classification-models/?WT.mc_id=academic-77952-leestott)\n",
|
||||
"\n",
|
||||
"## Předpoklady\n",
|
||||
"\n",
|
||||
"Po práci s daty o dýních jsme nyní dostatečně obeznámeni s tím, že existuje jedna binární kategorie, se kterou můžeme pracovat: `Color`.\n",
|
||||
"\n",
|
||||
"Postavme model logistické regrese, který předpoví, na základě některých proměnných, *jakou barvu bude mít daná dýně* (oranžová 🎃 nebo bílá 👻).\n",
|
||||
"\n",
|
||||
"> Proč mluvíme o binární klasifikaci v lekci zaměřené na regresi? Pouze z jazykového pohodlí, protože logistická regrese je [ve skutečnosti klasifikační metoda](https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression), i když založená na lineární regresi. O dalších způsobech klasifikace dat se dozvíte v další skupině lekcí.\n",
|
||||
"\n",
|
||||
"Pro tuto lekci budeme potřebovat následující balíčky:\n",
|
||||
"\n",
|
||||
"- `tidyverse`: [tidyverse](https://www.tidyverse.org/) je [kolekce balíčků pro R](https://www.tidyverse.org/packages), která usnadňuje, zrychluje a zpříjemňuje práci s datovou vědou!\n",
|
||||
"\n",
|
||||
"- `tidymodels`: [tidymodels](https://www.tidymodels.org/) je rámec [kolekce balíčků](https://www.tidymodels.org/packages/) pro modelování a strojové učení.\n",
|
||||
"\n",
|
||||
"- `janitor`: [janitor balíček](https://github.com/sfirke/janitor) poskytuje jednoduché nástroje pro zkoumání a čištění špinavých dat.\n",
|
||||
"\n",
|
||||
"- `ggbeeswarm`: [ggbeeswarm balíček](https://github.com/eclarke/ggbeeswarm) nabízí metody pro vytváření grafů ve stylu \"beeswarm\" pomocí ggplot2.\n",
|
||||
"\n",
|
||||
"Můžete je nainstalovat pomocí:\n",
|
||||
"\n",
|
||||
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"janitor\", \"ggbeeswarm\"))`\n",
|
||||
"\n",
|
||||
"Alternativně níže uvedený skript zkontroluje, zda máte potřebné balíčky pro dokončení tohoto modulu, a v případě jejich absence je nainstaluje.\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": [
|
||||
"## **Definujte otázku**\n",
|
||||
"\n",
|
||||
"Pro naše účely ji vyjádříme jako binární: 'Bílá' nebo 'Ne bílá'. V našem datasetu je také kategorie 'pruhovaná', ale má málo záznamů, takže ji nebudeme používat. Stejně zmizí, jakmile odstraníme nulové hodnoty z datasetu.\n",
|
||||
"\n",
|
||||
"> 🎃 Zajímavost: bílé dýně někdy nazýváme 'duchové' dýně. Nejsou příliš snadné na vyřezávání, takže nejsou tak populární jako oranžové, ale vypadají zajímavě! Mohli bychom tedy naši otázku přeformulovat na: 'Duch' nebo 'Ne duch'. 👻\n",
|
||||
"\n",
|
||||
"## **O logistické regresi**\n",
|
||||
"\n",
|
||||
"Logistická regrese se liší od lineární regrese, kterou jste se naučili dříve, v několika důležitých ohledech.\n",
|
||||
"\n",
|
||||
"#### **Binární klasifikace**\n",
|
||||
"\n",
|
||||
"Logistická regrese nenabízí stejné funkce jako lineární regrese. První z nich poskytuje předpověď o `binární kategorii` (\"oranžová nebo ne oranžová\"), zatímco druhá je schopna předpovídat `kontinuální hodnoty`, například na základě původu dýně a času sklizně, *o kolik se zvýší její cena*.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"### Další klasifikace\n",
|
||||
"\n",
|
||||
"Existují i jiné typy logistické regrese, včetně multinomiální a ordinální:\n",
|
||||
"\n",
|
||||
"- **Multinomiální**, která zahrnuje více než jednu kategorii - \"Oranžová, Bílá a Pruhovaná\".\n",
|
||||
"\n",
|
||||
"- **Ordinální**, která zahrnuje uspořádané kategorie, užitečné, pokud bychom chtěli logicky uspořádat naše výsledky, například naše dýně, které jsou uspořádány podle konečného počtu velikostí (mini,sm,med,lg,xl,xxl).\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"#### **Proměnné NEMUSÍ být korelované**\n",
|
||||
"\n",
|
||||
"Pamatujete si, jak lineární regrese fungovala lépe s více korelovanými proměnnými? Logistická regrese je opakem - proměnné nemusí být v souladu. To funguje pro tato data, která mají poměrně slabé korelace.\n",
|
||||
"\n",
|
||||
"#### **Potřebujete hodně čistých dat**\n",
|
||||
"\n",
|
||||
"Logistická regrese poskytne přesnější výsledky, pokud použijete více dat; náš malý dataset není pro tento úkol optimální, takže na to pamatujte.\n",
|
||||
"\n",
|
||||
"✅ Zamyslete se nad typy dat, které by se dobře hodily pro logistickou regresi.\n",
|
||||
"\n",
|
||||
"## Cvičení - úprava dat\n",
|
||||
"\n",
|
||||
"Nejprve data trochu vyčistěte, odstraňte nulové hodnoty a vyberte pouze některé sloupce:\n",
|
||||
"\n",
|
||||
"1. Přidejte následující 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 se můžete podívat na svůj nový dataframe pomocí funkce [*glimpse()*](https://pillar.r-lib.org/reference/glimpse.html), jak je uvedeno níže:\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"vscode": {
|
||||
"languageId": "r"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"pumpkins_select %>% \n",
|
||||
" glimpse()\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Pojďme si potvrdit, že se skutečně budeme zabývat problémem binární klasifikace:\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": [
|
||||
"### Vizualizace - kategorický graf\n",
|
||||
"Nyní jste znovu načetli data o dýních a vyčistili je tak, aby obsahovala dataset s několika proměnnými, včetně barvy. Pojďme vizualizovat dataframe v notebooku pomocí knihovny ggplot.\n",
|
||||
"\n",
|
||||
"Knihovna ggplot nabízí několik skvělých způsobů, jak vizualizovat vaše data. Například můžete porovnat rozložení dat pro každou odrůdu a barvu v kategorickém grafu.\n",
|
||||
"\n",
|
||||
"1. Vytvořte takový graf pomocí funkce geombar, použijte naše data o dýních a specifikujte barevné mapování pro každou kategorii dýní (oranžová nebo bílá):\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": [
|
||||
"Pozorováním dat můžete vidět, jak se údaje o barvě vztahují k odrůdě.\n",
|
||||
"\n",
|
||||
"✅ Na základě tohoto kategorického grafu, jaké zajímavé průzkumy si dokážete představit?\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Předzpracování dat: kódování atributů\n",
|
||||
"\n",
|
||||
"Náš dataset dýní obsahuje textové hodnoty ve všech svých sloupcích. Práce s kategoriálními daty je pro lidi intuitivní, ale pro stroje nikoliv. Algoritmy strojového učení pracují dobře s čísly. Proto je kódování velmi důležitým krokem ve fázi předzpracování dat, protože nám umožňuje převést kategoriální data na numerická, aniž bychom ztratili jakékoliv informace. Dobré kódování vede k vytvoření kvalitního modelu.\n",
|
||||
"\n",
|
||||
"Pro kódování atributů existují dva hlavní typy kódovačů:\n",
|
||||
"\n",
|
||||
"1. Ordinalní kódovač: hodí se pro ordinalní proměnné, což jsou kategoriální proměnné, jejichž data mají logické pořadí, jako například sloupec `item_size` v našem datasetu. Vytváří mapování, kde každá kategorie je reprezentována číslem, které odpovídá pořadí kategorie ve sloupci.\n",
|
||||
"\n",
|
||||
"2. Kategoriální kódovač: hodí se pro nominální proměnné, což jsou kategoriální proměnné, jejichž data nemají logické pořadí, jako všechny atributy kromě `item_size` v našem datasetu. Jedná se o one-hot kódování, což znamená, že každá kategorie je reprezentována binárním sloupcem: kódovaná proměnná je rovna 1, pokud dýně patří do dané Variety, a 0 v opačném případě.\n",
|
||||
"\n",
|
||||
"Tidymodels poskytuje další šikovný balíček: [recipes](https://recipes.tidymodels.org/) - balíček pro předzpracování dat. Definujeme `recipe`, který specifikuje, že všechny sloupce prediktorů by měly být kódovány na sadu celých čísel, `prep` pro odhad potřebných množství a statistik potřebných pro jakékoliv operace, a nakonec `bake` pro aplikaci výpočtů na nová data.\n",
|
||||
"\n",
|
||||
"> Obvykle se recipes používá jako předzpracovatel pro modelování, kde definuje, jaké kroky by měly být aplikovány na dataset, aby byl připraven pro modelování. V takovém případě je **vysoce doporučeno**, abyste použili `workflow()` místo ručního odhadu recipe pomocí prep a bake. Vše si ukážeme za chvíli.\n",
|
||||
">\n",
|
||||
"> Prozatím však používáme recipes + prep + bake k tomu, abychom specifikovali, jaké kroky by měly být aplikovány na dataset, aby byl připraven pro analýzu dat, a následně extrahovali předzpracovaná data s aplikovanými kroky.\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": [
|
||||
"✅ Jaké jsou výhody použití ordinálního enkodéru pro sloupec Item Size?\n",
|
||||
"\n",
|
||||
"### Analýza vztahů mezi proměnnými\n",
|
||||
"\n",
|
||||
"Nyní, když jsme předzpracovali naše data, můžeme analyzovat vztahy mezi vlastnostmi a štítkem, abychom získali představu o tom, jak dobře bude model schopen předpovědět štítek na základě vlastností. Nejlepší způsob, jak provést tento typ analýzy, je vizualizace dat. \n",
|
||||
"Opět použijeme funkci ggplot geom_boxplot_, abychom zobrazili vztahy mezi Item Size, Variety a Color v kategorickém grafu. Pro lepší vizualizaci dat použijeme zakódovaný sloupec Item Size a nekódovaný sloupec 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žijte swarm plot\n",
|
||||
"\n",
|
||||
"Protože Barva je binární kategorie (Bílá nebo Ne), vyžaduje '[specializovaný přístup](https://github.com/rstudio/cheatsheets/blob/main/data-visualization.pdf) k vizualizaci'.\n",
|
||||
"\n",
|
||||
"Vyzkoušejte `swarm plot`, abyste zobrazili rozložení barvy vzhledem k velikosti položky.\n",
|
||||
"\n",
|
||||
"Použijeme balíček [ggbeeswarm](https://github.com/eclarke/ggbeeswarm), který poskytuje metody pro vytváření grafů ve stylu beeswarm pomocí ggplot2. Beeswarm grafy jsou způsobem vykreslování bodů, které by se za normálních okolností překrývaly, tak, aby se zobrazily vedle sebe.\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": [
|
||||
"Nyní, když máme představu o vztahu mezi binárními kategoriemi barvy a širší skupinou velikostí, pojďme prozkoumat logistickou regresi, abychom určili pravděpodobnou barvu dané dýně.\n",
|
||||
"\n",
|
||||
"## Vytvořte svůj model\n",
|
||||
"\n",
|
||||
"Vyberte proměnné, které chcete použít ve svém klasifikačním modelu, a rozdělte data na trénovací a testovací sady. [rsample](https://rsample.tidymodels.org/), balíček v Tidymodels, poskytuje infrastrukturu pro efektivní rozdělování dat a resampling:\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": [
|
||||
"🙌 Nyní jsme připraveni trénovat model tím, že přizpůsobíme tréninkové vlastnosti tréninkovému štítku (barvě).\n",
|
||||
"\n",
|
||||
"Začneme vytvořením receptu, který určuje kroky předzpracování, jež by měly být provedeny na našich datech, aby byla připravena pro modelování, tj. kódování kategoriálních proměnných do sady celých čísel. Stejně jako `baked_pumpkins` vytvoříme `pumpkins_recipe`, ale nebudeme používat `prep` a `bake`, protože to bude zahrnuto do pracovního postupu, který uvidíte za pár kroků.\n",
|
||||
"\n",
|
||||
"Existuje poměrně mnoho způsobů, jak specifikovat logistický regresní model v Tidymodels. Podívejte se na `?logistic_reg()`. Prozatím specifikujeme logistický regresní model pomocí výchozí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": [
|
||||
"Nyní, když máme recept a specifikaci modelu, musíme najít způsob, jak je spojit dohromady do objektu, který nejprve předzpracuje data (příprava + pečení na pozadí), přizpůsobí model na předzpracovaná data a také umožní případné aktivity po zpracování.\n",
|
||||
"\n",
|
||||
"V Tidymodels se tento praktický objekt nazývá [`workflow`](https://workflows.tidymodels.org/) a pohodlně uchovává vaše modelovací 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": [
|
||||
"Poté, co byl pracovní postup *definován*, může být model `natrénován` pomocí funkce [`fit()`](https://tidymodels.github.io/parsnip/reference/fit.html). Pracovní postup odhadne recept a předzpracuje data před tréninkem, takže to nebudeme muset dělat ručně pomocí funkcí 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 vytiskne koeficienty naučené během trénování.\n",
|
||||
"\n",
|
||||
"Nyní, když jsme model natrénovali pomocí trénovacích dat, můžeme provádět predikce na testovacích datech pomocí [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html). Začněme tím, že použijeme model k predikci štítků pro naši testovací sadu a pravděpodobností pro každý štítek. Pokud je pravděpodobnost vyšší než 0,5, predikovaná třída je `WHITE`, jinak `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": [
|
||||
"Velmi pěkné! To poskytuje další vhledy do toho, jak funguje logistická regrese.\n",
|
||||
"\n",
|
||||
"### Lepší pochopení pomocí matice záměn\n",
|
||||
"\n",
|
||||
"Porovnávání každé předpovědi s odpovídající „skutečnou hodnotou“ není příliš efektivní způsob, jak zjistit, jak dobře model předpovídá. Naštěstí má Tidymodels ještě několik triků v rukávu: [`yardstick`](https://yardstick.tidymodels.org/) - balíček používaný k měření účinnosti modelů pomocí metrik výkonu.\n",
|
||||
"\n",
|
||||
"Jednou z metrik výkonu spojených s klasifikačními problémy je [`matice záměn`](https://wikipedia.org/wiki/Confusion_matrix). Matice záměn popisuje, jak dobře klasifikační model funguje. Matice záměn zaznamenává, kolik příkladů v každé třídě bylo modelem správně klasifikováno. V našem případě vám ukáže, kolik oranžových dýní bylo klasifikováno jako oranžové a kolik bílých dýní bylo klasifikováno jako bílé; matice záměn také ukazuje, kolik bylo klasifikováno do **nesprávných** kategorií.\n",
|
||||
"\n",
|
||||
"Funkce [**`conf_mat()`**](https://tidymodels.github.io/yardstick/reference/conf_mat.html) z yardsticku vypočítává tuto křížovou tabulku pozorovaných a předpovězených tříd.\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": [
|
||||
"Pojďme si vysvětlit matici záměn. Náš model má za úkol klasifikovat dýně do dvou binárních kategorií, kategorie `bílá` a kategorie `ne-bílá`.\n",
|
||||
"\n",
|
||||
"- Pokud váš model předpoví dýni jako bílou a ve skutečnosti patří do kategorie 'bílá', nazýváme to `pravý pozitivní`, což je znázorněno číslem v levém horním rohu.\n",
|
||||
"\n",
|
||||
"- Pokud váš model předpoví dýni jako ne-bílou a ve skutečnosti patří do kategorie 'bílá', nazýváme to `falešný negativní`, což je znázorněno číslem v levém dolním rohu.\n",
|
||||
"\n",
|
||||
"- Pokud váš model předpoví dýni jako bílou a ve skutečnosti patří do kategorie 'ne-bílá', nazýváme to `falešný pozitivní`, což je znázorněno číslem v pravém horním rohu.\n",
|
||||
"\n",
|
||||
"- Pokud váš model předpoví dýni jako ne-bílou a ve skutečnosti patří do kategorie 'ne-bílá', nazýváme to `pravý negativní`, což je znázorněno číslem v pravém dolním rohu.\n",
|
||||
"\n",
|
||||
"| Skutečnost |\n",
|
||||
"|:----------:|\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"| | | |\n",
|
||||
"|---------------|--------|-------|\n",
|
||||
"| **Předpověď** | BÍLÁ | ORANŽOVÁ |\n",
|
||||
"| BÍLÁ | TP | FP |\n",
|
||||
"| ORANŽOVÁ | FN | TN |\n",
|
||||
"\n",
|
||||
"Jak jste možná uhodli, je žádoucí mít větší počet pravých pozitivních a pravých negativních a nižší počet falešných pozitivních a falešných negativních, což naznačuje, že model funguje lépe.\n",
|
||||
"\n",
|
||||
"Matice záměn je užitečná, protože z ní vycházejí další metriky, které nám mohou pomoci lépe vyhodnotit výkon klasifikačního modelu. Pojďme si je projít:\n",
|
||||
"\n",
|
||||
"🎓 Přesnost: `TP/(TP + FP)` definovaná jako podíl předpovězených pozitivních, které jsou skutečně pozitivní. Také se nazývá [pozitivní prediktivní hodnota](https://en.wikipedia.org/wiki/Positive_predictive_value \"Positive predictive value\").\n",
|
||||
"\n",
|
||||
"🎓 Záchyt: `TP/(TP + FN)` definovaný jako podíl pozitivních výsledků z počtu vzorků, které byly skutečně pozitivní. Také známý jako `citlivost`.\n",
|
||||
"\n",
|
||||
"🎓 Specifičnost: `TN/(TN + FP)` definovaná jako podíl negativních výsledků z počtu vzorků, které byly skutečně negativní.\n",
|
||||
"\n",
|
||||
"🎓 Přesnost modelu: `TP + TN/(TP + TN + FP + FN)` Procento štítků správně předpovězených pro vzorek.\n",
|
||||
"\n",
|
||||
"🎓 F míra: Vážený průměr přesnosti a záchytu, přičemž nejlepší hodnota je 1 a nejhorší je 0.\n",
|
||||
"\n",
|
||||
"Pojďme tyto metriky vypočítat!\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": [
|
||||
"## Vizualizace ROC křivky tohoto modelu\n",
|
||||
"\n",
|
||||
"Provedeme ještě jednu vizualizaci, abychom si prohlédli tzv. [`ROC křivku`](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 křivky se často používají k zobrazení výstupu klasifikátoru z hlediska jeho skutečných vs. falešných pozitivních výsledků. ROC křivky obvykle zobrazují `True Positive Rate`/citlivost na ose Y a `False Positive Rate`/1-specificitu na ose X. Strmost křivky a prostor mezi středovou čarou a křivkou jsou důležité: chcete křivku, která rychle stoupá a překračuje čáru. V našem případě se na začátku objevují falešné pozitivní výsledky, poté čára správně stoupá a překračuje.\n",
|
||||
"\n",
|
||||
"Nakonec použijme `yardstick::roc_auc()` k výpočtu skutečné plochy pod křivkou. Jedním ze způsobů interpretace AUC je pravděpodobnost, že model zařadí náhodný pozitivní příklad výše než náhodný negativní pří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ýsledek je přibližně `0.975`. Vzhledem k tomu, že AUC se pohybuje v rozmezí od 0 do 1, chcete dosáhnout vysokého skóre, protože model, který je ve svých předpovědích 100% přesný, bude mít AUC rovno 1; v tomto případě je model *docela dobrý*.\n",
|
||||
"\n",
|
||||
"V budoucích lekcích o klasifikacích se naučíte, jak zlepšit skóre svého modelu (například jak se vypořádat s nevyváženými daty v tomto případě).\n",
|
||||
"\n",
|
||||
"## 🚀Výzva\n",
|
||||
"\n",
|
||||
"Logistická regrese nabízí mnohem více k prozkoumání! Nejlepší způsob, jak se učit, je experimentovat. Najděte dataset, který se hodí k tomuto typu analýzy, a vytvořte s ním model. Co jste se naučili? tip: zkuste [Kaggle](https://www.kaggle.com/search?q=logistic+regression+datasets) pro zajímavé datové sady.\n",
|
||||
"\n",
|
||||
"## Přehled & Samostudium\n",
|
||||
"\n",
|
||||
"Přečtěte si první několik stran [tohoto článku ze Stanfordu](https://web.stanford.edu/~jurafsky/slp3/5.pdf) o praktickém využití logistické regrese. Zamyslete se nad úkoly, které jsou lépe vhodné pro jeden nebo druhý typ regresních úkolů, které jsme dosud studovali. Co by fungovalo nejlépe?\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n---\n\n**Prohlášení**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.\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-04T06:48:07+00:00",
|
||||
"source_file": "2-Regression/4-Logistic/solution/R/lesson_4-R.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"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-04T08:16:46+00:00",
|
||||
"source_file": "3-Web-App/1-Web-App/solution/notebook.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"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, TX. Lights racing acros... 12/16/2005 29.384210 \n",
|
||||
"2 Green/Orange circular disc over Chester, 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&#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&#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**Upozornění**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.\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-04T08:44:11+00:00",
|
||||
"source_file": "4-Classification/1-Introduction/notebook.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2,
|
||||
"cells": [
|
||||
{
|
||||
"source": [],
|
||||
"cell_type": "markdown",
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n---\n\n**Prohlášení**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,727 @@
|
||||
{
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"name": "lesson_10-R.ipynb",
|
||||
"provenance": [],
|
||||
"collapsed_sections": []
|
||||
},
|
||||
"kernelspec": {
|
||||
"name": "ir",
|
||||
"display_name": "R"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "R"
|
||||
},
|
||||
"coopTranslator": {
|
||||
"original_hash": "2621e24705e8100893c9bf84e0fc8aef",
|
||||
"translation_date": "2025-09-04T08:50:44+00:00",
|
||||
"source_file": "4-Classification/1-Introduction/solution/R/lesson_10-R.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"# Vytvořte klasifikační model: Lahodné asijské a indické kuchyně\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "ItETB4tSFprR"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Úvod do klasifikace: Čištění, příprava a vizualizace dat\n",
|
||||
"\n",
|
||||
"V těchto čtyřech lekcích se zaměříme na základní téma klasického strojového učení - *klasifikaci*. Projdeme si použití různých klasifikačních algoritmů na datasetu o všech skvělých kuchyních Asie a Indie. Doufáme, že máte hlad!\n",
|
||||
"\n",
|
||||
"<p >\n",
|
||||
" <img src=\"../../images/pinch.png\"\n",
|
||||
" width=\"600\"/>\n",
|
||||
" <figcaption>Oslavte panasijské kuchyně v těchto lekcích! Obrázek od Jen Looper</figcaption>\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"<!---->\n",
|
||||
"\n",
|
||||
"Klasifikace je forma [učeného učení](https://wikipedia.org/wiki/Supervised_learning), která má mnoho společného s regresními technikami. Při klasifikaci trénujete model, aby předpověděl, do které `kategorie` daná položka patří. Pokud je strojové učení o předpovídání hodnot nebo názvů věcí pomocí datasetů, pak klasifikace obecně spadá do dvou skupin: *binární klasifikace* a *vícetřídová klasifikace*.\n",
|
||||
"\n",
|
||||
"Pamatujte:\n",
|
||||
"\n",
|
||||
"- **Lineární regrese** vám pomohla předpovědět vztahy mezi proměnnými a provádět přesné předpovědi, kam nový datový bod spadne ve vztahu k této linii. Například jste mohli předpovědět číselné hodnoty, jako *jaká bude cena dýně v září oproti prosinci*.\n",
|
||||
"\n",
|
||||
"- **Logistická regrese** vám pomohla objevit \"binární kategorie\": při této cenové hladině, *je tato dýně oranžová nebo neoranžová*?\n",
|
||||
"\n",
|
||||
"Klasifikace využívá různé algoritmy k určení dalších způsobů, jak určit štítek nebo třídu datového bodu. Pojďme pracovat s těmito daty o kuchyních a zjistit, zda můžeme na základě skupiny ingrediencí určit původní kuchyni.\n",
|
||||
"\n",
|
||||
"### [**Kvíz před lekcí**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/19/)\n",
|
||||
"\n",
|
||||
"### **Úvod**\n",
|
||||
"\n",
|
||||
"Klasifikace je jednou ze základních činností výzkumníka strojového učení a datového vědce. Od základní klasifikace binární hodnoty (\"je tento e-mail spam nebo ne?\") až po složitou klasifikaci a segmentaci obrázků pomocí počítačového vidění, je vždy užitečné být schopen třídit data do tříd a klást jim otázky.\n",
|
||||
"\n",
|
||||
"Řečeno vědecky, vaše klasifikační metoda vytváří prediktivní model, který vám umožňuje mapovat vztah mezi vstupními proměnnými a výstupními proměnnými.\n",
|
||||
"\n",
|
||||
"<p >\n",
|
||||
" <img src=\"../../images/binary-multiclass.png\"\n",
|
||||
" width=\"600\"/>\n",
|
||||
" <figcaption>Binární vs. vícetřídové problémy, které klasifikační algoritmy řeší. Infografika od Jen Looper</figcaption>\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Než začneme s procesem čištění našich dat, jejich vizualizací a přípravou na úkoly strojového učení, pojďme se trochu seznámit s různými způsoby, jak lze strojové učení využít ke klasifikaci dat.\n",
|
||||
"\n",
|
||||
"Odvozeno ze [statistiky](https://wikipedia.org/wiki/Statistical_classification), klasifikace pomocí klasického strojového učení využívá vlastnosti, jako jsou `kuřák`, `váha` a `věk`, k určení *pravděpodobnosti vývoje X nemoci*. Jako technika učeného učení podobná regresním cvičením, která jste prováděli dříve, jsou vaše data označena a algoritmy strojového učení používají tyto štítky k klasifikaci a předpovědi tříd (nebo 'vlastností') datasetu a jejich přiřazení ke skupině nebo výsledku.\n",
|
||||
"\n",
|
||||
"✅ Udělejte si chvíli a představte si dataset o kuchyních. Na co by mohl odpovědět vícetřídový model? Na co by mohl odpovědět binární model? Co kdybyste chtěli určit, zda daná kuchyně pravděpodobně používá pískavici? Co kdybyste chtěli zjistit, zda byste mohli z tašky s potravinami plné badyánu, artyčoků, květáku a křenu vytvořit typické indické jídlo?\n",
|
||||
"\n",
|
||||
"### **Ahoj 'klasifikátore'**\n",
|
||||
"\n",
|
||||
"Otázka, kterou chceme položit tomuto datasetu o kuchyních, je vlastně **vícetřídová otázka**, protože máme několik potenciálních národních kuchyní, se kterými můžeme pracovat. Na základě dávky ingrediencí, do které z těchto mnoha tříd budou data spadat?\n",
|
||||
"\n",
|
||||
"Tidymodels nabízí několik různých algoritmů pro klasifikaci dat, v závislosti na typu problému, který chcete řešit. V následujících dvou lekcích se naučíte o několika z těchto algoritmů.\n",
|
||||
"\n",
|
||||
"#### **Předpoklady**\n",
|
||||
"\n",
|
||||
"Pro tuto lekci budeme potřebovat následující balíčky pro čištění, přípravu a vizualizaci našich dat:\n",
|
||||
"\n",
|
||||
"- `tidyverse`: [tidyverse](https://www.tidyverse.org/) je [kolekce balíčků pro R](https://www.tidyverse.org/packages), která dělá datovou vědu rychlejší, jednodušší a zábavnější!\n",
|
||||
"\n",
|
||||
"- `tidymodels`: [tidymodels](https://www.tidymodels.org/) je [rámec balíčků](https://www.tidymodels.org/packages/) pro modelování a strojové učení.\n",
|
||||
"\n",
|
||||
"- `DataExplorer`: [balíček DataExplorer](https://cran.r-project.org/web/packages/DataExplorer/vignettes/dataexplorer-intro.html) je určen k zjednodušení a automatizaci procesu EDA a generování reportů.\n",
|
||||
"\n",
|
||||
"- `themis`: [balíček themis](https://themis.tidymodels.org/) poskytuje další kroky pro práci s nevyváženými daty.\n",
|
||||
"\n",
|
||||
"Můžete je nainstalovat pomocí:\n",
|
||||
"\n",
|
||||
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"DataExplorer\", \"here\"))`\n",
|
||||
"\n",
|
||||
"Alternativně, skript níže zkontroluje, zda máte balíčky potřebné k dokončení tohoto modulu, a nainstaluje je za vás, pokud chybí.\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": [
|
||||
"Později načteme tyto skvělé balíčky a zpřístupníme je v naší aktuální relaci R. (Toto je pouze pro ilustraci, `pacman::p_load()` to již za vás udělal)\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "YkKAxOJvGD4C"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Cvičení - vyčistěte a vyvažte svá data\n",
|
||||
"\n",
|
||||
"Prvním úkolem, než začnete s tímto projektem, je vyčistit a **vyvážit** svá data, abyste dosáhli lepších výsledků.\n",
|
||||
"\n",
|
||||
"Seznamme se s daty! 🕵️\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": [
|
||||
"Zajímavé! Podle všeho je první sloupec jakýsi sloupec `id`. Zjistíme si trochu více informací o těchto datech.\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žitě vidět, že máme `2448` řádků a `385` sloupců a `0` chybějících hodnot. Máme také 1 diskrétní sloupec, *cuisine*.\n",
|
||||
"\n",
|
||||
"## Cvičení - poznávání kuchyní\n",
|
||||
"\n",
|
||||
"Teď začíná práce být zajímavější. Pojďme objevit rozložení dat podle jednotlivých kuchyní.\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 kuchyní, ale rozložení dat je nerovnoměrné. To můžete napravit! Než tak učiníte, prozkoumejte to trochu více.\n",
|
||||
"\n",
|
||||
"Dále přiřaďme každou kuchyni do jejího vlastního tibble a zjistěme, kolik dat je k dispozici (řádky, sloupce) pro jednotlivé kuchyně.\n",
|
||||
"\n",
|
||||
"> [Tibble](https://tibble.tidyverse.org/) je moderní datový rámec.\n",
|
||||
"\n",
|
||||
"<p >\n",
|
||||
" <img src=\"../../images/dplyr_filter.jpg\"\n",
|
||||
" width=\"600\"/>\n",
|
||||
" <figcaption>Ilustrace 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čení - Objevování nejlepších ingrediencí podle kuchyně pomocí dplyr**\n",
|
||||
"\n",
|
||||
"Nyní se můžete ponořit hlouběji do dat a zjistit, jaké jsou typické ingredience pro jednotlivé kuchyně. Měli byste odstranit opakující se data, která vytvářejí zmatek mezi kuchyněmi, takže se podíváme na tento problém.\n",
|
||||
"\n",
|
||||
"Vytvořte funkci `create_ingredient()` v R, která vrátí dataframe s ingrediencemi. Tato funkce začne odstraněním nepotřebného sloupce a seřadí ingredience podle jejich počtu.\n",
|
||||
"\n",
|
||||
"Základní struktura funkce v R vypadá takto:\n",
|
||||
"\n",
|
||||
"`myFunction <- function(arglist){`\n",
|
||||
"\n",
|
||||
"**`...`**\n",
|
||||
"\n",
|
||||
"**`return`**`(value)`\n",
|
||||
"\n",
|
||||
"`}`\n",
|
||||
"\n",
|
||||
"Přehledný úvod do funkcí v R najdete [zde](https://skirmer.github.io/presentations/functions_with_r.html#1).\n",
|
||||
"\n",
|
||||
"Pojďme na to! Využijeme [dplyr sloves](https://dplyr.tidyverse.org/), které jsme se učili v předchozích lekcích. Pro připomenutí:\n",
|
||||
"\n",
|
||||
"- `dplyr::select()`: pomáhá vám vybrat, které **sloupce** chcete ponechat nebo vyloučit.\n",
|
||||
"\n",
|
||||
"- `dplyr::pivot_longer()`: pomáhá \"prodloužit\" data, zvýšit počet řádků a snížit počet sloupců.\n",
|
||||
"\n",
|
||||
"- `dplyr::group_by()` a `dplyr::summarise()`: pomáhá najít souhrnné statistiky pro různé skupiny a uspořádat je do přehledné tabulky.\n",
|
||||
"\n",
|
||||
"- `dplyr::filter()`: vytváří podmnožinu dat obsahující pouze řádky, které splňují vaše podmínky.\n",
|
||||
"\n",
|
||||
"- `dplyr::mutate()`: pomáhá vytvořit nebo upravit sloupce.\n",
|
||||
"\n",
|
||||
"Podívejte se na tento [*uměním* naplněný learnr tutoriál](https://allisonhorst.shinyapps.io/dplyr-learnr/#section-welcome) od Allison Horst, který představuje některé užitečné funkce pro zpracování dat v dplyr *(součást 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": [
|
||||
"Nyní můžeme použít funkci, abychom získali představu o deseti nejoblíbenějších ingrediencích podle kuchyně. Pojďme si to vyzkoušet 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 předchozí části jsme použili `geom_col()`, podívejme se, jak můžete použít také `geom_bar` k vytvoření sloupcových grafů. Použijte `?geom_bar` pro další čtení.\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": [
|
||||
"Pojďme udělat totéž pro japonská data\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": [
|
||||
"Co třeba čínská kuchyně?\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": [
|
||||
"Nakonec vykreslete korejské ingredience.\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": [
|
||||
"Z datových vizualizací nyní můžeme vyřadit nejběžnější ingredience, které způsobují záměnu mezi různými kuchyněmi, pomocí `dplyr::select()`.\n",
|
||||
"\n",
|
||||
"Každý miluje rýži, česnek 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": [
|
||||
"## Předzpracování dat pomocí receptů 👩🍳👨🍳 - Práce s nevyváženými daty ⚖️\n",
|
||||
"\n",
|
||||
"<p >\n",
|
||||
" <img src=\"../../images/recipes.png\"\n",
|
||||
" width=\"600\"/>\n",
|
||||
" <figcaption>Ilustrace od @allison_horst</figcaption>\n",
|
||||
"\n",
|
||||
"Vzhledem k tomu, že tato lekce je o kuchyních, musíme dát `recepty` do kontextu.\n",
|
||||
"\n",
|
||||
"Tidymodels nabízí další šikovný balíček: `recipes` - balíček pro předzpracování dat.\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "kkFd-JxdIaL6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"Pojďme se znovu podívat na rozložení našich kuchyní.\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": [
|
||||
"Jak vidíte, počet kuchyní je značně nerovnoměrně rozložen. Korejské kuchyně jsou téměř třikrát početnější než thajské kuchyně. Nevyvážená data často negativně ovlivňují výkon modelu. Představte si binární klasifikaci. Pokud většina vašich dat patří do jedné třídy, model strojového učení bude tuto třídu předpovídat častěji, jednoduše proto, že pro ni má více dat. Vyvážení dat odstraňuje jakoukoli nerovnováhu v datech. Mnoho modelů dosahuje nejlepšího výkonu, když je počet pozorování stejný, a proto mají tendenci mít problémy s nevyváženými daty.\n",
|
||||
"\n",
|
||||
"Existují dvě hlavní metody, jak pracovat s nevyváženými datovými sadami:\n",
|
||||
"\n",
|
||||
"- přidání pozorování do minoritní třídy: `Over-sampling`, například použití algoritmu SMOTE\n",
|
||||
"\n",
|
||||
"- odstranění pozorování z majoritní třídy: `Under-sampling`\n",
|
||||
"\n",
|
||||
"Nyní si ukážeme, jak pracovat s nevyváženými datovými sadami pomocí `receptu`. Recept si můžete představit jako plán, který popisuje, jaké kroky by měly být aplikovány na datovou sadu, aby byla připravena pro analýzu dat.\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": [
|
||||
"Pojďme si rozebrat kroky předzpracování.\n",
|
||||
"\n",
|
||||
"- Volání `recipe()` s formulí říká receptu *role* proměnných pomocí dat `df_select` jako referenčního bodu. Například sloupec `cuisine` byl přiřazen roli `outcome`, zatímco ostatní sloupce byly přiřazeny roli `predictor`.\n",
|
||||
"\n",
|
||||
"- [`step_smote(cuisine)`](https://themis.tidymodels.org/reference/step_smote.html) vytváří *specifikaci* kroku receptu, který synteticky generuje nové příklady minoritní třídy pomocí nejbližších sousedů těchto případů.\n",
|
||||
"\n",
|
||||
"Pokud bychom nyní chtěli vidět předzpracovaná data, museli bychom [**`prep()`**](https://recipes.tidymodels.org/reference/prep.html) a [**`bake()`**](https://recipes.tidymodels.org/reference/bake.html) náš recept.\n",
|
||||
"\n",
|
||||
"`prep()`: odhaduje potřebné parametry z trénovací sady, které mohou být později aplikovány na jiné datové sady.\n",
|
||||
"\n",
|
||||
"`bake()`: vezme připravený recept a aplikuje operace na jakoukoli datovou sadu.\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": [
|
||||
"Pojďme nyní zkontrolovat rozložení našich kuchyní a porovnat je s nevyváženými daty.\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! Data jsou pěkně čistá, vyvážená a velmi chutná 😋!\n",
|
||||
"\n",
|
||||
"> Obvykle se recept používá jako předzpracovatel pro modelování, kde definuje, jaké kroky by měly být aplikovány na datovou sadu, aby byla připravena pro modelování. V takovém případě se obvykle používá `workflow()` (jak jsme již viděli v našich předchozích lekcích) místo ručního odhadu receptu.\n",
|
||||
">\n",
|
||||
"> Proto obvykle nemusíte používat **`prep()`** a **`bake()`** recepty, když používáte tidymodels, ale jsou to užitečné funkce, které můžete mít ve své sadě nástrojů pro ověření, že recepty fungují podle vašich očekávání, jako v našem případě.\n",
|
||||
">\n",
|
||||
"> Když použijete **`bake()`** na připravený recept s **`new_data = NULL`**, získáte zpět data, která jste poskytli při definování receptu, ale prošla kroky předzpracování.\n",
|
||||
"\n",
|
||||
"Teď si uložíme kopii těchto dat pro použití v budoucích lekcí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 soubor nyní najdete v kořenové složce dat.\n",
|
||||
"\n",
|
||||
"**🚀Výzva**\n",
|
||||
"\n",
|
||||
"Tento kurz obsahuje několik zajímavých datových sad. Projděte složky `data` a zjistěte, zda některé obsahují datové sady vhodné pro binární nebo vícetřídní klasifikaci. Jaké otázky byste si k této datové sadě položili?\n",
|
||||
"\n",
|
||||
"## [**Kvíz po přednášce**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/20/)\n",
|
||||
"\n",
|
||||
"## **Opakování & Samostudium**\n",
|
||||
"\n",
|
||||
"- Podívejte se na [balíček themis](https://github.com/tidymodels/themis). Jaké další techniky bychom mohli použít k řešení problémů s nevyváženými daty?\n",
|
||||
"\n",
|
||||
"- Referenční web [Tidy models](https://www.tidymodels.org/start/).\n",
|
||||
"\n",
|
||||
"- H. Wickham a G. Grolemund, [*R for Data Science: Visualize, Model, Transform, Tidy, and Import Data*](https://r4ds.had.co.nz/).\n",
|
||||
"\n",
|
||||
"#### DĚKUJEME:\n",
|
||||
"\n",
|
||||
"[`Allison Horst`](https://twitter.com/allison_horst/) za vytvoření úžasných ilustrací, které činí R přívětivějším a poutavějším. Další ilustrace najdete v její [galerii](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 vytvoření původní verze tohoto modulu v Pythonu ♥️\n",
|
||||
"\n",
|
||||
"<p >\n",
|
||||
" <img src=\"../../images/r_learners_sm.jpeg\"\n",
|
||||
" width=\"600\"/>\n",
|
||||
" <figcaption>Ilustrace od @allison_horst</figcaption>\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "WQs5621pMGwf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n---\n\n**Upozornění**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.\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-04T08:17:22+00:00",
|
||||
"source_file": "4-Classification/2-Classifiers-1/notebook.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2,
|
||||
"cells": [
|
||||
{
|
||||
"source": [
|
||||
"Vytváření klasifikačních modelů\n"
|
||||
],
|
||||
"cell_type": "markdown",
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n---\n\n**Prohlášení**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Za autoritativní zdroj by měl být považován původní dokument v jeho původním jazyce. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,650 @@
|
||||
{
|
||||
"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-04T08:35:13+00:00",
|
||||
"source_file": "4-Classification/3-Classifiers-2/solution/R/lesson_12-R.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "jsFutf_ygqSx"
|
||||
},
|
||||
"source": [
|
||||
"# Vytvořte klasifikační model: Lahodné asijské a indické kuchyně\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "HD54bEefgtNO"
|
||||
},
|
||||
"source": [
|
||||
"## Klasifikátory kuchyní 2\n",
|
||||
"\n",
|
||||
"V této druhé lekci o klasifikaci se podíváme na `další způsoby`, jak klasifikovat kategorická data. Také se zaměříme na důsledky výběru jednoho klasifikátoru oproti jinému.\n",
|
||||
"\n",
|
||||
"### [**Kvíz před lekcí**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/23/)\n",
|
||||
"\n",
|
||||
"### **Předpoklady**\n",
|
||||
"\n",
|
||||
"Předpokládáme, že jste dokončili předchozí lekce, protože budeme navazovat na některé koncepty, které jsme se již naučili.\n",
|
||||
"\n",
|
||||
"Pro tuto lekci budeme potřebovat následující balíčky:\n",
|
||||
"\n",
|
||||
"- `tidyverse`: [tidyverse](https://www.tidyverse.org/) je [kolekce balíčků pro R](https://www.tidyverse.org/packages), která usnadňuje, zrychluje a zpříjemňuje práci s datovou vědou!\n",
|
||||
"\n",
|
||||
"- `tidymodels`: [tidymodels](https://www.tidymodels.org/) je rámec [kolekce balíčků](https://www.tidymodels.org/packages/) pro modelování a strojové učení.\n",
|
||||
"\n",
|
||||
"- `themis`: [balíček themis](https://themis.tidymodels.org/) poskytuje další kroky pro recepty, které řeší problém nevyvážených dat.\n",
|
||||
"\n",
|
||||
"Můžete je nainstalovat pomocí:\n",
|
||||
"\n",
|
||||
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"kernlab\", \"themis\", \"ranger\", \"xgboost\", \"kknn\"))`\n",
|
||||
"\n",
|
||||
"Alternativně níže uvedený skript zkontroluje, zda máte balíčky potřebné k dokončení tohoto modulu, a v případě, že chybí, je nainstaluje.\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 klasifikace**\n",
|
||||
"\n",
|
||||
"V naší [předchozí lekci](https://github.com/microsoft/ML-For-Beginners/tree/main/4-Classification/2-Classifiers-1) jsme se snažili odpovědět na otázku: jak si vybrat mezi více modely? Do značné míry to závisí na charakteristikách dat a typu problému, který chceme řešit (například klasifikace nebo regrese?).\n",
|
||||
"\n",
|
||||
"Dříve jsme se seznámili s různými možnostmi, které máte při klasifikaci dat, pomocí přehledové tabulky od Microsoftu. Pythonův framework pro strojové učení, Scikit-learn, nabízí podobnou, ale podrobnější přehledovou tabulku, která vám může dále pomoci zúžit výběr odhadovačů (jiný termín pro 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štivte tuto mapu online](https://scikit-learn.org/stable/tutorial/machine_learning_map/) a klikněte na cestu, abyste si přečetli dokumentaci.\n",
|
||||
">\n",
|
||||
"> [Referenční stránka Tidymodels](https://www.tidymodels.org/find/parsnip/#models) také poskytuje vynikající dokumentaci o různých typech modelů.\n",
|
||||
"\n",
|
||||
"### **Plán** 🗺️\n",
|
||||
"\n",
|
||||
"Tato mapa je velmi užitečná, jakmile máte jasnou představu o svých datech, protože se můžete „procházet“ po jejích cestách k rozhodnutí:\n",
|
||||
"\n",
|
||||
"- Máme více než 50 vzorků\n",
|
||||
"\n",
|
||||
"- Chceme předpovědět kategorii\n",
|
||||
"\n",
|
||||
"- Máme označená data\n",
|
||||
"\n",
|
||||
"- Máme méně než 100 tisíc vzorků\n",
|
||||
"\n",
|
||||
"- ✨ Můžeme zvolit Linear SVC\n",
|
||||
"\n",
|
||||
"- Pokud to nefunguje, protože máme číselná data\n",
|
||||
"\n",
|
||||
" - Můžeme zkusit ✨ KNeighbors Classifier\n",
|
||||
"\n",
|
||||
" - Pokud to nefunguje, zkusíme ✨ SVC a ✨ Ensemble Classifiers\n",
|
||||
"\n",
|
||||
"Toto je velmi užitečná cesta, kterou se můžeme řídit. Teď se do toho pustíme pomocí [tidymodels](https://www.tidymodels.org/) frameworku pro modelování: konzistentní a flexibilní kolekce balíčků v R, vyvinutá pro podporu dobré statistické praxe 😊.\n",
|
||||
"\n",
|
||||
"## 2. Rozdělení dat a práce s nevyváženým datovým souborem.\n",
|
||||
"\n",
|
||||
"Z našich předchozích lekcí jsme se naučili, že existuje sada společných ingrediencí napříč našimi kuchyněmi. Také jsme zjistili, že rozložení počtu kuchyní bylo dost nerovnoměrné.\n",
|
||||
"\n",
|
||||
"S tím se vypořádáme takto:\n",
|
||||
"\n",
|
||||
"- Odstraníme nejběžnější ingredience, které vytvářejí zmatek mezi odlišnými kuchyněmi, pomocí `dplyr::select()`.\n",
|
||||
"\n",
|
||||
"- Použijeme `recipe`, který předzpracuje data, aby byla připravena pro modelování, aplikací algoritmu `over-sampling`.\n",
|
||||
"\n",
|
||||
"Toto jsme již probírali v předchozí lekci, 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": [
|
||||
"### Práce s nevyváženými daty\n",
|
||||
"\n",
|
||||
"Nevyvážená data často negativně ovlivňují výkon modelu. Mnoho modelů dosahuje nejlepších výsledků, když je počet pozorování vyrovnaný, a proto mají tendenci mít problémy s nevyváženými daty.\n",
|
||||
"\n",
|
||||
"Existují dvě hlavní metody, jak pracovat s nevyváženými datovými sadami:\n",
|
||||
"\n",
|
||||
"- přidání pozorování do menšinové třídy: `Over-sampling`, například použitím algoritmu SMOTE, který synteticky generuje nové příklady menšinové třídy na základě nejbližších sousedů těchto případů.\n",
|
||||
"\n",
|
||||
"- odstranění pozorování z většinové třídy: `Under-sampling`\n",
|
||||
"\n",
|
||||
"V naší předchozí lekci jsme ukázali, jak pracovat s nevyváženými datovými sadami pomocí `receptu`. Recept si můžeme představit jako plán, který popisuje, jaké kroky by měly být aplikovány na datovou sadu, aby byla připravena pro analýzu dat. V našem případě chceme dosáhnout rovnoměrného rozložení počtu našich kuchyní v `trénovací sadě`. Pojďme se do toho pustit.\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": [
|
||||
"Teď jsme připraveni trénovat modely 👩💻👨💻!\n",
|
||||
"\n",
|
||||
"## 3. Nad rámec multinomiálních regresních modelů\n",
|
||||
"\n",
|
||||
"V naší předchozí lekci jsme se zabývali multinomiálními regresními modely. Pojďme prozkoumat některé flexibilnější modely pro klasifikaci.\n",
|
||||
"\n",
|
||||
"### Support Vector Machines\n",
|
||||
"\n",
|
||||
"V kontextu klasifikace je `Support Vector Machines` technika strojového učení, která se snaží najít *hyperrovinu*, která \"nejlépe\" odděluje třídy. Podívejme se na jednoduchý pří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~ nerozděluje třídy. H2~ je rozděluje, ale pouze s malým okrajem. H3~ je rozděluje s maximálním okrajem.\n",
|
||||
"\n",
|
||||
"#### Lineární klasifikátor podpůrných vektorů\n",
|
||||
"\n",
|
||||
"Shlukování pomocí podpůrných vektorů (SVC) je součástí rodiny technik strojového učení založených na podpůrných vektorech. V SVC je hyperrovina zvolena tak, aby správně oddělila `většinu` tréninkových pozorování, ale `může nesprávně klasifikovat` několik pozorování. Tím, že umožníme některým bodům být na nesprávné straně, se SVM stává odolnějším vůči odlehlým hodnotám, což vede k lepší generalizaci na nová data. Parametr, který reguluje toto porušení, se nazývá `cost` a má výchozí hodnotu 1 (viz `help(\"svm_poly\")`).\n",
|
||||
"\n",
|
||||
"Vytvořme lineární SVC nastavením `degree = 1` v polynomiálním 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": [
|
||||
"Nyní, když jsme zachytili kroky předzpracování a specifikaci modelu do *workflow*, můžeme pokračovat s trénováním lineárního SVC a zároveň vyhodnocovat výsledky. Pro metriky výkonu vytvořme sadu metrik, která bude hodnotit: `přesnost`, `citlivost`, `Pozitivní prediktivní hodnotu` a `F míru`.\n",
|
||||
"\n",
|
||||
"> `augment()` přidá sloupec/sloupce s predikcemi do daných dat.\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šířením support vector classifier, které umožňuje zohlednit nelineární hranici mezi třídami. V podstatě SVM využívají *kernel trick* k rozšíření prostoru příznaků, aby se přizpůsobily nelineárním vztahům mezi třídami. Jednou z populárních a velmi flexibilních kernel funkcí používaných v SVM je *Radial basis function.* Podívejme se, jak si povede na našich datech.\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": [
|
||||
"Mnohem lepší 🤩!\n",
|
||||
"\n",
|
||||
"> ✅ Podívejte se:\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",
|
||||
"> pro další čtení.\n",
|
||||
"\n",
|
||||
"### Klasifikátory nejbližšího souseda\n",
|
||||
"\n",
|
||||
"*K*-nejbližší soused (KNN) je algoritmus, ve kterém je každé pozorování předpovězeno na základě jeho *podobnosti* s ostatními pozorováními.\n",
|
||||
"\n",
|
||||
"Pojďme ho aplikovat na naše data.\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á se, že tento model nefunguje příliš dobře. Pravděpodobně změna parametrů modelu (viz `help(\"nearest_neighbor\")`) zlepší jeho výkon. Určitě to vyzkoušejte.\n",
|
||||
"\n",
|
||||
"> ✅ Podívejte se:\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",
|
||||
"> pro více informací o klasifikátorech *K*-Nearest Neighbors.\n",
|
||||
"\n",
|
||||
"### Ensemble klasifikátory\n",
|
||||
"\n",
|
||||
"Ensemble algoritmy fungují tak, že kombinují více základních odhadů, aby vytvořily optimální model buď:\n",
|
||||
"\n",
|
||||
"`bagging`: použitím *průměrovací funkce* na kolekci základních modelů\n",
|
||||
"\n",
|
||||
"`boosting`: vytvořením sekvence modelů, které na sebe navazují a zlepšují prediktivní výkon.\n",
|
||||
"\n",
|
||||
"Začněme tím, že vyzkoušíme model Random Forest, který vytváří velkou kolekci rozhodovacích stromů a poté aplikuje průměrovací funkci pro vytvoření lepšího 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áce 👏!\n",
|
||||
"\n",
|
||||
"Pojďme také experimentovat s modelem Boosted Tree.\n",
|
||||
"\n",
|
||||
"Boosted Tree definuje ensemble metodu, která vytváří sérii sekvenčních rozhodovacích stromů, kde každý strom závisí na výsledcích předchozích stromů ve snaze postupně snižovat chybu. Zaměřuje se na váhy nesprávně klasifikovaných položek a upravuje přizpůsobení pro další klasifikátor, aby chybu napravil.\n",
|
||||
"\n",
|
||||
"Existují různé způsoby, jak tento model přizpůsobit (viz `help(\"boost_tree\")`). V tomto příkladu budeme přizpůsobovat Boosted trees pomocí 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": [
|
||||
"> ✅ Podívejte se:\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/> - Zkoumá model AdaBoost, který je dobrou alternativou k xgboost.\n",
|
||||
">\n",
|
||||
"> pro více informací o Ensemble klasifikátorech.\n",
|
||||
"\n",
|
||||
"## 4. Extra - porovnání více modelů\n",
|
||||
"\n",
|
||||
"V tomto cvičení jsme vytvořili poměrně velké množství modelů 🙌. Může být únavné nebo zdlouhavé vytvářet mnoho workflowů z různých sad předzpracování a/nebo specifikací modelů a poté jeden po druhém počítat metriky výkonu.\n",
|
||||
"\n",
|
||||
"Podívejme se, zda to můžeme vyřešit vytvořením funkce, která aplikuje seznam workflowů na trénovací sadu a poté vrátí metriky výkonu na základě testovací sady. Použijeme `map()` a `map_dfr()` z balíčku [purrr](https://purrr.tidyverse.org/) k aplikaci funkcí na každý prvek seznamu.\n",
|
||||
"\n",
|
||||
"> Funkce [`map()`](https://purrr.tidyverse.org/reference/map.html) vám umožňují nahradit mnoho for smyček kódem, který je stručnější a snadněji čitelný. Nejlepší místo, kde se naučit o funkcích [`map()`](https://purrr.tidyverse.org/reference/map.html), je [kapitola o iteraci](http://r4ds.had.co.nz/iteration.html) v 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íček umožňuje uživatelům vytvářet a snadno aplikovat velké množství modelů, ale je primárně navržen pro práci s technikami resamplingu, jako je `cross-validation`, přístup, který teprve budeme probírat.\n",
|
||||
"\n",
|
||||
"## **🚀Výzva**\n",
|
||||
"\n",
|
||||
"Každá z těchto technik má velké množství parametrů, které můžete upravovat, například `cost` u SVM, `neighbors` u KNN, `mtry` (náhodně vybraní prediktory) u Random Forest.\n",
|
||||
"\n",
|
||||
"Prozkoumejte výchozí parametry každého z nich a zamyslete se nad tím, co by úprava těchto parametrů znamenala pro kvalitu modelu.\n",
|
||||
"\n",
|
||||
"Chcete-li zjistit více o konkrétním modelu a jeho parametrech, použijte: `help(\"model\")`, například `help(\"rand_forest\")`.\n",
|
||||
"\n",
|
||||
"> V praxi obvykle *odhadujeme* *nejlepší hodnoty* těchto parametrů tím, že trénujeme mnoho modelů na `simulovaném datovém souboru` a měříme, jak dobře všechny tyto modely fungují. Tento proces se nazývá **ladění**.\n",
|
||||
"\n",
|
||||
"### [**Kvíz po přednášce**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/24/)\n",
|
||||
"\n",
|
||||
"### **Přehled & Samostudium**\n",
|
||||
"\n",
|
||||
"V těchto lekcích je hodně odborných termínů, takže si udělejte chvíli na přezkoumání [tohoto seznamu](https://docs.microsoft.com/dotnet/machine-learning/resources/glossary?WT.mc_id=academic-77952-leestott) užitečné terminologie!\n",
|
||||
"\n",
|
||||
"#### DĚKUJEME:\n",
|
||||
"\n",
|
||||
"[`Allison Horst`](https://twitter.com/allison_horst/) za vytvoření úžasných ilustrací, které činí R přívětivějším a poutavějším. Další ilustrace najdete v její [galerii](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 vytvoření původní verze tohoto modulu v Pythonu ♥️\n",
|
||||
"\n",
|
||||
"Šťastné učení,\n",
|
||||
"\n",
|
||||
"[Eric](https://twitter.com/ericntay), Zlatý ambasador Microsoft Learn Student.\n",
|
||||
"\n",
|
||||
"<p >\n",
|
||||
" <img src=\"../../images/r_learners_sm.jpeg\"\n",
|
||||
" width=\"569\"/>\n",
|
||||
" <figcaption>Ilustrace od @allison_horst</figcaption>\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n---\n\n**Upozornění**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.\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": 4,
|
||||
"coopTranslator": {
|
||||
"original_hash": "2f3e0d9e9ac5c301558fb8bf733ac0cb",
|
||||
"translation_date": "2025-09-04T08:30:32+00:00",
|
||||
"source_file": "4-Classification/4-Applied/notebook.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2,
|
||||
"cells": [
|
||||
{
|
||||
"source": [],
|
||||
"cell_type": "markdown",
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n---\n\n**Prohlášení**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o přesnost, mějte na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.\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-04T07:41:57+00:00",
|
||||
"source_file": "5-Clustering/1-Visualize/notebook.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"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**Upozornění**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.\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,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-04T08:06:44+00:00",
|
||||
"source_file": "5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "GULATlQXLXyR"
|
||||
},
|
||||
"source": [
|
||||
"## Prozkoumejte shlukování metodou K-Means pomocí R a principů tidy dat.\n",
|
||||
"\n",
|
||||
"### [**Kvíz před lekcí**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/29/)\n",
|
||||
"\n",
|
||||
"V této lekci se naučíte, jak vytvářet shluky pomocí balíčku Tidymodels a dalších balíčků z ekosystému R (říkejme jim přátelé 🧑🤝🧑) a nigerijského hudebního datasetu, který jste si dříve importovali. Probereme základy metody K-Means pro shlukování. Mějte na paměti, že jak jste se naučili v předchozí lekci, existuje mnoho způsobů, jak pracovat se shluky, a metoda, kterou použijete, závisí na vašich datech. Vyzkoušíme metodu K-Means, protože je to nejběžnější technika shlukování. Pojďme začít!\n",
|
||||
"\n",
|
||||
"Pojmy, o kterých se dozvíte:\n",
|
||||
"\n",
|
||||
"- Silhouette skóre\n",
|
||||
"\n",
|
||||
"- Metoda lokte\n",
|
||||
"\n",
|
||||
"- Inerční moment\n",
|
||||
"\n",
|
||||
"- Variance\n",
|
||||
"\n",
|
||||
"### **Úvod**\n",
|
||||
"\n",
|
||||
"[Shlukování metodou K-Means](https://wikipedia.org/wiki/K-means_clustering) je metoda pocházející z oblasti zpracování signálů. Používá se k rozdělení a seskupení dat do `k shluků` na základě podobností jejich vlastností.\n",
|
||||
"\n",
|
||||
"Shluky lze vizualizovat jako [Voronoiovy diagramy](https://wikipedia.org/wiki/Voronoi_diagram), které zahrnují bod (nebo „semínko“) a jeho odpovídající oblast.\n",
|
||||
"\n",
|
||||
"<p >\n",
|
||||
" <img src=\"../../images/voronoi.png\"\n",
|
||||
" width=\"500\"/>\n",
|
||||
" <figcaption>Infografika od Jen Looper</figcaption>\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Shlukování metodou K-Means zahrnuje následující kroky:\n",
|
||||
"\n",
|
||||
"1. Datový vědec nejprve určí požadovaný počet shluků, které mají být vytvořeny.\n",
|
||||
"\n",
|
||||
"2. Algoritmus poté náhodně vybere K pozorování z datové sady, která budou sloužit jako počáteční středy shluků (tj. centroidy).\n",
|
||||
"\n",
|
||||
"3. Každé z ostatních pozorování je následně přiřazeno k nejbližšímu centroidu.\n",
|
||||
"\n",
|
||||
"4. Poté se vypočítá nový průměr každého shluku a centroid se přesune na tento průměr.\n",
|
||||
"\n",
|
||||
"5. Jakmile jsou středy přepočítány, každé pozorování se znovu zkontroluje, zda by nemohlo být blíže jinému shluku. Všechna pozorování jsou znovu přiřazena pomocí aktualizovaných průměrů shluků. Kroky přiřazení shluků a aktualizace centroidů se iterativně opakují, dokud se přiřazení shluků nepřestane měnit (tj. dokud není dosaženo konvergence). Algoritmus obvykle končí, když každá nová iterace vede k zanedbatelnému pohybu centroidů a shluky se stanou statickými.\n",
|
||||
"\n",
|
||||
"<div>\n",
|
||||
"\n",
|
||||
"> Všimněte si, že kvůli náhodnosti počátečních k pozorování použitých jako výchozí centroidy můžeme pokaždé, když aplikujeme tento postup, získat mírně odlišné výsledky. Z tohoto důvodu většina algoritmů používá několik *náhodných startů* a vybírá iteraci s nejnižší hodnotou WCSS. Proto se důrazně doporučuje vždy spouštět metodu K-Means s několika hodnotami *nstart*, aby se předešlo *nežádoucímu lokálnímu optimu.*\n",
|
||||
"\n",
|
||||
"</div>\n",
|
||||
"\n",
|
||||
"Tato krátká animace využívající [ilustrace](https://github.com/allisonhorst/stats-illustrations) od Allison Horst vysvětluje proces shlukování:\n",
|
||||
"\n",
|
||||
"<p >\n",
|
||||
" <img src=\"../../images/kmeans.gif\"\n",
|
||||
" width=\"550\"/>\n",
|
||||
" <figcaption>Ilustrace od @allison_horst</figcaption>\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Základní otázka, která při shlukování vyvstává, zní: jak zjistíte, na kolik shluků máte svá data rozdělit? Jednou z nevýhod metody K-Means je skutečnost, že musíte určit `k`, tedy počet `centroidů`. Naštěstí vám `metoda lokte` pomůže odhadnout dobrý výchozí počet `k`. Za chvíli si to vyzkoušíte.\n",
|
||||
"\n",
|
||||
"### \n",
|
||||
"\n",
|
||||
"**Předpoklady**\n",
|
||||
"\n",
|
||||
"Navážeme přesně tam, kde jsme skončili v [předchozí lekci](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb), kde jsme analyzovali datovou sadu, vytvořili spoustu vizualizací a filtrovali datovou sadu na pozorování, která nás zajímají. Určitě si ji projděte!\n",
|
||||
"\n",
|
||||
"Budeme potřebovat několik balíčků, abychom mohli začít s tímto modulem. Můžete si je nainstalovat pomocí: `install.packages(c('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork'))`\n",
|
||||
"\n",
|
||||
"Alternativně níže uvedený skript zkontroluje, zda máte balíčky potřebné k dokončení tohoto modulu, a v případě, že některé chybí, je pro vás nainstaluje.\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": [
|
||||
"Pojďme rovnou na věc!\n",
|
||||
"\n",
|
||||
"## 1. Tanec s daty: Zúžení na 3 nejoblíbenější hudební žánry\n",
|
||||
"\n",
|
||||
"Toto je rekapitulace toho, co jsme dělali v předchozí lekci. Pojďme si trochu pohrát s daty!\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 šlo dobře!\n",
|
||||
"\n",
|
||||
"## 2. Další průzkum dat.\n",
|
||||
"\n",
|
||||
"Jak čistá jsou tato data? Podívejme se na odlehlé hodnoty pomocí krabicových grafů. Zaměříme se na číselné sloupce s menším počtem odlehlých hodnot (i když byste mohli odlehlé hodnoty odstranit). Krabicové grafy mohou ukázat rozsah dat a pomohou vybrat, které sloupce použít. Všimněte si, že krabicové grafy neukazují rozptyl, což je důležitý prvek pro dobře seskupitelná data. Další informace naleznete v [této diskusi](https://stats.stackexchange.com/questions/91536/deduce-variance-from-boxplot).\n",
|
||||
"\n",
|
||||
"[Krabicové grafy](https://en.wikipedia.org/wiki/Box_plot) se používají k grafickému znázornění rozložení `číselných` dat, takže začněme *výběrem* všech číselných sloupců spolu s oblíbenými hudebními žánry.\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": [
|
||||
"Podívejte se, jak výběrový pomocník `where` usnadňuje tento proces 💁? Prozkoumejte další podobné funkce [zde](https://tidyselect.r-lib.org/).\n",
|
||||
"\n",
|
||||
"Protože budeme vytvářet krabicové grafy pro každou číselnou vlastnost a chceme se vyhnout použití smyček, přeformátujeme naše data do *delšího* formátu, který nám umožní využít `facets` - podgrafy, z nichž každý zobrazuje jednu podmnožinu dat.\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": [
|
||||
"Mnohem delší! Teď je čas na nějaké `ggplots`! Tak jaký `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": [
|
||||
"Teď můžeme vidět, že tato data jsou trochu hlučná: při pohledu na jednotlivé sloupce jako boxploty můžete vidět odlehlé hodnoty. Mohli byste projít dataset a tyto odlehlé hodnoty odstranit, ale to by data značně zredukovalo.\n",
|
||||
"\n",
|
||||
"Prozatím si vybereme, které sloupce použijeme pro náš cvičný úkol shlukování. Vybereme číselné sloupce s podobnými rozsahy. Mohli bychom zakódovat `artist_top_genre` jako číselné hodnoty, ale prozatím 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 shlukování v R\n",
|
||||
"\n",
|
||||
"K-means můžeme vypočítat v R pomocí vestavěné funkce `kmeans`, viz `help(\"kmeans()\")`. Funkce `kmeans()` přijímá datový rámec, který obsahuje pouze číselné sloupce, jako svůj hlavní argument.\n",
|
||||
"\n",
|
||||
"Prvním krokem při použití k-means shlukování je specifikace počtu shluků (k), které budou vytvořeny ve finálním řešení. Víme, že máme 3 hudební žánry, které jsme vyčlenili z datasetu, takže zkusme 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 několik informací, které jsou dobře vysvětleny v `help(\"kmeans()\")`. Prozatím se zaměříme na několik z nich. Vidíme, že data byla rozdělena do 3 klastrů o velikostech 65, 110, 111. Výstup také obsahuje středové body (průměry) pro 3 skupiny napříč 5 proměnnými.\n",
|
||||
"\n",
|
||||
"Vektor klastrů představuje přiřazení klastru pro každé pozorování. Použijme funkci `augment`, abychom přidali přiřazení klastru do původního datového souboru.\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ávě jsme rozdělili náš datový soubor do 3 skupin. Takže, jak dobré je naše shlukování 🤷? Podívejme se na `Silhouette skóre`.\n",
|
||||
"\n",
|
||||
"### **Silhouette skóre**\n",
|
||||
"\n",
|
||||
"[Silhouette analýza](https://en.wikipedia.org/wiki/Silhouette_(clustering)) může být použita ke studiu vzdálenosti mezi výslednými shluky. Toto skóre se pohybuje od -1 do 1, a pokud je skóre blízko 1, shluk je hustý a dobře oddělený od ostatních shluků. Hodnota blízko 0 představuje překrývající se shluky se vzorky velmi blízko rozhodovací hranice sousedních shluků. [zdroj](https://dzone.com/articles/kmeans-silhouette-score-explained-with-python-exam).\n",
|
||||
"\n",
|
||||
"Metoda průměrného silhouette skóre počítá průměrné silhouette skóre pozorování pro různé hodnoty *k*. Vysoké průměrné silhouette skóre naznačuje dobré shlukování.\n",
|
||||
"\n",
|
||||
"Funkce `silhouette` v balíčku cluster slouží k výpočtu průměrné šířky silhouette.\n",
|
||||
"\n",
|
||||
"> Silhouette lze vypočítat pomocí jakékoli [vzdálenostní](https://en.wikipedia.org/wiki/Distance \"Distance\") metriky, jako je [Euklidovská vzdálenost](https://en.wikipedia.org/wiki/Euclidean_distance \"Euclidean distance\") nebo [Manhattanská vzdálenost](https://en.wikipedia.org/wiki/Manhattan_distance \"Manhattan distance\"), které jsme probírali v [předchozí lekci](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 **.549**, tedy přesně uprostřed. To naznačuje, že naše data nejsou obzvlášť vhodná pro tento typ shlukování. Podívejme se, zda můžeme tento předpoklad vizuálně potvrdit. Balíček [factoextra](https://rpkgs.datanovia.com/factoextra/index.html) poskytuje funkce (`fviz_cluster()`) pro vizualizaci shlukování.\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": [
|
||||
"Překrývání v klastrech naznačuje, že naše data nejsou příliš vhodná pro tento typ klastrování, ale pojďme pokračovat.\n",
|
||||
"\n",
|
||||
"## 4. Určení optimálního počtu klastrů\n",
|
||||
"\n",
|
||||
"Základní otázka, která často vyvstává při klastrování metodou K-Means, je tato: bez známých třídních štítků, jak zjistíte, na kolik klastrů rozdělit svá data?\n",
|
||||
"\n",
|
||||
"Jedním ze způsobů, jak to zjistit, je použít vzorek dat k `vytvoření série modelů klastrování` s postupně se zvyšujícím počtem klastrů (např. od 1 do 10) a vyhodnotit metriky klastrování, jako je **Silhouette skóre.**\n",
|
||||
"\n",
|
||||
"Určeme optimální počet klastrů výpočtem algoritmu klastrování pro různé hodnoty *k* a vyhodnocením **součtu čtverců uvnitř klastrů** (WCSS). Celkový součet čtverců uvnitř klastrů (WCSS) měří kompaktnost klastrování a chceme, aby byl co nejmenší, přičemž nižší hodnoty znamenají, že datové body jsou blíže u sebe.\n",
|
||||
"\n",
|
||||
"Prozkoumejme vliv různých voleb hodnoty `k`, od 1 do 10, na toto klastrování.\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": [
|
||||
"Nyní, když máme celkový součet čtverců uvnitř klastrů (tot.withinss) pro každý algoritmus shlukování s centrem *k*, použijeme [metodu lokte](https://en.wikipedia.org/wiki/Elbow_method_(clustering)) k nalezení optimálního počtu klastrů. Tato metoda spočívá v zakreslení WCSS jako funkce počtu klastrů a výběru [lokte křivky](https://en.wikipedia.org/wiki/Elbow_of_the_curve \"Elbow of the curve\") jako počtu klastrů, které použijeme.\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é snížení WCSS (tedy větší *soudržnost*), když se počet klastrů zvýší z jednoho na dva, a další znatelné snížení při přechodu ze dvou na tři klastry. Poté je snížení méně výrazné, což vede k vytvoření `lokte` 💪 na grafu přibližně u tří klastrů. To je dobrý náznak, že existují dva až tři poměrně dobře oddělené klastry datových bodů.\n",
|
||||
"\n",
|
||||
"Nyní můžeme přistoupit k extrakci modelu klastrování, kde `k = 3`:\n",
|
||||
"\n",
|
||||
"> `pull()`: používá se k extrakci jednoho sloupce\n",
|
||||
">\n",
|
||||
"> `pluck()`: používá se k indexování datových struktur, jako jsou seznamy\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": [
|
||||
"Skvělé! Pojďme si vizualizovat získané clustery. Máte chuť na trochu interaktivity s použitím `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žná bychom očekávali, že každý klastr (reprezentovaný různými barvami) bude mít odlišné žánry (reprezentované různými tvary).\n",
|
||||
"\n",
|
||||
"Podívejme se na přesnost 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": [
|
||||
"Přesnost tohoto modelu není špatná, ale ani skvělá. Může to být způsobeno tím, že data nejsou vhodná pro K-Means Clustering. Tato data jsou příliš nevyvážená, málo korelovaná a mezi hodnotami sloupců je příliš velká variabilita, což ztěžuje jejich seskupování. Ve skutečnosti jsou vytvořené clustery pravděpodobně silně ovlivněny nebo zkresleny třemi kategoriemi žánrů, které jsme výše definovali.\n",
|
||||
"\n",
|
||||
"Nicméně, i tak to byl skvělý proces učení!\n",
|
||||
"\n",
|
||||
"V dokumentaci Scikit-learn můžete vidět, že model jako tento, s clustery, které nejsou příliš dobře vymezené, má problém s „variabilitou“:\n",
|
||||
"\n",
|
||||
"<p >\n",
|
||||
" <img src=\"../../images/problems.png\"\n",
|
||||
" width=\"500\"/>\n",
|
||||
" <figcaption>Infografika ze Scikit-learn</figcaption>\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"## **Variabilita**\n",
|
||||
"\n",
|
||||
"Variabilita je definována jako „průměr čtverců odchylek od průměru“ [zdroj](https://www.mathsisfun.com/data/standard-deviation.html). V kontextu tohoto problému seskupování to znamená, že hodnoty v našem datasetu mají tendenci se od průměru odchylovat až příliš.\n",
|
||||
"\n",
|
||||
"✅ Toto je skvělý moment k zamyšlení nad všemi způsoby, jak tento problém vyřešit. Můžete data ještě více upravit? Použít jiné sloupce? Nebo jiný algoritmus? Tip: Zkuste [škálovat svá data](https://www.mygreatlearning.com/blog/learning-data-science-with-k-means-clustering/), abyste je normalizovali, a otestujte jiné sloupce.\n",
|
||||
"\n",
|
||||
"> Vyzkoušejte tento '[kalkulátor variability](https://www.calculatorsoup.com/calculators/statistics/variance-calculator.php)', abyste lépe pochopili tento koncept.\n",
|
||||
"\n",
|
||||
"------------------------------------------------------------------------\n",
|
||||
"\n",
|
||||
"## **🚀Výzva**\n",
|
||||
"\n",
|
||||
"Stravte nějaký čas s tímto notebookem a upravujte parametry. Dokážete zlepšit přesnost modelu tím, že data více vyčistíte (například odstraněním odlehlých hodnot)? Můžete použít váhy, abyste některým vzorkům dat přidali větší důležitost. Co dalšího můžete udělat, abyste vytvořili lepší clustery?\n",
|
||||
"\n",
|
||||
"Tip: Zkuste škálovat svá data. V notebooku je zakomentovaný kód, který přidává standardní škálování, aby se hodnoty sloupců více podobaly z hlediska rozsahu. Zjistíte, že i když skóre siluety klesne, „zlom“ v grafu lokte se vyhladí. To je proto, že ponechání dat neškálovaných umožňuje, aby data s menší variabilitou měla větší váhu. Přečtěte si o tomto problému více [zde](https://stats.stackexchange.com/questions/21222/are-mean-normalization-and-feature-scaling-needed-for-k-means-clustering/21226#21226).\n",
|
||||
"\n",
|
||||
"## [**Kvíz po přednášce**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/30/)\n",
|
||||
"\n",
|
||||
"## **Opakování a samostudium**\n",
|
||||
"\n",
|
||||
"- Podívejte se na simulátor K-Means [například tento](https://user.ceng.metu.edu.tr/~akifakkus/courses/ceng574/k-means/). Tento nástroj můžete použít k vizualizaci vzorků datových bodů a určení jejich centroidů. Můžete upravit náhodnost dat, počet clusterů a počet centroidů. Pomáhá vám to získat představu o tom, jak lze data seskupit?\n",
|
||||
"\n",
|
||||
"- Podívejte se také na [tento materiál o K-Means](https://stanford.edu/~cpiech/cs221/handouts/kmeans.html) ze Stanfordu.\n",
|
||||
"\n",
|
||||
"Chcete si vyzkoušet své nově nabyté dovednosti v seskupování na datasetech, které se dobře hodí pro K-Means clustering? Podívejte se na:\n",
|
||||
"\n",
|
||||
"- [Trénování a hodnocení modelů seskupování](https://rpubs.com/eR_ic/clustering) pomocí Tidymodels a dalších nástrojů\n",
|
||||
"\n",
|
||||
"- [Analýza clusterů pomocí K-means](https://uc-r.github.io/kmeans_clustering), UC Business Analytics R Programming Guide\n",
|
||||
"\n",
|
||||
"- [K-means clustering s principy tidy dat](https://www.tidymodels.org/learn/statistics/k-means/)\n",
|
||||
"\n",
|
||||
"## **Úkol**\n",
|
||||
"\n",
|
||||
"[Vyzkoušejte různé metody seskupování](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/2-K-Means/assignment.md)\n",
|
||||
"\n",
|
||||
"## PODĚKOVÁNÍ:\n",
|
||||
"\n",
|
||||
"[Jen Looper](https://www.twitter.com/jenlooper) za vytvoření původní verze tohoto modulu v Pythonu ♥️\n",
|
||||
"\n",
|
||||
"[`Allison Horst`](https://twitter.com/allison_horst/) za vytvoření úžasných ilustrací, které dělají R přívětivějším a poutavějším. Další ilustrace najdete v její [galerii](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n",
|
||||
"\n",
|
||||
"Přejeme příjemné učení,\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>Ilustrace od @allison_horst</figcaption>\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n---\n\n**Prohlášení**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). Přestože se snažíme o přesnost, mějte na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.\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-04T09:29:49+00:00",
|
||||
"source_file": "6-NLP/3-Translation-Sentiment/solution/notebook.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"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**Prohlášení**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.\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-04T09:29:20+00:00",
|
||||
"source_file": "6-NLP/4-Hotel-Reviews-1/solution/notebook.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"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**Upozornění**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.\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-04T09:30:20+00:00",
|
||||
"source_file": "6-NLP/5-Hotel-Reviews-2/solution/1-notebook.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"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**Prohlášení**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.\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-04T09:30:49+00:00",
|
||||
"source_file": "6-NLP/5-Hotel-Reviews-2/solution/2-notebook.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"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**Prohlášení**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.\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-04T09:31:20+00:00",
|
||||
"source_file": "6-NLP/5-Hotel-Reviews-2/solution/3-notebook.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"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**Upozornění**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Za závazný zdroj by měl být považován originální dokument v jeho původním jazyce. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,63 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"source": [
|
||||
"# Nastavení dat\n",
|
||||
"\n",
|
||||
"V tomto notebooku ukážeme, jak:\n",
|
||||
"\n",
|
||||
"nastavit časová řadová data pro tento modul\n",
|
||||
"vizualizovat data\n",
|
||||
"Data v tomto příkladu pocházejí ze soutěže GEFCom2014 v oblasti prognózování1. Obsahují 3 roky hodinových hodnot spotřeby elektřiny a teploty mezi lety 2012 a 2014.\n",
|
||||
"\n",
|
||||
"1Tao 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, sv.32, č.3, str. 896-913, červenec-září, 2016.\n"
|
||||
],
|
||||
"cell_type": "markdown",
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n---\n\n**Prohlášení**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.\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-04T07:33:27+00:00",
|
||||
"source_file": "7-TimeSeries/1-Introduction/working/notebook.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@ -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
|
||||
},
|
||||
"orig_nbformat": 2,
|
||||
"coopTranslator": {
|
||||
"original_hash": "523ec472196307b3c4235337353c9ceb",
|
||||
"translation_date": "2025-09-04T07:30:54+00:00",
|
||||
"source_file": "7-TimeSeries/2-ARIMA/working/notebook.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2,
|
||||
"cells": [
|
||||
{
|
||||
"source": [
|
||||
"Tao Hong, Pierre Pinson, Shu Fan, Hamidreza Zareipour, Alberto Troccoli a Rob J. Hyndman, \"Probabilistické energetické předpovědi: Globální soutěž v energetickém předpovídání 2014 a dále\", International Journal of Forecasting, sv.32, č.3, str. 896-913, červenec-září, 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**Prohlášení**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,699 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "fv9OoQsMFk5A"
|
||||
},
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"V tomto zápisníku si ukážeme, jak:\n",
|
||||
"\n",
|
||||
"- připravit 2D časové řady pro trénování modelu SVM regresoru\n",
|
||||
"- implementovat SVR s RBF jádrem\n",
|
||||
"- vyhodnotit model pomocí grafů a MAPE\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Importování modulů\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": [
|
||||
"## Příprava dat\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "8fywSjC6GsRz"
|
||||
},
|
||||
"source": [
|
||||
"### Načíst data\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": [
|
||||
"Nyní je potřeba připravit data pro trénink provedením filtrování a škálování vašich dat.\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": [
|
||||
"Škálujte data tak, aby byla 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": [
|
||||
"### Vytváření dat s časovými kroky\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "fdmxTZtOQ8xs"
|
||||
},
|
||||
"source": [
|
||||
"Pro náš SVR transformujeme vstupní data do formy `[batch, timesteps]`. Proto přetváříme existující `train_data` a `test_data` tak, aby existovala nová dimenze, která odkazuje na časové kroky. V našem příkladu bereme `timesteps = 5`. Vstupy do modelu jsou tedy data pro první 4 časové kroky a výstupem budou data pro 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": [
|
||||
"### Proveďte predikci 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": [
|
||||
"## Predikce úplné datové sady\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**Prohlášení**: \nTento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Za autoritativní zdroj by měl být považován původní dokument v jeho původním jazyce. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.\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-04T07:38:57+00:00",
|
||||
"source_file": "7-TimeSeries/3-SVR/working/notebook.ipynb",
|
||||
"language_code": "cs"
|
||||
}
|
||||
},
|
||||
"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
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue