You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
686 lines
30 KiB
686 lines
30 KiB
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Izgradnja modela logističke regresije - Lekcija 4\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"#### **[Kviz prije predavanja](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/15/)**\n",
|
|
"\n",
|
|
"#### Uvod\n",
|
|
"\n",
|
|
"U ovoj završnoj lekciji o regresiji, jednoj od osnovnih *klasičnih* tehnika strojnog učenja, pogledat ćemo logističku regresiju. Ovu tehniku koristite za otkrivanje obrazaca kako biste predvidjeli binarne kategorije. Je li ovaj slatkiš čokolada ili nije? Je li ova bolest zarazna ili nije? Hoće li ovaj kupac odabrati ovaj proizvod ili neće?\n",
|
|
"\n",
|
|
"U ovoj lekciji naučit ćete:\n",
|
|
"\n",
|
|
"- Tehnike za logističku regresiju\n",
|
|
"\n",
|
|
"✅ Produbite svoje razumijevanje rada s ovom vrstom regresije u ovom [modulu za učenje](https://learn.microsoft.com/training/modules/introduction-classification-models/?WT.mc_id=academic-77952-leestott)\n",
|
|
"\n",
|
|
"## Preduvjet\n",
|
|
"\n",
|
|
"Radili smo s podacima o bundevama i sada smo dovoljno upoznati s njima da shvatimo da postoji jedna binarna kategorija s kojom možemo raditi: `Color`.\n",
|
|
"\n",
|
|
"Izgradimo model logističke regresije kako bismo predvidjeli, na temelju nekih varijabli, *koje je boje određena bundeva najvjerojatnije* (narančasta 🎃 ili bijela 👻).\n",
|
|
"\n",
|
|
"> Zašto govorimo o binarnoj klasifikaciji u lekciji koja se bavi regresijom? Isključivo zbog jezične praktičnosti, budući da je logistička regresija [zapravo metoda klasifikacije](https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression), iako se temelji na linearnom pristupu. Saznajte više o drugim načinima klasifikacije podataka u sljedećoj grupi lekcija.\n",
|
|
"\n",
|
|
"Za ovu lekciju trebat će nam sljedeći paketi:\n",
|
|
"\n",
|
|
"- `tidyverse`: [tidyverse](https://www.tidyverse.org/) je [zbirka R paketa](https://www.tidyverse.org/packages) dizajnirana da učini znanost o podacima bržom, lakšom i zabavnijom!\n",
|
|
"\n",
|
|
"- `tidymodels`: [tidymodels](https://www.tidymodels.org/) okvir je [zbirka paketa](https://www.tidymodels.org/packages/) za modeliranje i strojno učenje.\n",
|
|
"\n",
|
|
"- `janitor`: [janitor paket](https://github.com/sfirke/janitor) pruža jednostavne alate za pregled i čišćenje neurednih podataka.\n",
|
|
"\n",
|
|
"- `ggbeeswarm`: [ggbeeswarm paket](https://github.com/eclarke/ggbeeswarm) omogućuje stvaranje grafova u stilu \"beeswarm\" koristeći ggplot2.\n",
|
|
"\n",
|
|
"Možete ih instalirati pomoću:\n",
|
|
"\n",
|
|
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"janitor\", \"ggbeeswarm\"))`\n",
|
|
"\n",
|
|
"Alternativno, skripta ispod provjerava imate li potrebne pakete za dovršavanje ovog modula i instalira ih za vas ako nedostaju.\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": [
|
|
"## **Definirajte pitanje**\n",
|
|
"\n",
|
|
"Za naše potrebe, izrazit ćemo ovo kao binarno: 'Bijelo' ili 'Nije bijelo'. U našem skupu podataka postoji i kategorija 'prugasto', ali ima malo primjera, pa je nećemo koristiti. Ionako nestaje kad uklonimo null vrijednosti iz skupa podataka.\n",
|
|
"\n",
|
|
"> 🎃 Zanimljiva činjenica, bijele bundeve ponekad nazivamo 'duhovima'. Nisu baš jednostavne za rezbarenje, pa nisu toliko popularne kao narančaste, ali izgledaju zanimljivo! Dakle, mogli bismo također preformulirati naše pitanje kao: 'Duh' ili 'Nije duh'. 👻\n",
|
|
"\n",
|
|
"## **O logističkoj regresiji**\n",
|
|
"\n",
|
|
"Logistička regresija razlikuje se od linearne regresije, o kojoj ste ranije učili, na nekoliko važnih načina.\n",
|
|
"\n",
|
|
"#### **Binarna klasifikacija**\n",
|
|
"\n",
|
|
"Logistička regresija ne nudi iste značajke kao linearna regresija. Prva nudi predviđanje o `binarnoj kategoriji` (\"narančasto ili nije narančasto\"), dok je druga sposobna predvidjeti `kontinuirane vrijednosti`, na primjer, s obzirom na podrijetlo bundeve i vrijeme berbe, *koliko će joj cijena porasti*.\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"### Ostale klasifikacije\n",
|
|
"\n",
|
|
"Postoje i druge vrste logističke regresije, uključujući multinomijalnu i ordinalnu:\n",
|
|
"\n",
|
|
"- **Multinomijalna**, koja uključuje više od jedne kategorije - \"Narančasto, Bijelo i Prugasto\".\n",
|
|
"\n",
|
|
"- **Ordinalna**, koja uključuje poredane kategorije, korisno ako želimo logično poredati naše ishode, poput bundeva koje su poredane prema ograničenom broju veličina (mini,sm,med,lg,xl,xxl).\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"#### **Varijable NE MORAJU biti povezane**\n",
|
|
"\n",
|
|
"Sjećate se kako je linearna regresija bolje funkcionirala s više povezanih varijabli? Logistička regresija je suprotna - varijable ne moraju biti povezane. To odgovara ovom skupu podataka koji ima relativno slabe korelacije.\n",
|
|
"\n",
|
|
"#### **Potrebno je puno čistih podataka**\n",
|
|
"\n",
|
|
"Logistička regresija daje točnije rezultate ako koristite više podataka; naš mali skup podataka nije optimalan za ovaj zadatak, pa to imajte na umu.\n",
|
|
"\n",
|
|
"✅ Razmislite o vrstama podataka koje bi bile prikladne za logističku regresiju\n",
|
|
"\n",
|
|
"## Vježba - očistite podatke\n",
|
|
"\n",
|
|
"Prvo, malo očistite podatke, uklonite null vrijednosti i odaberite samo neke od stupaca:\n",
|
|
"\n",
|
|
"1. Dodajte sljedeći kod:\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": [
|
|
"Uvijek možete zaviriti u svoj novi dataframe koristeći funkciju [*glimpse()*](https://pillar.r-lib.org/reference/glimpse.html) kao što je prikazano dolje:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"pumpkins_select %>% \n",
|
|
" glimpse()\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Hajdemo potvrditi da ćemo zapravo raditi na problemu binarne klasifikacije:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Subset distinct observations in outcome column\n",
|
|
"pumpkins_select %>% \n",
|
|
" distinct(color)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Vizualizacija - kategorijalni graf\n",
|
|
"Do sada ste ponovno učitali podatke o bundevama i očistili ih kako biste sačuvali skup podataka koji sadrži nekoliko varijabli, uključujući Boju. Vizualizirajmo dataframe u bilježnici koristeći ggplot biblioteku.\n",
|
|
"\n",
|
|
"Biblioteka ggplot nudi zanimljive načine za vizualizaciju vaših podataka. Na primjer, možete usporediti distribucije podataka za svaku Sortu i Boju u kategorijalnom grafu.\n",
|
|
"\n",
|
|
"1. Kreirajte takav graf koristeći funkciju geombar, koristeći naše podatke o bundevama, i specificirajte mapiranje boja za svaku kategoriju bundeva (narančasta ili bijela):\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": [
|
|
"Promatrajući podatke, možete vidjeti kako se podaci o Boji odnose na Sortu.\n",
|
|
"\n",
|
|
"✅ S obzirom na ovaj kategorijski grafikon, koja zanimljiva istraživanja možete zamisliti?\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Obrada podataka: kodiranje značajki\n",
|
|
"\n",
|
|
"Naš skup podataka o bundevama sadrži tekstualne vrijednosti u svim stupcima. Rad s kategorijskim podacima je intuitivan za ljude, ali ne i za strojeve. Algoritmi strojnog učenja bolje funkcioniraju s brojčanim podacima. Zato je kodiranje vrlo važan korak u fazi obrade podataka, jer nam omogućuje pretvaranje kategorijskih podataka u brojčane, bez gubitka informacija. Dobro kodiranje vodi do izgradnje dobrog modela.\n",
|
|
"\n",
|
|
"Za kodiranje značajki postoje dvije glavne vrste kodera:\n",
|
|
"\n",
|
|
"1. **Ordinalni koder**: dobro odgovara za ordinalne varijable, koje su kategorijske varijable čiji podaci slijede logički redoslijed, poput stupca `item_size` u našem skupu podataka. Stvara mapiranje tako da je svaka kategorija predstavljena brojem, koji odgovara redoslijedu kategorije u stupcu.\n",
|
|
"\n",
|
|
"2. **Kategorijski koder**: dobro odgovara za nominalne varijable, koje su kategorijske varijable čiji podaci ne slijede logički redoslijed, poput svih značajki koje nisu `item_size` u našem skupu podataka. Ovo je kodiranje s jednom vrućom vrijednošću (one-hot encoding), što znači da je svaka kategorija predstavljena binarnim stupcem: kodirana varijabla jednaka je 1 ako bundeva pripada toj sorti, a 0 inače.\n",
|
|
"\n",
|
|
"Tidymodels pruža još jedan koristan paket: [recipes](https://recipes.tidymodels.org/) - paket za obradu podataka. Definirat ćemo `recipe` koji specificira da svi stupci prediktora trebaju biti kodirani u skup cijelih brojeva, `prep` za procjenu potrebnih količina i statistika potrebnih za bilo koje operacije, i na kraju `bake` za primjenu izračuna na nove podatke.\n",
|
|
"\n",
|
|
"> Obično se recipes koristi kao preprocesor za modeliranje, gdje definira koje korake treba primijeniti na skup podataka kako bi bio spreman za modeliranje. U tom slučaju **toplo se preporučuje** korištenje `workflow()` umjesto ručnog procjenjivanja recepta pomoću prep i bake. Sve ćemo to vidjeti uskoro.\n",
|
|
">\n",
|
|
"> Međutim, za sada koristimo recipes + prep + bake kako bismo specificirali koje korake treba primijeniti na skup podataka kako bi bio spreman za analizu podataka, a zatim izdvojili prethodno obrađene podatke s primijenjenim koracima.\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": [
|
|
"✅ Koje su prednosti korištenja ordinalnog kodera za stupac Veličina artikla?\n",
|
|
"\n",
|
|
"### Analizirajte odnose između varijabli\n",
|
|
"\n",
|
|
"Sada kada smo unaprijed obradili naše podatke, možemo analizirati odnose između značajki i oznake kako bismo stekli ideju o tome koliko će model biti uspješan u predviđanju oznake na temelju značajki. Najbolji način za provođenje ove vrste analize je vizualizacija podataka. \n",
|
|
"Ponovno ćemo koristiti funkciju ggplot geom_boxplot_ kako bismo vizualizirali odnose između Veličine artikla, Sorte i Boje u kategorijalnom grafu. Za bolju vizualizaciju podataka koristit ćemo kodirani stupac Veličina artikla i nekodirani stupac Sorta.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Define the color palette\n",
|
|
"palette <- c(ORANGE = \"orange\", WHITE = \"wheat\")\n",
|
|
"\n",
|
|
"# We need the encoded Item Size column to use it as the x-axis values in the plot\n",
|
|
"pumpkins_select_plot<-pumpkins_select\n",
|
|
"pumpkins_select_plot$item_size <- baked_pumpkins$item_size\n",
|
|
"\n",
|
|
"# Create the grouped box plot\n",
|
|
"ggplot(pumpkins_select_plot, aes(x = `item_size`, y = color, fill = color)) +\n",
|
|
" geom_boxplot() +\n",
|
|
" facet_grid(variety ~ ., scales = \"free_x\") +\n",
|
|
" scale_fill_manual(values = palette) +\n",
|
|
" labs(x = \"Item Size\", y = \"\") +\n",
|
|
" theme_minimal() +\n",
|
|
" theme(strip.text = element_text(size = 12)) +\n",
|
|
" theme(axis.text.x = element_text(size = 10)) +\n",
|
|
" theme(axis.title.x = element_text(size = 12)) +\n",
|
|
" theme(axis.title.y = element_blank()) +\n",
|
|
" theme(legend.position = \"bottom\") +\n",
|
|
" guides(fill = guide_legend(title = \"Color\")) +\n",
|
|
" theme(panel.spacing = unit(0.5, \"lines\"))+\n",
|
|
" theme(strip.text.y = element_text(size = 4, hjust = 0)) \n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### Koristite swarm plot\n",
|
|
"\n",
|
|
"Budući da je Color binarna kategorija (Bijela ili Ne), potrebna je '[specijalizirani pristup](https://github.com/rstudio/cheatsheets/blob/main/data-visualization.pdf)' za vizualizaciju.\n",
|
|
"\n",
|
|
"Isprobajte `swarm plot` kako biste prikazali distribuciju boje u odnosu na item_size.\n",
|
|
"\n",
|
|
"Koristit ćemo [ggbeeswarm paket](https://github.com/eclarke/ggbeeswarm) koji pruža metode za kreiranje grafova u stilu \"beeswarm\" koristeći ggplot2. Beeswarm grafovi omogućuju prikaz točaka koje bi se inače preklapale tako da se smjeste jedna pored druge.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Create beeswarm plots of color and item_size\n",
|
|
"baked_pumpkins %>% \n",
|
|
" mutate(color = factor(color)) %>% \n",
|
|
" ggplot(mapping = aes(x = color, y = item_size, color = color)) +\n",
|
|
" geom_quasirandom() +\n",
|
|
" scale_color_brewer(palette = \"Dark2\", direction = -1) +\n",
|
|
" theme(legend.position = \"none\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Sad kad imamo ideju o odnosu između binarnih kategorija boje i šire skupine veličina, istražimo logističku regresiju kako bismo odredili vjerojatnu boju određene bundeve.\n",
|
|
"\n",
|
|
"## Izgradite svoj model\n",
|
|
"\n",
|
|
"Odaberite varijable koje želite koristiti u svom klasifikacijskom modelu i podijelite podatke na skupove za treniranje i testiranje. [rsample](https://rsample.tidymodels.org/), paket u Tidymodels, pruža infrastrukturu za učinkovito dijeljenje i ponovnu uzorkovanje podataka:\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": [
|
|
"🙌 Sada smo spremni trenirati model prilagođavanjem značajki za treniranje oznaci za treniranje (boji).\n",
|
|
"\n",
|
|
"Počet ćemo stvaranjem recepta koji određuje korake predobrade koje treba provesti na našim podacima kako bi ih pripremili za modeliranje, tj. kodiranjem kategorijalnih varijabli u skup cijelih brojeva. Baš kao `baked_pumpkins`, kreiramo `pumpkins_recipe`, ali ne koristimo `prep` i `bake` jer će biti uključeni u tijek rada, što ćete vidjeti za nekoliko koraka.\n",
|
|
"\n",
|
|
"Postoji prilično mnogo načina za specificiranje logističke regresije u Tidymodels. Pogledajte `?logistic_reg()`. Za sada ćemo specificirati model logističke regresije putem zadane `stats::glm()` pogonske jedinice.\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": [
|
|
"Sada kada imamo recept i specifikaciju modela, trebamo pronaći način da ih spojimo u objekt koji će prvo obraditi podatke (priprema + pečenje u pozadini), prilagoditi model na obrađenim podacima i također omogućiti potencijalne aktivnosti post-obrade.\n",
|
|
"\n",
|
|
"U Tidymodels-u, ovaj praktičan objekt naziva se [`workflow`](https://workflows.tidymodels.org/) i praktično drži vaše komponente modeliranja.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Bundle modelling components in a workflow\n",
|
|
"log_reg_wf <- workflow() %>% \n",
|
|
" add_recipe(pumpkins_recipe) %>% \n",
|
|
" add_model(log_reg)\n",
|
|
"\n",
|
|
"# Print out the workflow\n",
|
|
"log_reg_wf\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Nakon što je tijek rada *specificiran*, model se može `trenirati` koristeći funkciju [`fit()`](https://tidymodels.github.io/parsnip/reference/fit.html). Tijek rada će procijeniti recept i unaprijed obraditi podatke prije treniranja, tako da to nećemo morati ručno raditi koristeći prep i 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 ispisuje koeficijente naučene tijekom treniranja.\n",
|
|
"\n",
|
|
"Sada kada smo model istrenirali koristeći podatke za treniranje, možemo napraviti predikcije na testnim podacima koristeći [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html). Počnimo tako da koristimo model za predviđanje oznaka za naš testni skup i vjerojatnosti za svaku oznaku. Kada je vjerojatnost veća od 0.5, predviđena klasa je `WHITE`, inače je `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": [
|
|
"Vrlo dobro! Ovo pruža dodatne uvide u to kako logistička regresija funkcionira.\n",
|
|
"\n",
|
|
"### Bolje razumijevanje putem matrice zabune\n",
|
|
"\n",
|
|
"Uspoređivanje svake predikcije s odgovarajućom \"stvarnom\" vrijednošću nije baš učinkovit način za određivanje koliko dobro model predviđa. Srećom, Tidymodels ima još nekoliko trikova u rukavu: [`yardstick`](https://yardstick.tidymodels.org/) - paket koji se koristi za mjerenje učinkovitosti modela pomoću metrika izvedbe.\n",
|
|
"\n",
|
|
"Jedna od metrika izvedbe povezanih s problemima klasifikacije je [`matrica zabune`](https://wikipedia.org/wiki/Confusion_matrix). Matrica zabune opisuje koliko dobro klasifikacijski model funkcionira. Matrica zabune prikazuje koliko je primjera u svakoj klasi model ispravno klasificirao. U našem slučaju, pokazat će vam koliko je narančastih bundeva klasificirano kao narančaste, a koliko bijelih bundeva kao bijele; matrica zabune također pokazuje koliko je primjera klasificirano u **pogrešne** kategorije.\n",
|
|
"\n",
|
|
"Funkcija [**`conf_mat()`**](https://tidymodels.github.io/yardstick/reference/conf_mat.html) iz paketa yardstick izračunava ovu križnu tablicu promatranih i predviđenih klasa.\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": [
|
|
"Hajdemo interpretirati matricu konfuzije. Naš model treba klasificirati bundeve u dvije binarne kategorije, kategoriju `bijela` i kategoriju `ne-bijela`.\n",
|
|
"\n",
|
|
"- Ako vaš model predvidi bundevu kao bijelu, a ona stvarno pripada kategoriji 'bijela', to nazivamo `istinitim pozitivnim` (true positive), prikazano gornjim lijevim brojem.\n",
|
|
"\n",
|
|
"- Ako vaš model predvidi bundevu kao ne-bijelu, a ona stvarno pripada kategoriji 'bijela', to nazivamo `lažno negativnim` (false negative), prikazano donjim lijevim brojem.\n",
|
|
"\n",
|
|
"- Ako vaš model predvidi bundevu kao bijelu, a ona stvarno pripada kategoriji 'ne-bijela', to nazivamo `lažno pozitivnim` (false positive), prikazano gornjim desnim brojem.\n",
|
|
"\n",
|
|
"- Ako vaš model predvidi bundevu kao ne-bijelu, a ona stvarno pripada kategoriji 'ne-bijela', to nazivamo `istinitim negativnim` (true negative), prikazano donjim desnim brojem.\n",
|
|
"\n",
|
|
"| Istina |\n",
|
|
"|:-----:|\n",
|
|
"\n",
|
|
"\n",
|
|
"| | | |\n",
|
|
"|---------------|--------|-------|\n",
|
|
"| **Predviđeno** | BIJELA | NARANČASTA |\n",
|
|
"| BIJELA | TP | FP |\n",
|
|
"| NARANČASTA | FN | TN |\n",
|
|
"\n",
|
|
"Kao što ste možda pretpostavili, poželjno je imati veći broj istinitih pozitivnih i istinitih negativnih te manji broj lažno pozitivnih i lažno negativnih, što implicira da model bolje radi.\n",
|
|
"\n",
|
|
"Matrica konfuzije je korisna jer omogućuje izračun drugih metrika koje nam mogu pomoći u boljoj procjeni performansi modela klasifikacije. Pogledajmo neke od njih:\n",
|
|
"\n",
|
|
"🎓 Preciznost: `TP/(TP + FP)` definirana kao udio predviđenih pozitivnih koji su stvarno pozitivni. Također se naziva [pozitivna prediktivna vrijednost](https://en.wikipedia.org/wiki/Positive_predictive_value \"Positive predictive value\").\n",
|
|
"\n",
|
|
"🎓 Odziv: `TP/(TP + FN)` definiran kao udio pozitivnih rezultata u odnosu na broj uzoraka koji su stvarno pozitivni. Također poznat kao `osjetljivost`.\n",
|
|
"\n",
|
|
"🎓 Specifičnost: `TN/(TN + FP)` definirana kao udio negativnih rezultata u odnosu na broj uzoraka koji su stvarno negativni.\n",
|
|
"\n",
|
|
"🎓 Točnost: `TP + TN/(TP + TN + FP + FN)` Postotak oznaka koje su točno predviđene za uzorak.\n",
|
|
"\n",
|
|
"🎓 F mjera: Ponderirani prosjek preciznosti i odziva, gdje je najbolji rezultat 1, a najgori 0.\n",
|
|
"\n",
|
|
"Izračunajmo ove metrike!\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Combine metric functions and calculate them all at once\n",
|
|
"eval_metrics <- metric_set(ppv, recall, spec, f_meas, accuracy)\n",
|
|
"eval_metrics(data = results, truth = color, estimate = .pred_class)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Vizualiziraj ROC krivulju ovog modela\n",
|
|
"\n",
|
|
"Napravimo još jednu vizualizaciju kako bismo vidjeli takozvanu [`ROC krivulju`](https://en.wikipedia.org/wiki/Receiver_operating_characteristic):\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Make a roc_curve\n",
|
|
"results %>% \n",
|
|
" roc_curve(color, .pred_ORANGE) %>% \n",
|
|
" autoplot()\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"ROC krivulje često se koriste za prikaz rezultata klasifikatora u smislu njegovih pravih naspram lažnih pozitivnih rezultata. ROC krivulje obično prikazuju `True Positive Rate`/osjetljivost na Y osi i `False Positive Rate`/1-specifičnost na X osi. Dakle, važni su nagib krivulje i prostor između središnje linije i krivulje: želite krivulju koja brzo ide prema gore i prelazi liniju. U našem slučaju, postoje lažno pozitivni rezultati na početku, a zatim linija pravilno ide prema gore i prelazi.\n",
|
|
"\n",
|
|
"Na kraju, koristimo `yardstick::roc_auc()` za izračunavanje stvarnog područja ispod krivulje (Area Under the Curve). Jedan od načina tumačenja AUC-a je kao vjerojatnost da model rangira slučajni pozitivni primjer više od slučajnog negativnog primjera.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Calculate area under curve\n",
|
|
"results %>% \n",
|
|
" roc_auc(color, .pred_ORANGE)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Rezultat je oko `0.975`. S obzirom na to da AUC varira od 0 do 1, želite postići visok rezultat, jer model koji je 100% točan u svojim predviđanjima ima AUC od 1; u ovom slučaju, model je *prilično dobar*.\n",
|
|
"\n",
|
|
"U budućim lekcijama o klasifikacijama naučit ćete kako poboljšati rezultate svog modela (kao što je rješavanje problema neuravnoteženih podataka u ovom slučaju).\n",
|
|
"\n",
|
|
"## 🚀Izazov\n",
|
|
"\n",
|
|
"Logistička regresija krije još mnogo toga! No, najbolji način za učenje je eksperimentiranje. Pronađite skup podataka koji se može analizirati ovom metodom i izgradite model na temelju njega. Što ste naučili? savjet: isprobajte [Kaggle](https://www.kaggle.com/search?q=logistic+regression+datasets) za zanimljive skupove podataka.\n",
|
|
"\n",
|
|
"## Pregled i samostalno učenje\n",
|
|
"\n",
|
|
"Pročitajte prvih nekoliko stranica [ovog rada sa Stanforda](https://web.stanford.edu/~jurafsky/slp3/5.pdf) o nekim praktičnim primjenama logističke regresije. Razmislite o zadacima koji su bolje prilagođeni jednoj ili drugoj vrsti regresije koje smo do sada proučavali. Što bi najbolje funkcioniralo?\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n---\n\n**Odricanje od odgovornosti**: \nOvaj dokument je preveden pomoću AI usluge za prevođenje [Co-op Translator](https://github.com/Azure/co-op-translator). Iako nastojimo osigurati točnost, imajte na umu da automatski prijevodi mogu sadržavati pogreške ili netočnosti. Izvorni dokument na izvornom jeziku treba smatrati autoritativnim izvorom. Za ključne informacije preporučuje se profesionalni prijevod od strane ljudskog prevoditelja. Ne preuzimamo odgovornost za bilo kakve nesporazume ili pogrešne interpretacije koje proizlaze iz korištenja ovog prijevoda.\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:55:17+00:00",
|
|
"source_file": "2-Regression/4-Logistic/solution/R/lesson_4-R.ipynb",
|
|
"language_code": "hr"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 1
|
|
} |