{ "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-06T13:51:44+00:00", "source_file": "2-Regression/2-Data/solution/R/lesson_2-R.ipynb", "language_code": "sv" } }, "cells": [ { "cell_type": "markdown", "source": [ "# Bygg en regressionsmodell: förbered och visualisera data\n", "\n", "## **Linjär regression för pumpor - Lektion 2**\n", "#### Introduktion\n", "\n", "Nu när du har verktygen du behöver för att börja bygga maskininlärningsmodeller med Tidymodels och Tidyverse, är du redo att börja ställa frågor till dina data. När du arbetar med data och tillämpar ML-lösningar är det mycket viktigt att förstå hur man ställer rätt fråga för att verkligen utnyttja potentialen i din dataset.\n", "\n", "I den här lektionen kommer du att lära dig:\n", "\n", "- Hur du förbereder dina data för modellbyggande.\n", "\n", "- Hur du använder `ggplot2` för datavisualisering.\n", "\n", "Frågan du behöver svar på avgör vilken typ av ML-algoritmer du kommer att använda. Och kvaliteten på svaret du får tillbaka kommer att vara starkt beroende av datans natur.\n", "\n", "Låt oss se detta genom att arbeta igenom en praktisk övning.\n", "\n", "\n", "
\n",
" \n",
"
\n",
"\n",
"> En påminnelse: Pipe-operatorn (`%>%`) utför operationer i logisk sekvens genom att skicka ett objekt framåt in i en funktion eller ett uttryck. Du kan tänka på pipe-operatorn som att säga \"och sedan\" i din kod.\n"
],
"metadata": {
"id": "REWcIv9yX29v"
}
},
{
"cell_type": "markdown",
"source": [
"## 2. Kontrollera för saknade data\n",
"\n",
"Ett av de vanligaste problemen som dataanalytiker måste hantera är ofullständig eller saknad data. R representerar saknade eller okända värden med ett speciellt sentinelvärde: `NA` (Not Available).\n",
"\n",
"Så hur kan vi veta att dataframen innehåller saknade värden?\n",
"
\n",
"- Ett direkt sätt skulle vara att använda R:s inbyggda funktion `anyNA`, som returnerar de logiska objekten `TRUE` eller `FALSE`.\n"
],
"metadata": {
"id": "Zxfb3AM5YbUe"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" anyNA()"
],
"outputs": [],
"metadata": {
"id": "G--DQutAYltj"
}
},
{
"cell_type": "markdown",
"source": [
"Bra, det verkar som att det saknas viss data! Det är en bra utgångspunkt.\n",
"\n",
"- Ett annat sätt skulle vara att använda funktionen `is.na()` som visar vilka enskilda kolumnelement som saknas med ett logiskt värde `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": [
"Okej, jobbet är klart men med en så stor dataram som denna skulle det vara ineffektivt och praktiskt taget omöjligt att granska alla rader och kolumner individuellt😴.\n",
"\n",
"- Ett mer intuitivt sätt skulle vara att beräkna summan av de saknade värdena för varje kolumn:\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": [
"Mycket bättre! Det saknas data, men kanske spelar det ingen roll för uppgiften. Låt oss se vad vidare analys ger.\n",
"\n",
"> Tillsammans med de fantastiska uppsättningarna av paket och funktioner har R en mycket bra dokumentation. Till exempel, använd `help(colSums)` eller `?colSums` för att ta reda på mer om funktionen.\n"
],
"metadata": {
"id": "9gv-crB6ZD1Y"
}
},