{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Construiește un model de regresie logistică - Lecția 4\n", "\n", "![Infografic despre regresia logistică vs. regresia liniară](../../../../../../2-Regression/4-Logistic/images/linear-vs-logistic.png)\n", "\n", "#### **[Chestionar înainte de lecție](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/15/)**\n", "\n", "#### Introducere\n", "\n", "În această ultimă lecție despre regresie, una dintre tehnicile de bază *clasice* ale ML, vom analiza regresia logistică. Această tehnică este utilizată pentru a descoperi modele care prezic categorii binare. Este acest bomboană ciocolată sau nu? Este această boală contagioasă sau nu? Va alege acest client produsul sau nu?\n", "\n", "În această lecție, vei învăța:\n", "\n", "- Tehnici pentru regresia logistică\n", "\n", "✅ Aprofundează înțelegerea lucrului cu acest tip de regresie în acest [modul de învățare](https://learn.microsoft.com/training/modules/introduction-classification-models/?WT.mc_id=academic-77952-leestott)\n", "\n", "## Prerechizite\n", "\n", "După ce am lucrat cu datele despre dovleci, suntem suficient de familiarizați cu ele pentru a realiza că există o categorie binară cu care putem lucra: `Color`.\n", "\n", "Să construim un model de regresie logistică pentru a prezice, având în vedere anumite variabile, *ce culoare este probabil să aibă un dovleac* (portocaliu 🎃 sau alb 👻).\n", "\n", "> De ce discutăm despre clasificarea binară într-o lecție despre regresie? Doar din comoditate lingvistică, deoarece regresia logistică este [de fapt o metodă de clasificare](https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression), deși bazată pe metode liniare. Învață despre alte modalități de clasificare a datelor în următorul grup de lecții.\n", "\n", "Pentru această lecție, vom avea nevoie de următoarele pachete:\n", "\n", "- `tidyverse`: [tidyverse](https://www.tidyverse.org/) este o [colecție de pachete R](https://www.tidyverse.org/packages) concepută pentru a face știința datelor mai rapidă, mai ușoară și mai distractivă!\n", "\n", "- `tidymodels`: [tidymodels](https://www.tidymodels.org/) este un cadru format dintr-o [colecție de pachete](https://www.tidymodels.org/packages/) pentru modelare și învățare automată.\n", "\n", "- `janitor`: Pachetul [janitor](https://github.com/sfirke/janitor) oferă instrumente simple pentru examinarea și curățarea datelor murdare.\n", "\n", "- `ggbeeswarm`: Pachetul [ggbeeswarm](https://github.com/eclarke/ggbeeswarm) oferă metode pentru crearea de grafice în stil \"beeswarm\" folosind ggplot2.\n", "\n", "Le poți instala astfel:\n", "\n", "`install.packages(c(\"tidyverse\", \"tidymodels\", \"janitor\", \"ggbeeswarm\"))`\n", "\n", "Alternativ, scriptul de mai jos verifică dacă ai pachetele necesare pentru a finaliza acest modul și le instalează pentru tine în cazul în care lipsesc.\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": [ "## **Definirea întrebării**\n", "\n", "Pentru scopurile noastre, vom exprima aceasta ca un binar: 'Alb' sau 'Nu Alb'. Există și o categorie 'dungat' în setul nostru de date, dar sunt puține instanțe ale acesteia, așa că nu o vom folosi. Oricum dispare odată ce eliminăm valorile nule din setul de date.\n", "\n", "> 🎃 Fapt amuzant, uneori numim dovlecii albi 'dovleci fantomă'. Nu sunt foarte ușor de sculptat, așa că nu sunt la fel de populari ca cei portocalii, dar arată interesant! Așadar, am putea reformula întrebarea noastră ca: 'Fantomă' sau 'Nu Fantomă'. 👻\n", "\n", "## **Despre regresia logistică**\n", "\n", "Regresia logistică diferă de regresia liniară, pe care ai învățat-o anterior, în câteva moduri importante.\n", "\n", "#### **Clasificare binară**\n", "\n", "Regresia logistică nu oferă aceleași caracteristici ca regresia liniară. Prima oferă o predicție despre o `categorie binară` (\"portocaliu sau nu portocaliu\"), în timp ce cea de-a doua este capabilă să prezică `valori continue`, de exemplu, având în vedere originea unui dovleac și momentul recoltării, *cât de mult va crește prețul său*.\n", "\n", "![Infografic de Dasani Madipalli](../../../../../../2-Regression/4-Logistic/images/pumpkin-classifier.png)\n", "\n", "### Alte clasificări\n", "\n", "Există alte tipuri de regresie logistică, inclusiv multinomială și ordonată:\n", "\n", "- **Multinomială**, care implică mai mult de o categorie - \"Portocaliu, Alb și Dungat\".\n", "\n", "- **Ordonată**, care implică categorii ordonate, utilă dacă dorim să ordonăm rezultatele logic, cum ar fi dovlecii noștri care sunt ordonați după un număr finit de dimensiuni (mini, mic, mediu, mare, xl, xxl).\n", "\n", "![Regresie multinomială vs ordonată](../../../../../../2-Regression/4-Logistic/images/multinomial-vs-ordinal.png)\n", "\n", "#### **Variabilele NU trebuie să fie corelate**\n", "\n", "Îți amintești cum regresia liniară funcționa mai bine cu variabile mai corelate? Regresia logistică este opusul - variabilele nu trebuie să fie aliniate. Acest lucru funcționează pentru acest set de date, care are corelații destul de slabe.\n", "\n", "#### **Ai nevoie de multe date curate**\n", "\n", "Regresia logistică va oferi rezultate mai precise dacă folosești mai multe date; setul nostru mic de date nu este optim pentru această sarcină, așa că ține cont de acest lucru.\n", "\n", "✅ Gândește-te la tipurile de date care s-ar potrivi bine regresiei logistice.\n", "\n", "## Exercițiu - curățarea datelor\n", "\n", "Mai întâi, curăță datele puțin, eliminând valorile nule și selectând doar câteva dintre coloane:\n", "\n", "1. Adaugă următorul cod:\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": [ "Poți oricând să arunci o privire asupra noului tău dataframe, utilizând funcția [*glimpse()*](https://pillar.r-lib.org/reference/glimpse.html) așa cum este prezentat mai jos:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "r" } }, "outputs": [], "source": [ "pumpkins_select %>% \n", " glimpse()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Să confirmăm că vom rezolva, de fapt, o problemă de clasificare binară:\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": [ "### Vizualizare - grafic categorial\n", "Până acum ai încărcat din nou datele despre dovleci și le-ai curățat astfel încât să păstrezi un set de date care conține câteva variabile, inclusiv Culoare. Hai să vizualizăm dataframe-ul în notebook folosind biblioteca ggplot.\n", "\n", "Biblioteca ggplot oferă câteva modalități interesante de a vizualiza datele tale. De exemplu, poți compara distribuțiile datelor pentru fiecare varietate și culoare într-un grafic categorial.\n", "\n", "1. Creează un astfel de grafic folosind funcția geombar, utilizând datele despre dovleci și specificând o mapare de culori pentru fiecare categorie de dovleci (portocaliu sau alb):\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": [ "Observând datele, poți vedea cum se raportează datele despre Culoare la Varietate.\n", "\n", "✅ Având în vedere acest grafic categorial, ce explorări interesante îți poți imagina?\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Pre-procesarea datelor: codificarea caracteristicilor\n", "\n", "Setul nostru de date despre dovleci conține valori de tip șir pentru toate coloanele sale. Lucrul cu date categorice este intuitiv pentru oameni, dar nu și pentru mașini. Algoritmii de învățare automată funcționează bine cu numere. De aceea, codificarea este un pas foarte important în faza de pre-procesare a datelor, deoarece ne permite să transformăm datele categorice în date numerice, fără a pierde informații. O codificare bună duce la construirea unui model bun.\n", "\n", "Pentru codificarea caracteristicilor există două tipuri principale de codificatori:\n", "\n", "1. Codificator ordinal: este potrivit pentru variabile ordinale, care sunt variabile categorice ale căror date urmează o ordine logică, cum ar fi coloana `item_size` din setul nostru de date. Creează o mapare astfel încât fiecare categorie este reprezentată de un număr, care corespunde ordinii categoriei în coloană.\n", "\n", "2. Codificator categorial: este potrivit pentru variabile nominale, care sunt variabile categorice ale căror date nu urmează o ordine logică, cum ar fi toate caracteristicile diferite de `item_size` din setul nostru de date. Este o codificare one-hot, ceea ce înseamnă că fiecare categorie este reprezentată de o coloană binară: variabila codificată este egală cu 1 dacă dovleacul aparține acelei varietăți și 0 în caz contrar.\n", "\n", "Tidymodels oferă un alt pachet interesant: [recipes](https://recipes.tidymodels.org/) - un pachet pentru pre-procesarea datelor. Vom defini o `recipe` care specifică faptul că toate coloanele predictori ar trebui să fie codificate într-un set de numere întregi, o vom `prep` pentru a estima cantitățile și statisticile necesare pentru orice operațiuni și, în final, o vom `bake` pentru a aplica calculele pe date noi.\n", "\n", "> De obicei, recipes este utilizat ca un pre-procesor pentru modelare, unde definește ce pași ar trebui aplicați unui set de date pentru a-l pregăti pentru modelare. În acest caz, este **foarte recomandat** să folosiți un `workflow()` în loc să estimați manual o rețetă folosind prep și bake. Vom vedea toate acestea în scurt timp.\n", ">\n", "> Totuși, pentru moment, folosim recipes + prep + bake pentru a specifica ce pași ar trebui aplicați unui set de date pentru a-l pregăti pentru analiza datelor și apoi extragem datele pre-procesate cu pașii aplicați.\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": [ "✅ Care sunt avantajele utilizării unui encoder ordinal pentru coloana Item Size?\n", "\n", "### Analiza relațiilor dintre variabile\n", "\n", "Acum că am pre-procesat datele, putem analiza relațiile dintre caracteristici și etichetă pentru a înțelege cât de bine va putea modelul să prezică eticheta pe baza caracteristicilor. Cel mai bun mod de a realiza acest tip de analiză este prin reprezentarea grafică a datelor. \n", "Vom folosi din nou funcția ggplot geom_boxplot_ pentru a vizualiza relațiile dintre Item Size, Variety și Color într-un grafic categoric. Pentru a reprezenta mai bine datele, vom folosi coloana codificată Item Size și coloana necodificată 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": [ "#### Utilizați un grafic swarm\n", "\n", "Deoarece Color este o categorie binară (Alb sau Nu), necesită 'o [abordare specializată](https://github.com/rstudio/cheatsheets/blob/main/data-visualization.pdf) pentru vizualizare'.\n", "\n", "Încercați un `grafic swarm` pentru a arăta distribuția culorii în raport cu item_size.\n", "\n", "Vom folosi [pachetul ggbeeswarm](https://github.com/eclarke/ggbeeswarm), care oferă metode pentru a crea grafice în stil beeswarm utilizând ggplot2. Graficele beeswarm sunt o modalitate de a reprezenta punctele care, în mod normal, s-ar suprapune, astfel încât să fie plasate unul lângă altul.\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": [ "Acum că avem o idee despre relația dintre categoriile binare de culoare și grupul mai mare de dimensiuni, să explorăm regresia logistică pentru a determina culoarea probabilă a unui dovleac.\n", "\n", "## Construiește modelul tău\n", "\n", "Selectează variabilele pe care vrei să le folosești în modelul de clasificare și împarte datele în seturi de antrenament și testare. [rsample](https://rsample.tidymodels.org/), un pachet din Tidymodels, oferă infrastructură pentru o împărțire și resampling eficient al datelor:\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": [ "🙌 Suntem gata să antrenăm un model prin ajustarea caracteristicilor de antrenament la eticheta de antrenament (culoare).\n", "\n", "Vom începe prin crearea unei rețete care specifică pașii de preprocesare ce trebuie efectuați asupra datelor noastre pentru a le pregăti pentru modelare, adică: codificarea variabilelor categorice într-un set de întregi. La fel ca `baked_pumpkins`, creăm o `pumpkins_recipe`, dar nu folosim `prep` și `bake`, deoarece acestea vor fi incluse într-un flux de lucru, pe care îl veți vedea în doar câțiva pași de acum înainte.\n", "\n", "Există destul de multe moduri de a specifica un model de regresie logistică în Tidymodels. Vezi `?logistic_reg()`. Deocamdată, vom specifica un model de regresie logistică prin motorul implicit `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": [ "Acum că avem o rețetă și o specificație a modelului, trebuie să găsim o modalitate de a le combina într-un obiect care să preproceseze mai întâi datele (prep+bake în fundal), să ajusteze modelul pe datele preprocesate și să permită, de asemenea, activități potențiale de post-procesare.\n", "\n", "În Tidymodels, acest obiect convenabil se numește [`workflow`](https://workflows.tidymodels.org/) și reunește în mod convenabil componentele tale de modelare.\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": [ "După ce un flux de lucru a fost *specificat*, un model poate fi `antrenat` folosind funcția [`fit()`](https://tidymodels.github.io/parsnip/reference/fit.html). Fluxul de lucru va estima o rețetă și va preprocesa datele înainte de antrenare, astfel încât nu va fi necesar să facem acest lucru manual folosind 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": [ "Modelul afișează coeficienții învățați în timpul antrenamentului.\n", "\n", "Acum că am antrenat modelul folosind datele de antrenament, putem face predicții asupra datelor de testare utilizând [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html). Să începem prin utilizarea modelului pentru a prezice etichetele setului nostru de testare și probabilitățile pentru fiecare etichetă. Când probabilitatea este mai mare de 0.5, clasa prezisă este `WHITE`, altfel `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": [ "Foarte bine! Acest lucru oferă câteva informații suplimentare despre modul în care funcționează regresia logistică.\n", "\n", "### O mai bună înțelegere printr-o matrice de confuzie\n", "\n", "Compararea fiecărei predicții cu valoarea sa reală \"ground truth\" corespunzătoare nu este o metodă foarte eficientă pentru a determina cât de bine prezice modelul. Din fericire, Tidymodels are câteva trucuri suplimentare: [`yardstick`](https://yardstick.tidymodels.org/) - un pachet utilizat pentru a măsura eficiența modelelor folosind metrici de performanță.\n", "\n", "O metrică de performanță asociată problemelor de clasificare este [`matricea de confuzie`](https://wikipedia.org/wiki/Confusion_matrix). O matrice de confuzie descrie cât de bine performează un model de clasificare. O matrice de confuzie înregistrează câte exemple din fiecare clasă au fost clasificate corect de un model. În cazul nostru, aceasta îți va arăta câte dovleci portocalii au fost clasificați ca portocalii și câți dovleci albi au fost clasificați ca albi; matricea de confuzie îți va arăta, de asemenea, câți au fost clasificați în categorii **greșite**.\n", "\n", "Funcția [**`conf_mat()`**](https://tidymodels.github.io/yardstick/reference/conf_mat.html) din yardstick calculează această tabelare încrucișată a claselor observate și prezise.\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": [ "Să interpretăm matricea de confuzie. Modelul nostru este solicitat să clasifice dovlecii între două categorii binare, categoria `alb` și categoria `non-alb`.\n", "\n", "- Dacă modelul tău prezice un dovleac ca fiind alb și acesta aparține categoriei 'alb' în realitate, îl numim `adevărat pozitiv`, reprezentat de numărul din colțul stânga sus.\n", "\n", "- Dacă modelul tău prezice un dovleac ca fiind non-alb și acesta aparține categoriei 'alb' în realitate, îl numim `fals negativ`, reprezentat de numărul din colțul stânga jos.\n", "\n", "- Dacă modelul tău prezice un dovleac ca fiind alb și acesta aparține categoriei 'non-alb' în realitate, îl numim `fals pozitiv`, reprezentat de numărul din colțul dreapta sus.\n", "\n", "- Dacă modelul tău prezice un dovleac ca fiind non-alb și acesta aparține categoriei 'non-alb' în realitate, îl numim `adevărat negativ`, reprezentat de numărul din colțul dreapta jos.\n", "\n", "| Adevăr |\n", "|:-----:|\n", "\n", "\n", "| | | |\n", "|---------------|--------|-------|\n", "| **Prezicere** | ALB | PORTOCALIU |\n", "| ALB | TP | FP |\n", "| PORTOCALIU | FN | TN |\n", "\n", "Probabil ai ghicit că este de preferat să avem un număr mai mare de adevărate pozitive și adevărate negative și un număr mai mic de false pozitive și false negative, ceea ce implică faptul că modelul funcționează mai bine.\n", "\n", "Matricea de confuzie este utilă deoarece dă naștere altor metrici care ne pot ajuta să evaluăm mai bine performanța unui model de clasificare. Să trecem prin câteva dintre ele:\n", "\n", "🎓 Precizie: `TP/(TP + FP)` definită ca proporția de rezultate pozitive prezise care sunt de fapt pozitive. Se mai numește și [valoare predictivă pozitivă](https://en.wikipedia.org/wiki/Positive_predictive_value \"Positive predictive value\").\n", "\n", "🎓 Rechemare: `TP/(TP + FN)` definită ca proporția de rezultate pozitive din numărul de mostre care au fost de fapt pozitive. Se mai numește și `sensibilitate`.\n", "\n", "🎓 Specificitate: `TN/(TN + FP)` definită ca proporția de rezultate negative din numărul de mostre care au fost de fapt negative.\n", "\n", "🎓 Acuratețe: `TP + TN/(TP + TN + FP + FN)` Procentul de etichete prezise corect pentru o mostră.\n", "\n", "🎓 Măsura F: O medie ponderată a preciziei și rechemării, cu cel mai bun rezultat fiind 1 și cel mai slab fiind 0.\n", "\n", "Să calculăm aceste metrici!\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": [ "## Vizualizați curba ROC a acestui model\n", "\n", "Să realizăm încă o vizualizare pentru a observa așa-numita [`curbă ROC`](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": [ "Curbele ROC sunt adesea utilizate pentru a obține o perspectivă asupra performanței unui clasificator în termeni de pozitive adevărate vs. pozitive false. Curbele ROC prezintă de obicei `True Positive Rate`/Sensibilitatea pe axa Y și `False Positive Rate`/1-Specificitatea pe axa X. Astfel, abruptul curbei și spațiul dintre linia de mijloc și curbă sunt importante: se dorește o curbă care urcă rapid și depășește linia. În cazul nostru, există pozitive false la început, iar apoi linia urcă și depășește corect.\n", "\n", "În cele din urmă, să folosim `yardstick::roc_auc()` pentru a calcula efectiv Aria de sub Curbă. O modalitate de a interpreta AUC este ca probabilitatea ca modelul să clasifice un exemplu pozitiv aleator mai sus decât un exemplu negativ aleator.\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": [ "Rezultatul este în jur de `0.975`. Având în vedere că AUC variază între 0 și 1, îți dorești un scor mare, deoarece un model care este 100% corect în predicțiile sale va avea un AUC de 1; în acest caz, modelul este *destul de bun*.\n", "\n", "În lecțiile viitoare despre clasificări, vei învăța cum să îmbunătățești scorurile modelului tău (cum ar fi gestionarea datelor dezechilibrate în acest caz).\n", "\n", "## 🚀Provocare\n", "\n", "Există mult mai multe de descoperit despre regresia logistică! Dar cea mai bună modalitate de a învăța este să experimentezi. Găsește un set de date care se pretează acestui tip de analiză și construiește un model cu el. Ce înveți? sugestie: încearcă [Kaggle](https://www.kaggle.com/search?q=logistic+regression+datasets) pentru seturi de date interesante.\n", "\n", "## Recapitulare și Studiu Individual\n", "\n", "Citește primele câteva pagini din [acest articol de la Stanford](https://web.stanford.edu/~jurafsky/slp3/5.pdf) despre câteva utilizări practice ale regresiei logistice. Gândește-te la sarcini care sunt mai potrivite pentru unul sau altul dintre tipurile de regresie pe care le-am studiat până acum. Ce ar funcționa cel mai bine?\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n---\n\n**Declinarea responsabilității**: \nAcest document a fost tradus folosind serviciul de traducere AI [Co-op Translator](https://github.com/Azure/co-op-translator). Deși depunem eforturi pentru a asigura acuratețea, vă rugăm să aveți în vedere că traducerile automate pot conține erori sau inexactități. Documentul original în limba sa nativă ar trebui considerat sursa autoritară. Pentru informații critice, se recomandă traducerea profesională realizată de un specialist uman. Nu ne asumăm răspunderea pentru eventualele neînțelegeri sau interpretări greșite care pot apărea din utilizarea acestei traduceri.\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-06T11:47:57+00:00", "source_file": "2-Regression/4-Logistic/solution/R/lesson_4-R.ipynb", "language_code": "ro" } }, "nbformat": 4, "nbformat_minor": 1 }