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-04T07:06:26+00:00",
|
|
"source_file": "2-Regression/1-Tools/solution/R/lesson_1-R.ipynb",
|
|
"language_code": "fi"
|
|
}
|
|
},
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [],
|
|
"metadata": {
|
|
"id": "YJUHCXqK57yz"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## Johdanto regressioon - Oppitunti 1\n",
|
|
"\n",
|
|
"#### Aiheen hahmottaminen\n",
|
|
"\n",
|
|
"✅ Regressiomenetelmiä on monenlaisia, ja valinta riippuu siitä, millaiseen kysymykseen etsit vastausta. Jos haluat ennustaa todennäköisen pituuden tietyn ikäiselle henkilölle, käyttäisit `lineaarista regressiota`, koska etsit **numeerista arvoa**. Jos taas haluat selvittää, pitäisikö tiettyä ruokakulttuuria pitää vegaanisena vai ei, etsit **luokittelua**, jolloin käyttäisit `logistista regressiota`. Opit lisää logistisesta regressiosta myöhemmin. Mieti hetki, millaisia kysymyksiä voisit esittää datalle, ja mikä näistä menetelmistä olisi sopivampi.\n",
|
|
"\n",
|
|
"Tässä osiossa työskentelet [pienen diabetesdatan kanssa](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html). Kuvittele, että haluaisit testata hoitoa diabeetikoille. Koneoppimismallit voisivat auttaa sinua määrittämään, mitkä potilaat reagoisivat hoitoon paremmin, perustuen muuttujien yhdistelmiin. Jopa hyvin yksinkertainen regressiomalli, kun se visualisoidaan, saattaa paljastaa tietoa muuttujista, jotka auttaisivat sinua järjestämään teoreettisia kliinisiä kokeita.\n",
|
|
"\n",
|
|
"Siispä, aloitetaan tämä tehtävä!\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/encouRage.jpg\"\n",
|
|
" width=\"630\"/>\n",
|
|
" <figcaption>Taiteilija: @allison_horst</figcaption>\n",
|
|
"\n",
|
|
"<!--<br>Taiteilija: @allison_horst-->\n"
|
|
],
|
|
"metadata": {
|
|
"id": "LWNNzfqd6feZ"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 1. Työkalujen lataaminen\n",
|
|
"\n",
|
|
"Tätä tehtävää varten tarvitsemme seuraavat paketit:\n",
|
|
"\n",
|
|
"- `tidyverse`: [tidyverse](https://www.tidyverse.org/) on [kokoelma R-paketteja](https://www.tidyverse.org/packages), jotka on suunniteltu tekemään datatieteestä nopeampaa, helpompaa ja hauskempaa!\n",
|
|
"\n",
|
|
"- `tidymodels`: [tidymodels](https://www.tidymodels.org/) -kehys on [kokoelma paketteja](https://www.tidymodels.org/packages/) mallintamiseen ja koneoppimiseen.\n",
|
|
"\n",
|
|
"Voit asentaa ne seuraavasti:\n",
|
|
"\n",
|
|
"`install.packages(c(\"tidyverse\", \"tidymodels\"))`\n",
|
|
"\n",
|
|
"Alla oleva skripti tarkistaa, onko sinulla tarvittavat paketit tämän moduulin suorittamiseen, ja asentaa puuttuvat paketit puolestasi.\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": [
|
|
"Ladataan nyt nämä mahtavat paketit ja tehdään ne saataville nykyiseen R-istuntoomme. (Tämä on vain havainnollistamista varten, `pacman::p_load()` teki sen jo puolestasi)\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-aineisto\n",
|
|
"\n",
|
|
"Tässä harjoituksessa käytämme regressiotaitojamme ennustamalla diabetes-aineiston avulla. [Diabetes-aineisto](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt) sisältää `442 näytettä` diabetekseen liittyvistä tiedoista, joissa on 10 ennustavaa muuttujaa: `ikä`, `sukupuoli`, `painoindeksi`, `keskimääräinen verenpaine` ja `kuusi veren seerumimittausta` sekä tulosmuuttuja `y`: kvantitatiivinen mittari taudin etenemisestä vuoden kuluttua lähtötilanteesta.\n",
|
|
"\n",
|
|
"|Havaintojen määrä|442|\n",
|
|
"|------------------|:---|\n",
|
|
"|Ennustavien muuttujien määrä|Ensimmäiset 10 saraketta ovat numeerisia ennustavia|\n",
|
|
"|Tulos/Tavoite|Sarakkeessa 11 on kvantitatiivinen mittari taudin etenemisestä vuoden kuluttua lähtötilanteesta|\n",
|
|
"|Ennustemuuttujien tiedot|- ikä vuosina\n",
|
|
"||- sukupuoli\n",
|
|
"||- bmi painoindeksi\n",
|
|
"||- bp keskimääräinen verenpaine\n",
|
|
"||- s1 tc, kokonaisseerumin kolesteroli\n",
|
|
"||- s2 ldl, matalatiheyksiset lipoproteiinit\n",
|
|
"||- s3 hdl, korkeatiheyksiset lipoproteiinit\n",
|
|
"||- s4 tch, kokonaiskolesteroli / HDL\n",
|
|
"||- s5 ltg, mahdollisesti seerumin triglyseridien logaritmi\n",
|
|
"||- s6 glu, verensokeritaso|\n",
|
|
"\n",
|
|
"> 🎓 Muista, tämä on ohjattua oppimista, ja tarvitsemme nimettyä 'y'-tavoitemuuttujaa.\n",
|
|
"\n",
|
|
"Ennen kuin voit käsitellä dataa R:llä, sinun täytyy tuoda data R:n muistiin tai luoda yhteys dataan, jonka avulla R voi käyttää dataa etänä.\n",
|
|
"\n",
|
|
"> [readr](https://readr.tidyverse.org/) -paketti, joka on osa Tidyversea, tarjoaa nopean ja käyttäjäystävällisen tavan lukea suorakulmaista dataa R:ään.\n",
|
|
"\n",
|
|
"Ladataan nyt diabetes-aineisto, joka on saatavilla tässä lähde-URL:ssä: <https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html>\n",
|
|
"\n",
|
|
"Lisäksi teemme datalle tarkistuksen käyttämällä `glimpse()`-funktiota ja näytämme ensimmäiset 5 riviä `slice()`-funktiolla.\n",
|
|
"\n",
|
|
"Ennen kuin jatkamme pidemmälle, esitellään myös jotain, mitä kohtaat usein R-koodissa 🥁🥁: putkioperaattori `%>%`\n",
|
|
"\n",
|
|
"Putkioperaattori (`%>%`) suorittaa operaatioita loogisessa järjestyksessä siirtämällä objektin eteenpäin funktioon tai kutsulausekkeeseen. Voit ajatella putkioperaattorin tarkoittavan \"ja sitten\" koodissasi.\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()` näyttää, että tässä datassa on 442 riviä ja 11 saraketta, joista kaikki ovat tietotyyppiä `double`.\n",
|
|
"\n",
|
|
"<br>\n",
|
|
"\n",
|
|
"> glimpse() ja slice() ovat [`dplyr`](https://dplyr.tidyverse.org/) -kirjaston funktioita. Dplyr, joka on osa Tidyversea, on datan käsittelyn kieli, joka tarjoaa yhtenäisen joukon verbejä, jotka auttavat ratkaisemaan yleisimmät datan käsittelyn haasteet.\n",
|
|
"\n",
|
|
"<br>\n",
|
|
"\n",
|
|
"Nyt kun meillä on data, keskitytään yhteen ominaisuuteen (`bmi`) tämän harjoituksen kohteena. Tämä vaatii haluttujen sarakkeiden valitsemista. Miten tämä tehdään?\n",
|
|
"\n",
|
|
"[`dplyr::select()`](https://dplyr.tidyverse.org/reference/select.html) mahdollistaa sarakkeiden *valitsemisen* (ja tarvittaessa uudelleennimeämisen) dataframessa.\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. Koulutus- ja testausdata\n",
|
|
"\n",
|
|
"Ohjatussa oppimisessa on yleistä käytäntöä *jakaa* data kahteen osajoukkoon: (yleensä suurempaan) joukkoon, jolla mallia koulutetaan, ja pienempään \"pidätettyyn\" joukkoon, jolla nähdään, miten malli suoriutui.\n",
|
|
"\n",
|
|
"Nyt kun meillä on data valmiina, voimme tarkistaa, voiko kone auttaa määrittämään loogisen jaon tämän datasetin lukujen välillä. Voimme käyttää [rsample](https://tidymodels.github.io/rsample/) -pakettia, joka on osa Tidymodels-kehystä, luodaksemme objektin, joka sisältää tiedot siitä, *miten* data jaetaan, ja sitten käyttää kahta muuta rsample-funktiota saadaksemme luodut koulutus- ja testausjoukot:\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. Kouluta lineaarinen regressiomalli Tidymodelsilla\n",
|
|
"\n",
|
|
"Nyt olemme valmiita kouluttamaan mallimme!\n",
|
|
"\n",
|
|
"Tidymodelsissa mallit määritellään käyttämällä `parsnip()`-funktiota, jossa määritellään kolme käsitettä:\n",
|
|
"\n",
|
|
"- Mallin **tyyppi** erottaa toisistaan mallit, kuten lineaarinen regressio, logistinen regressio, päätöspuumallit ja niin edelleen.\n",
|
|
"\n",
|
|
"- Mallin **tila** sisältää yleisiä vaihtoehtoja, kuten regressio ja luokittelu; jotkut mallityypit tukevat molempia, kun taas toiset toimivat vain yhdessä tilassa.\n",
|
|
"\n",
|
|
"- Mallin **moottori** on laskennallinen työkalu, jota käytetään mallin sovittamiseen. Usein nämä ovat R-paketteja, kuten **`\"lm\"`** tai **`\"ranger\"`**.\n",
|
|
"\n",
|
|
"Tämä mallinnustieto tallennetaan mallin määrittelyyn, joten luodaan sellainen!\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": [
|
|
"Kun malli on *määritelty*, malli voidaan `arvioida` tai `kouluttaa` käyttämällä [`fit()`](https://parsnip.tidymodels.org/reference/fit.html)-funktiota, yleensä kaavan ja datan avulla.\n",
|
|
"\n",
|
|
"`y ~ .` tarkoittaa, että sovitamme `y`:n ennustettavana määränä/kohteena, jota selittävät kaikki ennustajat/piirteet eli `.` (tässä tapauksessa meillä on vain yksi ennustaja: `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": [
|
|
"Mallin tuloksista voimme nähdä koulutuksen aikana opitut kertoimet. Ne edustavat parhaiten sovitetun suoran kertoimia, jotka antavat meille pienimmän kokonaisvirheen todellisen ja ennustetun muuttujan välillä.\n",
|
|
"<br>\n",
|
|
"\n",
|
|
"## 5. Ennusteiden tekeminen testijoukolle\n",
|
|
"\n",
|
|
"Nyt kun olemme kouluttaneet mallin, voimme käyttää sitä ennustamaan sairauden etenemistä y testidatasta käyttäen [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html). Tätä käytetään piirtämään viiva dataryhmien välille.\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! 💃🕺 Juuri koulutimme mallin ja käytimme sitä ennusteiden tekemiseen!\n",
|
|
"\n",
|
|
"Ennusteita tehdessä tidymodels-käytäntö on aina tuottaa tuloksista tibble/data frame, jossa on standardoidut sarakenimet. Tämä helpottaa alkuperäisen datan ja ennusteiden yhdistämistä käyttökelpoiseen muotoon myöhempiä toimintoja, kuten visualisointia, varten.\n",
|
|
"\n",
|
|
"`dplyr::bind_cols()` yhdistää tehokkaasti useita data frameja sarakkeittain.\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. Mallinnustulosten visualisointi\n",
|
|
"\n",
|
|
"Nyt on aika tarkastella tätä visuaalisesti 📈. Luomme hajontakaavion kaikista testijoukon `y`- ja `bmi`-arvoista ja käytämme ennusteita piirtääksemme viivan sopivimpaan kohtaan mallin dataryhmien väliin.\n",
|
|
"\n",
|
|
"R:llä on useita järjestelmiä kaavioiden tekemiseen, mutta `ggplot2` on yksi tyylikkäimmistä ja monipuolisimmista. Sen avulla voit koostaa kaavioita **yhdistämällä itsenäisiä komponentteja**.\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": [
|
|
"✅ Mieti hetki, mitä tässä tapahtuu. Suora viiva kulkee monien pienten datapisteiden läpi, mutta mitä se tarkalleen ottaen tekee? Voitko nähdä, miten tämän viivan avulla pitäisi pystyä ennustamaan, mihin uusi, ennennäkemätön datapiste sijoittuu suhteessa kuvaajan y-akseliin? Yritä pukea sanoiksi tämän mallin käytännön hyöty.\n",
|
|
"\n",
|
|
"Onnittelut, loit ensimmäisen lineaarisen regressiomallisi, teit ennusteen sen avulla ja esitit sen kuvaajassa!\n"
|
|
],
|
|
"metadata": {
|
|
"id": "zrPtHIxx_tNI"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n---\n\n**Vastuuvapauslauseke**: \nTämä asiakirja on käännetty käyttämällä tekoälypohjaista käännöspalvelua [Co-op Translator](https://github.com/Azure/co-op-translator). Vaikka pyrimme tarkkuuteen, huomioithan, että automaattiset käännökset voivat sisältää virheitä tai epätarkkuuksia. Alkuperäistä asiakirjaa sen alkuperäisellä kielellä tulee pitää ensisijaisena lähteenä. Kriittisen tiedon osalta suositellaan ammattimaista ihmiskääntämistä. Emme ole vastuussa väärinkäsityksistä tai virhetulkinnoista, jotka johtuvat tämän käännöksen käytöstä.\n"
|
|
]
|
|
}
|
|
]
|
|
} |