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.
1085 lines
42 KiB
1085 lines
42 KiB
{
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2,
|
|
"metadata": {
|
|
"colab": {
|
|
"name": "lesson_3-R.ipynb",
|
|
"provenance": [],
|
|
"collapsed_sections": [],
|
|
"toc_visible": true
|
|
},
|
|
"kernelspec": {
|
|
"name": "ir",
|
|
"display_name": "R"
|
|
},
|
|
"language_info": {
|
|
"name": "R"
|
|
},
|
|
"coopTranslator": {
|
|
"original_hash": "5015d65d61ba75a223bfc56c273aa174",
|
|
"translation_date": "2025-09-04T06:32:15+00:00",
|
|
"source_file": "2-Regression/3-Linear/solution/R/lesson_3-R.ipynb",
|
|
"language_code": "fi"
|
|
}
|
|
},
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"# Rakenna regressiomalli: lineaariset ja polynomiset regressiomallit\n"
|
|
],
|
|
"metadata": {
|
|
"id": "EgQw8osnsUV-"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## Lineaarinen ja polynominen regressio kurpitsan hinnoitteluun - Oppitunti 3\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/linear-polynomial.png\"\n",
|
|
" width=\"800\"/>\n",
|
|
" <figcaption>Infografiikka: Dasani Madipalli</figcaption>\n",
|
|
"\n",
|
|
"\n",
|
|
"<!--{width=\"800\"}-->\n",
|
|
"\n",
|
|
"#### Johdanto\n",
|
|
"\n",
|
|
"Tähän mennessä olet tutustunut siihen, mitä regressio tarkoittaa, käyttäen esimerkkidataa kurpitsan hinnoitteludatasetistä, jota käytämme koko tämän oppitunnin ajan. Olet myös visualisoinut sitä `ggplot2`:n avulla.💪\n",
|
|
"\n",
|
|
"Nyt olet valmis sukeltamaan syvemmälle regressioon koneoppimisen näkökulmasta. Tässä oppitunnissa opit lisää kahdesta regressiotyypistä: *yksinkertainen lineaarinen regressio* ja *polynominen regressio*, sekä hieman näiden tekniikoiden taustalla olevasta matematiikasta.\n",
|
|
"\n",
|
|
"> Koko tämän kurssin ajan oletamme vain vähäistä matematiikan osaamista ja pyrimme tekemään sisällön helposti lähestyttäväksi opiskelijoille, jotka tulevat muilta aloilta. Huomioi siis muistiinpanot, 🧮 matemaattiset esimerkit, kaaviot ja muut oppimistyökalut, jotka auttavat ymmärtämisessä.\n",
|
|
"\n",
|
|
"#### Valmistelu\n",
|
|
"\n",
|
|
"Muistutuksena, lataat tätä dataa, jotta voit esittää kysymyksiä siitä.\n",
|
|
"\n",
|
|
"- Milloin on paras aika ostaa kurpitsoja?\n",
|
|
"\n",
|
|
"- Minkä hinnan voin odottaa minikurpitsojen laatikolle?\n",
|
|
"\n",
|
|
"- Pitäisikö minun ostaa niitä puolibushelin koreissa vai 1 1/9 bushelin laatikoissa? Jatketaan datan tutkimista.\n",
|
|
"\n",
|
|
"Edellisessä oppitunnissa loit `tibble`:n (nykyaikainen uudelleentulkinta dataframesta) ja täytit sen osalla alkuperäistä datasettiä, standardisoiden hinnoittelun bushelin mukaan. Tällä tavalla pystyit kuitenkin keräämään vain noin 400 datapistettä ja vain syksyn kuukausilta. Ehkä voimme saada hieman enemmän yksityiskohtia datan luonteesta puhdistamalla sitä lisää? Katsotaan... 🕵️♀️\n",
|
|
"\n",
|
|
"Tätä tehtävää varten tarvitsemme seuraavat paketit:\n",
|
|
"\n",
|
|
"- `tidyverse`: [tidyverse](https://www.tidyverse.org/) on [R-pakettien kokoelma](https://www.tidyverse.org/packages), joka on suunniteltu tekemään datatiede nopeammaksi, helpommaksi ja hauskemmaksi!\n",
|
|
"\n",
|
|
"- `tidymodels`: [tidymodels](https://www.tidymodels.org/) -kehys on [pakettikokoelma](https://www.tidymodels.org/packages/) mallintamiseen ja koneoppimiseen.\n",
|
|
"\n",
|
|
"- `janitor`: [janitor-paketti](https://github.com/sfirke/janitor) tarjoaa yksinkertaisia työkaluja likaisen datan tarkasteluun ja puhdistamiseen.\n",
|
|
"\n",
|
|
"- `corrplot`: [corrplot-paketti](https://cran.r-project.org/web/packages/corrplot/vignettes/corrplot-intro.html) tarjoaa visuaalisen tutkimustyökalun korrelaatiomatriisille, joka tukee automaattista muuttujien järjestämistä piilotettujen kuvioiden havaitsemiseksi muuttujien välillä.\n",
|
|
"\n",
|
|
"Voit asentaa ne seuraavasti:\n",
|
|
"\n",
|
|
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"janitor\", \"corrplot\"))`\n",
|
|
"\n",
|
|
"Alla oleva skripti tarkistaa, onko sinulla tarvittavat paketit tämän moduulin suorittamiseen, ja asentaa ne puolestasi, jos ne puuttuvat.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "WqQPS1OAsg3H"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"suppressWarnings(if (!require(\"pacman\")) install.packages(\"pacman\"))\n",
|
|
"\n",
|
|
"pacman::p_load(tidyverse, tidymodels, janitor, corrplot)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "tA4C2WN3skCf",
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"outputId": "c06cd805-5534-4edc-f72b-d0d1dab96ac0"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Lataamme myöhemmin nämä upeat paketit ja teemme ne saatavilla nykyisessä R-istunnossamme. (Tämä on vain havainnollistamista varten, `pacman::p_load()` teki tämän jo puolestasi)\n",
|
|
"\n",
|
|
"## 1. Lineaarinen regressioviiva\n",
|
|
"\n",
|
|
"Kuten opit oppitunnilla 1, lineaarisen regressioharjoituksen tavoitteena on pystyä piirtämään *paras sovitusviiva*:\n",
|
|
"\n",
|
|
"- **Näytä muuttujien väliset suhteet**. Näytä muuttujien välinen suhde.\n",
|
|
"\n",
|
|
"- **Tee ennusteita**. Tee tarkkoja ennusteita siitä, mihin uusi datapiste sijoittuisi suhteessa tähän viivaan.\n",
|
|
"\n",
|
|
"Tämän tyyppisen viivan piirtämiseen käytämme tilastollista menetelmää nimeltä **Pienimmän neliösumman regressio**. Termi `pienimmän neliösumman` tarkoittaa, että kaikki regressioviivan ympärillä olevat datapisteet neliöidään ja sitten summataan. Ihanteellisesti tämä lopullinen summa on mahdollisimman pieni, koska haluamme vähän virheitä eli `pienimmän neliösumman`. Näin ollen paras sovitusviiva on viiva, joka antaa meille pienimmän arvon neliöityjen virheiden summalle - tästä nimi *pienimmän neliösumman regressio*.\n",
|
|
"\n",
|
|
"Teemme tämän, koska haluamme mallintaa viivan, jolla on pienin kumulatiivinen etäisyys kaikista datapisteistämme. Neliöimme myös termit ennen niiden yhteenlaskemista, koska olemme kiinnostuneita niiden suuruudesta, emmekä suunnasta.\n",
|
|
"\n",
|
|
"> **🧮 Näytä matematiikka**\n",
|
|
">\n",
|
|
"> Tämä viiva, nimeltään *paras sovitusviiva*, voidaan ilmaista [yhtälöllä](https://en.wikipedia.org/wiki/Simple_linear_regression):\n",
|
|
">\n",
|
|
"> Y = a + bX\n",
|
|
">\n",
|
|
"> `X` on '`selittävä muuttuja` tai `ennustaja`'. `Y` on '`riippuva muuttuja` tai `tulos`'. Viivan kulmakerroin on `b` ja `a` on y-akselin leikkauspiste, joka viittaa `Y`:n arvoon, kun `X = 0`.\n",
|
|
">\n",
|
|
"\n",
|
|
"> \n",
|
|
" Infografiikka: Jen Looper\n",
|
|
">\n",
|
|
"> Ensin lasketaan kulmakerroin `b`.\n",
|
|
">\n",
|
|
"> Toisin sanoen, viitaten kurpitsadatan alkuperäiseen kysymykseen: \"ennusta kurpitsan hinta per bushel kuukauden mukaan\", `X` viittaa hintaan ja `Y` viittaa myyntikuukauteen.\n",
|
|
">\n",
|
|
"> \n",
|
|
" Infografiikka: Jen Looper\n",
|
|
"> \n",
|
|
"> Laske Y:n arvo. Jos maksat noin 4 dollaria, sen täytyy olla huhtikuu!\n",
|
|
">\n",
|
|
"> Matematiikka, joka laskee viivan, täytyy osoittaa viivan kulmakerroin, joka riippuu myös leikkauspisteestä, eli siitä, missä `Y` sijaitsee, kun `X = 0`.\n",
|
|
">\n",
|
|
"> Voit tarkastella näiden arvojen laskentamenetelmää [Math is Fun](https://www.mathsisfun.com/data/least-squares-regression.html) -sivustolla. Käy myös [tällä pienimmän neliösumman laskimella](https://www.mathsisfun.com/data/least-squares-calculator.html) nähdäksesi, miten lukuarvot vaikuttavat viivaan.\n",
|
|
"\n",
|
|
"Ei niin pelottavaa, eikö? 🤓\n",
|
|
"\n",
|
|
"#### Korrelaatio\n",
|
|
"\n",
|
|
"Yksi termi, joka on hyvä ymmärtää, on **korrelaatiokerroin** annettujen X- ja Y-muuttujien välillä. Hajontakaavion avulla voit nopeasti visualisoida tämän kertoimen. Kaavio, jossa datapisteet ovat siistissä linjassa, omaa korkean korrelaation, mutta kaavio, jossa datapisteet ovat hajallaan X:n ja Y:n välillä, omaa matalan korrelaation.\n",
|
|
"\n",
|
|
"Hyvä lineaarinen regressiomalli on sellainen, jolla on korkea (lähempänä 1 kuin 0) korrelaatiokerroin käyttäen pienimmän neliösumman regressiomenetelmää ja regressioviivaa.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "cdX5FRpvsoP5"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## **2. Tanssi datan kanssa: luodaan data frame mallinnusta varten**\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/janitor.jpg\"\n",
|
|
" width=\"700\"/>\n",
|
|
" <figcaption>Taiteilija: @allison_horst</figcaption>\n",
|
|
"\n",
|
|
"\n",
|
|
"<!--{width=\"700\"}-->\n"
|
|
],
|
|
"metadata": {
|
|
"id": "WdUKXk7Bs8-V"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Lataa tarvittavat kirjastot ja datasetti. Muunna data data frameksi, joka sisältää osajoukon datasta:\n",
|
|
"\n",
|
|
"- Valitse vain kurpitsat, joiden hinta on ilmoitettu tynnyrillisinä\n",
|
|
"\n",
|
|
"- Muunna päivämäärä kuukaudeksi\n",
|
|
"\n",
|
|
"- Laske hinta korkeiden ja matalien hintojen keskiarvona\n",
|
|
"\n",
|
|
"- Muunna hinta vastaamaan tynnyrillistä kohden laskettua hinnoittelua\n",
|
|
"\n",
|
|
"> Kävimme nämä vaiheet läpi [edellisessä oppitunnissa](https://github.com/microsoft/ML-For-Beginners/blob/main/2-Regression/2-Data/solution/lesson_2-R.ipynb).\n"
|
|
],
|
|
"metadata": {
|
|
"id": "fMCtu2G2s-p8"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Load the core Tidyverse packages\n",
|
|
"library(tidyverse)\n",
|
|
"library(lubridate)\n",
|
|
"\n",
|
|
"# Import the pumpkins data\n",
|
|
"pumpkins <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/2-Regression/data/US-pumpkins.csv\")\n",
|
|
"\n",
|
|
"\n",
|
|
"# Get a glimpse and dimensions of the data\n",
|
|
"glimpse(pumpkins)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Print the first 50 rows of the data set\n",
|
|
"pumpkins %>% \n",
|
|
" slice_head(n = 5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "ryMVZEEPtERn"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Seikkailun hengessä tutustutaan [`janitor-pakettiin`](../../../../../../2-Regression/3-Linear/solution/R/github.com/sfirke/janitor), joka tarjoaa yksinkertaisia funktioita likaisen datan tarkasteluun ja puhdistamiseen. Esimerkiksi tarkastellaan datamme sarakenimiä:\n"
|
|
],
|
|
"metadata": {
|
|
"id": "xcNxM70EtJjb"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Return column names\n",
|
|
"pumpkins %>% \n",
|
|
" names()"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "5XtpaIigtPfW"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"🤔 Voimme tehdä paremmin. Muutetaan nämä sarakenimet `friendR` käyttämällä [snake_case](https://en.wikipedia.org/wiki/Snake_case) -konventiota `janitor::clean_names` avulla. Lisätietoja tästä funktiosta: `?clean_names`\n"
|
|
],
|
|
"metadata": {
|
|
"id": "IbIqrMINtSHe"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Clean names to the snake_case convention\n",
|
|
"pumpkins <- pumpkins %>% \n",
|
|
" clean_names(case = \"snake\")\n",
|
|
"\n",
|
|
"# Return column names\n",
|
|
"pumpkins %>% \n",
|
|
" names()"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "a2uYvclYtWvX"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Paljon siistimpää 🧹! Nyt tanssia datan kanssa käyttäen `dplyr` kuten edellisessä oppitunnissa! 💃\n"
|
|
],
|
|
"metadata": {
|
|
"id": "HfhnuzDDtaDd"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Select desired columns\n",
|
|
"pumpkins <- pumpkins %>% \n",
|
|
" select(variety, city_name, package, low_price, high_price, date)\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"# Extract the month from the dates to a new column\n",
|
|
"pumpkins <- pumpkins %>%\n",
|
|
" mutate(date = mdy(date),\n",
|
|
" month = month(date)) %>% \n",
|
|
" select(-date)\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"# Create a new column for average Price\n",
|
|
"pumpkins <- pumpkins %>% \n",
|
|
" mutate(price = (low_price + high_price)/2)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Retain only pumpkins with the string \"bushel\"\n",
|
|
"new_pumpkins <- pumpkins %>% \n",
|
|
" filter(str_detect(string = package, pattern = \"bushel\"))\n",
|
|
"\n",
|
|
"\n",
|
|
"# Normalize the pricing so that you show the pricing per bushel, not per 1 1/9 or 1/2 bushel\n",
|
|
"new_pumpkins <- new_pumpkins %>% \n",
|
|
" mutate(price = case_when(\n",
|
|
" str_detect(package, \"1 1/9\") ~ price/(1.1),\n",
|
|
" str_detect(package, \"1/2\") ~ price*2,\n",
|
|
" TRUE ~ price))\n",
|
|
"\n",
|
|
"# Relocate column positions\n",
|
|
"new_pumpkins <- new_pumpkins %>% \n",
|
|
" relocate(month, .before = variety)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Display the first 5 rows\n",
|
|
"new_pumpkins %>% \n",
|
|
" slice_head(n = 5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "X0wU3gQvtd9f"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Hyvää työtä!👌 Sinulla on nyt siisti ja järjestetty datajoukko, jonka pohjalta voit rakentaa uuden regressiomallisi!\n",
|
|
"\n",
|
|
"Miltä kuulostaisi hajontakaavio?\n"
|
|
],
|
|
"metadata": {
|
|
"id": "UpaIwaxqth82"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Set theme\n",
|
|
"theme_set(theme_light())\n",
|
|
"\n",
|
|
"# Make a scatter plot of month and price\n",
|
|
"new_pumpkins %>% \n",
|
|
" ggplot(mapping = aes(x = month, y = price)) +\n",
|
|
" geom_point(size = 1.6)\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "DXgU-j37tl5K"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Hajontakaavio muistuttaa meitä siitä, että meillä on kuukausitietoja vain elokuusta joulukuuhun. Tarvitsemme luultavasti lisää tietoa voidaksemme tehdä johtopäätöksiä lineaarisesti.\n",
|
|
"\n",
|
|
"Katsotaanpa mallinnustietojamme uudelleen:\n"
|
|
],
|
|
"metadata": {
|
|
"id": "Ve64wVbwtobI"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Display first 5 rows\n",
|
|
"new_pumpkins %>% \n",
|
|
" slice_head(n = 5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "HFQX2ng1tuSJ"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Entä jos haluaisimme ennustaa kurpitsan `hinnan` perustuen `kaupunki`- tai `paketti`-sarakkeisiin, jotka ovat merkkijonotyyppisiä? Tai vielä yksinkertaisemmin, miten voisimme löytää korrelaation (joka vaatii molempien syötteiden olevan numeerisia) esimerkiksi `paketti`- ja `hinta`-sarakkeiden välillä? 🤷🤷\n",
|
|
"\n",
|
|
"Koneoppimismallit toimivat parhaiten numeeristen ominaisuuksien kanssa tekstiarvojen sijaan, joten yleensä täytyy muuntaa kategoriset ominaisuudet numeerisiksi esityksiksi.\n",
|
|
"\n",
|
|
"Tämä tarkoittaa, että meidän täytyy löytää tapa muokata ennustettavia muuttujia, jotta malli voi käyttää niitä tehokkaasti. Tätä prosessia kutsutaan nimellä `ominaisuuksien suunnittelu` (feature engineering).\n"
|
|
],
|
|
"metadata": {
|
|
"id": "7hsHoxsStyjJ"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 3. Datan esikäsittely mallinnusta varten reseptien avulla 👩🍳👨🍳\n",
|
|
"\n",
|
|
"Toiminnot, jotka muokkaavat ennustearvoja, jotta malli voi käyttää niitä tehokkaammin, tunnetaan nimellä `ominaisuuksien muokkaus`.\n",
|
|
"\n",
|
|
"Eri malleilla on erilaiset esikäsittelyvaatimukset. Esimerkiksi pienimmän neliösumman menetelmä vaatii `kategoristen muuttujien koodaamista`, kuten kuukausi, lajike ja city_name. Tämä tarkoittaa yksinkertaisesti `kategoristen arvojen sisältävän sarakkeen` muuttamista yhdeksi tai useammaksi `numeeriseksi sarakkeeksi`, jotka korvaavat alkuperäisen.\n",
|
|
"\n",
|
|
"Esimerkiksi, jos datasi sisältää seuraavan kategorisen ominaisuuden:\n",
|
|
"\n",
|
|
"| kaupunki |\n",
|
|
"|:-----------:|\n",
|
|
"| Denver |\n",
|
|
"| Nairobi |\n",
|
|
"| Tokio |\n",
|
|
"\n",
|
|
"Voit käyttää *järjestyskooodausta* korvataksesi jokaisen kategorian ainutlaatuisella kokonaisluvulla, kuten näin:\n",
|
|
"\n",
|
|
"| kaupunki |\n",
|
|
"|:--------:|\n",
|
|
"| 0 |\n",
|
|
"| 1 |\n",
|
|
"| 2 |\n",
|
|
"\n",
|
|
"Ja juuri näin teemme datallemme!\n",
|
|
"\n",
|
|
"Tässä osiossa tutustumme toiseen upeaan Tidymodels-pakettiin: [recipes](https://tidymodels.github.io/recipes/) - joka on suunniteltu auttamaan datan esikäsittelyssä **ennen** mallin kouluttamista. Resepti on pohjimmiltaan objekti, joka määrittelee, mitä vaiheita dataan tulee soveltaa, jotta se olisi valmis mallinnusta varten.\n",
|
|
"\n",
|
|
"Nyt luodaan resepti, joka valmistaa datamme mallinnusta varten korvaamalla ainutlaatuisen kokonaisluvun kaikille ennustearvojen sarakkeiden havainnoille:\n"
|
|
],
|
|
"metadata": {
|
|
"id": "AD5kQbcvt3Xl"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Specify a recipe\n",
|
|
"pumpkins_recipe <- recipe(price ~ ., data = new_pumpkins) %>% \n",
|
|
" step_integer(all_predictors(), zero_based = TRUE)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Print out the recipe\n",
|
|
"pumpkins_recipe"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "BNaFKXfRt9TU"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Mahtavaa! 👏 Juuri loimme ensimmäisen reseptimme, joka määrittää lopputuloksen (hinta) ja siihen liittyvät ennustajat, ja että kaikki ennustajakolumnit tulisi koodata kokonaislukujen joukkoon 🙌! Puretaanpa tämä nopeasti:\n",
|
|
"\n",
|
|
"- Kutsu `recipe()`-funktiolle kaavan kanssa kertoo reseptille muuttujien *roolit* käyttäen `new_pumpkins`-dataa viitteenä. Esimerkiksi `price`-kolumnille on annettu `outcome`-rooli, kun taas lopuille kolumneille on annettu `predictor`-rooli.\n",
|
|
"\n",
|
|
"- `step_integer(all_predictors(), zero_based = TRUE)` määrittää, että kaikki ennustajat tulisi muuntaa kokonaislukujen joukkoon, jossa numerointi alkaa nollasta.\n",
|
|
"\n",
|
|
"Olemme varmoja, että sinulla saattaa olla ajatuksia, kuten: \"Tämä on niin siistiä!! Mutta entä jos minun pitäisi varmistaa, että reseptit tekevät juuri sen, mitä odotan niiden tekevän? 🤔\"\n",
|
|
"\n",
|
|
"Se on loistava ajatus! Katsos, kun resepti on määritelty, voit arvioida tarvittavat parametrit datan esikäsittelyä varten ja sitten poimia esikäsitellyn datan. Tätä ei yleensä tarvitse tehdä, kun käytät Tidymodels-kirjastoa (näemme normaalin käytännön aivan pian -> `workflows`), mutta siitä voi olla hyötyä, kun haluat tehdä jonkinlaisen järkevyystarkistuksen varmistaaksesi, että reseptit toimivat odotetusti.\n",
|
|
"\n",
|
|
"Tätä varten tarvitset kaksi lisäverbiä: `prep()` ja `bake()`, ja kuten aina, pienet R-ystävämme [`Allison Horst`](https://github.com/allisonhorst/stats-illustrations) auttavat sinua ymmärtämään tämän paremmin!\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/recipes.png\"\n",
|
|
" width=\"550\"/>\n",
|
|
" <figcaption>Taiteilija: @allison_horst</figcaption>\n"
|
|
],
|
|
"metadata": {
|
|
"id": "KEiO0v7kuC9O"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"[`prep()`](https://recipes.tidymodels.org/reference/prep.html): arvioi tarvittavat parametrit harjoitusaineistosta, joita voidaan myöhemmin soveltaa muihin aineistoihin. Esimerkiksi, tietylle ennustajan sarakkeelle, mikä havainto saa kokonaisluvun 0, 1, 2 jne.\n",
|
|
"\n",
|
|
"[`bake()`](https://recipes.tidymodels.org/reference/bake.html): ottaa valmiiksi käsitellyn reseptin ja soveltaa toimenpiteet mihin tahansa aineistoon.\n",
|
|
"\n",
|
|
"Sanottuani tämän, valmistellaan ja sovelletaan reseptimme varmistaaksemme, että pinnan alla ennustajan sarakkeet koodataan ensin ennen mallin sovittamista.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "Q1xtzebuuTCP"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Prep the recipe\n",
|
|
"pumpkins_prep <- prep(pumpkins_recipe)\n",
|
|
"\n",
|
|
"# Bake the recipe to extract a preprocessed new_pumpkins data\n",
|
|
"baked_pumpkins <- bake(pumpkins_prep, new_data = NULL)\n",
|
|
"\n",
|
|
"# Print out the baked data set\n",
|
|
"baked_pumpkins %>% \n",
|
|
" slice_head(n = 10)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "FGBbJbP_uUUn"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Woo-hoo!🥳 Käsitelty data `baked_pumpkins` sisältää kaikki ennustemuuttujat koodattuina, mikä vahvistaa, että määritellyt esikäsittelyvaiheet toimivat odotetusti. Tämä tekee datan lukemisesta vaikeampaa sinulle, mutta paljon ymmärrettävämpää Tidymodelsille! Käytä hetki aikaa selvittääksesi, mikä havainto on yhdistetty vastaavaan kokonaislukuun.\n",
|
|
"\n",
|
|
"On myös syytä mainita, että `baked_pumpkins` on data frame, jonka avulla voimme suorittaa laskutoimituksia.\n",
|
|
"\n",
|
|
"Esimerkiksi, yritetään löytää hyvä korrelaatio kahden datasi pisteen välillä, jotta voimme mahdollisesti rakentaa hyvän ennustemallin. Käytämme tähän funktiota `cor()`. Kirjoita `?cor()` saadaksesi lisätietoa funktiosta.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "1dvP0LBUueAW"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Find the correlation between the city_name and the price\n",
|
|
"cor(baked_pumpkins$city_name, baked_pumpkins$price)\n",
|
|
"\n",
|
|
"# Find the correlation between the package and the price\n",
|
|
"cor(baked_pumpkins$package, baked_pumpkins$price)\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "3bQzXCjFuiSV"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Kuten käy ilmi, kaupungin ja hinnan välillä on vain heikko korrelaatio. Sen sijaan paketin ja sen hinnan välillä on hieman parempi korrelaatio. Tämä on järkevää, eikö? Yleensä mitä suurempi tuotekuori, sitä korkeampi hinta.\n",
|
|
"\n",
|
|
"Samalla voimme myös yrittää visualisoida kaikkien sarakkeiden korrelaatiomatriisin käyttämällä `corrplot`-pakettia.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "BToPWbgjuoZw"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Load the corrplot package\n",
|
|
"library(corrplot)\n",
|
|
"\n",
|
|
"# Obtain correlation matrix\n",
|
|
"corr_mat <- cor(baked_pumpkins %>% \n",
|
|
" # Drop columns that are not really informative\n",
|
|
" select(-c(low_price, high_price)))\n",
|
|
"\n",
|
|
"# Make a correlation plot between the variables\n",
|
|
"corrplot(corr_mat, method = \"shade\", shade.col = NA, tl.col = \"black\", tl.srt = 45, addCoef.col = \"black\", cl.pos = \"n\", order = \"original\")"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "ZwAL3ksmutVR"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"🤩🤩 Paljon parempi.\n",
|
|
"\n",
|
|
"Hyvä kysymys, jonka voimme nyt esittää tästä datasta, on: '`Mitä hintaa voin odottaa tietylle kurpitsapaketille?`' Mennään suoraan asiaan!\n",
|
|
"\n",
|
|
"> Huomio: Kun **`bake()`**-funktiolla käsittelet valmisteltua reseptiä **`pumpkins_prep`** käyttäen **`new_data = NULL`**, saat käsitellyn (eli koodatun) harjoitusdatan. Jos sinulla olisi toinen datasetti, esimerkiksi testidatasetti, ja haluaisit nähdä, miten resepti esikäsittelisi sen, voisit yksinkertaisesti käsitellä **`pumpkins_prep`**-reseptiä käyttäen **`new_data = test_set`**.\n",
|
|
"\n",
|
|
"## 4. Rakenna lineaarinen regressiomalli\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/linear-polynomial.png\"\n",
|
|
" width=\"800\"/>\n",
|
|
" <figcaption>Infografiikka: Dasani Madipalli</figcaption>\n"
|
|
],
|
|
"metadata": {
|
|
"id": "YqXjLuWavNxW"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Nyt kun olemme rakentaneet reseptin ja vahvistaneet, että data esikäsitellään asianmukaisesti, rakennetaan nyt regressiomalli vastataksemme kysymykseen: `Mitä hintaa voin odottaa tietylle kurpitsapakkaukselle?`\n",
|
|
"\n",
|
|
"#### Koulutetaan lineaarinen regressiomalli käyttämällä harjoitusjoukkoa\n",
|
|
"\n",
|
|
"Kuten olet ehkä jo huomannut, sarake *price* on `tulosmuuttuja`, kun taas sarake *package* on `ennustemuuttuja`.\n",
|
|
"\n",
|
|
"Tätä varten jaamme ensin datan siten, että 80 % menee harjoitusjoukkoon ja 20 % testijoukkoon, määrittelemme reseptin, joka koodaa ennustemuuttujan sarakkeen kokonaislukujen joukkoon, ja rakennamme mallin spesifikaation. Emme valmistele ja paista reseptiämme, koska tiedämme jo, että se esikäsittelee datan odotetulla tavalla.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "Pq0bSzCevW-h"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"set.seed(2056)\n",
|
|
"# Split the data into training and test sets\n",
|
|
"pumpkins_split <- new_pumpkins %>% \n",
|
|
" initial_split(prop = 0.8)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Extract training and test data\n",
|
|
"pumpkins_train <- training(pumpkins_split)\n",
|
|
"pumpkins_test <- testing(pumpkins_split)\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"# Create a recipe for preprocessing the data\n",
|
|
"lm_pumpkins_recipe <- recipe(price ~ package, data = pumpkins_train) %>% \n",
|
|
" step_integer(all_predictors(), zero_based = TRUE)\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"# Create a linear model specification\n",
|
|
"lm_spec <- linear_reg() %>% \n",
|
|
" set_engine(\"lm\") %>% \n",
|
|
" set_mode(\"regression\")"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "CyoEh_wuvcLv"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Hyvää työtä! Nyt kun meillä on resepti ja mallin määrittely, meidän täytyy löytää tapa yhdistää ne yhdeksi objektiksi, joka ensin esikäsittelee datan (prep+bake kulissien takana), sovittaa mallin esikäsiteltyyn dataan ja mahdollistaa myös mahdolliset jälkikäsittelytoimet. Kuulostaa hyvältä, eikö vain!🤩\n",
|
|
"\n",
|
|
"Tidymodels-paketissa tämä kätevä objekti tunnetaan nimellä [`workflow`](https://workflows.tidymodels.org/), ja se pitää mallikomponenttisi kätevästi yhdessä! Tätä kutsuttaisiin *pipelines*-nimellä *Pythonissa*.\n",
|
|
"\n",
|
|
"Joten paketoidaan kaikki yhteen workflow-objektiin!📦\n"
|
|
],
|
|
"metadata": {
|
|
"id": "G3zF_3DqviFJ"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Hold modelling components in a workflow\n",
|
|
"lm_wf <- workflow() %>% \n",
|
|
" add_recipe(lm_pumpkins_recipe) %>% \n",
|
|
" add_model(lm_spec)\n",
|
|
"\n",
|
|
"# Print out the workflow\n",
|
|
"lm_wf"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "T3olroU3v-WX"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Kaupan päälle, työnkulku voidaan sovittaa/kouluttaa samalla tavalla kuin malli.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "zd1A5tgOwEPX"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Train the model\n",
|
|
"lm_wf_fit <- lm_wf %>% \n",
|
|
" fit(data = pumpkins_train)\n",
|
|
"\n",
|
|
"# Print the model coefficients learned \n",
|
|
"lm_wf_fit"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "NhJagFumwFHf"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Mallin tuloksista voimme nähdä koulutuksen aikana opitut kertoimet. Ne edustavat parhaiten sovitetun suoran kertoimia, joka antaa meille pienimmän kokonaisvirheen todellisen ja ennustetun muuttujan välillä.\n",
|
|
"\n",
|
|
"#### Mallin suorituskyvyn arviointi testijoukon avulla\n",
|
|
"\n",
|
|
"On aika nähdä, miten malli suoriutui 📏! Miten tämä tehdään?\n",
|
|
"\n",
|
|
"Nyt kun olemme kouluttaneet mallin, voimme käyttää sitä tekemään ennusteita testijoukolle `parsnip::predict()`-funktiolla. Sen jälkeen voimme verrata näitä ennusteita todellisiin arvoihin arvioidaksemme, kuinka hyvin (tai huonosti!) malli toimii.\n",
|
|
"\n",
|
|
"Aloitetaan tekemällä ennusteita testijoukolle ja liitetään sitten sarakkeet testijoukkoon.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "_4QkGtBTwItF"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Make predictions for the test set\n",
|
|
"predictions <- lm_wf_fit %>% \n",
|
|
" predict(new_data = pumpkins_test)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Bind predictions to the test set\n",
|
|
"lm_results <- pumpkins_test %>% \n",
|
|
" select(c(package, price)) %>% \n",
|
|
" bind_cols(predictions)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Print the first ten rows of the tibble\n",
|
|
"lm_results %>% \n",
|
|
" slice_head(n = 10)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "UFZzTG0gwTs9"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Kyllä, olet juuri kouluttanut mallin ja käyttänyt sitä ennusteiden tekemiseen!🔮 Onko se hyvä? Arvioidaan mallin suorituskykyä!\n",
|
|
"\n",
|
|
"Tidymodels-paketissa tämä tehdään `yardstick::metrics()`-funktiolla! Lineaarisessa regressiossa keskitytään seuraaviin mittareihin:\n",
|
|
"\n",
|
|
"- `Root Mean Square Error (RMSE)`: [MSE](https://en.wikipedia.org/wiki/Mean_squared_error)-arvon neliöjuuri. Tämä antaa absoluuttisen mittarin samassa yksikössä kuin kohde (tässä tapauksessa kurpitsan hinta). Mitä pienempi arvo, sitä parempi malli (yksinkertaistetusti tämä edustaa keskimääräistä hintaa, jolla ennusteet ovat väärässä!)\n",
|
|
"\n",
|
|
"- `Coefficient of Determination (yleisesti tunnettu nimellä R-squared tai R2)`: Suhteellinen mittari, jossa suurempi arvo tarkoittaa parempaa mallin sovitusta. Käytännössä tämä mittari kuvaa, kuinka paljon mallin ennusteiden ja todellisten kohdearvojen välinen vaihtelu pystytään selittämään.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "0A5MjzM7wW9M"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Evaluate performance of linear regression\n",
|
|
"metrics(data = lm_results,\n",
|
|
" truth = price,\n",
|
|
" estimate = .pred)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "reJ0UIhQwcEH"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Siinä meni mallin suorituskyky. Katsotaan, voimmeko saada paremman käsityksen visualisoimalla hajontakaavion paketin ja hinnan välillä ja käyttämällä ennusteita parhaan sovituslinjan piirtämiseen.\n",
|
|
"\n",
|
|
"Tämä tarkoittaa, että meidän täytyy valmistella ja käsitellä testijoukko koodataksemme pakettisarakkeen ja yhdistääksemme tämän mallimme tekemien ennusteiden kanssa.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "fdgjzjkBwfWt"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Encode package column\n",
|
|
"package_encode <- lm_pumpkins_recipe %>% \n",
|
|
" prep() %>% \n",
|
|
" bake(new_data = pumpkins_test) %>% \n",
|
|
" select(package)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Bind encoded package column to the results\n",
|
|
"lm_results <- lm_results %>% \n",
|
|
" bind_cols(package_encode %>% \n",
|
|
" rename(package_integer = package)) %>% \n",
|
|
" relocate(package_integer, .after = package)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Print new results data frame\n",
|
|
"lm_results %>% \n",
|
|
" slice_head(n = 5)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Make a scatter plot\n",
|
|
"lm_results %>% \n",
|
|
" ggplot(mapping = aes(x = package_integer, y = price)) +\n",
|
|
" geom_point(size = 1.6) +\n",
|
|
" # Overlay a line of best fit\n",
|
|
" geom_line(aes(y = .pred), color = \"orange\", size = 1.2) +\n",
|
|
" xlab(\"package\")\n",
|
|
" \n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "R0nw719lwkHE"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Hienoa! Kuten huomaat, lineaarinen regressiomalli ei kovin hyvin yleistä suhdetta paketin ja sen vastaavan hinnan välillä.\n",
|
|
"\n",
|
|
"🎃 Onnittelut, loit juuri mallin, joka voi auttaa ennustamaan muutamien kurpitsalajikkeiden hinnan. Kurpitsatilasi tulee olemaan upea tänä juhlapyhänä. Mutta luultavasti voit luoda vielä paremman mallin!\n",
|
|
"\n",
|
|
"## 5. Rakenna polynomiregressiomalli\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/linear-polynomial.png\"\n",
|
|
" width=\"800\"/>\n",
|
|
" <figcaption>Infografiikka: Dasani Madipalli</figcaption>\n",
|
|
"\n",
|
|
"\n",
|
|
"<!--{width=\"800\"}-->\n"
|
|
],
|
|
"metadata": {
|
|
"id": "HOCqJXLTwtWI"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Joskus datamme ei välttämättä noudata lineaarista suhdetta, mutta haluamme silti ennustaa lopputuloksen. Polynominen regressio voi auttaa meitä tekemään ennusteita monimutkaisemmille epälineaarisille suhteille.\n",
|
|
"\n",
|
|
"Otetaan esimerkiksi suhde paketin ja hinnan välillä kurpitsadatasarjassamme. Vaikka muuttujien välillä joskus on lineaarinen suhde - mitä suurempi kurpitsa tilavuudeltaan, sitä korkeampi hinta - näitä suhteita ei aina voida kuvata tasolla tai suoralla viivalla.\n",
|
|
"\n",
|
|
"> ✅ Tässä on [joitakin esimerkkejä](https://online.stat.psu.edu/stat501/lesson/9/9.8) datasta, joka voisi hyötyä polynomisesta regressiosta\n",
|
|
">\n",
|
|
"> Katsotaanpa uudelleen suhdetta lajikkeen ja hinnan välillä edellisessä kaaviossa. Vaikuttaako tämä hajontakaavio siltä, että sitä pitäisi välttämättä analysoida suoralla viivalla? Ehkä ei. Tässä tapauksessa voit kokeilla polynomista regressiota.\n",
|
|
">\n",
|
|
"> ✅ Polynomit ovat matemaattisia lausekkeita, jotka voivat koostua yhdestä tai useammasta muuttujasta ja kertoimesta\n",
|
|
"\n",
|
|
"#### Kouluta polynominen regressiomalli käyttämällä harjoitusjoukkoa\n",
|
|
"\n",
|
|
"Polynominen regressio luo *kaarevan viivan*, joka sopii paremmin epälineaariseen dataan.\n",
|
|
"\n",
|
|
"Katsotaan, suoriutuuko polynominen malli paremmin ennusteiden tekemisessä. Noudatamme melko samanlaista menettelyä kuin aiemmin:\n",
|
|
"\n",
|
|
"- Luo resepti, joka määrittää esikäsittelyvaiheet, jotka datalle tulee suorittaa, jotta se on valmis mallinnukseen, kuten: ennustajien koodaus ja polynomien laskeminen asteelle *n*\n",
|
|
"\n",
|
|
"- Rakenna mallin spesifikaatio\n",
|
|
"\n",
|
|
"- Yhdistä resepti ja mallin spesifikaatio työnkulkuun\n",
|
|
"\n",
|
|
"- Luo malli sovittamalla työnkulku\n",
|
|
"\n",
|
|
"- Arvioi, kuinka hyvin malli suoriutuu testidatalla\n",
|
|
"\n",
|
|
"Aloitetaan heti!\n"
|
|
],
|
|
"metadata": {
|
|
"id": "VcEIpRV9wzYr"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Specify a recipe\r\n",
|
|
"poly_pumpkins_recipe <-\r\n",
|
|
" recipe(price ~ package, data = pumpkins_train) %>%\r\n",
|
|
" step_integer(all_predictors(), zero_based = TRUE) %>% \r\n",
|
|
" step_poly(all_predictors(), degree = 4)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Create a model specification\r\n",
|
|
"poly_spec <- linear_reg() %>% \r\n",
|
|
" set_engine(\"lm\") %>% \r\n",
|
|
" set_mode(\"regression\")\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Bundle recipe and model spec into a workflow\r\n",
|
|
"poly_wf <- workflow() %>% \r\n",
|
|
" add_recipe(poly_pumpkins_recipe) %>% \r\n",
|
|
" add_model(poly_spec)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Create a model\r\n",
|
|
"poly_wf_fit <- poly_wf %>% \r\n",
|
|
" fit(data = pumpkins_train)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Print learned model coefficients\r\n",
|
|
"poly_wf_fit\r\n",
|
|
"\r\n",
|
|
" "
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "63n_YyRXw3CC"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"#### Arvioi mallin suorituskyky\n",
|
|
"\n",
|
|
"👏👏Olet rakentanut polynomimallin, tehdään ennusteita testijoukolla!\n"
|
|
],
|
|
"metadata": {
|
|
"id": "-LHZtztSxDP0"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Make price predictions on test data\r\n",
|
|
"poly_results <- poly_wf_fit %>% predict(new_data = pumpkins_test) %>% \r\n",
|
|
" bind_cols(pumpkins_test %>% select(c(package, price))) %>% \r\n",
|
|
" relocate(.pred, .after = last_col())\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Print the results\r\n",
|
|
"poly_results %>% \r\n",
|
|
" slice_head(n = 10)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "YUFpQ_dKxJGx"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Woo-hoo, arvioidaan kuinka malli suoriutui testijoukosta käyttämällä `yardstick::metrics()`.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "qxdyj86bxNGZ"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"metrics(data = poly_results, truth = price, estimate = .pred)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "8AW5ltkBxXDm"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"🤩🤩 Paljon parempi suorituskyky.\n",
|
|
"\n",
|
|
"`rmse` pieneni noin 7:stä noin 3:een, mikä osoittaa, että todellisen hinnan ja ennustetun hinnan välinen virhe on vähentynyt. Voit *vapaasti* tulkita tämän tarkoittavan, että keskimäärin väärät ennusteet ovat noin 3 dollaria pielessä. `rsq` nousi noin 0.4:stä 0.8:aan.\n",
|
|
"\n",
|
|
"Kaikki nämä mittarit osoittavat, että polynomimalli toimii huomattavasti paremmin kuin lineaarinen malli. Hyvää työtä!\n",
|
|
"\n",
|
|
"Katsotaanpa, voimmeko visualisoida tämän!\n"
|
|
],
|
|
"metadata": {
|
|
"id": "6gLHNZDwxYaS"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Bind encoded package column to the results\r\n",
|
|
"poly_results <- poly_results %>% \r\n",
|
|
" bind_cols(package_encode %>% \r\n",
|
|
" rename(package_integer = package)) %>% \r\n",
|
|
" relocate(package_integer, .after = package)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Print new results data frame\r\n",
|
|
"poly_results %>% \r\n",
|
|
" slice_head(n = 5)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Make a scatter plot\r\n",
|
|
"poly_results %>% \r\n",
|
|
" ggplot(mapping = aes(x = package_integer, y = price)) +\r\n",
|
|
" geom_point(size = 1.6) +\r\n",
|
|
" # Overlay a line of best fit\r\n",
|
|
" geom_line(aes(y = .pred), color = \"midnightblue\", size = 1.2) +\r\n",
|
|
" xlab(\"package\")\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "A83U16frxdF1"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Voit nähdä kaarevan viivan, joka sopii paremmin dataasi! 🤩\n",
|
|
"\n",
|
|
"Voit tehdä tästä vielä tasaisemman antamalla polynomikaavan `geom_smooth`-funktiolle näin:\n"
|
|
],
|
|
"metadata": {
|
|
"id": "4U-7aHOVxlGU"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Make a scatter plot\r\n",
|
|
"poly_results %>% \r\n",
|
|
" ggplot(mapping = aes(x = package_integer, y = price)) +\r\n",
|
|
" geom_point(size = 1.6) +\r\n",
|
|
" # Overlay a line of best fit\r\n",
|
|
" geom_smooth(method = lm, formula = y ~ poly(x, degree = 4), color = \"midnightblue\", size = 1.2, se = FALSE) +\r\n",
|
|
" xlab(\"package\")"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "5vzNT0Uexm-w"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Aivan kuin tasainen käyrä!🤩\n",
|
|
"\n",
|
|
"Näin voit tehdä uuden ennusteen:\n"
|
|
],
|
|
"metadata": {
|
|
"id": "v9u-wwyLxq4G"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Make a hypothetical data frame\r\n",
|
|
"hypo_tibble <- tibble(package = \"bushel baskets\")\r\n",
|
|
"\r\n",
|
|
"# Make predictions using linear model\r\n",
|
|
"lm_pred <- lm_wf_fit %>% predict(new_data = hypo_tibble)\r\n",
|
|
"\r\n",
|
|
"# Make predictions using polynomial model\r\n",
|
|
"poly_pred <- poly_wf_fit %>% predict(new_data = hypo_tibble)\r\n",
|
|
"\r\n",
|
|
"# Return predictions in a list\r\n",
|
|
"list(\"linear model prediction\" = lm_pred, \r\n",
|
|
" \"polynomial model prediction\" = poly_pred)\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "jRPSyfQGxuQv"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"`polynomial model` -ennuste vaikuttaa järkevältä, kun tarkastellaan `price` ja `package` hajontakaavioita! Ja jos tämä malli on parempi kuin edellinen, samoja tietoja tarkasteltaessa, sinun täytyy budjetoida näitä kalliimpia kurpitsoja varten!\n",
|
|
"\n",
|
|
"🏆 Hyvin tehty! Loit kaksi regressiomallia yhden oppitunnin aikana. Regressioon liittyvän viimeisen osion aikana opit logistisesta regressiosta kategorioiden määrittämiseksi.\n",
|
|
"\n",
|
|
"## **🚀Haaste**\n",
|
|
"\n",
|
|
"Testaa useita eri muuttujia tässä muistikirjassa ja katso, miten korrelaatio vaikuttaa mallin tarkkuuteen.\n",
|
|
"\n",
|
|
"## [**Oppitunnin jälkeinen kysely**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/14/)\n",
|
|
"\n",
|
|
"## **Kertaus & Itseopiskelu**\n",
|
|
"\n",
|
|
"Tässä oppitunnissa opimme lineaarisesta regressiosta. On olemassa myös muita tärkeitä regressiotyyppejä. Lue Stepwise-, Ridge-, Lasso- ja Elasticnet-tekniikoista. Hyvä kurssi lisäopiskeluun on [Stanford Statistical Learning -kurssi](https://online.stanford.edu/courses/sohs-ystatslearning-statistical-learning).\n",
|
|
"\n",
|
|
"Jos haluat oppia lisää siitä, miten käyttää upeaa Tidymodels-kehystä, tutustu seuraaviin resursseihin:\n",
|
|
"\n",
|
|
"- Tidymodels-verkkosivusto: [Aloita Tidymodelsilla](https://www.tidymodels.org/start/)\n",
|
|
"\n",
|
|
"- Max Kuhn ja Julia Silge, [*Tidy Modeling with R*](https://www.tmwr.org/)*.*\n",
|
|
"\n",
|
|
"###### **KIITOS:**\n",
|
|
"\n",
|
|
"[Allison Horst](https://twitter.com/allison_horst?lang=en) upeiden kuvitusten luomisesta, jotka tekevät R:stä kutsuvamman ja kiinnostavamman. Löydät lisää kuvituksia hänen [galleriastaan](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n"
|
|
],
|
|
"metadata": {
|
|
"id": "8zOLOWqMxzk5"
|
|
}
|
|
},
|
|
{
|
|
"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ä tulisi pitää ensisijaisena lähteenä. Kriittisen tiedon osalta suositellaan ammattimaista ihmiskäännöstä. Emme ole vastuussa väärinkäsityksistä tai virhetulkinnoista, jotka johtuvat tämän käännöksen käytöstä.\n"
|
|
]
|
|
}
|
|
]
|
|
} |