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.
447 lines
17 KiB
447 lines
17 KiB
{
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2,
|
|
"metadata": {
|
|
"colab": {
|
|
"name": "lesson_1-R.ipynb",
|
|
"provenance": [],
|
|
"collapsed_sections": [],
|
|
"toc_visible": true
|
|
},
|
|
"kernelspec": {
|
|
"name": "ir",
|
|
"display_name": "R"
|
|
},
|
|
"language_info": {
|
|
"name": "R"
|
|
},
|
|
"coopTranslator": {
|
|
"original_hash": "c18d3bd0bd8ae3878597e89dcd1fa5c1",
|
|
"translation_date": "2025-09-06T13:42:52+00:00",
|
|
"source_file": "2-Regression/1-Tools/solution/R/lesson_1-R.ipynb",
|
|
"language_code": "sv"
|
|
}
|
|
},
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [],
|
|
"metadata": {
|
|
"id": "YJUHCXqK57yz"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## Introduktion till regression - Lektion 1\n",
|
|
"\n",
|
|
"#### Sätta det i perspektiv\n",
|
|
"\n",
|
|
"✅ Det finns många typer av regressionsmetoder, och vilken du väljer beror på vilken typ av svar du söker. Om du vill förutsäga den sannolika längden för en person i en viss ålder, skulle du använda `linjär regression`, eftersom du söker ett **numeriskt värde**. Om du är intresserad av att avgöra om en viss typ av mat ska betraktas som vegansk eller inte, söker du en **kategoriindelning** och skulle använda `logistisk regression`. Du kommer att lära dig mer om logistisk regression senare. Fundera lite på några frågor du kan ställa till data, och vilken av dessa metoder som skulle vara mest lämplig.\n",
|
|
"\n",
|
|
"I det här avsnittet kommer du att arbeta med en [liten dataset om diabetes](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html). Föreställ dig att du ville testa en behandling för diabetiker. Maskininlärningsmodeller kan hjälpa dig att avgöra vilka patienter som skulle svara bättre på behandlingen, baserat på kombinationer av variabler. Även en mycket enkel regressionsmodell, när den visualiseras, kan visa information om variabler som kan hjälpa dig att organisera dina teoretiska kliniska studier.\n",
|
|
"\n",
|
|
"Med det sagt, låt oss sätta igång med denna uppgift!\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/encouRage.jpg\"\n",
|
|
" width=\"630\"/>\n",
|
|
" <figcaption>Konstverk av @allison_horst</figcaption>\n",
|
|
"\n",
|
|
"<!--<br>Konstverk av @allison_horst-->\n"
|
|
],
|
|
"metadata": {
|
|
"id": "LWNNzfqd6feZ"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 1. Ladda upp vårt verktygspaket\n",
|
|
"\n",
|
|
"För den här uppgiften behöver vi följande paket:\n",
|
|
"\n",
|
|
"- `tidyverse`: [tidyverse](https://www.tidyverse.org/) är en [samling av R-paket](https://www.tidyverse.org/packages) som är utformade för att göra dataanalys snabbare, enklare och roligare!\n",
|
|
"\n",
|
|
"- `tidymodels`: [tidymodels](https://www.tidymodels.org/) är ett ramverk som består av en [samling paket](https://www.tidymodels.org/packages/) för modellering och maskininlärning.\n",
|
|
"\n",
|
|
"Du kan installera dem med följande kommando:\n",
|
|
"\n",
|
|
"`install.packages(c(\"tidyverse\", \"tidymodels\"))`\n",
|
|
"\n",
|
|
"Skriptet nedan kontrollerar om du har de paket som krävs för att slutföra denna modul och installerar dem åt dig om några saknas.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "FIo2YhO26wI9"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"source": [
|
|
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\n",
|
|
"pacman::p_load(tidyverse, tidymodels)"
|
|
],
|
|
"outputs": [
|
|
{
|
|
"output_type": "stream",
|
|
"name": "stderr",
|
|
"text": [
|
|
"Loading required package: pacman\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"id": "cIA9fz9v7Dss",
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"outputId": "2df7073b-86b2-4b32-cb86-0da605a0dc11"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Nu, låt oss ladda dessa fantastiska paket och göra dem tillgängliga i vår nuvarande R-session. (Detta är bara för illustration, `pacman::p_load()` har redan gjort det åt dig)\n"
|
|
],
|
|
"metadata": {
|
|
"id": "gpO_P_6f9WUG"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# load the core Tidyverse packages\r\n",
|
|
"library(tidyverse)\r\n",
|
|
"\r\n",
|
|
"# load the core Tidymodels packages\r\n",
|
|
"library(tidymodels)\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "NLMycgG-9ezO"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 2. Diabetes-datasetet\n",
|
|
"\n",
|
|
"I den här övningen ska vi använda våra regressionskunskaper för att göra förutsägelser på ett diabetes-dataset. [Diabetes-datasetet](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt) innehåller `442 prover` med data relaterad till diabetes, med 10 prediktorvariabler: `ålder`, `kön`, `kroppsmasseindex`, `genomsnittligt blodtryck` och `sex blodserummätningar` samt en utfallsvariabel `y`: ett kvantitativt mått på sjukdomsprogression ett år efter baslinjen.\n",
|
|
"\n",
|
|
"|Antal observationer|442|\n",
|
|
"|-------------------|:---|\n",
|
|
"|Antal prediktorer|De första 10 kolumnerna är numeriska prediktorer|\n",
|
|
"|Utfall/Mål|Kolumn 11 är ett kvantitativt mått på sjukdomsprogression ett år efter baslinjen|\n",
|
|
"|Information om prediktorer|- ålder i år\n",
|
|
"||- kön\n",
|
|
"||- bmi kroppsmasseindex\n",
|
|
"||- bp genomsnittligt blodtryck\n",
|
|
"||- s1 tc, totalt serumkolesterol\n",
|
|
"||- s2 ldl, lågdensitetslipoproteiner\n",
|
|
"||- s3 hdl, högdensitetslipoproteiner\n",
|
|
"||- s4 tch, totalt kolesterol / HDL\n",
|
|
"||- s5 ltg, möjligen logaritmen av serumtriglyceridnivå\n",
|
|
"||- s6 glu, blodsockernivå|\n",
|
|
"\n",
|
|
"> 🎓 Kom ihåg, detta är övervakad inlärning, och vi behöver ett namngivet mål 'y'.\n",
|
|
"\n",
|
|
"Innan du kan manipulera data med R, måste du importera data till R:s minne eller skapa en anslutning till data som R kan använda för att komma åt den på distans.\n",
|
|
"\n",
|
|
"> Paketet [readr](https://readr.tidyverse.org/), som är en del av Tidyverse, erbjuder ett snabbt och användarvänligt sätt att läsa in rektangulära data i R.\n",
|
|
"\n",
|
|
"Nu ska vi ladda diabetes-datasetet från denna käll-URL: <https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html>\n",
|
|
"\n",
|
|
"Vi ska också göra en snabb kontroll av vår data med hjälp av `glimpse()` och visa de första 5 raderna med `slice()`.\n",
|
|
"\n",
|
|
"Innan vi går vidare, låt oss introducera något du ofta kommer att stöta på i R-kod 🥁🥁: pipe-operatorn `%>%`\n",
|
|
"\n",
|
|
"Pipe-operatorn (`%>%`) utför operationer i logisk sekvens genom att skicka ett objekt vidare till en funktion eller ett uttryck. Du kan tänka på pipe-operatorn som att säga \"och sedan\" i din kod.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "KM6iXLH996Cl"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Import the data set\r\n",
|
|
"diabetes <- read_table2(file = \"https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt\")\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Get a glimpse and dimensions of the data\r\n",
|
|
"glimpse(diabetes)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Select the first 5 rows of the data\r\n",
|
|
"diabetes %>% \r\n",
|
|
" slice(1:5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "Z1geAMhM-bSP"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"`glimpse()` visar oss att denna data har 442 rader och 11 kolumner, där alla kolumner är av datatypen `double`.\n",
|
|
"\n",
|
|
"<br>\n",
|
|
"\n",
|
|
"> glimpse() och slice() är funktioner i [`dplyr`](https://dplyr.tidyverse.org/). Dplyr, som är en del av Tidyverse, är en grammatik för datamanipulation som erbjuder en konsekvent uppsättning verb för att lösa de vanligaste utmaningarna inom datamanipulation.\n",
|
|
"\n",
|
|
"<br>\n",
|
|
"\n",
|
|
"Nu när vi har datan, låt oss fokusera på en specifik variabel (`bmi`) som mål för denna övning. Detta kräver att vi väljer ut de önskade kolumnerna. Så, hur gör vi detta?\n",
|
|
"\n",
|
|
"[`dplyr::select()`](https://dplyr.tidyverse.org/reference/select.html) låter oss *välja* (och eventuellt byta namn på) kolumner i en data frame.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "UwjVT1Hz-c3Z"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Select predictor feature `bmi` and outcome `y`\r\n",
|
|
"diabetes_select <- diabetes %>% \r\n",
|
|
" select(c(bmi, y))\r\n",
|
|
"\r\n",
|
|
"# Print the first 5 rows\r\n",
|
|
"diabetes_select %>% \r\n",
|
|
" slice(1:10)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "RDY1oAKI-m80"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 3. Tränings- och testdata\n",
|
|
"\n",
|
|
"Det är vanligt inom övervakad inlärning att *dela upp* data i två delmängder; en (vanligtvis större) uppsättning för att träna modellen, och en mindre \"håll-ut\" uppsättning för att se hur modellen presterade.\n",
|
|
"\n",
|
|
"Nu när vi har data redo kan vi se om en maskin kan hjälpa till att avgöra en logisk uppdelning mellan siffrorna i detta dataset. Vi kan använda paketet [rsample](https://tidymodels.github.io/rsample/), som är en del av Tidymodels-ramverket, för att skapa ett objekt som innehåller information om *hur* man delar upp data, och sedan två ytterligare rsample-funktioner för att extrahera de skapade tränings- och testuppsättningarna:\n"
|
|
],
|
|
"metadata": {
|
|
"id": "SDk668xK-tc3"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"set.seed(2056)\r\n",
|
|
"# Split 67% of the data for training and the rest for tesing\r\n",
|
|
"diabetes_split <- diabetes_select %>% \r\n",
|
|
" initial_split(prop = 0.67)\r\n",
|
|
"\r\n",
|
|
"# Extract the resulting train and test sets\r\n",
|
|
"diabetes_train <- training(diabetes_split)\r\n",
|
|
"diabetes_test <- testing(diabetes_split)\r\n",
|
|
"\r\n",
|
|
"# Print the first 3 rows of the training set\r\n",
|
|
"diabetes_train %>% \r\n",
|
|
" slice(1:10)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "EqtHx129-1h-"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 4. Träna en linjär regressionsmodell med Tidymodels\n",
|
|
"\n",
|
|
"Nu är vi redo att träna vår modell!\n",
|
|
"\n",
|
|
"I Tidymodels specificerar du modeller med `parsnip()` genom att ange tre koncept:\n",
|
|
"\n",
|
|
"- Modellens **typ** skiljer mellan olika modeller som linjär regression, logistisk regression, beslutsträd och så vidare.\n",
|
|
"\n",
|
|
"- Modellens **läge** inkluderar vanliga alternativ som regression och klassificering; vissa modelltyper stödjer båda dessa medan andra bara har ett läge.\n",
|
|
"\n",
|
|
"- Modellens **motor** är det beräkningsverktyg som kommer att användas för att anpassa modellen. Ofta är dessa R-paket, såsom **`\"lm\"`** eller **`\"ranger\"`**\n",
|
|
"\n",
|
|
"Denna modellinformation fångas i en modelspecifikation, så låt oss skapa en!\n"
|
|
],
|
|
"metadata": {
|
|
"id": "sBOS-XhB-6v7"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Build a linear model specification\r\n",
|
|
"lm_spec <- \r\n",
|
|
" # Type\r\n",
|
|
" linear_reg() %>% \r\n",
|
|
" # Engine\r\n",
|
|
" set_engine(\"lm\") %>% \r\n",
|
|
" # Mode\r\n",
|
|
" set_mode(\"regression\")\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Print the model specification\r\n",
|
|
"lm_spec"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "20OwEw20--t3"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Efter att en modell har *specificerats* kan modellen `estimeras` eller `tränas` med hjälp av funktionen [`fit()`](https://parsnip.tidymodels.org/reference/fit.html), vanligtvis med en formel och lite data.\n",
|
|
"\n",
|
|
"`y ~ .` betyder att vi kommer att anpassa `y` som den förutsagda kvantiteten/målet, förklarad av alla prediktorer/funktioner, dvs. `.` (i det här fallet har vi bara en prediktor: `bmi`).\n"
|
|
],
|
|
"metadata": {
|
|
"id": "_oDHs89k_CJj"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Build a linear model specification\r\n",
|
|
"lm_spec <- linear_reg() %>% \r\n",
|
|
" set_engine(\"lm\") %>%\r\n",
|
|
" set_mode(\"regression\")\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Train a linear regression model\r\n",
|
|
"lm_mod <- lm_spec %>% \r\n",
|
|
" fit(y ~ ., data = diabetes_train)\r\n",
|
|
"\r\n",
|
|
"# Print the model\r\n",
|
|
"lm_mod"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "YlsHqd-q_GJQ"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Från modellens output kan vi se de koefficienter som lärdes in under träningen. Dessa representerar koefficienterna för den bästa anpassade linjen som ger oss det lägsta totala felet mellan den faktiska och den förutsagda variabeln.\n",
|
|
"<br>\n",
|
|
"\n",
|
|
"## 5. Gör förutsägelser på testuppsättningen\n",
|
|
"\n",
|
|
"Nu när vi har tränat en modell kan vi använda den för att förutsäga sjukdomsprogressionen y för testdatamängden med hjälp av [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html). Detta kommer att användas för att dra linjen mellan datagrupper.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "kGZ22RQj_Olu"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Make predictions for the test set\r\n",
|
|
"predictions <- lm_mod %>% \r\n",
|
|
" predict(new_data = diabetes_test)\r\n",
|
|
"\r\n",
|
|
"# Print out some of the predictions\r\n",
|
|
"predictions %>% \r\n",
|
|
" slice(1:5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "nXHbY7M2_aao"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Woohoo! 💃🕺 Vi har precis tränat en modell och använt den för att göra förutsägelser!\n",
|
|
"\n",
|
|
"När man gör förutsägelser är tidymodels-konventionen att alltid skapa en tibble/data frame med resultat och standardiserade kolumnnamn. Detta gör det enkelt att kombinera den ursprungliga datan med förutsägelserna i ett användbart format för efterföljande operationer, såsom att skapa diagram.\n",
|
|
"\n",
|
|
"`dplyr::bind_cols()` binder effektivt flera data frames kolumnvis.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "R_JstwUY_bIs"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Combine the predictions and the original test set\r\n",
|
|
"results <- diabetes_test %>% \r\n",
|
|
" bind_cols(predictions)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"results %>% \r\n",
|
|
" slice(1:5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "RybsMJR7_iI8"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 6. Visa modellresultat\n",
|
|
"\n",
|
|
"Nu är det dags att se detta visuellt 📈. Vi ska skapa ett spridningsdiagram med alla `y`- och `bmi`-värden från testuppsättningen och sedan använda förutsägelserna för att rita en linje på den mest lämpliga platsen, mellan modellens datagrupperingar.\n",
|
|
"\n",
|
|
"R har flera system för att skapa grafer, men `ggplot2` är ett av de mest eleganta och mångsidiga. Det gör det möjligt att komponera grafer genom att **kombinera oberoende komponenter**.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "XJbYbMZW_n_s"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Set a theme for the plot\r\n",
|
|
"theme_set(theme_light())\r\n",
|
|
"# Create a scatter plot\r\n",
|
|
"results %>% \r\n",
|
|
" ggplot(aes(x = bmi)) +\r\n",
|
|
" # Add a scatter plot\r\n",
|
|
" geom_point(aes(y = y), size = 1.6) +\r\n",
|
|
" # Add a line plot\r\n",
|
|
" geom_line(aes(y = .pred), color = \"blue\", size = 1.5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "R9tYp3VW_sTn"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"✅ Fundera lite på vad som händer här. En rak linje går genom många små datapunkter, men vad gör den egentligen? Kan du se hur du borde kunna använda denna linje för att förutsäga var en ny, osedd datapunkt borde passa i förhållande till diagrammets y-axel? Försök att formulera den praktiska användningen av denna modell.\n",
|
|
"\n",
|
|
"Grattis, du har byggt din första linjära regressionsmodell, gjort en förutsägelse med den och visat den i ett diagram!\n"
|
|
],
|
|
"metadata": {
|
|
"id": "zrPtHIxx_tNI"
|
|
}
|
|
},
|
|
{
|
|
"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 originalsprå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"
|
|
]
|
|
}
|
|
]
|
|
} |