
{
"cell_type": "markdown",
"source": [
"## 3. Dplyr: En grammatik för datamanipulation\n",
"\n",
"
\n",
" \n",
"
\n"
],
"metadata": {
"id": "i5o33MQBZWWw"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::select()\n",
"\n",
"`select()` är en funktion i paketet `dplyr` som hjälper dig att välja vilka kolumner du vill behålla eller exkludera.\n",
"\n",
"För att göra din data frame enklare att arbeta med, ta bort flera av dess kolumner med hjälp av `select()` och behåll endast de kolumner du behöver.\n",
"\n",
"Till exempel, i denna övning kommer vår analys att involvera kolumnerna `Package`, `Low Price`, `High Price` och `Date`. Låt oss välja dessa kolumner.\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()` är en funktion i paketet `dplyr` som hjälper dig att skapa eller ändra kolumner, samtidigt som de befintliga kolumnerna behålls.\n",
"\n",
"Den generella strukturen för mutate är:\n",
"\n",
"`data %>% mutate(new_column_name = what_it_contains)`\n",
"\n",
"Låt oss testa `mutate` med hjälp av kolumnen `Date` genom att utföra följande operationer:\n",
"\n",
"1. Konvertera datumen (som för närvarande är av typen tecken) till ett månadsformat (det här är amerikanska datum, så formatet är `MM/DD/YYYY`).\n",
"\n",
"2. Extrahera månaden från datumen till en ny kolumn.\n",
"\n",
"I R gör paketet [lubridate](https://lubridate.tidyverse.org/) det enklare att arbeta med datum- och tidsdata. Så låt oss använda `dplyr::mutate()`, `lubridate::mdy()`, `lubridate::month()` och se hur vi kan uppnå ovanstående mål. Vi kan ta bort kolumnen Date eftersom vi inte kommer att behöva den igen i efterföljande operationer.\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": [
"Woohoo! 🤩\n",
"\n",
"Nu ska vi skapa en ny kolumn `Price`, som representerar det genomsnittliga priset på en pumpa. Låt oss nu ta genomsnittet av kolumnerna `Low Price` och `High Price` för att fylla i den nya kolumnen 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": [
"Jaaa!💪\n",
"\n",
"\"Men vänta lite!\", säger du efter att ha skummat igenom hela datasettet med `View(pumpkins)`, \"Det är något konstigt här!\"🤔\n",
"\n",
"Om du tittar på kolumnen `Package`, säljs pumpor i många olika konfigurationer. Vissa säljs i mått som `1 1/9 bushel`, andra i `1/2 bushel`, några per pumpa, några per pund, och vissa i stora lådor med varierande bredder.\n",
"\n",
"Låt oss kontrollera detta:\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": [
"Fantastiskt!👏\n",
"\n",
"Pumpor verkar vara väldigt svåra att väga konsekvent, så låt oss filtrera dem genom att välja endast pumpor med strängen *bushel* i kolumnen `Package` och lägga detta i en ny data frame `new_pumpkins`.\n"
],
"metadata": {
"id": "7sMjiVujaZxY"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::filter() och stringr::str_detect()\n",
"\n",
"[`dplyr::filter()`](https://dplyr.tidyverse.org/reference/filter.html): skapar en delmängd av data som endast innehåller **rader** som uppfyller dina villkor, i detta fall pumpor med strängen *bushel* i kolumnen `Package`.\n",
"\n",
"[stringr::str_detect()](https://stringr.tidyverse.org/reference/str_detect.html): identifierar förekomsten eller frånvaron av ett mönster i en sträng.\n",
"\n",
"Paketet [`stringr`](https://github.com/tidyverse/stringr) erbjuder enkla funktioner för vanliga strängoperationer.\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": [
"Du kan se att vi har begränsat oss till ungefär 415 rader med data som innehåller pumpor i skäppor.🤩 \n",
"
\n"
],
"metadata": {
"id": "VrDwF031avlR"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::case_when()\n",
"\n",
"**Men vänta! Det finns en sak till att göra**\n",
"\n",
"Märkte du att mängden per skäppa varierar per rad? Du behöver normalisera prissättningen så att du visar priset per skäppa, inte per 1 1/9 eller 1/2 skäppa. Dags att göra lite matematik för att standardisera det.\n",
"\n",
"Vi kommer att använda funktionen [`case_when()`](https://dplyr.tidyverse.org/reference/case_when.html) för att *mutera* kolumnen Price beroende på vissa villkor. `case_when` gör det möjligt att vektorisera flera `if_else()`-satser.\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": [
"Nu kan vi analysera priset per enhet baserat på deras mått i bushels. All denna undersökning av pumpors bushels visar dock hur `viktigt` det är att `förstå din datas natur`!\n",
"\n",
"> ✅ Enligt [The Spruce Eats](https://www.thespruceeats.com/how-much-is-a-bushel-1389308) beror en bushels vikt på typen av gröda, eftersom det är en volymmätning. \"En bushel tomater, till exempel, ska väga 56 pund... Blad och gröna tar upp mer plats med mindre vikt, så en bushel spenat väger bara 20 pund.\" Det är ganska komplicerat! Låt oss inte bry oss om att göra en omvandling från bushel till pund, utan istället prissätta per bushel. All denna undersökning av pumpors bushels visar dock hur viktigt det är att förstå din datas natur!\n",
">\n",
"> ✅ Lade du märke till att pumpor som säljs per halv-bushel är väldigt dyra? Kan du lista ut varför? Tips: små pumpor är mycket dyrare än stora, antagligen eftersom det finns så många fler av dem per bushel, med tanke på det outnyttjade utrymmet som en stor ihålig pajpumpa tar upp.\n"
],
"metadata": {
"id": "pS2GNPagbSdb"
}
},