{ "nbformat": 4, "nbformat_minor": 2, "metadata": { "colab": { "name": "lesson_2-R.ipynb", "provenance": [], "collapsed_sections": [], "toc_visible": true }, "kernelspec": { "name": "ir", "display_name": "R" }, "language_info": { "name": "R" }, "coopTranslator": { "original_hash": "f3c335f9940cfd76528b3ef918b9b342", "translation_date": "2025-09-06T11:59:41+00:00", "source_file": "2-Regression/2-Data/solution/R/lesson_2-R.ipynb", "language_code": "ro" } }, "cells": [ { "cell_type": "markdown", "source": [ "# Construiește un model de regresie: pregătește și vizualizează datele\n", "\n", "## **Regresie liniară pentru dovleci - Lecția 2**\n", "#### Introducere\n", "\n", "Acum că ai configurat instrumentele necesare pentru a începe să construiești modele de învățare automată folosind Tidymodels și Tidyverse, ești pregătit să începi să pui întrebări despre datele tale. Pe măsură ce lucrezi cu date și aplici soluții de învățare automată, este foarte important să înțelegi cum să formulezi întrebarea corectă pentru a valorifica în mod adecvat potențialul setului tău de date.\n", "\n", "În această lecție, vei învăța:\n", "\n", "- Cum să pregătești datele pentru construirea unui model.\n", "\n", "- Cum să folosești `ggplot2` pentru vizualizarea datelor.\n", "\n", "Întrebarea la care vrei să obții un răspuns va determina ce tip de algoritmi de învățare automată vei utiliza. Iar calitatea răspunsului pe care îl primești va depinde în mare măsură de natura datelor tale.\n", "\n", "Să vedem acest lucru printr-un exercițiu practic.\n", "\n", "\n", "
\n",
" \n",
"
\n",
"\n",
"> O recapitulare: Operatorul pipe (`%>%`) efectuează operațiuni într-o succesiune logică, transmițând un obiect mai departe într-o funcție sau expresie. Poți considera operatorul pipe ca și cum ai spune \"și apoi\" în codul tău.\n"
],
"metadata": {
"id": "REWcIv9yX29v"
}
},
{
"cell_type": "markdown",
"source": [
"## 2. Verificarea datelor lipsă\n",
"\n",
"Una dintre cele mai frecvente probleme cu care se confruntă oamenii de știință în domeniul datelor este existența datelor incomplete sau lipsă. R reprezintă valorile lipsă sau necunoscute printr-o valoare specială: `NA` (Not Available).\n",
"\n",
"Deci, cum putem afla dacă cadrul de date conține valori lipsă?\n",
"
\n",
"- O metodă directă ar fi utilizarea funcției de bază din R `anyNA`, care returnează obiecte logice `TRUE` sau `FALSE`.\n"
],
"metadata": {
"id": "Zxfb3AM5YbUe"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" anyNA()"
],
"outputs": [],
"metadata": {
"id": "G--DQutAYltj"
}
},
{
"cell_type": "markdown",
"source": [
"Grozav, se pare că lipsesc unele date! Acesta este un punct bun de plecare.\n",
"\n",
"- O altă metodă ar fi să folosești funcția `is.na()` care indică ce elemente individuale din coloană lipsesc, returnând un `TRUE` logic.\n"
],
"metadata": {
"id": "mU-7-SB6YokF"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" is.na() %>% \n",
" head(n = 7)"
],
"outputs": [],
"metadata": {
"id": "W-DxDOR4YxSW"
}
},
{
"cell_type": "markdown",
"source": [
"Bine, am terminat treaba, dar cu un cadru de date atât de mare, ar fi ineficient și practic imposibil să revizuim toate rândurile și coloanele individual 😴.\n",
"\n",
"- O modalitate mai intuitivă ar fi să calculăm suma valorilor lipsă pentru fiecare coloană:\n"
],
"metadata": {
"id": "xUWxipKYY0o7"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" is.na() %>% \n",
" colSums()"
],
"outputs": [],
"metadata": {
"id": "ZRBWV6P9ZArL"
}
},
{
"cell_type": "markdown",
"source": [
"Mult mai bine! Lipsesc unele date, dar poate că nu va conta pentru sarcina de față. Să vedem ce va aduce analiza ulterioară.\n",
"\n",
"> Pe lângă seturile impresionante de pachete și funcții, R are o documentație foarte bună. De exemplu, folosește `help(colSums)` sau `?colSums` pentru a afla mai multe despre funcție.\n"
],
"metadata": {
"id": "9gv-crB6ZD1Y"
}
},