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.
ML-For-Beginners/translations/ro/2-Regression/3-Linear/solution/R/lesson_3-R.ipynb

1086 lines
43 KiB

{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {
"colab": {
"name": "lesson_3-R.ipynb",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true
},
"kernelspec": {
"name": "ir",
"display_name": "R"
},
"language_info": {
"name": "R"
},
"coopTranslator": {
"original_hash": "5015d65d61ba75a223bfc56c273aa174",
"translation_date": "2025-09-06T11:40:23+00:00",
"source_file": "2-Regression/3-Linear/solution/R/lesson_3-R.ipynb",
"language_code": "ro"
}
},
"cells": [
{
"cell_type": "markdown",
"source": [],
"metadata": {
"id": "EgQw8osnsUV-"
}
},
{
"cell_type": "markdown",
"source": [
"## Regresie Liniară și Polinomială pentru Stabilirea Prețului Dovlecilor - Lecția 3\n",
"<p >\n",
" <img src=\"../../images/linear-polynomial.png\"\n",
" width=\"800\"/>\n",
" <figcaption>Infografic de Dasani Madipalli</figcaption>\n",
"\n",
"\n",
"<!--![Infografic de Dasani Madipalli](../../../../../../2-Regression/3-Linear/images/linear-polynomial.png){width=\"800\"}-->\n",
"\n",
"#### Introducere\n",
"\n",
"Până acum, ai explorat ce este regresia folosind date de probă din setul de date privind prețurile dovlecilor, pe care îl vom utiliza pe parcursul acestei lecții. De asemenea, l-ai vizualizat folosind `ggplot2`. 💪\n",
"\n",
"Acum ești pregătit să aprofundezi regresia pentru ML. În această lecție, vei învăța mai multe despre două tipuri de regresie: *regresia liniară de bază* și *regresia polinomială*, împreună cu câteva aspecte matematice care stau la baza acestor tehnici.\n",
"\n",
"> Pe parcursul acestui curriculum, presupunem cunoștințe minime de matematică și încercăm să o facem accesibilă pentru studenții care vin din alte domenii, așa că fii atent la notițe, 🧮 explicații, diagrame și alte instrumente de învățare care să te ajute să înțelegi mai bine.\n",
"\n",
"#### Pregătire\n",
"\n",
"Ca o reamintire, încarci aceste date pentru a pune întrebări despre ele.\n",
"\n",
"- Care este cel mai bun moment pentru a cumpăra dovleci?\n",
"\n",
"- Ce preț pot să mă aștept pentru o ladă de dovleci miniaturali?\n",
"\n",
"- Ar trebui să îi cumpăr în coșuri de jumătate de bushel sau în cutii de 1 1/9 bushel? Hai să continuăm să explorăm aceste date.\n",
"\n",
"În lecția anterioară, ai creat un `tibble` (o reinterpretare modernă a cadrului de date) și l-ai populat cu o parte din setul de date original, standardizând prețurile pe bushel. Totuși, făcând asta, ai reușit să aduni doar aproximativ 400 de puncte de date și doar pentru lunile de toamnă. Poate putem obține mai multe detalii despre natura datelor printr-o curățare mai amănunțită? Vom vedea... 🕵️‍♀️\n",
"\n",
"Pentru această sarcină, 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 din 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",
"- `corrplot`: Pachetul [corrplot](https://cran.r-project.org/web/packages/corrplot/vignettes/corrplot-intro.html) oferă un instrument vizual exploratoriu pentru matricea de corelație, care sprijină reordonarea automată a variabilelor pentru a ajuta la detectarea tiparelor ascunse între variabile.\n",
"\n",
"Le poți instala astfel:\n",
"\n",
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"janitor\", \"corrplot\"))`\n",
"\n",
"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"
],
"metadata": {
"id": "WqQPS1OAsg3H"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"suppressWarnings(if (!require(\"pacman\")) install.packages(\"pacman\"))\n",
"\n",
"pacman::p_load(tidyverse, tidymodels, janitor, corrplot)"
],
"outputs": [],
"metadata": {
"id": "tA4C2WN3skCf",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "c06cd805-5534-4edc-f72b-d0d1dab96ac0"
}
},
{
"cell_type": "markdown",
"source": [
"Vom încărca ulterior aceste pachete grozave și le vom face disponibile în sesiunea noastră curentă de R. (Aceasta este doar pentru ilustrare, `pacman::p_load()` a făcut deja acest lucru pentru tine)\n",
"\n",
"## 1. O linie de regresie liniară\n",
"\n",
"Așa cum ai învățat în Lecția 1, scopul unui exercițiu de regresie liniară este să poți trasa o *linie* *de* *cea mai bună potrivire* pentru a:\n",
"\n",
"- **Arăta relațiile dintre variabile**. Arată relația dintre variabile.\n",
"\n",
"- **Face predicții**. Realizează predicții precise despre unde ar putea să se încadreze un nou punct de date în raport cu acea linie.\n",
"\n",
"Pentru a trasa acest tip de linie, folosim o tehnică statistică numită **Regresie prin metoda celor mai mici pătrate**. Termenul `cei mai mici pătrate` înseamnă că toate punctele de date din jurul liniei de regresie sunt ridicate la pătrat și apoi adunate. Ideal, suma finală este cât mai mică posibil, deoarece dorim un număr redus de erori, sau `cei mai mici pătrate`. Astfel, linia de cea mai bună potrivire este linia care ne oferă cea mai mică valoare pentru suma erorilor pătrate - de aici numele *regresie prin metoda celor mai mici pătrate*.\n",
"\n",
"Facem acest lucru deoarece dorim să modelăm o linie care are cea mai mică distanță cumulativă față de toate punctele noastre de date. De asemenea, ridicăm termenii la pătrat înainte de a-i aduna, deoarece ne preocupă magnitudinea lor, nu direcția.\n",
"\n",
"> **🧮 Arată-mi matematica**\n",
">\n",
"> Această linie, numită *linia de cea mai bună potrivire*, poate fi exprimată prin [o ecuație](https://en.wikipedia.org/wiki/Simple_linear_regression):\n",
">\n",
"> Y = a + bX\n",
">\n",
"> `X` este '`variabila explicativă` sau `predictor`'. `Y` este '`variabila dependentă` sau `rezultat`'. Panta liniei este `b`, iar `a` este interceptul pe axa Y, care se referă la valoarea lui `Y` când `X = 0`.\n",
">\n",
"\n",
"> ![](../../../../../../2-Regression/3-Linear/solution/images/slope.png \"panta = $y/x$\")\n",
" Infografic de Jen Looper\n",
">\n",
"> Mai întâi, calculează panta `b`.\n",
">\n",
"> Cu alte cuvinte, referindu-ne la întrebarea originală despre datele dovleacului: \"prezice prețul unui dovleac pe bucată în funcție de lună\", `X` ar reprezenta prețul, iar `Y` ar reprezenta luna vânzării.\n",
">\n",
"> ![](../../../../../../2-Regression/3-Linear/solution/images/calculation.png)\n",
" Infografic de Jen Looper\n",
"> \n",
"> Calculează valoarea lui Y. Dacă plătești în jur de \\$4, trebuie să fie aprilie!\n",
">\n",
"> Matematica care calculează linia trebuie să demonstreze panta liniei, care depinde și de interceptul, sau unde se află `Y` când `X = 0`.\n",
">\n",
"> Poți observa metoda de calcul pentru aceste valori pe site-ul [Math is Fun](https://www.mathsisfun.com/data/least-squares-regression.html). Vizitează și [acest calculator pentru metoda celor mai mici pătrate](https://www.mathsisfun.com/data/least-squares-calculator.html) pentru a vedea cum valorile numerelor influențează linia.\n",
"\n",
"Nu e chiar atât de înfricoșător, nu-i așa? 🤓\n",
"\n",
"#### Corelație\n",
"\n",
"Un alt termen de înțeles este **Coeficientul de Corelație** între variabilele X și Y date. Folosind un grafic de dispersie, poți vizualiza rapid acest coeficient. Un grafic cu puncte de date distribuite într-o linie ordonată are o corelație ridicată, dar un grafic cu puncte de date distribuite aleatoriu între X și Y are o corelație scăzută.\n",
"\n",
"Un model bun de regresie liniară va fi unul care are un Coeficient de Corelație ridicat (mai aproape de 1 decât de 0) folosind metoda regresiei prin cei mai mici pătrate cu o linie de regresie.\n"
],
"metadata": {
"id": "cdX5FRpvsoP5"
}
},
{
"cell_type": "markdown",
"source": [
"## **2. Un dans cu datele: crearea unui cadru de date care va fi utilizat pentru modelare**\n",
"\n",
"<p >\n",
" <img src=\"../../images/janitor.jpg\"\n",
" width=\"700\"/>\n",
" <figcaption>Ilustrație de @allison_horst</figcaption>\n",
"\n",
"\n",
"<!--![Ilustrație de \\@allison_horst](../../../../../../2-Regression/3-Linear/images/janitor.jpg){width=\"700\"}-->\n"
],
"metadata": {
"id": "WdUKXk7Bs8-V"
}
},
{
"cell_type": "markdown",
"source": [
"Încarcă bibliotecile necesare și setul de date. Convertește datele într-un cadru de date care conține un subset al datelor:\n",
"\n",
"- Selectează doar dovlecii prețuiți pe bușel\n",
"\n",
"- Convertește data într-o lună\n",
"\n",
"- Calculează prețul ca medie între prețurile maxime și minime\n",
"\n",
"- Convertește prețul pentru a reflecta prețul pe cantitatea de bușel\n",
"\n",
"> Am acoperit acești pași în [lecția anterioară](https://github.com/microsoft/ML-For-Beginners/blob/main/2-Regression/2-Data/solution/lesson_2-R.ipynb).\n"
],
"metadata": {
"id": "fMCtu2G2s-p8"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Load the core Tidyverse packages\n",
"library(tidyverse)\n",
"library(lubridate)\n",
"\n",
"# Import the pumpkins data\n",
"pumpkins <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/2-Regression/data/US-pumpkins.csv\")\n",
"\n",
"\n",
"# Get a glimpse and dimensions of the data\n",
"glimpse(pumpkins)\n",
"\n",
"\n",
"# Print the first 50 rows of the data set\n",
"pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "ryMVZEEPtERn"
}
},
{
"cell_type": "markdown",
"source": [
"În spiritul aventurii pure, să explorăm [`pachetul janitor`](../../../../../../2-Regression/3-Linear/solution/R/github.com/sfirke/janitor) care oferă funcții simple pentru examinarea și curățarea datelor murdare. De exemplu, să aruncăm o privire asupra numelor coloanelor pentru datele noastre:\n"
],
"metadata": {
"id": "xcNxM70EtJjb"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Return column names\n",
"pumpkins %>% \n",
" names()"
],
"outputs": [],
"metadata": {
"id": "5XtpaIigtPfW"
}
},
{
"cell_type": "markdown",
"source": [
"🤔 Putem face mai bine. Haideți să transformăm aceste nume de coloane în `friendR` prin convertirea lor la convenția [snake_case](https://en.wikipedia.org/wiki/Snake_case) folosind `janitor::clean_names`. Pentru a afla mai multe despre această funcție: `?clean_names`\n"
],
"metadata": {
"id": "IbIqrMINtSHe"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Clean names to the snake_case convention\n",
"pumpkins <- pumpkins %>% \n",
" clean_names(case = \"snake\")\n",
"\n",
"# Return column names\n",
"pumpkins %>% \n",
" names()"
],
"outputs": [],
"metadata": {
"id": "a2uYvclYtWvX"
}
},
{
"cell_type": "markdown",
"source": [
"Mult mai ordonat 🧹! Acum, un dans cu datele folosind `dplyr`, la fel ca în lecția anterioară! 💃\n"
],
"metadata": {
"id": "HfhnuzDDtaDd"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Select desired columns\n",
"pumpkins <- pumpkins %>% \n",
" select(variety, city_name, package, low_price, high_price, date)\n",
"\n",
"\n",
"\n",
"# Extract the month from the dates to a new column\n",
"pumpkins <- pumpkins %>%\n",
" mutate(date = mdy(date),\n",
" month = month(date)) %>% \n",
" select(-date)\n",
"\n",
"\n",
"\n",
"# Create a new column for average Price\n",
"pumpkins <- pumpkins %>% \n",
" mutate(price = (low_price + high_price)/2)\n",
"\n",
"\n",
"# Retain only pumpkins with the string \"bushel\"\n",
"new_pumpkins <- pumpkins %>% \n",
" filter(str_detect(string = package, pattern = \"bushel\"))\n",
"\n",
"\n",
"# Normalize the pricing so that you show the pricing per bushel, not per 1 1/9 or 1/2 bushel\n",
"new_pumpkins <- new_pumpkins %>% \n",
" mutate(price = case_when(\n",
" str_detect(package, \"1 1/9\") ~ price/(1.1),\n",
" str_detect(package, \"1/2\") ~ price*2,\n",
" TRUE ~ price))\n",
"\n",
"# Relocate column positions\n",
"new_pumpkins <- new_pumpkins %>% \n",
" relocate(month, .before = variety)\n",
"\n",
"\n",
"# Display the first 5 rows\n",
"new_pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "X0wU3gQvtd9f"
}
},
{
"cell_type": "markdown",
"source": [
"Bravo! 👌 Acum ai un set de date curat și ordonat pe care poți construi noul tău model de regresie!\n",
"\n",
"Ce zici de un grafic scatter?\n"
],
"metadata": {
"id": "UpaIwaxqth82"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Set theme\n",
"theme_set(theme_light())\n",
"\n",
"# Make a scatter plot of month and price\n",
"new_pumpkins %>% \n",
" ggplot(mapping = aes(x = month, y = price)) +\n",
" geom_point(size = 1.6)\n"
],
"outputs": [],
"metadata": {
"id": "DXgU-j37tl5K"
}
},
{
"cell_type": "markdown",
"source": [
"Un grafic de tip scatter ne amintește că avem date doar din lunile august până în decembrie. Probabil avem nevoie de mai multe date pentru a putea trage concluzii într-un mod liniar.\n",
"\n",
"Să aruncăm din nou o privire asupra datelor noastre de modelare:\n"
],
"metadata": {
"id": "Ve64wVbwtobI"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Display first 5 rows\n",
"new_pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "HFQX2ng1tuSJ"
}
},
{
"cell_type": "markdown",
"source": [
"Ce-ar fi dacă am vrea să prezicem `price` (prețul) unui dovleac bazându-ne pe coloanele `city` (oraș) sau `package` (ambalaj), care sunt de tip caracter? Sau, și mai simplu, cum am putea găsi corelația (care necesită ca ambele intrări să fie numerice) între, de exemplu, `package` și `price`? 🤷🤷\n",
"\n",
"Modelele de învățare automată funcționează cel mai bine cu caracteristici numerice, mai degrabă decât cu valori text, așa că, în general, trebuie să convertiți caracteristicile categorice în reprezentări numerice.\n",
"\n",
"Aceasta înseamnă că trebuie să găsim o modalitate de a reformata predictorii noștri pentru a-i face mai ușor de utilizat de către un model, un proces cunoscut sub numele de `feature engineering`.\n"
],
"metadata": {
"id": "7hsHoxsStyjJ"
}
},
{
"cell_type": "markdown",
"source": [
"## 3. Preprocesarea datelor pentru modelare cu recipes 👩‍🍳👨‍🍳\n",
"\n",
"Activitățile care reformatează valorile predictorilor pentru a le face mai ușor de utilizat de către un model sunt denumite `feature engineering`.\n",
"\n",
"Modelele diferite au cerințe diferite de preprocesare. De exemplu, metoda celor mai mici pătrate necesită `codificarea variabilelor categorice`, cum ar fi luna, varietatea și city_name. Acest lucru implică pur și simplu `transformarea` unei coloane cu `valori categorice` într-una sau mai multe `coloane numerice` care înlocuiesc coloana originală.\n",
"\n",
"De exemplu, să presupunem că datele tale includ următoarea caracteristică categorică:\n",
"\n",
"| city |\n",
"|:-------:|\n",
"| Denver |\n",
"| Nairobi |\n",
"| Tokyo |\n",
"\n",
"Poți aplica *codificarea ordinală* pentru a înlocui fiecare categorie cu o valoare întreagă unică, astfel:\n",
"\n",
"| city |\n",
"|:----:|\n",
"| 0 |\n",
"| 1 |\n",
"| 2 |\n",
"\n",
"Și exact asta vom face cu datele noastre!\n",
"\n",
"În această secțiune, vom explora un alt pachet uimitor din Tidymodels: [recipes](https://tidymodels.github.io/recipes/) - care este conceput pentru a te ajuta să preprocesezi datele **înainte** de antrenarea modelului. În esență, o rețetă este un obiect care definește ce pași ar trebui aplicați unui set de date pentru a-l pregăti pentru modelare.\n",
"\n",
"Acum, să creăm o rețetă care pregătește datele noastre pentru modelare prin înlocuirea fiecărei observații din coloanele predictorilor cu un întreg unic:\n"
],
"metadata": {
"id": "AD5kQbcvt3Xl"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Specify a recipe\n",
"pumpkins_recipe <- recipe(price ~ ., data = new_pumpkins) %>% \n",
" step_integer(all_predictors(), zero_based = TRUE)\n",
"\n",
"\n",
"# Print out the recipe\n",
"pumpkins_recipe"
],
"outputs": [],
"metadata": {
"id": "BNaFKXfRt9TU"
}
},
{
"cell_type": "markdown",
"source": [
"Super! 👏 Tocmai am creat prima noastră rețetă care specifică un rezultat (prețul) și predictorii corespunzători, iar toate coloanele de predictori trebuie să fie codificate într-un set de numere întregi 🙌! Hai să o descompunem rapid:\n",
"\n",
"- Apelul la `recipe()` cu o formulă indică rețetei *rolurile* variabilelor folosind datele `new_pumpkins` ca referință. De exemplu, coloana `price` a fost atribuită rolul de `outcome`, în timp ce restul coloanelor au fost atribuite rolul de `predictor`.\n",
"\n",
"- `step_integer(all_predictors(), zero_based = TRUE)` specifică faptul că toți predictorii trebuie să fie convertiți într-un set de numere întregi, numerotarea începând de la 0.\n",
"\n",
"Suntem siguri că te gândești: \"Este atât de tare!! Dar ce fac dacă vreau să confirm că rețetele fac exact ceea ce mă aștept să facă? 🤔\"\n",
"\n",
"Este o idee grozavă! Vezi tu, odată ce rețeta ta este definită, poți estima parametrii necesari pentru a preprocesa efectiv datele și apoi să extragi datele procesate. De obicei, nu trebuie să faci acest lucru când folosești Tidymodels (vom vedea convenția normală în doar un minut-\\> `workflows`), dar poate fi util atunci când vrei să faci un fel de verificare pentru a confirma că rețetele funcționează conform așteptărilor.\n",
"\n",
"Pentru asta, vei avea nevoie de două verbe suplimentare: `prep()` și `bake()`, iar ca întotdeauna, micii noștri prieteni din R de la [`Allison Horst`](https://github.com/allisonhorst/stats-illustrations) te ajută să înțelegi mai bine acest lucru!\n",
"\n",
"<p >\n",
" <img src=\"../../images/recipes.png\"\n",
" width=\"550\"/>\n",
" <figcaption>Ilustrație de @allison_horst</figcaption>\n"
],
"metadata": {
"id": "KEiO0v7kuC9O"
}
},
{
"cell_type": "markdown",
"source": [
"[`prep()`](https://recipes.tidymodels.org/reference/prep.html): estimează parametrii necesari dintr-un set de antrenament care pot fi aplicați ulterior altor seturi de date. De exemplu, pentru o anumită coloană predictor, ce observație va fi atribuită ca întreg 0 sau 1 sau 2 etc.\n",
"\n",
"[`bake()`](https://recipes.tidymodels.org/reference/bake.html): ia o rețetă pregătită și aplică operațiunile pe orice set de date.\n",
"\n",
"Așadar, să pregătim și să aplicăm rețetele noastre pentru a confirma cu adevărat că, în spatele cortinei, coloanele predictor vor fi mai întâi codificate înainte ca un model să fie ajustat.\n"
],
"metadata": {
"id": "Q1xtzebuuTCP"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Prep the recipe\n",
"pumpkins_prep <- prep(pumpkins_recipe)\n",
"\n",
"# Bake the recipe to extract a preprocessed new_pumpkins data\n",
"baked_pumpkins <- bake(pumpkins_prep, new_data = NULL)\n",
"\n",
"# Print out the baked data set\n",
"baked_pumpkins %>% \n",
" slice_head(n = 10)"
],
"outputs": [],
"metadata": {
"id": "FGBbJbP_uUUn"
}
},
{
"cell_type": "markdown",
"source": [
"Ura! 🥳 Datele procesate `baked_pumpkins` au toți predictorii codificați, confirmând că pașii de preprocesare definiți ca rețeta noastră funcționează așa cum ne așteptam. Acest lucru face ca datele să fie mai greu de citit pentru tine, dar mult mai ușor de înțeles pentru Tidymodels! Ia-ți puțin timp să descoperi ce observație a fost mapată la un întreg corespunzător.\n",
"\n",
"De asemenea, merită menționat că `baked_pumpkins` este un cadru de date pe care putem efectua calcule.\n",
"\n",
"De exemplu, să încercăm să găsim o corelație bună între două puncte din datele tale pentru a construi un model predictiv eficient. Vom folosi funcția `cor()` pentru asta. Tastează `?cor()` pentru a afla mai multe despre funcție.\n"
],
"metadata": {
"id": "1dvP0LBUueAW"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Find the correlation between the city_name and the price\n",
"cor(baked_pumpkins$city_name, baked_pumpkins$price)\n",
"\n",
"# Find the correlation between the package and the price\n",
"cor(baked_pumpkins$package, baked_pumpkins$price)\n"
],
"outputs": [],
"metadata": {
"id": "3bQzXCjFuiSV"
}
},
{
"cell_type": "markdown",
"source": [
"Se pare că există doar o corelație slabă între Oraș și Preț. Totuși, există o corelație ceva mai bună între Pachet și Prețul acestuia. Are sens, nu-i așa? De obicei, cu cât cutia de produse este mai mare, cu atât prețul este mai ridicat.\n",
"\n",
"De vreme ce suntem aici, hai să încercăm să vizualizăm și o matrice de corelație pentru toate coloanele folosind pachetul `corrplot`.\n"
],
"metadata": {
"id": "BToPWbgjuoZw"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Load the corrplot package\n",
"library(corrplot)\n",
"\n",
"# Obtain correlation matrix\n",
"corr_mat <- cor(baked_pumpkins %>% \n",
" # Drop columns that are not really informative\n",
" select(-c(low_price, high_price)))\n",
"\n",
"# Make a correlation plot between the variables\n",
"corrplot(corr_mat, method = \"shade\", shade.col = NA, tl.col = \"black\", tl.srt = 45, addCoef.col = \"black\", cl.pos = \"n\", order = \"original\")"
],
"outputs": [],
"metadata": {
"id": "ZwAL3ksmutVR"
}
},
{
"cell_type": "markdown",
"source": [
"🤩🤩 Mult mai bine.\n",
"\n",
"O întrebare bună de pus acum despre aceste date ar fi: '`Ce preț pot să mă aștept pentru un pachet de dovleci?`' Hai să intrăm direct în subiect!\n",
"\n",
"> Notă: Când **`bake()`** rețeta pregătită **`pumpkins_prep`** cu **`new_data = NULL`**, extragi datele procesate (adică codificate) de antrenament. Dacă ai avea un alt set de date, de exemplu un set de testare, și ai vrea să vezi cum o rețetă l-ar pre-procesa, ai coace pur și simplu **`pumpkins_prep`** cu **`new_data = test_set`**\n",
"\n",
"## 4. Construiește un model de regresie liniară\n",
"\n",
"<p >\n",
" <img src=\"../../images/linear-polynomial.png\"\n",
" width=\"800\"/>\n",
" <figcaption>Infografic de Dasani Madipalli</figcaption>\n",
"\n",
"\n",
"<!--![Infografic de Dasani Madipalli](../../../../../../2-Regression/3-Linear/images/linear-polynomial.png){width=\"800\"}-->\n"
],
"metadata": {
"id": "YqXjLuWavNxW"
}
},
{
"cell_type": "markdown",
"source": [
"Acum că am construit o rețetă și am confirmat că datele vor fi pre-procesate corespunzător, să construim un model de regresie pentru a răspunde la întrebarea: `Ce preț pot să mă aștept pentru un pachet de dovleac dat?`\n",
"\n",
"#### Antrenează un model de regresie liniară folosind setul de antrenament\n",
"\n",
"După cum probabil ai dedus deja, coloana *price* este variabila `rezultat`, în timp ce coloana *package* este variabila `predictor`.\n",
"\n",
"Pentru a face acest lucru, mai întâi vom împărți datele astfel încât 80% să fie utilizate pentru antrenament și 20% pentru setul de testare, apoi vom defini o rețetă care va codifica coloana predictor într-un set de numere întregi, iar apoi vom construi o specificație de model. Nu vom pregăti și coace rețeta noastră, deoarece știm deja că va pre-procesa datele conform așteptărilor.\n"
],
"metadata": {
"id": "Pq0bSzCevW-h"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"set.seed(2056)\n",
"# Split the data into training and test sets\n",
"pumpkins_split <- new_pumpkins %>% \n",
" initial_split(prop = 0.8)\n",
"\n",
"\n",
"# Extract training and test data\n",
"pumpkins_train <- training(pumpkins_split)\n",
"pumpkins_test <- testing(pumpkins_split)\n",
"\n",
"\n",
"\n",
"# Create a recipe for preprocessing the data\n",
"lm_pumpkins_recipe <- recipe(price ~ package, data = pumpkins_train) %>% \n",
" step_integer(all_predictors(), zero_based = TRUE)\n",
"\n",
"\n",
"\n",
"# Create a linear model specification\n",
"lm_spec <- linear_reg() %>% \n",
" set_engine(\"lm\") %>% \n",
" set_mode(\"regression\")"
],
"outputs": [],
"metadata": {
"id": "CyoEh_wuvcLv"
}
},
{
"cell_type": "markdown",
"source": [
"Bravo! 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. Cum îți sună asta pentru liniștea ta sufletească!🤩\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! Acesta este ceea ce am numi *pipelines* în *Python*.\n",
"\n",
"Așadar, să împachetăm totul într-un workflow!📦\n"
],
"metadata": {
"id": "G3zF_3DqviFJ"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Hold modelling components in a workflow\n",
"lm_wf <- workflow() %>% \n",
" add_recipe(lm_pumpkins_recipe) %>% \n",
" add_model(lm_spec)\n",
"\n",
"# Print out the workflow\n",
"lm_wf"
],
"outputs": [],
"metadata": {
"id": "T3olroU3v-WX"
}
},
{
"cell_type": "markdown",
"source": [
"👌 În plus, un flux de lucru poate fi ajustat/antrenat în mod similar cu un model.\n"
],
"metadata": {
"id": "zd1A5tgOwEPX"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Train the model\n",
"lm_wf_fit <- lm_wf %>% \n",
" fit(data = pumpkins_train)\n",
"\n",
"# Print the model coefficients learned \n",
"lm_wf_fit"
],
"outputs": [],
"metadata": {
"id": "NhJagFumwFHf"
}
},
{
"cell_type": "markdown",
"source": [
"Din rezultatele modelului, putem observa coeficienții învățați în timpul antrenării. Aceștia reprezintă coeficienții liniei de ajustare optimă care ne oferă cea mai mică eroare totală între variabila reală și cea prezisă.\n",
"\n",
"#### Evaluarea performanței modelului folosind setul de testare\n",
"\n",
"Este momentul să vedem cum s-a descurcat modelul 📏! Cum facem acest lucru?\n",
"\n",
"Acum că am antrenat modelul, îl putem folosi pentru a face predicții pentru `test_set` utilizând `parsnip::predict()`. Apoi putem compara aceste predicții cu valorile reale ale etichetelor pentru a evalua cât de bine (sau nu!) funcționează modelul.\n",
"\n",
"Să începem prin a face predicții pentru setul de testare, apoi să legăm coloanele la setul de testare.\n"
],
"metadata": {
"id": "_4QkGtBTwItF"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Make predictions for the test set\n",
"predictions <- lm_wf_fit %>% \n",
" predict(new_data = pumpkins_test)\n",
"\n",
"\n",
"# Bind predictions to the test set\n",
"lm_results <- pumpkins_test %>% \n",
" select(c(package, price)) %>% \n",
" bind_cols(predictions)\n",
"\n",
"\n",
"# Print the first ten rows of the tibble\n",
"lm_results %>% \n",
" slice_head(n = 10)"
],
"outputs": [],
"metadata": {
"id": "UFZzTG0gwTs9"
}
},
{
"cell_type": "markdown",
"source": [
"Da, tocmai ai antrenat un model și l-ai folosit pentru a face predicții!🔮 Este bun? Hai să evaluăm performanța modelului!\n",
"\n",
"În Tidymodels, facem acest lucru folosind `yardstick::metrics()`! Pentru regresia liniară, să ne concentrăm pe următoarele metrici:\n",
"\n",
"- `Root Mean Square Error (RMSE)`: Rădăcina pătrată a [MSE](https://en.wikipedia.org/wiki/Mean_squared_error). Aceasta oferă o metrică absolută în aceeași unitate ca eticheta (în acest caz, prețul unui dovleac). Cu cât valoarea este mai mică, cu atât modelul este mai bun (într-un sens simplist, reprezintă prețul mediu cu care predicțiile sunt greșite!).\n",
"\n",
"- `Coefficient of Determination (cunoscut de obicei ca R-squared sau R2)`: O metrică relativă în care, cu cât valoarea este mai mare, cu atât modelul se potrivește mai bine. În esență, această metrică reprezintă cât de mult din variația dintre valorile etichetei prezise și cele reale modelul reușește să explice.\n"
],
"metadata": {
"id": "0A5MjzM7wW9M"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Evaluate performance of linear regression\n",
"metrics(data = lm_results,\n",
" truth = price,\n",
" estimate = .pred)"
],
"outputs": [],
"metadata": {
"id": "reJ0UIhQwcEH"
}
},
{
"cell_type": "markdown",
"source": [
"Acolo se duce performanța modelului. Să vedem dacă putem obține o indicație mai bună vizualizând un grafic de dispersie al pachetului și prețului, apoi folosind predicțiile făcute pentru a suprapune o linie de ajustare optimă.\n",
"\n",
"Aceasta înseamnă că va trebui să pregătim și să procesăm setul de testare pentru a codifica coloana pachet, apoi să legăm acest lucru de predicțiile făcute de modelul nostru.\n"
],
"metadata": {
"id": "fdgjzjkBwfWt"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Encode package column\n",
"package_encode <- lm_pumpkins_recipe %>% \n",
" prep() %>% \n",
" bake(new_data = pumpkins_test) %>% \n",
" select(package)\n",
"\n",
"\n",
"# Bind encoded package column to the results\n",
"lm_results <- lm_results %>% \n",
" bind_cols(package_encode %>% \n",
" rename(package_integer = package)) %>% \n",
" relocate(package_integer, .after = package)\n",
"\n",
"\n",
"# Print new results data frame\n",
"lm_results %>% \n",
" slice_head(n = 5)\n",
"\n",
"\n",
"# Make a scatter plot\n",
"lm_results %>% \n",
" ggplot(mapping = aes(x = package_integer, y = price)) +\n",
" geom_point(size = 1.6) +\n",
" # Overlay a line of best fit\n",
" geom_line(aes(y = .pred), color = \"orange\", size = 1.2) +\n",
" xlab(\"package\")\n",
" \n"
],
"outputs": [],
"metadata": {
"id": "R0nw719lwkHE"
}
},
{
"cell_type": "markdown",
"source": [
"Super! După cum se poate observa, modelul de regresie liniară nu generalizează foarte bine relația dintre un pachet și prețul său corespunzător.\n",
"\n",
"🎃 Felicitări, tocmai ai creat un model care poate ajuta la prezicerea prețului pentru câteva varietăți de dovleci. Grădina ta de dovleci pentru sărbători va fi minunată. Dar probabil poți crea un model mai bun!\n",
"\n",
"## 5. Construiește un model de regresie polinomială\n",
"\n",
"<p >\n",
" <img src=\"../../images/linear-polynomial.png\"\n",
" width=\"800\"/>\n",
" <figcaption>Infografic de Dasani Madipalli</figcaption>\n",
"\n",
"\n",
"<!--![Infografic de Dasani Madipalli](../../../../../../2-Regression/3-Linear/images/linear-polynomial.png){width=\"800\"}-->\n"
],
"metadata": {
"id": "HOCqJXLTwtWI"
}
},
{
"cell_type": "markdown",
"source": [
"Uneori, datele noastre pot să nu aibă o relație liniară, dar totuși dorim să prezicem un rezultat. Regresia polinomială ne poate ajuta să facem predicții pentru relații mai complexe, non-liniare.\n",
"\n",
"Luați, de exemplu, relația dintre ambalaj și preț în setul nostru de date despre dovleci. Deși uneori există o relație liniară între variabile - cu cât dovleacul este mai mare ca volum, cu atât prețul este mai mare - alteori aceste relații nu pot fi reprezentate ca un plan sau o linie dreaptă.\n",
"\n",
"> ✅ Iată [câteva exemple suplimentare](https://online.stat.psu.edu/stat501/lesson/9/9.8) de date care ar putea utiliza regresia polinomială\n",
">\n",
"> Priviți din nou relația dintre varietate și preț în graficul anterior. Pare că acest scatterplot ar trebui analizat neapărat printr-o linie dreaptă? Poate că nu. În acest caz, puteți încerca regresia polinomială.\n",
">\n",
"> ✅ Polinoamele sunt expresii matematice care pot consta din una sau mai multe variabile și coeficienți\n",
"\n",
"#### Antrenează un model de regresie polinomială folosind setul de antrenament\n",
"\n",
"Regresia polinomială creează o *linie curbată* pentru a se potrivi mai bine datelor non-liniare.\n",
"\n",
"Să vedem dacă un model polinomial va performa mai bine în realizarea predicțiilor. Vom urma un proces oarecum similar cu cel de dinainte:\n",
"\n",
"- Creează o rețetă care specifică pașii de preprocesare ce trebuie efectuați asupra datelor noastre pentru a le pregăti pentru modelare, adică: codificarea predictorilor și calcularea polinoamelor de gradul *n*\n",
"\n",
"- Construiește o specificație de model\n",
"\n",
"- Combină rețeta și specificația modelului într-un flux de lucru\n",
"\n",
"- Creează un model prin ajustarea fluxului de lucru\n",
"\n",
"- Evaluează cât de bine performează modelul pe datele de testare\n",
"\n",
"Să trecem direct la treabă!\n"
],
"metadata": {
"id": "VcEIpRV9wzYr"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Specify a recipe\r\n",
"poly_pumpkins_recipe <-\r\n",
" recipe(price ~ package, data = pumpkins_train) %>%\r\n",
" step_integer(all_predictors(), zero_based = TRUE) %>% \r\n",
" step_poly(all_predictors(), degree = 4)\r\n",
"\r\n",
"\r\n",
"# Create a model specification\r\n",
"poly_spec <- linear_reg() %>% \r\n",
" set_engine(\"lm\") %>% \r\n",
" set_mode(\"regression\")\r\n",
"\r\n",
"\r\n",
"# Bundle recipe and model spec into a workflow\r\n",
"poly_wf <- workflow() %>% \r\n",
" add_recipe(poly_pumpkins_recipe) %>% \r\n",
" add_model(poly_spec)\r\n",
"\r\n",
"\r\n",
"# Create a model\r\n",
"poly_wf_fit <- poly_wf %>% \r\n",
" fit(data = pumpkins_train)\r\n",
"\r\n",
"\r\n",
"# Print learned model coefficients\r\n",
"poly_wf_fit\r\n",
"\r\n",
" "
],
"outputs": [],
"metadata": {
"id": "63n_YyRXw3CC"
}
},
{
"cell_type": "markdown",
"source": [
"#### Evaluează performanța modelului\n",
"\n",
"👏👏 Ai construit un model polinomial, hai să facem predicții pe setul de testare!\n"
],
"metadata": {
"id": "-LHZtztSxDP0"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Make price predictions on test data\r\n",
"poly_results <- poly_wf_fit %>% predict(new_data = pumpkins_test) %>% \r\n",
" bind_cols(pumpkins_test %>% select(c(package, price))) %>% \r\n",
" relocate(.pred, .after = last_col())\r\n",
"\r\n",
"\r\n",
"# Print the results\r\n",
"poly_results %>% \r\n",
" slice_head(n = 10)"
],
"outputs": [],
"metadata": {
"id": "YUFpQ_dKxJGx"
}
},
{
"cell_type": "markdown",
"source": [
"Ura, să evaluăm cum s-a descurcat modelul pe test_set folosind `yardstick::metrics()`.\n"
],
"metadata": {
"id": "qxdyj86bxNGZ"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"metrics(data = poly_results, truth = price, estimate = .pred)"
],
"outputs": [],
"metadata": {
"id": "8AW5ltkBxXDm"
}
},
{
"cell_type": "markdown",
"source": [
"🤩🤩 Performanță mult mai bună.\n",
"\n",
"`rmse` a scăzut de la aproximativ 7 la aproximativ 3, ceea ce indică o reducere a erorii dintre prețul real și prețul prezis. Poți interpreta *în linii mari* acest lucru ca însemnând că, în medie, predicțiile incorecte sunt greșite cu aproximativ 3$. `rsq` a crescut de la aproximativ 0.4 la 0.8.\n",
"\n",
"Toate aceste metrici indică faptul că modelul polinomial funcționează mult mai bine decât modelul liniar. Bravo!\n",
"\n",
"Hai să vedem dacă putem vizualiza acest lucru!\n"
],
"metadata": {
"id": "6gLHNZDwxYaS"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Bind encoded package column to the results\r\n",
"poly_results <- poly_results %>% \r\n",
" bind_cols(package_encode %>% \r\n",
" rename(package_integer = package)) %>% \r\n",
" relocate(package_integer, .after = package)\r\n",
"\r\n",
"\r\n",
"# Print new results data frame\r\n",
"poly_results %>% \r\n",
" slice_head(n = 5)\r\n",
"\r\n",
"\r\n",
"# Make a scatter plot\r\n",
"poly_results %>% \r\n",
" ggplot(mapping = aes(x = package_integer, y = price)) +\r\n",
" geom_point(size = 1.6) +\r\n",
" # Overlay a line of best fit\r\n",
" geom_line(aes(y = .pred), color = \"midnightblue\", size = 1.2) +\r\n",
" xlab(\"package\")\r\n"
],
"outputs": [],
"metadata": {
"id": "A83U16frxdF1"
}
},
{
"cell_type": "markdown",
"source": [
"Poți vedea o linie curbată care se potrivește mai bine cu datele tale! 🤩\n",
"\n",
"Poți face aceasta mai netedă prin transmiterea unei formule polinomiale către `geom_smooth` astfel:\n"
],
"metadata": {
"id": "4U-7aHOVxlGU"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Make a scatter plot\r\n",
"poly_results %>% \r\n",
" ggplot(mapping = aes(x = package_integer, y = price)) +\r\n",
" geom_point(size = 1.6) +\r\n",
" # Overlay a line of best fit\r\n",
" geom_smooth(method = lm, formula = y ~ poly(x, degree = 4), color = \"midnightblue\", size = 1.2, se = FALSE) +\r\n",
" xlab(\"package\")"
],
"outputs": [],
"metadata": {
"id": "5vzNT0Uexm-w"
}
},
{
"cell_type": "markdown",
"source": [
"La fel de lin ca o curbă!🤩\n",
"\n",
"Iată cum poți face o nouă predicție:\n"
],
"metadata": {
"id": "v9u-wwyLxq4G"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Make a hypothetical data frame\r\n",
"hypo_tibble <- tibble(package = \"bushel baskets\")\r\n",
"\r\n",
"# Make predictions using linear model\r\n",
"lm_pred <- lm_wf_fit %>% predict(new_data = hypo_tibble)\r\n",
"\r\n",
"# Make predictions using polynomial model\r\n",
"poly_pred <- poly_wf_fit %>% predict(new_data = hypo_tibble)\r\n",
"\r\n",
"# Return predictions in a list\r\n",
"list(\"linear model prediction\" = lm_pred, \r\n",
" \"polynomial model prediction\" = poly_pred)\r\n"
],
"outputs": [],
"metadata": {
"id": "jRPSyfQGxuQv"
}
},
{
"cell_type": "markdown",
"source": [
"Predicția modelului `polynomial` are sens, având în vedere graficele de dispersie ale `price` și `package`! Și, dacă acesta este un model mai bun decât cel anterior, privind aceleași date, trebuie să bugetezi pentru aceste dovleci mai scumpi!\n",
"\n",
"🏆 Bravo! Ai creat două modele de regresie într-o singură lecție. În secțiunea finală despre regresie, vei învăța despre regresia logistică pentru a determina categorii.\n",
"\n",
"## **🚀Provocare**\n",
"\n",
"Testează mai multe variabile diferite în acest notebook pentru a vedea cum corelația corespunde cu acuratețea modelului.\n",
"\n",
"## [**Quiz după lecție**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/14/)\n",
"\n",
"## **Recapitulare & Studiu individual**\n",
"\n",
"În această lecție am învățat despre regresia liniară. Există și alte tipuri importante de regresie. Citește despre tehnicile Stepwise, Ridge, Lasso și Elasticnet. Un curs bun pentru a învăța mai multe este [cursul de Învățare Statistică de la Stanford](https://online.stanford.edu/courses/sohs-ystatslearning-statistical-learning).\n",
"\n",
"Dacă vrei să afli mai multe despre cum să folosești cadrul uimitor Tidymodels, te rugăm să consulți următoarele resurse:\n",
"\n",
"- Website-ul Tidymodels: [Începe cu Tidymodels](https://www.tidymodels.org/start/)\n",
"\n",
"- Max Kuhn și Julia Silge, [*Tidy Modeling with R*](https://www.tmwr.org/)*.*\n",
"\n",
"###### **MULȚUMIRI SPECIALE:**\n",
"\n",
"[Allison Horst](https://twitter.com/allison_horst?lang=en) pentru crearea ilustrațiilor uimitoare care fac R mai primitor și captivant. Găsește mai multe ilustrații în [galeria ei](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n"
],
"metadata": {
"id": "8zOLOWqMxzk5"
}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Declinare de responsabilitate**: \nAcest document a fost tradus folosind serviciul de traducere AI [Co-op Translator](https://github.com/Azure/co-op-translator). Deși ne străduim să asigurăm acuratețea, vă rugăm să rețineți că traducerile automate pot conține erori sau inexactități. Documentul original în limba sa natală ar trebui considerat sursa autoritară. Pentru informații critice, se recomandă traducerea profesională realizată de un specialist uman. Nu ne asumăm responsabilitatea pentru eventualele neînțelegeri sau interpretări greșite care pot apărea din utilizarea acestei traduceri.\n"
]
}
]
}