
{
"cell_type": "markdown",
"source": [
"Nu slutligen, för äventyrets skull 💁♀️, låt oss också flytta kolumnen Månad till första positionen, dvs `före` kolumnen `Paket`.\n",
"\n",
"`dplyr::relocate()` används för att ändra kolumnpositioner.\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": [
"Bra jobbat! 👌 Du har nu ett rent och prydligt dataset som du kan använda för att bygga din nya regressionsmodell! \n",
"
\n"
],
"metadata": {
"id": "y8TJ0Za_bn5Y"
}
},
{
"cell_type": "markdown",
"source": [
"## 4. Datavisualisering med ggplot2\n",
"\n",
"
\n",
" \n",
"
\n"
],
"metadata": {
"id": "Ml7SDCLQcPvE"
}
},
{
"cell_type": "markdown",
"source": [
"### **Hur gör vi det användbart?**\n",
"\n",
"För att få diagram att visa användbar data behöver du oftast gruppera datan på något sätt. Till exempel, i vårt fall skulle det ge mer insikt i de underliggande mönstren i vår data om vi hittar det genomsnittliga priset på pumpor för varje månad. Detta leder oss till ännu en snabbgenomgång av **dplyr**:\n",
"\n",
"#### `dplyr::group_by() %>% summarize()`\n",
"\n",
"Grupperad aggregering i R kan enkelt beräknas med\n",
"\n",
"`dplyr::group_by() %>% summarize()`\n",
"\n",
"- `dplyr::group_by()` ändrar analysenheten från hela datasetet till individuella grupper, som per månad.\n",
"\n",
"- `dplyr::summarize()` skapar en ny dataram med en kolumn för varje grupperingsvariabel och en kolumn för varje sammanfattningsstatistik som du har specificerat.\n",
"\n",
"Till exempel kan vi använda `dplyr::group_by() %>% summarize()` för att gruppera pumporna i grupper baserade på **Month**-kolumnen och sedan hitta **medelpriset** för varje månad.\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": [
"Kategoriska funktioner, såsom månader, representeras bäst med ett stapeldiagram 📊. De lager som används för stapeldiagram är `geom_bar()` och `geom_col()`. Konsultera `?geom_bar` för att lära dig mer.\n",
"\n",
"Låt oss skapa ett!\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": [
"🤩🤩Det här är en mer användbar datavisualisering! Det verkar indikera att det högsta priset för pumpor inträffar i september och oktober. Stämmer det med dina förväntningar? Varför eller varför inte?\n",
"\n",
"Grattis till att ha avslutat den andra lektionen 👏! Du förberedde dina data för modellbyggande och upptäckte sedan fler insikter med hjälp av visualiseringar!\n"
],
"metadata": {
"id": "zDm0VOzzcuzR"
}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Ansvarsfriskrivning**: \nDetta dokument har översatts med hjälp av AI-översättningstjänsten [Co-op Translator](https://github.com/Azure/co-op-translator). Även om vi strävar efter noggrannhet, vänligen notera att automatiska översättningar kan innehålla fel eller felaktigheter. Det ursprungliga dokumentet på sitt ursprungliga språk bör betraktas som den auktoritativa källan. För kritisk information rekommenderas professionell mänsklig översättning. Vi ansvarar inte för eventuella missförstånd eller feltolkningar som uppstår vid användning av denna översättning.\n"
]
}
]
}