{ "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" } }, "cells": [ { "cell_type": "markdown", "source": [ "# សាងសង់ម៉ូដែលរេហ្គ្រេស្សិន: ម៉ូដែលរេហ្គ្រេស្សិនតូចតាង និងម៉ូដែលរេហ្គ្រេស្សិនពហុធារៈ\n" ], "metadata": { "id": "EgQw8osnsUV-" } }, { "cell_type": "markdown", "source": [ "## ការសម្គាល់ជាអាក្សរសម្រាប់តម្លៃដល់ក្រហមផ្កាពោធិ៍ - មេរៀនទី 3\n", "

\n", " \n", "

រូបភាពព័ត៌មានដោយ Dasani Madipalli
\n", "\n", "\n", "\n", "\n", "#### ការណែនាំ\n", "\n", "ផ្តើមពីនេះ អ្នកបានស្រាវជ្រាវចំពោះអ្វីដែល regression គឺជាមួយទិន្នន័យគំរូយកមកពីឃ្លាំងតម្លៃក្រហមផ្កាពោធិ៍ ដែលយើងនឹងប្រើក្នុងមេរៀននេះ។ អ្នកក៏បានបង្ហាញវាដោយប្រើ `ggplot2`។💪\n", "\n", "ឥឡូវនេះ អ្នកបានត្រៀមខ្លួនរួចដើម្បីចូលទៅជ្រាបជ្រៅចំពោះ regression សម្រាប់ ML។ ក្នុងមេរៀននេះ អ្នកនឹងរៀនបន្ថែមអំពីប្រភេទ regression ស្រាលពី *linear regression* និង *polynomial regression*, ជាមួយនឹងគណិតវិទ្យាអ្នកក៏នឹងស្គាល់យ៉ាងខ្លី។\n", "\n", "> ក្នុងវគ្គសិក្សានេះ យើងសន្មត់ថាយើងមានចំណេះដឹងគណិតវិទ្យាអប្បបរមា ហើយព្យាយាមធ្វើអោយវា​មានភាពងាយស្រួលសម្រាប់សិស្សដែលមកពីដែនកំណត់ផ្សេងទៀត ដូច្នេះសូមចំណាំកំណត់ចំណាំ, 🧮 ការផ្តល់ព្រមាន, រូបភាព, និងឧបករណ៍សិក្សាផ្សេងៗ ដើម្បីជួយឱ្យយល់ច្បាស់។\n", "\n", "#### ការរៀបចំ\n", "\n", "ជាថ្លែងអនុញ្ញាត អ្នកកំពុងផ្ទុកទិន្នន័យនេះ ដើម្បីសួរប្រធានបទចំពោះវា។\n", "\n", "- តើពេលណាល្អបំផុតសម្រាប់ទិញក្រហមផ្កាពោធិ៍?\n", "\n", "- តម្លៃដែលខ្ញុំអាចរំពឹងទុកពីប្រអប់ក្រហមផ្កាពោធិ៍តូចៗជាម្ចាស់បៀបែបមួយ?\n", "\n", "- តើខ្ញុំគួរទិញវាទៅក្នុងធុងផ្លាស្ទិចកូបមួយចង្កោម ឬក្នុងប្រអប់ 1 1/9 bushel មួយ? មកពិនិត្យបន្តជ្រាបទិន្នន័យនេះចុះ។\n", "\n", "ក្នុងមេរៀនមុន អ្នកបានបង្កើត `tibble` (ដែលជារូបភាពបែបទំនើបនៃ data frame) ហើយបញ្ចូលវាដោយចំនួនមួយនៃទិន្នន័យដើម ដើម្បីគុណនឹងតម្លៃតាម bushel។ តែដោយរបៀបនេះ អ្នកអាចប្រមូលបានតែប្រហែល៤០០ចំណុចទិន្នន័យ ហើយសម្រាប់ខែរដូវស្លឹកឈើជ្រុះប៉ុណ្ណោះ។ ប្រហែលហើយយើងអាចទទួលបានព័ត៌មានលម្អិតបន្ថែមពីសភាពទិន្នន័យ ដោយសំអាតវាបន្ថែមទៀតទេ? យើងនឹងមើល... 🕵️‍♀️\n", "\n", "សម្រាប់ការងារនេះ យើងត្រូវការតំឡើងកម្មវិធីដូចខាងក្រោម៖\n", "\n", "- `tidyverse`: [tidyverse](https://www.tidyverse.org/) គឺជាកញ្ចប់កម្មវិធី R មួយដែលរួមបញ្ចូលជាច្រើនទៅក្នុងវិស័យវិទ្យាស្ថានទិន្នន័យ ដើម្បីធ្វើឲ្យការងារជាមួយទិន្នន័យកាន់តែលឿន, ងាយស្រួល និងរីករាយ!\n", "\n", "- `tidymodels`: ស៊ុម [tidymodels](https://www.tidymodels.org/) គឺជាកញ្ចប់ package សម្រាប់បង្កើតគំរូ និងការសិក្សាម៉ាស៊ីនលើការដឹកនាំ។\n", "\n", "- `janitor`: កញ្ចប់ [janitor](https://github.com/sfirke/janitor) ផ្ដល់ឧបករណ៍តូចៗសម្រាប់ពិនិត្យ និងសំអាតទិន្នន័យមិនស្អាត។\n", "\n", "- `corrplot`: កញ្ចប់ [corrplot](https://cran.r-project.org/web/packages/corrplot/vignettes/corrplot-intro.html) ផ្ដល់ឧបករណ៍មើលទិដ្ឋភាពនៃគំនូស correlation matrix ដែលគាំទ្រការផ្លាស់ប្តូរជួរឈរពណ៌ដោយស្វ័យប្រវត្តិ ដើម្បីជួយរកគំរូលាក់នៅចន្លោះអថេរ។\n", "\n", "អ្នកអាចតំឡើងវាជា:\n", "\n", "`install.packages(c(\"tidyverse\", \"tidymodels\", \"janitor\", \"corrplot\"))`\n", "\n", "ស្គ្រីបខាងក្រោមពិនិត្យថាតើអ្នកមាន package ត្រូវការដើម្បីបញ្ចប់ម៉ូឌុលនេះ ឬអត់ ហើយនឹងតំឡើងវាដើម្បីអ្នកបើវាខ្វះ។\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": [ "យើងនឹងបញ្ចូលកញ្ចប់ដ៏អស្ចារ្យទាំងនេះនៅពេលក្រោយ ហើយធ្វើអោយវាមានប្រើប្រាស់បានក្នុងសម័យ R បច្ចុប្បន្នរបស់យើង។ (នេះគឺសម្រាប់ការបង្ហាញតែមួយ `pacman::p_load()` បានធ្វើរួចហើយសម្រាប់អ្នក)\n", "\n", "## 1. របារចំណោមអាស៊ីតលីនេអ៊ែរ\n", "\n", "ដូចដែលអ្នកបានរៀននៅថ្នាក់មួយ គោលដៅនៃការប្រតិបត្តិរដ្ឋលីនេអ៊ែរ គឺដើម្បីឲ្យអាចគូរបាន *បន្ទាត់* *សម្រិតល្អបំផុត* ដើម្បី៖\n", "\n", "- **បង្ហាញទំនាក់ទំនងអថេរ**។ បង្ហាញទំនាក់ទំនងរវាងអថេរ\n", "\n", "- **ធ្វើការព្យាករណ៍**។ ធ្វើការព្យាករណ៍បានត្រឹមត្រូវពីនៅទីតាំងដែលទិន្នន័យថ្មីនឹងធ្លាក់នៅទំនាក់ទំនងទៅនឹងបន្ទាត់នោះ។\n", "\n", "ដើម្បីគូរប្រភេទបន្ទាត់នេះ យើងប្រើបច្ចេកទេសស្ថិតិដែលហៅថា **Least-Squares Regression**។ ពាក្យ `least-squares` មានន័យថាទិន្នន័យគ្រប់ចំនុចជុំវិញបន្ទាត់វាយតម្លៃត្រូវបានធ្វើការយករាងការ (square) ហើយបន្ថែមគ្នា។ យ៉ាងល្អបំផុត សរុបចុងក្រោយត្រូវតែលើកតិចបំផុត ព្រោះយើងចង់បានចំនួនកំហុសទាប ឬ `least-squares`។ ដូច្នេះ បន្ទាត់សម្រិតល្អបំផុតគឺជាបន្ទាត់ដែលផ្តល់តម្លៃទាបបំផុតសម្រាប់សរុបកំហុសរាងការ - ដូច្នេះឈ្មោះ *least squares regression* ។\n", "\n", "យើងធ្វើដូច្នេះ ព្រោះយើងចង់ម៉ូដែលបន្ទាត់ដែលមានចម្ងាយសរុបតិចបំផុតពីទិន្នន័យគ្រប់ចំនុចរបស់យើង។ យើងក៏ដាក់គូររាងការដើម្បីជម្រះចំនួនវិសាលភាពជាមូលដ្ឋានជាងទិសដៅ។\n", "\n", "> **🧮 បង្ហាញខ្ញុំគណនាគណិតវិទ្យា**\n", ">\n", "> បន្ទាត់នេះ ហៅថា *បន្ទាត់សម្រិតល្អបំផុត* អាចត្រូវបញ្ជាក់តាមរយៈ [សមីការ](https://en.wikipedia.org/wiki/Simple_linear_regression):\n", ">\n", "> Y = a + bX\n", ">\n", "> `X` គឺជា '`អថេរពន្យល់` ឬ `អ្នកព្យាករណ៍`'។ `Y` គឺជា '`អថេរពឹងផ្អែក` ឬ `លទ្ធផល`'។ រលកបន្ទាត់គឺជា `b` ហើយ `a` ជាចំណុចឈរ y-intercept ដែលមានន័យថាតម្លៃ `Y` នៅពេល `X = 0`។\n", ">\n", "\n", "> ![](../../../../../../2-Regression/3-Linear/solution/images/slope.png \"slope = $y/x$\")\n", " រូបភាពដោយ Jen Looper\n", ">\n", "> ចាប់ផ្តើម គណនា​រលក `b`។\n", ">\n", "> ផ្ទេរជាពាក្យផ្សេង ហើយយោងទៅកាន់សំនួរដើមពីទិន្នន័យផំពងរបស់យើង៖ \"ព្យាករណ៍តម្លៃផំពងក្នុងមួយប៊ូសែលតាមខែ\" `X` គឺតំណាងឲ្យតម្លៃ ក៏ដូចជា `Y` គឺតំណាងឲ្យខែមួយដែលបានលក់។\n", ">\n", "> ![](../../../../../../translated_images/km/calculation.989aa7822020d9d0.webp)\n", " រូបភាពដោយ Jen Looper\n", "> \n", "> គណនាតម្លៃ Y។ ប្រសិនបើអ្នកបង់ប្រហែល \\$4 នោះត្រូវតែលើខែមេសា!\n", ">\n", "> គណនាគណិតដែលគិតពីបន្ទាត់ ត្រូវបង្ហាញពីរលករបស់បន្ទាត់ ដែលក៏ពឹងផ្អែកទៅលើចំណុចឈរ ឬនៅទីតាំងដែល `Y` ស្ថិតនៅពេល `X = 0`។\n", ">\n", "> អ្នកអាចមើលមេធដ្ឋិការគណនាសម្រាប់តម្លៃទាំងនេះនៅគេហទំព័រ [Math is Fun](https://www.mathsisfun.com/data/least-squares-regression.html)។ ក៏សូមចូលទៅកាន់ [เครื่องคิดเลข Least-squares](https://www.mathsisfun.com/data/least-squares-calculator.html) ដើម្បីមើលថាតម្លៃលេខបានឥទ្ធិពលដូចម្តេចចំពោះបន្ទាត់។\n", "\n", "មិនរំខានប៉ុនណា ទេ មែនទេ? 🤓\n", "\n", "#### សមួង\n", "\n", "ពាក្យមួយទៀតដែលត្រូវយល់គឺ **សមួងរាងការ** រវាងអថេរ X និង Y ខណ្ឌមួយ។ ប្រើការគូរប្រភេទ scatterplot អ្នកអាចមើលឃើញសមួងនេះបានយ៉ាងឆាប់រហ័ស។ ការគូរដែលមានចំណុចចោលជួរដែលស្អាតមានសមួងខ្ពស់ ប៉ុន្តែការគូរដែលមានចំណុចចោលគ្រប់ទីតាំងរវាង X និង Y មានសមួងទាប។\n", "\n", "ម៉ូដែលរាងការលីនេអ៊ែរ ដែលល្អ គឺម៉ូដែលដែលមានសមួងខ្ពស់ (ជិត 1 ជាង 0) ប្រើវិធី Least-Squares Regression ជាមួយបន្ទាត់វាយតម្លៃ។\n" ], "metadata": { "id": "cdX5FRpvsoP5" } }, { "cell_type": "markdown", "source": [ "## **2. រាំជាមួយទិន្នន័យ៖ ការបង្កើតស៊ុមទិន្នន័យដែលនឹងត្រូវប្រើសម្រាប់សំណុំម៉ូដែល** \n", "\n", "

\n", " \n", "

សិល្បៈដោយ @allison_horst
\n", "\n", "\n", "\n" ], "metadata": { "id": "WdUKXk7Bs8-V" } }, { "cell_type": "markdown", "source": [ "Load up required libraries and dataset. Convert the data to a data frame containing a subset of the data:\n", "\n", "- ទទួលបានតែលោកគ្រូដែលមានតម្លៃតាមប៊ស្សែលប៉ុណ្ណោះ\n", "\n", "- បម្លែងកាលបរិច្ឆេទទៅជាខែ\n", "\n", "- គណនាតម្លៃឱ្យជា​មធ្យម​​រវាងតម្លៃខ្ពស់ និង តម្លៃទាប\n", "\n", "- បម្លែងតម្លៃឱ្យតំណាងលេខរាយតាមប៊ស្សែល\n", "\n", "> យើងបានគ្របដណ្តប់ចំណុចទាំងនេះក្នុង [មេរៀនមុន](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": [ "ក្នុងទឹកចិត្តនៃការផ្សងព្រេងអស់សោះ យើងមកស្វែងយល់អំពី [`janitor package`](../../../../../../2-Regression/3-Linear/solution/R/github.com/sfirke/janitor) ដែលផ្តល់នូវមុខងារងាយស្រួលសម្រាប់ពិនិត្យនិងសំអាតទិន្នន័យខូច។ ឧទាហរណ៍ យើងមកមើលឈ្មោះជួរឈររបស់ទិន្នន័យរបស់យើង៖\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": [ "🤔 យើងអាចធ្វើបានល្អជាងនេះ។ យើងមកបំលែងឈ្មោះជួរឈរទាំងនេះជារៀង `friendR` ដោយបម្លែងពួកវាទៅជារបៀប [snake_case](https://en.wikipedia.org/wiki/Snake_case) ដោយប្រើ `janitor::clean_names`។ ដើម្បីស្វែងយល់បន្ថែមអំពីមុខងារនេះ៖ `?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": [ "ស្អាតជាងមុនទៀត 🧹! ឥឡូវនេះ រាំជាមួយទិន្នន័យប្រើ `dplyr` ដូចក្នុងមេរៀនមុន! 💃\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": [ "ដោយការងារល្អ!👌 ឥឡូវនេះអ្នកមានចំណូលដើមទិន្នន័យស្អាត និងទៀងទាត់ ដែលអ្នកអាចប្រើសម្រាប់កសាងគំរូបន្ទាប់បន្សំថ្មីរបស់អ្នក!\n", "\n", "ចង់មានតារាងប៉ះមើលទេ?\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": [ "គំនូស​ព្រីន​កណ្តុរនេះ​រំលឹក​យើង​ថា​យើង​មាន​ទិន្នន័យ​ខែមួយ​តែមួយ​ចាប់ពីខែកញ្ញា​តទៅដល់ខែធ្នូ។ យើងប្រហែលជាត្រូវការទិន្នន័យបន្ថែមដើម្បីអាចរៀបចំសេចក្តីសន្និដ្ឋានដោយរបៀបបន្ទាត់។\n", "\n", "យើងចាំមើលទិន្នន័យម៉ូដែលរបស់យើងម្ដងទៀត៖\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": [ "តើតើយើងចង់ទាយតម្លៃ `price` នៃផ្លែដូងសៀងដោយផ្អែកលើជួរឈរ `city` ឬ `package` ដែលជា​ប្រភេទ​តួអក្សរ ឬ? ឬថែមទាំងភាសាទេទៀត យើងអាចស្វែងរកការតភ្ជាប់គ្នា (correlation) ដែលតម្រូវឱ្យទាំងពីរបញ្ចូលមានជាតិនិរន្តរភាព (numeric) រួច ដូចជា `package` និង `price` បានយ៉ាងដូចម្តេច? 🤷🤷\n", "\n", "ម៉ាស៊ីនរៀន (Machine learning models) ប្រើប្រាស់ល្អជាមួយលក្ខណៈជាតិនិរន្តរជាងតំម្លៃអត្ថបទដូច្នេះអ្នកត្រូវការបម្លែងលក្ខណៈអក្សរជាលក្ខណៈជាតិនិរន្តជាទូទៅ។\n", "\n", "នេះមានន័យថា យើងត្រូវស្វែងរកវិធីកែទ្រង់ទ្រាយអ្នកប៉ាន់ប្រមាណ (predictors) ដើម្បីឲ្យវាងាយស្រួលសម្រាប់ម៉ូដែលប្រើប្រាស់យ៉ាងមានប្រសិទ្ធភាព កាលវិភាគនេះហៅថា `feature engineering`។\n" ], "metadata": { "id": "7hsHoxsStyjJ" } }, { "cell_type": "markdown", "source": [ "## 3. ការកំណ preprocess ទិន្នន័យសម្រាប់ម៉ូដែលជាមួយ recipes 👩‍🍳👨‍🍳\n", "\n", "សកម្មភាពដែលបំលែងតម្លៃ predictor ដើម្បីធ្វើឱ្យវាងាយស្រួលសម្រាប់ម៉ូដែលប្រើប្រាស់ប្រសើរជាងមុន ត្រូវបានហៅថា `feature engineering`។\n", "\n", "ម៉ូដែលផ្សេងៗមានតម្រូវការកំណ preprocess ផ្សេងគ្នា។ ឧទាហរណ៍ least squares តម្រូវឱ្យមាន `encoding categorical variables` ដូចជា month, variety និង city_name។ វាទំនងស្មើនឹង `បកប្រែលេខមួយជួរឈរដែលមានតម្លៃកាតេហ្គរិ` ទៅជាជួរឈរលេខមួយឬច្រើន ដែលជំនួសកន្លែងដែលមានមូលដ្ឋាន ។\n", "\n", "ឧទាហរណ៍៖ សូមសន្មត់ថាទិន្នន័យរបស់អ្នកមានលក្ខណៈកាតេហ្គរិដូចខាងក្រោម៖\n", "\n", "| city |\n", "|:-------:|\n", "| Denver |\n", "| Nairobi |\n", "| Tokyo |\n", "\n", "អ្នកអាចអនុវត្ត *ordinal encoding* ដើម្បីជំនួសតម្លៃពេញលេញមួយសម្រាប់គ្រប់ប្រភេទ ដូចជា៖\n", "\n", "| city |\n", "|:----:|\n", "| 0 |\n", "| 1 |\n", "| 2 |\n", "\n", "ហើយនេះជាការដែលយើងនឹងធ្វើចំពោះទិន្នន័យរបស់យើង!\n", "\n", "នៅក្នុងផ្នែកនេះ យើងនឹងស្វែងយល់ពីកញ្ចប់ Tidymodels ជាមួយមួយទៀតដែលអស្ចារ្យ: [recipes](https://tidymodels.github.io/recipes/) - ដែលរចនាឡើងដើម្បីជួយអ្នក preprocess ទិន្នន័យរបស់អ្នក **មុន** ការបណ្តុះបណ្តាលម៉ូដែល។ នៅផ្នែកមូលដ្ឋានម្ដងទៀត ព្រោងគឺជាវត្ថុដែលកំណត់ថាតើជំហានណាដែលគួរត្រូវអនុវត្តទៅលើកំណត់ទិន្នន័យមួយ ដើម្បីធ្វើឱ្យវាស្រេចសម្រាប់ម៉ូដែល។\n", "\n", "ឥឡូវនេះ សូមបង្កើតព្រោងមួយដែលត្រៀមទិន្នន័យរបស់យើងសម្រាប់ម៉ូដែលដោយជំនួសលេខពេញលេញមួយសម្រាប់ការសង្កេតទាំងអស់ក្នុងជួរឈរព្យាករណ៍៖\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": [ "អស្ចារ្យណាស់! 👏 យើងទើបតែបង្កើតរូបមន្តដំបូងរបស់យើងដែលកំណត់លទ្ធផលមួយ (តម្លៃ) និងអ្នកចាប់ផ្តើមដែលទាក់ទង និងថាតើជួរឈរអ្នកចាប់ផ្តើមគ្រប់គ្រងគួរតែត្រូវបានបកប្រែទៅជាសំណុំលេខអាំងតេហ្សេរ 🙌! យើងមកបំបែកវាដោយរហ័ស៖\n", "\n", "- ការហៅទៅ `recipe()` ជាមួយរូបមន្តមួយប្រាប់រូបមន្តពី *តួនាទី* នៃអថេរដោយប្រើទិន្នន័យ `new_pumpkins` ជា​ជំនួយ។ ឧទាហរណ៍ជួរឈរ `price` ត្រូវបានផ្ដល់តួនាទី `outcome` ខណៈដែលជួរឈរផ្សេងទៀតត្រូវបានផ្ដល់តួនាទីជា `predictor`។\n", "\n", "- `step_integer(all_predictors(), zero_based = TRUE)` បញ្ជាក់ថាអ្នកចាប់ផ្តើមទាំងអស់គួរត្រូវបានបម្លែងទៅជាសំណុំលេខអាំងតេហ្សេរដោយលេខរាប់ចាប់ផ្តើមពី 0 ។\n", "\n", "យើងប្រាកដថាអ្នកប្រហែលជាកំពុងមានគំនិតយ៉ាងដូចជា៖ \"នេះគួរឲ្យចាប់អារម្មណ៍ណាស់!! តែកើតអ្វីមួយប្រសិនបើខ្ញុំចង់បញ្ជាក់ថារូបមន្តកំពុងធ្វើអ្វីដែលខ្ញុំរង់ចាំមែនទេ? 🤔\"\n", "\n", "នោះជាគំនិតដ៏អស្ចារ្យ! អ្នកឃើញទេ ថា ពេលដែលរូបមន្តរបស់អ្នកត្រូវបានកំណត់ អ្នកអាចប៉ាន់ប្រមាណប៉ារ៉ាម៉ែត្រ ដែលចាំបាច់សម្រាប់ធ្វើ​ដេតា​ការដំណើរការពិតប្រាកដ ហើយបន្ទាប់មកទាញយកទិន្នន័យដូចបានដំណើរការ។ អ្នកប្រៀបធៀបមិនចាំបាច់ធ្វើបែបនេះជាទូទៅនៅពេលប្រើ Tidymodels (យើងនឹងឃើញប្រព័ន្ធធម្មតាក្នុងរយៈពេលហើយនេះ- > `workflows`) ប៉ុន្តែវាអាចមានប្រយោជន៍នៅពេលអ្នកចង់ធ្វើតម្លើងការត្រួតពិនិត្យមួយ ដើម្បីបញ្ជាក់ថារូបមន្តកំពុងធ្វើអ្វីដែលអ្នករំពឹងទុក។\n", "\n", "សម្រាប់នេះ អ្នកត្រូវការពាក្យកិច្ចការ២​ជាងនេះទៀតគឺ៖ `prep()` និង `bake()` ហើយដូចជាគ្រប់ពេល ពួកមិត្តភក្តិ R ដូចជា [`Allison Horst`](https://github.com/allisonhorst/stats-illustrations) ជួយអ្នកយល់ដឹងល្អប្រសើរជាងនេះ!\n", "\n", "

\n", " \n", "

ស្នាដៃគំនូរដោយ @allison_horst
\n" ], "metadata": { "id": "KEiO0v7kuC9O" } }, { "cell_type": "markdown", "source": [ "[`prep()`](https://recipes.tidymodels.org/reference/prep.html): គណនាពីរបៀបដែលត្រូវការពីសំណុំព្យួរបង្ហាត់ដែលអាចត្រូវអនុវត្តទៅលើសំណុំទិន្នន័យផ្សេងទៀតបាន។ ឧទាហរណ៍ សម្រាប់ជួរឈរព្យួរដែលបានផ្ដល់ អ្វីទៅជាការបែងចែកឲ្យលំដាប់គត់ 0 ឬ 1 ឬ 2 ល។\n", "\n", "[`bake()`](https://recipes.tidymodels.org/reference/bake.html): យករឿងដែលបាន​បានធ្វើការ prep ហើយអនុវត្តន៍បច្ចេកទេសទៅលើសំណុំទិន្នន័យណាមួយ។\n", "\n", "និយាយទៅហើយ ចង់ឲ្យ prep និង bake រូបមន្តរបស់យើង ដើម្បីបញ្ជាក់ថា ក្រោមមួក ខ្សែព្យួរនឹងត្រូវបានកូដមុនពេលម៉ូដែលត្រូវបានហ្វិត។\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!🥳 ទិន្នន័យដែលបានដំណើរការ `baked_pumpkins` មានអ្នកព្យាករណ៍ទាំងអស់របស់វាត្រូវបានកូដសំរាប់បញ្ជាក់ថាការប្រមូលព័ត៌មានបឋមដែលបានកំណត់ជារេស៊ីពីរបស់យើង នឹងដំណើរការតាមការរំពឹង។ នេះធ្វើឱ្យវាពិបាកសម្រាប់អ្នកក្នុងការអាន ប៉ុន្តែមានភាពយល់ច្បាស់សម្រាប់ Tidymodels! សូមចំណាយពេលមួយដើម្បីរកមើលថាតើព្រឹត្តិការណ៍ណាមួយត្រូវបានផ្គូផ្គងទៅឱ្យអាំងតេជ័រដែលសមរម្យ។\n", "\n", "វាក៏គួរឲ្យរៀបរាប់ថា `baked_pumpkins` គឺជា data frame ដែលយើងអាចធ្វើកំណត់ត្រាពីលើវាបាន។\n", "\n", "ឧទាហរណ៍ សូមព្យាយាមរកកសម្លេងល្អរវាងចំណុចពីរនៃទិន្នន័យរបស់អ្នក ដើម្បីបង្កើតគំរូព្យាករណ៍ល្អមួយ។ យើងនឹងប្រើមុខងារ `cor()` ដើម្បីធ្វើការនេះ។ វាយ `?cor()` ដើម្បីស្វែងយល់បន្ថែមអំពីមុខងារ។\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": [ "ដូចដែលបង្ហាញថា មានតែការទាក់ទងខ្សោយរវាងទីក្រុងនិងតម្លៃប៉ុណ្ណោះ។ ទោះជាយ៉ាងណា មានការទាក់ទងល្អជាងបន្តិចរវាងកញ្ចប់និងតម្លៃរបស់វា។ វាមានហេតុផល មែនទេ? ទូទៅ ប្រអប់ផលិតផល越ធំ តម្លៃ越ខ្ពស់។ \n", "\n", "ខណៈពេលដែលយើងនៅទីនេះ សូមព្យាយាមបង្ហាញម៉ាទ្រិចទាក់ទងរវាងជួរឈរទាំងអស់ដោយប្រើកញ្ចប់ `corrplot` ផង។\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": [ "🤩🤩 ល្អជាងមុន។\n", "\n", "សំណួរល្អមួយដែលគួរតែសួរឥឡូវនេះនៃទិន្នន័យនេះគឺ៖ '`តើតម្លៃណាដែលខ្ញុំអាចរំពឹងទុកពីកញ្ចប់បន្ទះពន្លឺមួយដែលបានផ្ដល់?`' តោះចូលទៅរកវា!\n", "\n", "> Note: កាលណាអ្នក **`bake()`** ឆ្មាំ​បានរៀបចំរួចហើយ **`pumpkins_prep`** ជាមួយ **`new_data = NULL`**, អ្នកនឹងទាញយកទិន្នន័យហ្វឹកហាត់ដែលបានដំណើរការ (ឧ. បានកែឡើង)។ ប្រសិនបើអ្នកមានឈុតទិន្នន័យផ្សេងទៀតដូចជាឈុតសាកល្បង ហើយចង់មើលថាតើពន្លឺចំណីអ្វីដែលនឹងដំណើរការ វាអ្នកគ្រាន់តែប៊ិកឆ្មាំ **`pumpkins_prep`** ជាមួយ **`new_data = test_set`**\n", "\n", "## ៤. បង្កើតគំរូរ Regression ប្រភេទ Linear\n", "\n", "

\n", " \n", "

រូបភាពព័ត៌មានដោយ Dasani Madipalli
\n", "\n", "\n", "\n" ], "metadata": { "id": "YqXjLuWavNxW" } }, { "cell_type": "markdown", "source": [ "ឥឡូវនេះដែលយើងបានបង្កើតរូបមន្ដមួយ ហើយពិតជាសម្រេចថាប្រាក់ចំណូលនឹងត្រូវបានដំណើរការមុនយ៉ាងត្រឹមត្រូវ តោះ ឥឡូវសូមបង្កើតម៉ូដែលឌីហ្សិនសមីការជាស្តង់ដារមួយ ដើម្បីឆ្លើយសំណួរ៖ `តម្លៃអ្វីដែលខ្ញុំអាចរំពឹងទុកបានសម្រាប់កញ្ចប់ក្រូចឆ្មារពិសេសមួយ?`\n", "\n", "#### បណ្តុះម៉ូដែលឌីហ្សិនសមីការជាស្តង់ដារមួយ ដោយប្រើតំណាងបណ្តុះបណ្តាល\n", "\n", "ដូចដែលអ្នកប្រហែលជាបានសំគាល់ហើយ ថា ជួរឈរ *price* គឺជាផលប៉ះពាល់ `outcome` ខណៈដែលជួរឈរ *package* គឺជាផលប៉ះពាល់ `predictor` ។\n", "\n", "ដើម្បីធ្វើបែបនេះ យើងនឹងបំបែកទិន្នន័យជាមុនជាផ្នែកដែល 80% សម្រាប់បណ្តុះបណ្តាល និង 20% សម្រាប់សាកល្បង បន្ទាប់មកកំណត់រូបមន្ដមួយដែលនឹងកូដជួរឈរ predictor ទៅជាសំណុំនៃលេខលេខរៀង បន្ទាប់មកបង្កើតកំណត់សេចក្ដីបញ្ជាក់ម៉ូដែលមួយ។ យើងមិននឹងត្រៀម និងចម្អិនរូបមន្តរបស់យើង ដោយសារយើងបានដឹងហើយថាវានឹងដំណើរការនូវទិន្នន័យជាមុនដូចដែលបានរំពឹង។\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": [ "ការ​ធ្វើ​ការ​ល្អ​ណាស់! ឥឡូវនេះ​ក្នុង​ពេល​យើង​មាន​រូបមន្ត​និង​លក្ខណៈអ្នក​តំណាង​ម៉ូដែល មួយ​យើង​ត្រូវ​ការ​រក​វិធី​សាស្រ្ត​សម្រាប់​ធ្វើឱ្យ​ពួកវា​ជា​វត្ថុ​ដូច​ជា​វត្ថុ​មួយ​ដែល​នឹង​ធ្វើការ​ដំណើរការ​ទិន្នន័យជាមុន (prep+bake នៅ​ព្រំ​ផ្ទៃ) បង្ហាត់ម៉ូដែលលើ​ទិន្នន័យ​ដែលបាន​ដំណើរការ​មុន និង​អនុញ្ញាតឱ្យ​មានសកម្មភាព​បន្ទាប់​បង្ហោះ​មួយចំនួន។ តើ​នេះ​ជាសម្រាប់​ចិត្ត​សុខខណៈរបស់​អ្នក​បានដែរទេ!🤩\n", "\n", "ក្នុង Tidymodels វត្ថុ​សម្រួលនេះត្រូវ​ហៅថា [`workflow`](https://workflows.tidymodels.org/) ហើយ​រក្សាទុក​គ្រឿងផ្សំនៃ​ម៉ូដែល​របស់​អ្នក​យ៉ាង​ងាយស្រួល! នេះ​គឺជា​អ្វី​ដែល​យើង​នឹងហៅថា *pipelines* នៅ​ក្នុង *Python*។\n", "\n", "ដូច្នេះ​ទៅ បញ្ចូល​ទៅក្នុង workflow ទាំងអស់​គ្នា!📦\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": [ "👌 លើសពីនេះទៅទៀត ការងារដំណាក់កាលអាចត្រូវបានសមស្រប/បង្ហាត់ក្នុងវិធីដូចគ្នានឹងម៉ូឌែលមួយអាចធ្វើបាន។\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": [ "ពីលទ្ធផលនៃម៉ូដែល យើងអាចមើលឃើញមេគុណដែលបានរៀននៅពេលបណ្តុះបណ្តាល។ វាតំណាងឱ្យមេគុណនៃបន្ទាត់ផ្គូរផ្គងល្អបំផុត ដែលផ្តល់ឱ្យយើងនូវកំហុសសរុបទាបបំផុតរវាងអថេរពិតនិងអថេរដែលបានទាយ។\n", "\n", "\n", "#### ប៉ាន់ប្រមាណសមត្ថភាពម៉ូដែលដោយប្រើសំណុំតេស្ត\n", "\n", "ពេលវេលាជំរុញឲ្យយើងមើលថាម៉ូដែលបានអនុវត្តដូចម្តេច 📏! តើយើងធ្វើបានដូចម្តេច?\n", "\n", "ឥឡូវនេះពេលដែលយើងបានបណ្តុះបណ្តាលម៉ូដែលរួចវិញ យើងអាចប្រើវា​សម្រាប់ធ្វើការទាយសម្រាប់ test_set ដោយប្រើ `parsnip::predict()`។ បន្ទាប់មកយើងអាចប្រៀបធៀបការទាយទាំងនេះជាមួយតម្លៃស្លាកពិត ដើម្បីប៉ាន់ប្រមាណថាម៉ូដែលកំពុងដំណើរការល្អ (ឬមិនល្អ!) ប៉ុណ្ណា។\n", "\n", "ចូរចាប់ផ្តើមពីការធ្វើការទាយសម្រាប់សំណុំតេស្ទហើយបន្ទាប់មកភ្ជាប់កូឡុំទៅនឹងសំណុំតេស្ត។\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": [ "បាទ ឬ ចាស អ្នកទើបតែបណ្តុះម៉ូដែលមួយ ហើយប្រើវាដើម្បីធ្វើការព្យាករណ៍!🔮 តើវាល្អទេ មកវាយតម្លៃកម្រិតការងាររបស់ម៉ូដែលគ្នាដូចម្តេច!\n", "\n", "នៅ​ក្នុង Tidymodels យើងធ្វើរឿងនេះដោយ​ប្រើ `yardstick::metrics()`! សម្រាប់ការស្វ័យប្រវត្តិស៊ីមប៉ុលតួអក្សរ (linear regression) យើងអាចផ្តោតលើមាត្រដ្ឋានខាងក្រោមនេះៈ\n", "\n", "- `Root Mean Square Error (RMSE)`: ជាប្រភេទគណនា​ឫសការ​គោល MSE។ វាបង្ហាញដល់មាត្រ absolute នៅក្នុងឯកតាដដែលនឹងស្លាក (ក្នុងករណីនេះគឺតម្លៃផ្អែមបុកខ្មៅមួយ)។ តម្លៃតូចជាងនឹងកាន់តែល្អសម្រាប់ម៉ូដែល (មានន័យសាមញ្ញវា​តំណាងឲ្យ​តម្លៃមធ្យមដែលការព្យាករណ៍ខុស!)\n", "\n", "- `Coefficient of Determination (ជាទូទៅគេហៅថា R-squared ឬ R2)`: ជាមាត្រូបផលស نسب性的 ដែលតម្លៃ越ឧត្តម越ល្អសម្រាប់ការចោលម៉ូដែល។ នៅក្នុងន័យសំខាន់ មាត្រនេះ​តំណាងឲ្យចំនួនជាតុល្យភាពចន្លោះតម្លៃព្យាករណ៍ និងតម្លៃពិតដែលម៉ូដែលអាចពន្យល់បាន។\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": [ "នោះជាការសម្តែងប្រសិទ្ធភាពម៉ូដែល។ យើងមកមើលថាតើយើងអាចទទួលបានសញ្ញាដែលល្អជាងនេះដោយវិស្វកម្មប្លង់បង្ហាញចំរូងនៃកញ្ចប់ និងតម្លៃ រួចប្រើការព្យាករណ៍ដែលបានធ្វើដើម្បីប្រាប់បន្ទាត់ល្អបំផុត។\n", "\n", "នេះមានន័យថាយើងត្រូវតែត្រៀមខ្ទង់ និងរៀបចំសំណុំសាកល្បង ដើម្បីកូដកូឡុមកញ្ចប់ បន្ទាប់មកភ្ជាប់វានឹងការព្យាករណ៍ដែលបានធ្វើដោយម៉ូដែលរបស់យើង។\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": [ "អស្ចារ្យ! ដូចដែលអ្នកអាចមើលឃើញ គំរូបាញ់បត់បន្ទាត់មួយមិនបានធ្វើការបូករួមទំនាក់ទំនងរវាងកញ្ចប់មួយ និងតម្លៃសមរម្យរបស់វាទៅបានល្អណាស់។\n", "\n", "🎃 ជប់លៀងសំណាងល្អ អ្នកទើបតែបង្កើតបានគំរូមួយដែលអាចជួយទាយតម្លៃរបស់បុព្វហេតុនៃមិនខ្លះនៃម្សៅផ្លែដូង។ កន្លែងដាំផ្លែដូងឈ្មោលរបស់អ្នកនឹងស្អាតណាស់។ ប៉ុន្តែអ្នកអាចបង្កើតគំរូល្អជាងនេះបានទៀត!\n", "\n", "## 5. បង្កើតគំរូបាញ់បត់ប៉ូលីណូម\n", "\n", "

\n", " \n", "

Infographic by Dasani Madipalli
\n" ], "metadata": { "id": "HOCqJXLTwtWI" } }, { "cell_type": "markdown", "source": [ "ម្តងម្កាលទិន្នន័យរបស់យើងអាចមិនមានទំនាក់ទំនងរ៉ែស៊ីស៊ីណែរ ខណៈដែលយើងនៅតែចង់ទាយទំនាក់ទំនងមួយ។ ការកំណត់អត្រាពហុគុណអាចជួយយើងបង្កើតការទាយសម្រាប់ទំនាក់ទំនងមិនរ៉ែស៊ីស៊ីណែរដែលស្មុគស្មាញ។\n", "\n", "យកឧទាហរណ៍ទំនាក់ទំនងរវាងកញ្ចប់ និងតម្លៃសម្រាប់សំណុំទិន្នន័យដំណាំខ្នងពោតរបស់យើង។ ម្តងម្កាលមានទំនាក់ទំនងរ៉ែស៊ីស៊ីណែរ រវាងអថេរនីមួយៗ - បន្លែខ្នងពោតដែលធំជាយ៉ាងមួយក្នុងចំណោមទំហំ វានឹងមានតម្លៃខ្ពស់ជាង - ប៉ុន្តែម្តងម្កាលទំនាក់ទំនងទាំងនេះមិនអាចគូសជាផ្ទៃ ឬបន្ទាត់ត្រង់បាន។\n", "\n", "> ✅ នៅទីនេះមាន [ឧទាហរណ៍បន្ថែមមួយចំនួន](https://online.stat.psu.edu/stat501/lesson/9/9.8) នៃទិន្នន័យដែលអាចប្រើប្រាស់ការកំណត់អត្រាពហុគុណ\n", ">\n", "> សូមមើលម្ដងទៀតពីទំនាក់ទំនងរវាងចំណាំដំណាំទៅតម្លៃនៅក្នុងក្រាបមុន។ តើក្រាបចេញបែបនេះសមរម្យអោយវាអាចត្រូវបានវិភាគដោយបន្ទាត់ត្រង់មែនទេ? ប្រហែលមិនទេ។ ក្នុងករណីនេះ អ្នកអាចសាកល្បងការកំណត់អត្រាពហុគុណ។\n", ">\n", "> ✅ ពហុគុណគឺជាអប្បរមាកម្មវិធីគណិតវិទ្យាដែលអាចមានអថេរមួយឬច្រើន និងសមាមាត្រផ្សេងៗ\n", "\n", "#### បណ្តុះម៉ូដែលកំណត់អត្រាពហុគុណដោយប្រើសំណុំបណ្តុះបណ្ដាល\n", "\n", "ការកំណត់អត្រាពហុគុណបង្កើត *បន្ទាត់បត់* ដើម្បីសម្រួលទិន្នន័យមិនរ៉ែស៊ីស៊ីណែរ។\n", "\n", "យើងមកមើលថាម៉ូដែលពហុគុណនេះនឹងដំណើរការល្អជាងក្នុងការបង្កើតការទាយទេឬ? យើងនឹងអនុវត្តវិធីសាស្រ្តមួយស្រដៀងគ្នាដូចដែលធ្វើម្តងមុន៖\n", "\n", "- បង្កើតរូបមន្តមួយដែលបញ្ជាក់ដំណើរការប្រកាសមុនដែលគួរត្រូវបានអនុវត្តលើទិន្នន័យរបស់យើងដើម្បីត្រៀមខ្លួនសម្រាប់ការតម្រៀបម៉ូដែល ឧ.៖ ការអ៊ិនកូដអ្នកទាយ និងការគណនាពហុគុណនៃឧបករណ៍ដឺក្រេ *n*\n", "\n", "- សង់ការបញ្ជាក់ម៉ូដែលមួយ\n", "\n", "- បញ្ចូលរូបមន្ត និងការបញ្ជាក់ម៉ូដែលចូលទៅក្នុងលំហូរការងារ\n", "\n", "- បង្កើតម៉ូដែលដោយការចងក្រងលំហូរការងារ\n", "\n", "- វាយតម្លៃមើលថាម៉ូដែលដំណើរការរលូនលើទិន្នន័យសាកល្បងយ៉ាងដូចម្តេច\n", "\n", "មកចាប់ផ្តើមភ្លាម!\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": [ "#### វាយតម្លៃការសម្តែងម៉ូដែល\n", "\n", "👏👏អ្នកបានបង្កើតម៉ូដែលពហុប៉ូលូម let's បង្កើតការព្យាករណ៍លើសំណុំសាកល្បង!\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": [ "វូ-ហ៊ូ តោះយើងពិនិត្យមើលថា ម៉ូដែលបានធ្វើការប្រតិបត្តិលើ test_set ដោយប្រើ `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": [ "🤩🤩 ការសម្តែងប្រសើរជាងមុន។\n", "\n", "`rmse` បានកាត់បន្ថយចុះពីប្រហែល 7. ទៅប្រហែល 3. ដែលបង្ហាញពីកំហុសបានកាត់បន្ថយរវាងតម្លៃពិត និងតម្លៃប៉ាន់ប្រមាណ។ អ្នកអាច *យល់ឱ្យរលូន* ប្រហែលថា ជាមធ្យម ការប៉ាន់ប្រមាណខុសៗគ្នា មានកំហុសប្រហែល 3 ដុល្លារ។ `rsq` បាន​កើនឡើងពីប្រហែល 0.4 ទៅ 0.8។\n", "\n", "រ៉ូម៉ែត្រទាំងនេះបង្ហាញថា ម៉ូដែលពហុផលិច មានការសម្តែងល្អជាងម៉ូដែលរೇಖា។ សំណាងល្អ!\n", "\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": [ "អ្នកអាចមើលឃើញខ្សែកោងមួយដែលសមស្របជាងសម្រាប់ទិន្នន័យរបស់អ្នក! 🤩\n", "\n", "អ្នកអាចធ្វើឲ្យវាស្កាយជាងនេះបានដោយផ្តល់មូលដ្ឋានពហុបថទៅ `geom_smooth` ដូចនេះ៖\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": [ "ដូចជាកោងរលោងមួយ!🤩\n", "\n", "នេះ​ជា​របៀប​ដែល​អ្នក​នឹង​ធ្វើ​ការទាយ​ទាយថ្មី​មួយ៖\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": [ "ការព្យាករណ៍ `ម៉ូដែលពហុព្រីម` គឺមានហេតុផល ដែលផ្អែកលើក្រាផ្គុំចុចរវាង `តម្លៃ` និង `កញ្ចប់`! ហើយ ប្រសិនបើនេះជាម៉ូដែលល្អជាងម៉ូដែលមុន ដែលមើលទៅលើទិន្នន័យដដែល អ្នកត្រូវតែដាក់ថវិកាសម្រាប់ផ្លែសណ្ដែកខ្ញីដូច្នេះដែលមានតម្លៃថ្លៃជាង!\n", "\n", "🏆 ល្អណាស់! អ្នកបានបង្កើតម៉ូដែលអនុពាក់កណ្តាលពីរក្នុងមេរៀនមួយ។ នៅផ្នែកចុងក្រោយនៃមេរៀនអនុពាក់កណ្តាល អ្នកនឹងរៀនអំពីអនុពាក់កណ្តាលឡូជ៊ីស្ទិចដើម្បីកំណត់ប្រភេទ។\n", "\n", "## **🚀វិញ្ញាសា**\n", "\n", "សាកល្បងអថេរជាច្រើនខុសៗគ្នានៅក្នុងសៀវភៅកំណត់ត្រានេះដើម្បីឃើញថាអត្តសញ្ញាណចំពោះអត្រាច្បាស់លាស់ម៉ូដែល។\n", "\n", "## [**វិញ្ញាសាបន្ទាប់មកបន្ទប់ម៉ោង**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/14/)\n", "\n", "## **ពិនិត្យឡើងវិញ និងសិក្សាផ្ទាល់ខ្លួន**\n", "\n", "ក្នុងមេរៀននេះ យើងបានរៀនអំពីអនុពាក់កណ្តាលរាខ្សែ។ មានប្រភេទអនុពាក់កណ្តាលសំខាន់ផ្សេងទៀត។ សូមអានអំពីបច្ចេកទេស Stepwise, Ridge, Lasso និង Elasticnet។ មេរៀនល្អមួយសម្រាប់សិក្សាបន្ថែមគឺ [មេរៀនសិក្សាស្ថិតិ Stanford](https://online.stanford.edu/courses/sohs-ystatslearning-statistical-learning)\n", "\n", "បើអ្នកចង់រៀនបន្ថែមពីរបៀបប្រើបណ្ណាល័យ Tidymodels ដែលអស្ចារ្យ សូមពិនិត្យធនធានដូចខាងក្រោម៖\n", "\n", "- គេហទំព័រ Tidymodels: [ចាប់ផ្តើមជាមួយ Tidymodels](https://www.tidymodels.org/start/)\n", "\n", "- Max Kuhn និង Julia Silge, [*Tidy Modeling with R*](https://www.tmwr.org/)*.*\n", "\n", "###### **សូមអរគុណចំពោះ៖**\n", "\n", "[Allison Horst](https://twitter.com/allison_horst?lang=en) សម្រាប់ការបង្កើតរូបភាពអស្ចារ្យ ដែលធ្វើឲ្យ R មើលទៅទាក់ទាញ និងមានការចូលរួម។ អ្នកអាចរករូបភាពបន្ថែមនៅក្នុង [កន្លែងបង្ហាញរបស់នាង](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**ព័ត៌មានបដិសេធ**: \nឯកសារនេះត្រូវបានបកប្រែដោយប្រើសេវាកម្មបកប្រែ AI [Co-op Translator](https://github.com/Azure/co-op-translator)។ ខណៈដែលយើងខិតខំប្រឹងប្រែងសម្រាប់ភាពត្រឹមត្រូវ សូមយកចិត្តទុកដាក់ថាបកប្រែដោយស្វ័យប្រវត្តិអាចមានកំហុស ឬភាពមិនត្រឹមត្រូវបានផ្ទុកក្នុង។ ឯកសារដើមជាភាសាពុំមែនជារូបមន្តត្រឹមត្រូវបំផុត គួរត្រូវបានគេពិចារណាជាដើមកំណត់គ្រប់គ្រង។ សម្រាប់ព័ត៌មានសំខាន់ៗ ការបកប្រែដោយអ្នកជំនាញមនុស្សត្រូវបានផ្ដល់អនុសាសន៍។ យើងមិនទទួលខុសត្រូវចំពោះការយល់ច្រឡំ ឬការបកប្រែខុសឆ្គងណាមួយដែលកើត​ឡើងពីការប្រើប្រាស់បកប្រែនេះទេ។\n\n" ] } ] }