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/hu/2-Regression/3-Linear/solution/R/lesson_3-R.ipynb

1089 lines
44 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{
"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-04T06:38:05+00:00",
"source_file": "2-Regression/3-Linear/solution/R/lesson_3-R.ipynb",
"language_code": "hu"
}
},
"cells": [
{
"cell_type": "markdown",
"source": [],
"metadata": {
"id": "EgQw8osnsUV-"
}
},
{
"cell_type": "markdown",
"source": [
"## Lineáris és polinomiális regresszió a tök árának meghatározásához - 3. lecke\n",
"<p >\n",
" <img src=\"../../images/linear-polynomial.png\"\n",
" width=\"800\"/>\n",
" <figcaption>Infografika: Dasani Madipalli</figcaption>\n",
"\n",
"\n",
"<!--![Infografika: Dasani Madipalli](../../../../../../2-Regression/3-Linear/images/linear-polynomial.png){width=\"800\"}-->\n",
"\n",
"#### Bevezetés\n",
"\n",
"Eddig megismerkedtél azzal, hogy mi is az a regresszió, például a tök árának meghatározásához használt adatokkal, amelyeket ebben a leckében is használni fogunk. Emellett vizualizáltad is az adatokat a `ggplot2` segítségével. 💪\n",
"\n",
"Most készen állsz arra, hogy mélyebben belemerülj a gépi tanulás regressziójába. Ebben a leckében többet fogsz megtudni két regressziótípusról: *egyszerű lineáris regresszió* és *polinomiális regresszió*, valamint az ezek mögött álló matematikai alapokról.\n",
"\n",
"> Ebben a tananyagban minimális matematikai előismeretet feltételezünk, és arra törekszünk, hogy a tanulók számára más területekről érkezve is érthető legyen. Figyelj a jegyzetekre, 🧮 kiemelésekre, diagramokra és egyéb tanulást segítő eszközökre, amelyek megkönnyítik a megértést.\n",
"\n",
"#### Előkészületek\n",
"\n",
"Emlékeztetőül: az adatokat azért töltöd be, hogy kérdéseket tegyél fel velük kapcsolatban.\n",
"\n",
"- Mikor érdemes leginkább tököt vásárolni?\n",
"\n",
"- Milyen árat várhatok egy mini tökös dobozért?\n",
"\n",
"- Érdemes fél-bushel kosárban vagy 1 1/9 bushel dobozban vásárolni őket? Nézzük meg mélyebben az adatokat.\n",
"\n",
"Az előző leckében létrehoztál egy `tibble`-t (a data frame modern újragondolása), és feltöltötted az eredeti adatállomány egy részével, standardizálva az árakat bushelre. Ezzel azonban csak körülbelül 400 adatpontot tudtál összegyűjteni, és csak az őszi hónapokra vonatkozóan. Talán több részletet is megtudhatunk az adatok természetéről, ha jobban megtisztítjuk őket? Majd meglátjuk... 🕵️‍♀️\n",
"\n",
"Ehhez a feladathoz az alábbi csomagokra lesz szükségünk:\n",
"\n",
"- `tidyverse`: A [tidyverse](https://www.tidyverse.org/) egy [R csomaggyűjtemény](https://www.tidyverse.org/packages), amely gyorsabbá, könnyebbé és szórakoztatóbbá teszi az adatfeldolgozást!\n",
"\n",
"- `tidymodels`: A [tidymodels](https://www.tidymodels.org/) keretrendszer egy [csomaggyűjtemény](https://www.tidymodels.org/packages/) modellezéshez és gépi tanuláshoz.\n",
"\n",
"- `janitor`: A [janitor csomag](https://github.com/sfirke/janitor) egyszerű eszközöket kínál a piszkos adatok vizsgálatához és tisztításához.\n",
"\n",
"- `corrplot`: A [corrplot csomag](https://cran.r-project.org/web/packages/corrplot/vignettes/corrplot-intro.html) vizuális eszközt biztosít a korrelációs mátrix feltárásához, amely támogatja az automatikus változórendezést, hogy segítsen rejtett minták felismerésében a változók között.\n",
"\n",
"A csomagok telepítése az alábbi módon történhet:\n",
"\n",
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"janitor\", \"corrplot\"))`\n",
"\n",
"Az alábbi szkript ellenőrzi, hogy megvannak-e a szükséges csomagok a modul elvégzéséhez, és telepíti őket, ha hiányoznak.\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": [
"Ezeket a fantasztikus csomagokat később betöltjük, és elérhetővé tesszük a jelenlegi R munkamenetünkben. (Ez csak illusztráció, a `pacman::p_load()` már elvégezte ezt helyettünk.)\n",
"\n",
"## 1. Egy lineáris regressziós egyenes\n",
"\n",
"Ahogy az 1. leckében tanultad, a lineáris regresszió célja, hogy képesek legyünk megrajzolni egy *legjobban illeszkedő egyenest*, amely:\n",
"\n",
"- **Megmutatja a változók közötti kapcsolatot**. Bemutatja a változók közötti összefüggést.\n",
"\n",
"- **Előrejelzéseket készít**. Pontos előrejelzéseket ad arra vonatkozóan, hogy egy új adatpont hol helyezkedne el az egyeneshez viszonyítva.\n",
"\n",
"Ennek az egyenesnek a megrajzolásához egy statisztikai technikát használunk, amelyet **Legkisebb négyzetek módszerének** nevezünk. A `legkisebb négyzetek` kifejezés azt jelenti, hogy az egyenest körülvevő összes adatpontot négyzetre emeljük, majd összeadjuk. Ideális esetben ez az összeg a lehető legkisebb, mivel alacsony hibaszámot szeretnénk, vagyis `legkisebb négyzeteket`. Ezért a legjobban illeszkedő egyenes az, amely a legkisebb értéket adja a négyzetes hibák összegére - innen ered a *legkisebb négyzetek regresszió* elnevezés.\n",
"\n",
"Ezt azért tesszük, mert olyan egyenest szeretnénk modellezni, amelynek a legkisebb kumulatív távolsága van az összes adatpontunktól. Az értékeket négyzetre emeljük, mielőtt összeadnánk őket, mivel az irány helyett az érték nagysága érdekel minket.\n",
"\n",
"> **🧮 Mutasd a matekot**\n",
">\n",
"> Ez az egyenes, amelyet *legjobban illeszkedő egyenesnek* nevezünk, [egy egyenlettel](https://en.wikipedia.org/wiki/Simple_linear_regression) fejezhető ki:\n",
">\n",
"> Y = a + bX\n",
">\n",
"> `X` az '`magyarázó változó` vagy `prediktor`'. `Y` a '`függő változó` vagy `eredmény`'. Az egyenes meredeksége `b`, és `a` az y-metszet, amely arra utal, hogy `Y` értéke mennyi, amikor `X = 0`.\n",
">\n",
"\n",
"> ![](../../../../../../2-Regression/3-Linear/solution/images/slope.png \"meredekség = $y/x$\")\n",
" Infografika: Jen Looper\n",
">\n",
"> Először számítsd ki a meredekséget, `b`.\n",
">\n",
"> Más szavakkal, és utalva a tökadatok eredeti kérdésére: \"jósoljuk meg a tök árát hónaponként\", `X` az árra utal, míg `Y` az eladás hónapjára.\n",
">\n",
"> ![](../../../../../../2-Regression/3-Linear/solution/images/calculation.png)\n",
" Infografika: Jen Looper\n",
"> \n",
"> Számítsd ki `Y` értékét. Ha körülbelül 4 dollárt fizetsz, akkor április van!\n",
">\n",
"> Az egyenest számító matematikának meg kell mutatnia az egyenes meredekségét, amely az y-metszettől is függ, vagyis attól, hogy `Y` hol helyezkedik el, amikor `X = 0`.\n",
">\n",
"> Megfigyelheted ezeknek az értékeknek a számítási módját a [Math is Fun](https://www.mathsisfun.com/data/least-squares-regression.html) weboldalon. Látogasd meg [ezt a legkisebb négyzetek kalkulátort](https://www.mathsisfun.com/data/least-squares-calculator.html), hogy megnézd, hogyan befolyásolják a számok értékei az egyenest.\n",
"\n",
"Nem is olyan ijesztő, igaz? 🤓\n",
"\n",
"#### Korreláció\n",
"\n",
"Egy másik fontos fogalom, amit meg kell érteni, az **Korrelációs Együttható** az adott X és Y változók között. Egy szórásdiagram segítségével gyorsan vizualizálhatod ezt az együtthatót. Ha a pontok szépen egy egyenes mentén helyezkednek el, akkor magas korrelációról beszélünk, míg ha a pontok szanaszét helyezkednek el X és Y között, akkor alacsony korrelációról van szó.\n",
"\n",
"Egy jó lineáris regressziós modell olyan lesz, amely magas (1-hez közelebb álló, mint 0-hoz) Korrelációs Együtthatóval rendelkezik a Legkisebb Négyzetek módszerével és egy regressziós egyenessel.\n"
],
"metadata": {
"id": "cdX5FRpvsoP5"
}
},
{
"cell_type": "markdown",
"source": [
"## **2. Tánc az adatokkal: adatkeret létrehozása modellezéshez**\n",
"\n",
"<p >\n",
" <img src=\"../../images/janitor.jpg\"\n",
" width=\"700\"/>\n",
" <figcaption>Műalkotás: @allison_horst</figcaption>\n",
"\n",
"\n",
"<!--![Műalkotás: \\@allison_horst](../../../../../../2-Regression/3-Linear/images/janitor.jpg){width=\"700\"}-->\n"
],
"metadata": {
"id": "WdUKXk7Bs8-V"
}
},
{
"cell_type": "markdown",
"source": [
"Töltsd be a szükséges könyvtárakat és az adatállományt. Alakítsd az adatokat egy adatkeretté, amely az adatok egy részhalmazát tartalmazza:\n",
"\n",
"- Csak azokat a tököket válaszd ki, amelyeket véka szerint áraznak\n",
"\n",
"- Alakítsd át a dátumot hónappá\n",
"\n",
"- Számítsd ki az árat a magas és alacsony árak átlagaként\n",
"\n",
"- Alakítsd át az árat, hogy tükrözze a véka szerinti mennyiségi árazást\n",
"\n",
"> Ezeket a lépéseket a [korábbi leckében](https://github.com/microsoft/ML-For-Beginners/blob/main/2-Regression/2-Data/solution/lesson_2-R.ipynb) tárgyaltuk.\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": [
"A puszta kaland szellemében fedezzük fel a [`janitor csomagot`](../../../../../../2-Regression/3-Linear/solution/R/github.com/sfirke/janitor), amely egyszerű funkciókat kínál a piszkos adatok vizsgálatához és tisztításához. Például nézzük meg az adataink oszlopneveit:\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": [
"🤔 Jobban is csinálhatjuk. Tegyük ezeket az oszlopneveket `friendR`-ré azzal, hogy átalakítjuk őket a [snake_case](https://en.wikipedia.org/wiki/Snake_case) konvencióra a `janitor::clean_names` használatával. Ha többet szeretnél megtudni erről a függvényről: `?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": [
"Sokkal rendezettebb 🧹! Most egy tánc az adatokkal a `dplyr` segítségével, ahogy az előző leckében! 💃\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": [
"Szép munka!👌 Most már van egy tiszta, rendezett adathalmazod, amelyre építheted az új regressziós modelledet!\n",
"\n",
"Egy szórási diagramot?\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": [
"Egy szórási diagram emlékeztet minket arra, hogy csak augusztustól decemberig vannak havi adataink. Valószínűleg több adatra van szükségünk ahhoz, hogy lineáris módon tudjunk következtetéseket levonni.\n",
"\n",
"Nézzük meg újra a modellezési adatainkat:\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": [
"Mi lenne, ha meg szeretnénk jósolni egy tök `árát` a `város` vagy `csomag` oszlopok alapján, amelyek karakter típusúak? Vagy még egyszerűbben, hogyan találhatnánk meg a korrelációt (amihez mindkét bemenetnek numerikusnak kell lennie) például a `csomag` és az `ár` között? 🤷🤷\n",
"\n",
"A gépi tanulási modellek legjobban numerikus jellemzőkkel működnek, nem pedig szöveges értékekkel, ezért általában szükséges a kategóriális jellemzőket numerikus reprezentációkká alakítani.\n",
"\n",
"Ez azt jelenti, hogy meg kell találnunk egy módot arra, hogy átalakítsuk az előrejelzőinket, hogy a modellek hatékonyabban tudják használni őket. Ezt a folyamatot `jellemzők mérnöki tervezésének` nevezzük.\n"
],
"metadata": {
"id": "7hsHoxsStyjJ"
}
},
{
"cell_type": "markdown",
"source": [
"## 3. Adatok előfeldolgozása modellezéshez receptekkel 👩‍🍳👨‍🍳\n",
"\n",
"Azokat a tevékenységeket, amelyek átalakítják a prediktor értékeket, hogy a modell hatékonyabban tudja használni őket, `jellemzők mérnöki tervezésének` nevezzük.\n",
"\n",
"Különböző modelleknek eltérő előfeldolgozási követelményeik vannak. Például a legkisebb négyzetek módszere megköveteli a `kategóriális változók kódolását`, mint például hónap, fajta és városnév. Ez egyszerűen azt jelenti, hogy egy `kategóriális értékeket` tartalmazó oszlopot egy vagy több `numerikus oszlopra` fordítunk le, amelyek az eredeti oszlop helyét veszik át.\n",
"\n",
"Például, tegyük fel, hogy az adataid tartalmazzák a következő kategóriális jellemzőt:\n",
"\n",
"| város |\n",
"|:--------:|\n",
"| Denver |\n",
"| Nairobi |\n",
"| Tokió |\n",
"\n",
"Alkalmazhatod az *ordinális kódolást*, hogy minden kategóriát egyedi egész értékkel helyettesíts, így:\n",
"\n",
"| város |\n",
"|:-----:|\n",
"| 0 |\n",
"| 1 |\n",
"| 2 |\n",
"\n",
"Pontosan ezt fogjuk tenni az adatainkkal!\n",
"\n",
"Ebben a részben egy másik fantasztikus Tidymodels csomagot fogunk felfedezni: [recipes](https://tidymodels.github.io/recipes/) - amelyet arra terveztek, hogy segítsen az adatok előfeldolgozásában **mielőtt** a modellt betanítanánk. Lényegében egy recept egy olyan objektum, amely meghatározza, milyen lépéseket kell alkalmazni egy adathalmazon, hogy az készen álljon a modellezésre.\n",
"\n",
"Most hozzunk létre egy receptet, amely előkészíti az adatainkat a modellezéshez úgy, hogy minden megfigyelést egyedi egész számmal helyettesít a prediktor oszlopokban:\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": [
"Szuper! 👏 Most hoztuk létre az első receptünket, amely meghatározza az eredményt (árat) és a hozzá tartozó prediktorokat, valamint azt, hogy az összes prediktor oszlopot egész számokká kell kódolni 🙌! Nézzük meg gyorsan, hogyan is működik ez:\n",
"\n",
"- A `recipe()` függvény hívása egy formulával megadja a receptnek a változók *szerepeit*, a `new_pumpkins` adatok alapján. Például a `price` oszlop az `outcome` (eredmény) szerepet kapta, míg a többi oszlop a `predictor` (prediktor) szerepet.\n",
"\n",
"- A `step_integer(all_predictors(), zero_based = TRUE)` meghatározza, hogy az összes prediktort egy egész számokból álló halmazzá kell átalakítani, ahol a számozás 0-tól kezdődik.\n",
"\n",
"Biztosan eszedbe jutott már valami ilyesmi: \"Ez nagyon menő!! De mi van, ha meg kellene győződnöm arról, hogy a receptek pontosan azt csinálják, amit várok tőlük? 🤔\"\n",
"\n",
"Ez egy remek gondolat! Látod, ha egyszer meghatároztad a receptet, akkor becsülheted az adatok előfeldolgozásához szükséges paramétereket, majd kinyerheted a feldolgozott adatokat. Általában erre nincs szükség, amikor a Tidymodels-t használod (mindjárt látni fogjuk a szokásos megközelítést -\\> `workflows`), de hasznos lehet, ha valamilyen ellenőrzést szeretnél végezni annak érdekében, hogy megbizonyosodj arról, hogy a receptek azt csinálják, amit elvársz.\n",
"\n",
"Ehhez két további igére lesz szükséged: `prep()` és `bake()`. És ahogy mindig, kis R barátaink [`Allison Horst`](https://github.com/allisonhorst/stats-illustrations) által segítenek abban, hogy ezt jobban megértsd!\n",
"\n",
"<p >\n",
" <img src=\"../../images/recipes.png\"\n",
" width=\"550\"/>\n",
" <figcaption>Illusztráció: @allison_horst</figcaption>\n",
"\n",
"\n",
"<!--![Illusztráció: \\@allison_horst](../../../../../../2-Regression/3-Linear/images/recipes.png){width=\"550\"}-->\n"
],
"metadata": {
"id": "KEiO0v7kuC9O"
}
},
{
"cell_type": "markdown",
"source": [
"[`prep()`](https://recipes.tidymodels.org/reference/prep.html): becsli a szükséges paramétereket egy tanuló adathalmazból, amelyeket később más adathalmazokra is alkalmazni lehet. Például, egy adott prediktor oszlop esetében melyik megfigyelés kapja a 0, 1, 2 stb. egész számot.\n",
"\n",
"[`bake()`](https://recipes.tidymodels.org/reference/bake.html): egy előkészített receptet vesz, és az abban szereplő műveleteket alkalmazza bármely adathalmazra.\n",
"\n",
"Ezzel együtt, készítsük elő és alkalmazzuk a receptjeinket, hogy valóban megerősítsük, hogy a háttérben a prediktor oszlopok először kódolva lesznek, mielőtt a modell illesztésre kerül.\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": [
"Hurrá! 🥳 A feldolgozott `baked_pumpkins` adatok összes prediktora kódolva van, ami megerősíti, hogy az előfeldolgozási lépések, amelyeket receptként definiáltunk, valóban a vártnak megfelelően működnek. Ez nehezebbé teszi az olvasást számodra, de sokkal érthetőbbé teszi a Tidymodels számára! Szánj egy kis időt arra, hogy kiderítsd, melyik megfigyelés lett egy megfelelő egész számra leképezve.\n",
"\n",
"Érdemes megemlíteni, hogy a `baked_pumpkins` egy adatkeret, amelyen számításokat végezhetünk.\n",
"\n",
"Például próbáljunk meg jó korrelációt találni az adataid két pontja között, hogy esetlegesen egy jó prediktív modellt építhessünk. Ehhez a `cor()` függvényt fogjuk használni. Írd be, hogy `?cor()`, hogy többet megtudj a függvényről.\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": [
"Mint kiderült, csak gyenge összefüggés van a Város és az Ár között. Viszont valamivel jobb összefüggés mutatkozik a Csomag és annak Ára között. Ez logikus, nem? Általában minél nagyobb a termékdoboz, annál magasabb az ár.\n",
"\n",
"Amíg itt tartunk, próbáljuk meg vizualizálni az összes oszlop korrelációs mátrixát a `corrplot` csomag segítségével.\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": [
"🤩🤩 Sokkal jobb.\n",
"\n",
"Egy jó kérdés, amit most feltehetünk az adatokkal kapcsolatban: '`Milyen árat várhatok egy adott tökcsomagra?`' Vágjunk is bele!\n",
"\n",
"> Megjegyzés: Amikor a **`bake()`** függvényt használod az előkészített recepttel (**`pumpkins_prep`**) és **`new_data = NULL`** értékkel, akkor a feldolgozott (azaz kódolt) tanulóadatokat kapod meg. Ha lenne egy másik adathalmazod, például egy tesztkészlet, és szeretnéd látni, hogyan dolgozná fel azt a recept, egyszerűen süsd meg (**`bake`**) a **`pumpkins_prep`** receptet a **`new_data = test_set`** paraméterrel.\n",
"\n",
"## 4. Készítsünk egy lineáris regressziós modellt\n",
"\n",
"<p >\n",
" <img src=\"../../images/linear-polynomial.png\"\n",
" width=\"800\"/>\n",
" <figcaption>Infografika: Dasani Madipalli</figcaption>\n",
"\n",
"\n",
"<!--![Infografika: Dasani Madipalli](../../../../../../2-Regression/3-Linear/images/linear-polynomial.png){width=\"800\"}-->\n"
],
"metadata": {
"id": "YqXjLuWavNxW"
}
},
{
"cell_type": "markdown",
"source": [
"Most, hogy elkészítettük a receptet, és ténylegesen megerősítettük, hogy az adatok megfelelően elő lesznek dolgozva, építsünk egy regressziós modellt, hogy megválaszoljuk a kérdést: `Milyen árat várhatok egy adott tökcsomag esetében?`\n",
"\n",
"#### Tanítsunk egy lineáris regressziós modellt a tanuló adathalmazon\n",
"\n",
"Ahogy valószínűleg már kitaláltad, a *price* oszlop az `eredmény` változó, míg a *package* oszlop a `prediktor` változó.\n",
"\n",
"Ehhez először szétosztjuk az adatokat úgy, hogy 80% a tanuló adathalmazba, 20% pedig a teszt adathalmazba kerüljön, majd definiálunk egy receptet, amely a prediktor oszlopot egész számokká kódolja, és létrehozunk egy modell specifikációt. Nem fogjuk előkészíteni és sütni a receptet, mivel már tudjuk, hogy az adatok előfeldolgozása a vártnak megfelelően fog történni.\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": [
"Szép munka! Most, hogy van egy receptünk és egy modell specifikációnk, meg kell találnunk a módját, hogy ezeket egy olyan objektumba csomagoljuk, amely először előkészíti az adatokat (a háttérben előkészít és süt), illeszti a modellt az előkészített adatokra, és lehetőséget biztosít az esetleges utófeldolgozási tevékenységekre is. Na, ez aztán megnyugtató, nem igaz? 🤩\n",
"\n",
"A Tidymodels-ben ezt a praktikus objektumot [`workflow`](https://workflows.tidymodels.org/) néven ismerjük, és kényelmesen tartalmazza a modellezési komponenseidet! Ezt hívnánk *pipelines*-nak *Python*-ban.\n",
"\n",
"Szóval csomagoljunk össze mindent egy workflow-ba! 📦\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": [
"Ráadásul egy munkafolyamatot nagyjából ugyanúgy lehet illeszteni/betanítani, mint egy modellt.\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": [
"A modell tanítása során kapott eredményekből láthatjuk a tanulás során meghatározott együtthatókat. Ezek az együtthatók a legjobban illeszkedő egyenes együtthatói, amely a legkisebb összesített hibát adja az aktuális és a becsült változó között.\n",
"\n",
"#### A modell teljesítményének értékelése a tesztkészlettel\n",
"\n",
"Itt az idő, hogy megnézzük, hogyan teljesített a modell 📏! Hogyan tegyük ezt?\n",
"\n",
"Most, hogy betanítottuk a modellt, használhatjuk a `parsnip::predict()` függvényt, hogy előrejelzéseket készítsünk a tesztkészletre. Ezután összehasonlíthatjuk ezeket az előrejelzéseket a tényleges címkeértékekkel, hogy értékeljük, mennyire jól (vagy éppen nem!) működik a modell.\n",
"\n",
"Kezdjük azzal, hogy előrejelzéseket készítünk a tesztkészletre, majd összekapcsoljuk az oszlopokat a tesztkészlettel.\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": [
"Igen, éppen most tanítottál be egy modellt, és használtad előrejelzések készítésére!🔮 Mennyire jó? Nézzük meg a modell teljesítményét!\n",
"\n",
"A Tidymodels-ben ezt a `yardstick::metrics()` segítségével végezzük! Lineáris regresszió esetén az alábbi metrikákra összpontosítunk:\n",
"\n",
"- `Root Mean Square Error (RMSE)`: Az [MSE](https://en.wikipedia.org/wiki/Mean_squared_error) négyzetgyöke. Ez egy abszolút metrikát ad ugyanabban az egységben, mint a címke (ebben az esetben egy tök ára). Minél kisebb az érték, annál jobb a modell (egyszerűen fogalmazva, ez az átlagos ár, amellyel az előrejelzések tévesek!).\n",
"\n",
"- `Coefficient of Determination (általában R-négyzet vagy R2 néven ismert)`: Egy relatív metrika, amelynél minél magasabb az érték, annál jobb a modell illeszkedése. Lényegében ez a metrika azt mutatja meg, hogy a modell mennyire képes magyarázni az előrejelzett és a valós címkeértékek közötti varianciát.\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": [
"Ott megy a modell teljesítménye. Nézzük meg, hogy jobb képet kapunk-e, ha vizualizálunk egy szórásdiagramot a csomagokról és az árakról, majd az előrejelzéseket felhasználva ráillesztünk egy legjobban illeszkedő egyenest.\n",
"\n",
"Ez azt jelenti, hogy elő kell készítenünk és feldolgoznunk kell a tesztkészletet, hogy kódoljuk a csomag oszlopot, majd ezt összekapcsoljuk a modellünk által készített előrejelzésekkel.\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": [
"Nagyszerű! Ahogy látható, a lineáris regressziós modell nem igazán általánosítja jól a csomag és annak megfelelő ára közötti kapcsolatot.\n",
"\n",
"🎃 Gratulálok, éppen létrehoztál egy modellt, amely segíthet néhány tökféle árának előrejelzésében. Az ünnepi tökös kerted gyönyörű lesz. De valószínűleg létrehozhatsz egy jobb modellt is!\n",
"\n",
"## 5. Készíts egy polinomiális regressziós modellt\n",
"\n",
"<p >\n",
" <img src=\"../../images/linear-polynomial.png\"\n",
" width=\"800\"/>\n",
" <figcaption>Infografika: Dasani Madipalli</figcaption>\n",
"\n",
"\n",
"<!--![Infografika: Dasani Madipalli](../../../../../../2-Regression/3-Linear/images/linear-polynomial.png){width=\"800\"}-->\n"
],
"metadata": {
"id": "HOCqJXLTwtWI"
}
},
{
"cell_type": "markdown",
"source": [
"Néha az adataink nem mutatnak lineáris összefüggést, de mégis szeretnénk előre jelezni egy eredményt. A polinomiális regresszió segíthet bonyolultabb, nemlineáris kapcsolatok esetén is előrejelzéseket készíteni.\n",
"\n",
"Vegyük például a tökök adatállományában a csomagolás és az ár közötti kapcsolatot. Bár néha van lineáris összefüggés a változók között például minél nagyobb a tök térfogata, annál magasabb az ára , előfordulhat, hogy ezek a kapcsolatok nem ábrázolhatók síkként vagy egyenes vonalként.\n",
"\n",
"> ✅ Itt van [néhány további példa](https://online.stat.psu.edu/stat501/lesson/9/9.8) olyan adatokra, amelyekhez polinomiális regresszió alkalmazható\n",
">\n",
"> Nézd meg újra a korábbi ábrán a Fajta és Ár közötti kapcsolatot. Úgy tűnik, hogy ezt a szórásdiagramot feltétlenül egy egyenes vonallal kellene elemezni? Talán nem. Ebben az esetben érdemes lehet kipróbálni a polinomiális regressziót.\n",
">\n",
"> ✅ A polinomok olyan matematikai kifejezések, amelyek egy vagy több változóból és együtthatóból állhatnak\n",
"\n",
"#### Polinomiális regressziós modell betanítása a tanuló adathalmazon\n",
"\n",
"A polinomiális regresszió egy *görbe vonalat* hoz létre, amely jobban illeszkedik a nemlineáris adatokhoz.\n",
"\n",
"Nézzük meg, hogy egy polinomiális modell jobban teljesít-e az előrejelzések készítésében. Hasonló eljárást követünk, mint korábban:\n",
"\n",
"- Hozzunk létre egy receptet, amely meghatározza azokat az előfeldolgozási lépéseket, amelyeket az adatok modellezésre való előkészítése során el kell végezni, például: prediktorok kódolása és *n* fokú polinomok kiszámítása\n",
"\n",
"- Készítsünk egy modell specifikációt\n",
"\n",
"- Csomagoljuk össze a receptet és a modell specifikációt egy munkafolyamatba\n",
"\n",
"- Hozzunk létre egy modellt a munkafolyamat illesztésével\n",
"\n",
"- Értékeljük, hogy a modell mennyire teljesít jól a tesztadatokon\n",
"\n",
"Vágjunk is bele!\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": [
"#### Értékeljük a modell teljesítményét\n",
"\n",
"👏👏Létrehoztál egy polinomiális modellt, nézzük meg, hogyan teljesít az előrejelzések során a tesztkészleten!\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": [
"Hurrá, értékeljük, hogyan teljesített a modell a test_set-en a `yardstick::metrics()` segítségével.\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": [
"🤩🤩 Sokkal jobb teljesítmény.\n",
"\n",
"Az `rmse` körülbelül 7-ről körülbelül 3-ra csökkent, ami azt jelzi, hogy csökkent a tényleges ár és az előrejelzett ár közötti hiba. Ezt *nagyjából* úgy értelmezhetjük, hogy átlagosan a hibás előrejelzések körülbelül 3 dollárral tévednek. Az `rsq` körülbelül 0,4-ről 0,8-ra nőtt.\n",
"\n",
"Mindezek a mutatók azt jelzik, hogy a polinomiális modell sokkal jobban teljesít, mint a lineáris modell. Szép munka!\n",
"\n",
"Nézzük meg, hogy tudjuk-e ezt vizualizálni!\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": [
"Láthatod, hogy egy görbe vonal jobban illeszkedik az adataidhoz! 🤩\n",
"\n",
"Ezt még simábbá teheted, ha egy polinomiális képletet adsz át a `geom_smooth`-nak, például így:\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": [
"Akárcsak egy sima görbe!🤩\n",
"\n",
"Így készíthetsz egy új előrejelzést:\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": [
"A `polinomiális modell` előrejelzése logikusnak tűnik, tekintve a `price` és `package` szórásdiagramjait! És ha ez egy jobb modell, mint az előző, ugyanazon adatok alapján, akkor számolnod kell ezekkel a drágább tökökkel!\n",
"\n",
"🏆 Szép munka! Egy leckében két regressziós modellt hoztál létre. A regresszióval kapcsolatos utolsó részben a logisztikus regresszióról fogsz tanulni, amely kategóriák meghatározására szolgál.\n",
"\n",
"## **🚀Kihívás**\n",
"\n",
"Tesztelj több különböző változót ebben a notebookban, hogy lásd, hogyan függ össze a korreláció a modell pontosságával.\n",
"\n",
"## [**Előadás utáni kvíz**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/14/)\n",
"\n",
"## **Áttekintés és önálló tanulás**\n",
"\n",
"Ebben a leckében a lineáris regresszióról tanultunk. Vannak más fontos regressziós technikák is. Olvass utána a Stepwise, Ridge, Lasso és Elasticnet módszereknek. Egy jó kurzus, amely segít többet tanulni, a [Stanford Statistical Learning kurzus](https://online.stanford.edu/courses/sohs-ystatslearning-statistical-learning).\n",
"\n",
"Ha többet szeretnél megtudni a fantasztikus Tidymodels keretrendszer használatáról, nézd meg az alábbi forrásokat:\n",
"\n",
"- Tidymodels weboldal: [Kezdd el a Tidymodels használatát](https://www.tidymodels.org/start/)\n",
"\n",
"- Max Kuhn és Julia Silge, [*Tidy Modeling with R*](https://www.tmwr.org/)*.*\n",
"\n",
"###### **KÖSZÖNET ILLETI:**\n",
"\n",
"[Allison Horst](https://twitter.com/allison_horst?lang=en) az elképesztő illusztrációkért, amelyek barátságosabbá és vonzóbbá teszik az R-t. További illusztrációkat találhatsz a [galériájában](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**Felelősség kizárása**: \nEz a dokumentum az [Co-op Translator](https://github.com/Azure/co-op-translator) AI fordítási szolgáltatás segítségével lett lefordítva. Bár törekszünk a pontosságra, kérjük, vegye figyelembe, hogy az automatikus fordítások hibákat vagy pontatlanságokat tartalmazhatnak. Az eredeti dokumentum az eredeti nyelvén tekintendő hiteles forrásnak. Fontos információk esetén javasolt professzionális emberi fordítást igénybe venni. Nem vállalunk felelősséget semmilyen félreértésért vagy téves értelmezésért, amely a fordítás használatából eredhet.\n"
]
}
]
}