{ "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-10-11T12:27:12+00:00", "source_file": "2-Regression/2-Data/solution/R/lesson_2-R.ipynb", "language_code": "et" } }, "cells": [ { "cell_type": "markdown", "source": [ "# Ehita regressioonimudel: valmista ette ja visualiseeri andmed\n", "\n", "## **Lineaarne regressioon kõrvitsate jaoks - Õppetund 2**\n", "#### Sissejuhatus\n", "\n", "Nüüd, kui sul on olemas tööriistad, et alustada masinõppe mudelite loomist Tidymodelsi ja Tidyverse'i abil, oled valmis hakkama oma andmetele küsimusi esitama. Andmetega töötades ja ML-lahendusi rakendades on väga oluline osata esitada õigeid küsimusi, et täielikult avada oma andmekogumi potentsiaal.\n", "\n", "Selles õppetunnis õpid:\n", "\n", "- Kuidas valmistada andmeid ette mudeli loomiseks.\n", "\n", "- Kuidas kasutada `ggplot2` andmete visualiseerimiseks.\n", "\n", "Küsimus, millele vastust otsid, määrab, millist tüüpi ML-algoritme sa kasutad. Ja saadud vastuse kvaliteet sõltub suuresti sinu andmete olemusest.\n", "\n", "Vaatame seda praktilise harjutuse kaudu.\n", "\n", "\n", "
\n",
"
\n",
"
\n",
"\n",
"> Meeldetuletus: Pipe-operaator (`%>%`) teostab operatsioone loogilises järjestuses, edastades objekti edasi funktsiooni või väljendisse. Võid mõelda pipe-operaatorist kui koodis \"ja siis\" ütlemisest.\n"
],
"metadata": {
"id": "REWcIv9yX29v"
}
},
{
"cell_type": "markdown",
"source": [
"## 2. Kontrolli puuduvate andmete olemasolu\n",
"\n",
"Üks levinumaid probleeme, millega andmeteadlased peavad tegelema, on puudulikud või puuduvad andmed. R tähistab puuduvaid või teadmata väärtusi spetsiaalse märgiga: `NA` (Not Available).\n",
"\n",
"Kuidas siis teada saada, et andmeraamistik sisaldab puuduvaid väärtusi?\n",
"
\n",
"- Üks lihtne viis oleks kasutada R-i baasfunktsiooni `anyNA`, mis tagastab loogilised objektid `TRUE` või `FALSE`.\n"
],
"metadata": {
"id": "Zxfb3AM5YbUe"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" anyNA()"
],
"outputs": [],
"metadata": {
"id": "G--DQutAYltj"
}
},
{
"cell_type": "markdown",
"source": [
"Suurepärane, tundub, et mõned andmed on puudu! See on hea koht alustamiseks.\n",
"\n",
"- Teine võimalus oleks kasutada funktsiooni `is.na()`, mis näitab, millised üksikud veeru elemendid on puudu, tagastades loogilise väärtuse `TRUE`.\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": [
"Okei, töö sai tehtud, kuid nii suure andmeraamiga nagu see, oleks ebaefektiivne ja praktiliselt võimatu kõiki ridu ja veerge individuaalselt üle vaadata😴.\n",
"\n",
"- Intuitiivsem viis oleks arvutada puuduvate väärtuste summa iga veeru kohta:\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": [
"Palju parem! Mõned andmed on puudu, kuid võib-olla see ei ole antud ülesande jaoks oluline. Vaatame, mida edasine analüüs toob.\n",
"\n",
"> Lisaks suurepärastele pakettidele ja funktsioonidele on R-il väga hea dokumentatsioon. Näiteks kasuta `help(colSums)` või `?colSums`, et saada rohkem teavet funktsiooni kohta.\n"
],
"metadata": {
"id": "9gv-crB6ZD1Y"
}
},