
{
"cell_type": "markdown",
"source": [
"## 3. Dplyr: O gramatică a manipulării datelor\n",
"\n",
"
\n",
" \n",
"
\n"
],
"metadata": {
"id": "i5o33MQBZWWw"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::select()\n",
"\n",
"`select()` este o funcție din pachetul `dplyr` care te ajută să alegi coloanele pe care vrei să le păstrezi sau să le excluzi.\n",
"\n",
"Pentru a face cadrul de date mai ușor de utilizat, elimină mai multe dintre coloanele sale folosind `select()`, păstrând doar coloanele de care ai nevoie.\n",
"\n",
"De exemplu, în acest exercițiu, analiza noastră va implica coloanele `Package`, `Low Price`, `High Price` și `Date`. Hai să selectăm aceste coloane.\n"
],
"metadata": {
"id": "x3VGMAGBZiUr"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Select desired columns\n",
"pumpkins <- pumpkins %>% \n",
" select(Package, `Low Price`, `High Price`, Date)\n",
"\n",
"\n",
"# Print data set\n",
"pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "F_FgxQnVZnM0"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::mutate()\n",
"\n",
"`mutate()` este o funcție din pachetul `dplyr` care te ajută să creezi sau să modifici coloane, păstrând în același timp coloanele existente.\n",
"\n",
"Structura generală a funcției mutate este:\n",
"\n",
"`data %>% mutate(new_column_name = what_it_contains)`\n",
"\n",
"Să testăm funcția `mutate` folosind coloana `Date` prin realizarea următoarelor operații:\n",
"\n",
"1. Convertirea datelor (în prezent de tip caracter) într-un format de lună (acestea sunt date din SUA, deci formatul este `MM/DD/YYYY`).\n",
"\n",
"2. Extrage luna din date într-o coloană nouă.\n",
"\n",
"În R, pachetul [lubridate](https://lubridate.tidyverse.org/) face mai ușoară lucrul cu date și ore. Așadar, să folosim `dplyr::mutate()`, `lubridate::mdy()`, `lubridate::month()` și să vedem cum putem atinge obiectivele de mai sus. Putem elimina coloana Date, deoarece nu o vom mai folosi în operațiile ulterioare.\n"
],
"metadata": {
"id": "2KKo0Ed9Z1VB"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Load lubridate\n",
"library(lubridate)\n",
"\n",
"pumpkins <- pumpkins %>% \n",
" # Convert the Date column to a date object\n",
" mutate(Date = mdy(Date)) %>% \n",
" # Extract month from Date\n",
" mutate(Month = month(Date)) %>% \n",
" # Drop Date column\n",
" select(-Date)\n",
"\n",
"# View the first few rows\n",
"pumpkins %>% \n",
" slice_head(n = 7)"
],
"outputs": [],
"metadata": {
"id": "5joszIVSZ6xe"
}
},
{
"cell_type": "markdown",
"source": [
"Ura! 🤩\n",
"\n",
"În continuare, să creăm o nouă coloană `Price`, care reprezintă prețul mediu al unui dovleac. Acum, să calculăm media dintre coloanele `Low Price` și `High Price` pentru a completa noua coloană Price.\n",
"
\n"
],
"metadata": {
"id": "nIgLjNMCZ-6Y"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Create a new column Price\n",
"pumpkins <- pumpkins %>% \n",
" mutate(Price = (`Low Price` + `High Price`)/2)\n",
"\n",
"# View the first few rows of the data\n",
"pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "Zo0BsqqtaJw2"
}
},
{
"cell_type": "markdown",
"source": [
"Yeees!💪\n",
"\n",
"„Dar stai puțin!”, vei spune după ce ai răsfoit întregul set de date cu `View(pumpkins)`, „E ceva ciudat aici!”🤔\n",
"\n",
"Dacă te uiți la coloana `Package`, dovlecii sunt vânduți în multe configurații diferite. Unii sunt vânduți în măsuri de `1 1/9 bushel`, alții în măsuri de `1/2 bushel`, unii per dovleac, alții per kilogram, iar alții în cutii mari cu lățimi variabile.\n",
"\n",
"Hai să verificăm asta:\n"
],
"metadata": {
"id": "p77WZr-9aQAR"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Verify the distinct observations in Package column\n",
"pumpkins %>% \n",
" distinct(Package)"
],
"outputs": [],
"metadata": {
"id": "XISGfh0IaUy6"
}
},