{ "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-04T07:04:37+00:00", "source_file": "2-Regression/1-Tools/solution/R/lesson_1-R.ipynb", "language_code": "da" } }, "cells": [ { "cell_type": "markdown", "source": [], "metadata": { "id": "YJUHCXqK57yz" } }, { "cell_type": "markdown", "source": [ "## Introduktion til Regression - Lektion 1\n", "\n", "#### Sæt det i perspektiv\n", "\n", "✅ Der findes mange typer regressionsmetoder, og hvilken du vælger afhænger af det svar, du søger. Hvis du vil forudsige den sandsynlige højde for en person med en given alder, vil du bruge `lineær regression`, da du søger en **numerisk værdi**. Hvis du er interesseret i at finde ud af, om en type køkken skal betragtes som vegansk eller ej, leder du efter en **kategoriinddeling**, så du vil bruge `logistisk regression`. Du vil lære mere om logistisk regression senere. Tænk lidt over nogle spørgsmål, du kan stille til data, og hvilken af disse metoder der ville være mest passende.\n", "\n", "I denne sektion vil du arbejde med et [lille datasæt om diabetes](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html). Forestil dig, at du ville teste en behandling for diabetiske patienter. Maskinlæringsmodeller kan hjælpe dig med at afgøre, hvilke patienter der vil reagere bedre på behandlingen, baseret på kombinationer af variabler. Selv en meget grundlæggende regressionsmodel, når den visualiseres, kan vise information om variabler, der kan hjælpe dig med at organisere dine teoretiske kliniske forsøg.\n", "\n", "Med det sagt, lad os komme i gang med denne opgave!\n", "\n", "
\n",
" \n",
"
\n",
"\n",
"> glimpse() og slice() er funktioner i [`dplyr`](https://dplyr.tidyverse.org/). Dplyr, en del af Tidyverse, er en grammatik for datamanipulation, der tilbyder et konsistent sæt af verber, som hjælper dig med at løse de mest almindelige udfordringer inden for datamanipulation.\n",
"\n",
"
\n",
"\n",
"Nu hvor vi har dataen, lad os fokusere på én feature (`bmi`) som mål for denne øvelse. Dette kræver, at vi vælger de ønskede kolonner. Så hvordan gør vi dette?\n",
"\n",
"[`dplyr::select()`](https://dplyr.tidyverse.org/reference/select.html) giver os mulighed for at *vælge* (og eventuelt omdøbe) kolonner 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- og testdata\n",
"\n",
"Det er almindelig praksis inden for superviseret læring at *opdele* dataene i to undergrupper; et (typisk større) sæt til at træne modellen med, og et mindre \"tilbageholdt\" sæt til at evaluere, hvordan modellen klarer sig.\n",
"\n",
"Nu hvor vi har dataene klar, kan vi undersøge, om en maskine kan hjælpe med at finde en logisk opdeling mellem tallene i dette datasæt. Vi kan bruge pakken [rsample](https://tidymodels.github.io/rsample/), som er en del af Tidymodels-rammeværket, til at oprette et objekt, der indeholder information om *hvordan* dataene skal opdeles, og derefter to yderligere rsample-funktioner til at udtrække de oprettede trænings- og testsæt:\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æn en lineær regressionsmodel med Tidymodels\n",
"\n",
"Nu er vi klar til at træne vores model!\n",
"\n",
"I Tidymodels specificerer du modeller ved hjælp af `parsnip()` ved at angive tre begreber:\n",
"\n",
"- Model **type** adskiller modeller som lineær regression, logistisk regression, beslutningstræ-modeller og så videre.\n",
"\n",
"- Model **mode** inkluderer almindelige muligheder som regression og klassifikation; nogle modeltyper understøtter begge dele, mens andre kun har én tilstand.\n",
"\n",
"- Model **engine** er det beregningsværktøj, der vil blive brugt til at tilpasse modellen. Ofte er disse R-pakker, såsom **`\"lm\"`** eller **`\"ranger\"`**\n",
"\n",
"Denne modelinformation fanges i en modelspecifikation, så lad os bygge 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 en model er blevet *specificeret*, kan modellen `estimeres` eller `trænes` ved hjælp af [`fit()`](https://parsnip.tidymodels.org/reference/fit.html)-funktionen, typisk ved brug af en formel og nogle data.\n",
"\n",
"`y ~ .` betyder, at vi vil tilpasse `y` som den forudsagte værdi/mål, forklaret af alle prædiktorer/egenskaber, dvs. `.` (i dette tilfælde har vi kun én prædiktor: `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": [
"Fra modeloutputtet kan vi se de koefficienter, der blev lært under træningen. De repræsenterer koefficienterne for den bedste tilpasningslinje, som giver os den laveste samlede fejl mellem den faktiske og den forudsagte variabel.\n",
"
\n",
"\n",
"## 5. Lav forudsigelser på testdatasættet\n",
"\n",
"Nu hvor vi har trænet en model, kan vi bruge den til at forudsige sygdomsprogressionen y for testdatasættet ved hjælp af [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html). Dette vil blive brugt til at tegne linjen mellem 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 lige trænet en model og brugt den til at lave forudsigelser!\n",
"\n",
"Når man laver forudsigelser, er tidymodels-konventionen altid at producere en tibble/data frame med resultater og standardiserede kolonnenavne. Dette gør det nemt at kombinere de originale data og forudsigelserne i et brugbart format til efterfølgende operationer såsom visualisering.\n",
"\n",
"`dplyr::bind_cols()` binder effektivt flere data frames kolonnevis.\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. Visualisering af modelleringsresultater\n",
"\n",
"Nu er det tid til at se dette visuelt 📈. Vi laver et scatterplot af alle `y`- og `bmi`-værdierne fra testdatasættet og bruger derefter forudsigelserne til at tegne en linje på det mest passende sted mellem modellens datagrupperinger.\n",
"\n",
"R har flere systemer til at lave grafer, men `ggplot2` er en af de mest elegante og alsidige. Det giver dig mulighed for at sammensætte grafer ved **at kombinere uafhængige 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": [
"✅ Tænk lidt over, hvad der sker her. En lige linje løber gennem mange små datapunkter, men hvad gør den egentlig? Kan du se, hvordan du burde kunne bruge denne linje til at forudsige, hvor et nyt, uset datapunkt skulle passe i forhold til plottets y-akse? Prøv at sætte ord på den praktiske anvendelse af denne model.\n",
"\n",
"Tillykke, du har bygget din første lineære regressionsmodel, lavet en forudsigelse med den og vist den i et plot!\n"
],
"metadata": {
"id": "zrPtHIxx_tNI"
}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Ansvarsfraskrivelse**: \nDette dokument er blevet oversat ved hjælp af AI-oversættelsestjenesten [Co-op Translator](https://github.com/Azure/co-op-translator). Selvom vi bestræber os på nøjagtighed, skal du være opmærksom på, at automatiserede oversættelser kan indeholde fejl eller unøjagtigheder. Det originale dokument på dets oprindelige sprog bør betragtes som den autoritative kilde. For kritisk information anbefales professionel menneskelig oversættelse. Vi påtager os intet ansvar for misforståelser eller fejltolkninger, der måtte opstå som følge af brugen af denne oversættelse.\n"
]
}
]
}