
{
"cell_type": "markdown",
"source": [
"## 3. Dplyr: Andmete manipuleerimise grammatika\n",
"\n",
"
\n",
"
\n",
"
\n"
],
"metadata": {
"id": "i5o33MQBZWWw"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::select()\n",
"\n",
"`select()` on funktsioon paketis `dplyr`, mis aitab valida veerge, mida säilitada või välja jätta.\n",
"\n",
"Et muuta oma andmeraamistikku lihtsamini hallatavaks, eemalda mitmed veerud, kasutades `select()` ja säilitades ainult vajalikud veerud.\n",
"\n",
"Näiteks selles harjutuses hõlmab meie analüüs veerge `Package`, `Low Price`, `High Price` ja `Date`. Valime need veerud.\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()` on funktsioon paketis `dplyr`, mis aitab luua või muuta veerge, säilitades olemasolevad veerud.\n",
"\n",
"`mutate` üldine struktuur on:\n",
"\n",
"`data %>% mutate(new_column_name = what_it_contains)`\n",
"\n",
"Vaatame, kuidas `mutate` töötab, kasutades `Date` veergu ja tehes järgmised toimingud:\n",
"\n",
"1. Muudame kuupäevad (praegu tüüpi character) kuu formaadiks (need on USA kuupäevad, seega formaat on `MM/DD/YYYY`).\n",
"\n",
"2. Ekstraheerime kuupäevadest kuu uude veergu.\n",
"\n",
"R-is teeb pakett [lubridate](https://lubridate.tidyverse.org/) kuupäeva- ja ajandmetega töötamise lihtsamaks. Seega kasutame `dplyr::mutate()`, `lubridate::mdy()`, `lubridate::month()` ja vaatame, kuidas ülaltoodud eesmärke saavutada. Võime `Date` veeru eemaldada, kuna me ei vaja seda edasistes toimingutes.\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": [
"Hurraa! 🤩\n",
"\n",
"Järgmisena loome uue veeru `Price`, mis tähistab kõrvitsa keskmist hinda. Nüüd arvutame veergude `Low Price` ja `High Price` keskmise, et täita uus veerg 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": [
"Jah!💪\n",
"\n",
"\"Aga oota!\", ütled sa pärast kogu andmestiku kiiret ülevaatamist `View(pumpkins)` abil, \"Siin on midagi kummalist!\"🤔\n",
"\n",
"Kui vaatad `Package` veergu, müüakse kõrvitsaid mitmes erinevas konfiguratsioonis. Mõned müüakse `1 1/9 bushel` mõõtühikus, mõned `1/2 bushel` mõõtühikus, mõned tüki kaupa, mõned naela kaupa ja mõned suurtes kastides, mille laius varieerub.\n",
"\n",
"Kontrollime seda:\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": [
"Hämmastav!👏\n",
"\n",
"Tundub, et kõrvitsaid on väga raske järjepidevalt kaaluda, seega filtreerime need, valides ainult kõrvitsad, mille `Package` veerus on string *bushel*, ja paneme need uude andmeraami `new_pumpkins`.\n"
],
"metadata": {
"id": "7sMjiVujaZxY"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::filter() ja stringr::str_detect()\n",
"\n",
"[`dplyr::filter()`](https://dplyr.tidyverse.org/reference/filter.html): loob andmehulga alamhulga, mis sisaldab ainult **ridasi**, mis vastavad teie tingimustele, antud juhul kõrvitsaid, mille `Package` veerus on string *bushel*.\n",
"\n",
"[stringr::str_detect()](https://stringr.tidyverse.org/reference/str_detect.html): tuvastab mustri olemasolu või puudumise stringis.\n",
"\n",
"[`stringr`](https://github.com/tidyverse/stringr) pakett pakub lihtsaid funktsioone levinud stringitoimingute jaoks.\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": [
"Näete, et oleme kitsendanud andmed umbes 415 reani, mis sisaldavad kõrvitsaid korviga.🤩\n",
"
\n"
],
"metadata": {
"id": "VrDwF031avlR"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::case_when()\n",
"\n",
"**Aga oota! On veel üks asi, mida teha**\n",
"\n",
"Kas märkasid, et busheli kogus varieerub ridade kaupa? Pead hindade normaliseerimiseks näitama hinda ühe busheli kohta, mitte 1 1/9 või 1/2 busheli kohta. On aeg teha veidi matemaatikat, et seda standardiseerida.\n",
"\n",
"Kasutame funktsiooni [`case_when()`](https://dplyr.tidyverse.org/reference/case_when.html), et *muuta* Price veergu vastavalt teatud tingimustele. `case_when` võimaldab vektoriseerida mitmeid `if_else()` avaldusi.\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": [
"Nüüd saame analüüsida ühiku hinda, lähtudes nende mõõtmisest bushelites. Kogu see kõrvitsate bushelite uurimine näitab aga, kui `oluline` on `mõista oma andmete olemust`!\n",
"\n",
"> ✅ Vastavalt [The Spruce Eats](https://www.thespruceeats.com/how-much-is-a-bushel-1389308) andmetele sõltub busheli kaal toodete tüübist, kuna see on mahu mõõtühik. \"Näiteks peaks tomatite bushel kaaluma 56 naela... Lehed ja rohelised võtavad rohkem ruumi, kuid kaaluvad vähem, seega kaalub spinati bushel ainult 20 naela.\" See kõik on üsna keeruline! Ärgem vaevugem busheli ja naela vahelise teisendusega ning määrame hinna busheli järgi. Kogu see kõrvitsate bushelite uurimine näitab aga, kui oluline on mõista oma andmete olemust!\n",
">\n",
"> ✅ Kas märkasid, et poolte bushelite kaupa müüdavad kõrvitsad on väga kallid? Kas oskad arvata, miks? Vihje: väikesed kõrvitsad on palju kallimad kui suured, ilmselt seetõttu, et neid mahub bushelisse palju rohkem, arvestades, kui palju ruumi võtab üks suur õõnes pirukakõrvits.\n",
"
\n"
],
"metadata": {
"id": "pS2GNPagbSdb"
}
},