
{
"cell_type": "markdown",
"source": [
"Uimitor!👏\n",
"\n",
"Se pare că dovlecii sunt foarte greu de cântărit în mod constant, așa că hai să-i filtrăm selectând doar dovlecii care conțin șirul *bushel* în coloana `Package` și să punem acest lucru într-un nou cadru de date `new_pumpkins`.\n"
],
"metadata": {
"id": "7sMjiVujaZxY"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::filter() și stringr::str_detect()\n",
"\n",
"[`dplyr::filter()`](https://dplyr.tidyverse.org/reference/filter.html): creează un subset de date care conține doar **rândurile** ce îndeplinesc condițiile tale, în acest caz, dovleci cu șirul *bushel* în coloana `Package`.\n",
"\n",
"[stringr::str_detect()](https://stringr.tidyverse.org/reference/str_detect.html): detectează prezența sau absența unui model într-un șir de caractere.\n",
"\n",
"Pachetul [`stringr`](https://github.com/tidyverse/stringr) oferă funcții simple pentru operațiuni comune cu șiruri de caractere.\n"
],
"metadata": {
"id": "L8Qfcs92ageF"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Retain only pumpkins with \"bushel\"\n",
"new_pumpkins <- pumpkins %>% \n",
" filter(str_detect(Package, \"bushel\"))\n",
"\n",
"# Get the dimensions of the new data\n",
"dim(new_pumpkins)\n",
"\n",
"# View a few rows of the new data\n",
"new_pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "hy_SGYREampd"
}
},
{
"cell_type": "markdown",
"source": [
"Puteți observa că am restrâns selecția la aproximativ 415 rânduri de date care conțin dovleci la sac. 🤩 \n",
"
\n"
],
"metadata": {
"id": "VrDwF031avlR"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::case_when()\n",
"\n",
"**Dar stai! Mai este un lucru de făcut**\n",
"\n",
"Ai observat că cantitatea de bushel variază pe rânduri? Trebuie să normalizezi prețurile astfel încât să afișezi prețul pe bushel, nu pe 1 1/9 sau 1/2 bushel. Este momentul să facem câteva calcule pentru a standardiza acest lucru.\n",
"\n",
"Vom folosi funcția [`case_when()`](https://dplyr.tidyverse.org/reference/case_when.html) pentru a *modifica* coloana Price în funcție de anumite condiții. `case_when` îți permite să vectorizezi mai multe declarații `if_else()`.\n"
],
"metadata": {
"id": "mLpw2jH4a0tx"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Convert the price if the Package contains fractional bushel values\n",
"new_pumpkins <- new_pumpkins %>% \n",
" mutate(Price = case_when(\n",
" str_detect(Package, \"1 1/9\") ~ Price/(1 + 1/9),\n",
" str_detect(Package, \"1/2\") ~ Price/(1/2),\n",
" TRUE ~ Price))\n",
"\n",
"# View the first few rows of the data\n",
"new_pumpkins %>% \n",
" slice_head(n = 30)"
],
"outputs": [],
"metadata": {
"id": "P68kLVQmbM6I"
}
},
{
"cell_type": "markdown",
"source": [
"Acum putem analiza prețul pe unitate bazat pe măsurarea în busheli. Tot acest studiu despre busheli de dovleci, însă, arată cât de `important` este să `înțelegi natura datelor tale`!\n",
"\n",
"> ✅ Conform [The Spruce Eats](https://www.thespruceeats.com/how-much-is-a-bushel-1389308), greutatea unui bushel depinde de tipul de produs, deoarece este o măsurătoare de volum. \"Un bushel de roșii, de exemplu, ar trebui să cântărească 56 de livre... Frunzele și verdețurile ocupă mai mult spațiu cu o greutate mai mică, așa că un bushel de spanac cântărește doar 20 de livre.\" Este destul de complicat! Să nu ne batem capul cu o conversie din busheli în livre și, în schimb, să stabilim prețul pe bushel. Tot acest studiu despre busheli de dovleci, însă, arată cât de important este să înțelegi natura datelor tale!\n",
">\n",
"> ✅ Ai observat că dovlecii vânduți la jumătate de bushel sunt foarte scumpi? Poți să-ți dai seama de ce? Indiciu: dovlecii mici sunt mult mai scumpi decât cei mari, probabil pentru că sunt mult mai mulți într-un bushel, având în vedere spațiul neutilizat ocupat de un dovleac mare și gol pentru plăcintă.\n"
],
"metadata": {
"id": "pS2GNPagbSdb"
}
},
{
"cell_type": "markdown",
"source": [
"Acum, în cele din urmă, doar pentru distracție 💁♀️, să mutăm și coloana Lună în prima poziție, adică `înainte` de coloana `Pachet`.\n",
"\n",
"`dplyr::relocate()` este utilizat pentru a schimba pozițiile coloanelor.\n"
],
"metadata": {
"id": "qql1SowfbdnP"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Create a new data frame new_pumpkins\n",
"new_pumpkins <- new_pumpkins %>% \n",
" relocate(Month, .before = Package)\n",
"\n",
"new_pumpkins %>% \n",
" slice_head(n = 7)"
],
"outputs": [],
"metadata": {
"id": "JJ1x6kw8bixF"
}
},
{
"cell_type": "markdown",
"source": [
"Bravo! 👌 Acum ai un set de date curat și bine organizat pe care poți construi noul tău model de regresie! \n",
"
\n"
],
"metadata": {
"id": "y8TJ0Za_bn5Y"
}
},
{
"cell_type": "markdown",
"source": [
"## 4. Vizualizarea datelor cu ggplot2\n",
"\n",
"
\n",
" \n",
"
\n"
],
"metadata": {
"id": "Ml7SDCLQcPvE"
}
},
{
"cell_type": "markdown",
"source": [
"### **Cum îl facem util?**\n",
"\n",
"Pentru a afișa date utile în grafice, de obicei trebuie să grupăm datele într-un anumit mod. De exemplu, în cazul nostru, calcularea prețului mediu al dovlecilor pentru fiecare lună ar oferi mai multe informații despre tiparele de bază din datele noastre. Acest lucru ne conduce la încă o privire rapidă asupra **dplyr**:\n",
"\n",
"#### `dplyr::group_by() %>% summarize()`\n",
"\n",
"Agregarea grupată în R poate fi calculată ușor folosind\n",
"\n",
"`dplyr::group_by() %>% summarize()`\n",
"\n",
"- `dplyr::group_by()` schimbă unitatea de analiză de la întregul set de date la grupuri individuale, cum ar fi pe lună.\n",
"\n",
"- `dplyr::summarize()` creează un nou cadru de date cu o coloană pentru fiecare variabilă de grupare și o coloană pentru fiecare statistică sumară pe care ai specificat-o.\n",
"\n",
"De exemplu, putem folosi `dplyr::group_by() %>% summarize()` pentru a grupa dovlecii în funcție de coloana **Month** și apoi să calculăm **prețul mediu** pentru fiecare lună.\n"
],
"metadata": {
"id": "jMakvJZIcVkh"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Find the average price of pumpkins per month\r\n",
"new_pumpkins %>%\r\n",
" group_by(Month) %>% \r\n",
" summarise(mean_price = mean(Price))"
],
"outputs": [],
"metadata": {
"id": "6kVSUa2Bcilf"
}
},
{
"cell_type": "markdown",
"source": [
"Succint!✨\n",
"\n",
"Caracteristicile categorice, cum ar fi lunile, sunt mai bine reprezentate folosind un grafic cu bare 📊. Straturile responsabile pentru graficele cu bare sunt `geom_bar()` și `geom_col()`. Consultă `?geom_bar` pentru a afla mai multe.\n",
"\n",
"Hai să creăm unul!\n"
],
"metadata": {
"id": "Kds48GUBcj3W"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Find the average price of pumpkins per month then plot a bar chart\r\n",
"new_pumpkins %>%\r\n",
" group_by(Month) %>% \r\n",
" summarise(mean_price = mean(Price)) %>% \r\n",
" ggplot(aes(x = Month, y = mean_price)) +\r\n",
" geom_col(fill = \"midnightblue\", alpha = 0.7) +\r\n",
" ylab(\"Pumpkin Price\")"
],
"outputs": [],
"metadata": {
"id": "VNbU1S3BcrxO"
}
},
{
"cell_type": "markdown",
"source": [
"🤩🤩Aceasta este o vizualizare a datelor mai utilă! Se pare că indică faptul că prețul cel mai ridicat pentru dovleci apare în septembrie și octombrie. Se potrivește asta cu așteptările tale? De ce sau de ce nu?\n",
"\n",
"Felicitări pentru finalizarea celei de-a doua lecții 👏! Ai pregătit datele pentru construirea modelului, apoi ai descoperit mai multe informații folosind vizualizări!\n"
],
"metadata": {
"id": "zDm0VOzzcuzR"
}
},
{
"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ă rețineți 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"
]
}
]
}