
{
"cell_type": "markdown",
"source": [
"Nüüd, lihtsalt seikluse pärast 💁♀️, liigutame Kuu veeru esimeseks, st `enne` veergu `Package`.\n",
"\n",
"`dplyr::relocate()` kasutatakse veerupositioonide muutmiseks.\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": [
"Tubli töö!👌 Nüüd on sul puhas ja korrastatud andmestik, mille põhjal saad oma uue regressioonimudeli luua! \n",
"
\n"
],
"metadata": {
"id": "y8TJ0Za_bn5Y"
}
},
{
"cell_type": "markdown",
"source": [
"## 4. Andmete visualiseerimine ggplot2 abil\n",
"\n",
"
\n",
"
\n",
"
\n"
],
"metadata": {
"id": "Ml7SDCLQcPvE"
}
},
{
"cell_type": "markdown",
"source": [
"### **Kuidas muuta see kasulikuks?**\n",
"\n",
"Selleks, et graafikud kuvaksid kasulikku teavet, tuleb andmed tavaliselt kuidagi rühmitada. Näiteks meie puhul annaks kõrvitsate keskmise hinna leidmine iga kuu kohta rohkem ülevaadet andmete aluseks olevatest mustritest. See viib meid veel ühe **dplyr** kiirülevaateni:\n",
"\n",
"#### `dplyr::group_by() %>% summarize()`\n",
"\n",
"R-is saab rühmitatud koondandmeid hõlpsasti arvutada, kasutades\n",
"\n",
"`dplyr::group_by() %>% summarize()`\n",
"\n",
"- `dplyr::group_by()` muudab analüüsi üksuse kogu andmestikust individuaalseteks rühmadeks, näiteks kuude kaupa.\n",
"\n",
"- `dplyr::summarize()` loob uue andmeraami, kus igale rühmitamisvariandile on üks veerg ja igale määratud koondstatistikale üks veerg.\n",
"\n",
"Näiteks saame kasutada `dplyr::group_by() %>% summarize()`, et rühmitada kõrvitsad **Month** veeru alusel ja seejärel leida iga kuu kohta **keskmine hind**.\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": [
"Kategoorilised tunnused, nagu kuud, on paremini esitatavad tulpdiagrammi abil 📊. Tulpdiagrammide loomiseks kasutatakse kihte `geom_bar()` ja `geom_col()`. Lisateabe saamiseks vaata `?geom_bar`.\n",
"\n",
"Teeme ühe valmis!\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": [
"🤩🤩 See on kasulikum andmete visualiseerimine! Tundub, et kõrvitsate kõrgeim hind esineb septembris ja oktoobris. Kas see vastab sinu ootustele? Miks või miks mitte?\n",
"\n",
"Palju õnne teise õppetunni lõpetamise puhul 👏! Sa valmistasid oma andmed ette mudeli loomiseks ja avastasid seejärel visualiseerimiste abil rohkem teadmisi!\n"
],
"metadata": {
"id": "zDm0VOzzcuzR"
}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Lahtiütlus**: \nSee dokument on tõlgitud AI tõlketeenuse [Co-op Translator](https://github.com/Azure/co-op-translator) abil. Kuigi püüame tagada täpsust, palume arvestada, et automaatsed tõlked võivad sisaldada vigu või ebatäpsusi. Algne dokument selle algses keeles tuleks pidada autoriteetseks allikaks. Olulise teabe puhul soovitame kasutada professionaalset inimtõlget. Me ei vastuta selle tõlke kasutamisest tulenevate arusaamatuste või valesti tõlgenduste eest.\n"
]
}
]
}