{ "nbformat": 4, "nbformat_minor": 2, "metadata": { "colab": { "name": "lesson_1-R.ipynb", "provenance": [], "collapsed_sections": [], "toc_visible": true }, "kernelspec": { "name": "ir", "display_name": "R" }, "language_info": { "name": "R" }, "coopTranslator": { "original_hash": "c18d3bd0bd8ae3878597e89dcd1fa5c1", "translation_date": "2025-09-06T13:44:22+00:00", "source_file": "2-Regression/1-Tools/solution/R/lesson_1-R.ipynb", "language_code": "th" } }, "cells": [ { "cell_type": "markdown", "source": [], "metadata": { "id": "YJUHCXqK57yz" } }, { "cell_type": "markdown", "source": [ "## บทนำสู่การวิเคราะห์การถดถอย - บทเรียนที่ 1\n", "\n", "#### ทำความเข้าใจในมุมมอง\n", "\n", "✅ มีวิธีการวิเคราะห์การถดถอยหลายประเภท และการเลือกใช้วิธีใดขึ้นอยู่กับคำตอบที่คุณต้องการ หากคุณต้องการทำนายความสูงที่เป็นไปได้ของบุคคลในช่วงอายุหนึ่ง คุณจะใช้ `linear regression` เพราะคุณกำลังมองหาค่า **ตัวเลข** หากคุณสนใจที่จะค้นหาว่าประเภทของอาหารควรถือว่าเป็นมังสวิรัติหรือไม่ คุณกำลังมองหาการ **จัดหมวดหมู่** ดังนั้นคุณจะใช้ `logistic regression` คุณจะได้เรียนรู้เพิ่มเติมเกี่ยวกับ logistic regression ในภายหลัง ลองคิดถึงคำถามบางข้อที่คุณสามารถถามจากข้อมูล และวิธีการใดที่เหมาะสมที่สุด\n", "\n", "ในส่วนนี้ คุณจะได้ทำงานกับ [ชุดข้อมูลขนาดเล็กเกี่ยวกับโรคเบาหวาน](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html) ลองจินตนาการว่าคุณต้องการทดสอบการรักษาสำหรับผู้ป่วยโรคเบาหวาน โมเดล Machine Learning อาจช่วยคุณระบุว่าผู้ป่วยคนใดจะตอบสนองต่อการรักษาได้ดีกว่า โดยอิงจากการผสมผสานของตัวแปรต่าง ๆ แม้แต่โมเดลการถดถอยที่พื้นฐานที่สุด เมื่อถูกนำเสนอในรูปแบบภาพ อาจแสดงข้อมูลเกี่ยวกับตัวแปรที่ช่วยให้คุณจัดการทดลองทางคลินิกในเชิงทฤษฎีได้อย่างมีประสิทธิภาพ\n", "\n", "เมื่อกล่าวเช่นนั้น มาเริ่มต้นงานนี้กันเลย!\n", "\n", "
\n",
" \n",
"
\n",
"\n",
"> `glimpse()` และ `slice()` เป็นฟังก์ชันใน [`dplyr`](https://dplyr.tidyverse.org/) Dplyr ซึ่งเป็นส่วนหนึ่งของ Tidyverse เป็นไวยากรณ์สำหรับการจัดการข้อมูลที่ให้ชุดคำกริยาที่สอดคล้องกันเพื่อช่วยแก้ปัญหาท้าทายที่พบบ่อยที่สุดในการจัดการข้อมูล\n",
"\n",
"
\n",
"\n",
"ตอนนี้เมื่อเรามีข้อมูลแล้ว เรามาโฟกัสไปที่คุณลักษณะหนึ่ง (`bmi`) เพื่อใช้ในแบบฝึกหัดนี้ ซึ่งจะต้องเลือกคอลัมน์ที่ต้องการ แล้วเราจะทำสิ่งนี้ได้อย่างไร?\n",
"\n",
"[`dplyr::select()`](https://dplyr.tidyverse.org/reference/select.html) ช่วยให้เราสามารถ *เลือก* (และเปลี่ยนชื่อได้ถ้าต้องการ) คอลัมน์ใน data frame\n"
],
"metadata": {
"id": "UwjVT1Hz-c3Z"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Select predictor feature `bmi` and outcome `y`\r\n",
"diabetes_select <- diabetes %>% \r\n",
" select(c(bmi, y))\r\n",
"\r\n",
"# Print the first 5 rows\r\n",
"diabetes_select %>% \r\n",
" slice(1:10)"
],
"outputs": [],
"metadata": {
"id": "RDY1oAKI-m80"
}
},
{
"cell_type": "markdown",
"source": [
"## 3. ข้อมูลการฝึกและการทดสอบ\n",
"\n",
"ในกระบวนการเรียนรู้แบบมีผู้สอน มักจะมีการ *แบ่ง* ข้อมูลออกเป็นสองชุดย่อย; ชุดที่ใหญ่กว่า (โดยทั่วไป) สำหรับการฝึกโมเดล และชุดที่เล็กกว่า \"สำรองไว้\" เพื่อดูว่าโมเดลทำงานได้ดีเพียงใด\n",
"\n",
"ตอนนี้เรามีข้อมูลพร้อมแล้ว เราสามารถดูได้ว่ามีวิธีที่เครื่องสามารถช่วยกำหนดการแบ่งที่เหมาะสมระหว่างตัวเลขในชุดข้อมูลนี้หรือไม่ เราสามารถใช้แพ็กเกจ [rsample](https://tidymodels.github.io/rsample/) ซึ่งเป็นส่วนหนึ่งของเฟรมเวิร์ก Tidymodels เพื่อสร้างออบเจ็กต์ที่มีข้อมูลเกี่ยวกับ *วิธี* การแบ่งข้อมูล และใช้ฟังก์ชัน rsample อีกสองตัวเพื่อดึงชุดข้อมูลการฝึกและการทดสอบที่สร้างขึ้น:\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. ฝึกโมเดลการถดถอยเชิงเส้นด้วย Tidymodels\n",
"\n",
"ตอนนี้เราพร้อมที่จะฝึกโมเดลของเราแล้ว!\n",
"\n",
"ใน Tidymodels คุณสามารถกำหนดโมเดลโดยใช้ `parsnip()` โดยระบุแนวคิดสามอย่างดังนี้:\n",
"\n",
"- **ประเภทของโมเดล** ใช้เพื่อแยกแยะโมเดล เช่น การถดถอยเชิงเส้น การถดถอยโลจิสติก โมเดลต้นไม้ตัดสินใจ และอื่นๆ\n",
"\n",
"- **โหมดของโมเดล** รวมถึงตัวเลือกทั่วไป เช่น การถดถอยและการจำแนกประเภท; โมเดลบางประเภทสามารถรองรับทั้งสองโหมดนี้ ในขณะที่บางประเภทมีเพียงโหมดเดียว\n",
"\n",
"- **เครื่องมือของโมเดล** คือเครื่องมือคำนวณที่จะใช้ในการปรับโมเดล โดยมักจะเป็นแพ็กเกจใน R เช่น **`\"lm\"`** หรือ **`\"ranger\"`**\n",
"\n",
"ข้อมูลเกี่ยวกับการสร้างโมเดลนี้จะถูกบันทึกไว้ในสเปคโมเดล ดังนั้นเรามาสร้างกันเลย!\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": [
"หลังจากที่โมเดลถูก *กำหนด* แล้ว โมเดลสามารถถูก `ประเมิน` หรือ `ฝึกฝน` ได้โดยใช้ฟังก์ชัน [`fit()`](https://parsnip.tidymodels.org/reference/fit.html) ซึ่งมักจะใช้สูตรและข้อมูลบางส่วน\n",
"\n",
"`y ~ .` หมายความว่าเราจะปรับ `y` ให้เป็นค่าที่คาดการณ์/เป้าหมาย โดยอธิบายด้วยตัวแปรทำนาย/คุณลักษณะทั้งหมด เช่น `.` (ในกรณีนี้ เรามีตัวแปรทำนายเพียงตัวเดียว: `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": [
"จากผลลัพธ์ของโมเดล เราสามารถเห็นค่าสัมประสิทธิ์ที่ได้จากการฝึกฝน ซึ่งค่าสัมประสิทธิ์เหล่านี้แสดงถึงค่าของเส้นที่เหมาะสมที่สุดที่ช่วยลดข้อผิดพลาดโดยรวมระหว่างตัวแปรจริงและตัวแปรที่คาดการณ์\n",
"\n",
"
\n",
"\n",
"## 5. ทำนายผลบนชุดข้อมูลทดสอบ\n",
"\n",
"เมื่อเราได้ฝึกฝนโมเดลแล้ว เราสามารถใช้มันเพื่อทำนายการพัฒนาของโรค y สำหรับชุดข้อมูลทดสอบโดยใช้ [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html) ซึ่งจะถูกใช้เพื่อวาดเส้นแบ่งระหว่างกลุ่มข้อมูล\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": [
"เย้! 💃🕺 เราเพิ่งฝึกโมเดลและใช้มันเพื่อทำการพยากรณ์!\n",
"\n",
"เมื่อทำการพยากรณ์ ตามธรรมเนียมของ tidymodels จะสร้างผลลัพธ์ในรูปแบบ tibble หรือ data frame ที่มีชื่อคอลัมน์มาตรฐานเสมอ วิธีนี้ช่วยให้สามารถรวมข้อมูลต้นฉบับและผลการพยากรณ์ในรูปแบบที่ใช้งานได้ง่ายสำหรับการดำเนินการต่อ เช่น การสร้างกราฟ\n",
"\n",
"`dplyr::bind_cols()` ช่วยรวมหลาย data frame เข้าด้วยกันอย่างมีประสิทธิภาพในรูปแบบคอลัมน์\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. แสดงผลการสร้างโมเดล\n",
"\n",
"ถึงเวลาที่จะดูผลลัพธ์ในรูปแบบภาพแล้ว 📈 เราจะสร้างกราฟกระจายของค่าทั้งหมดใน `y` และ `bmi` จากชุดข้อมูลทดสอบ จากนั้นใช้ค่าที่คาดการณ์เพื่อวาดเส้นในตำแหน่งที่เหมาะสมที่สุด ระหว่างกลุ่มข้อมูลของโมเดล\n",
"\n",
"R มีระบบหลายแบบสำหรับการสร้างกราฟ แต่ `ggplot2` เป็นหนึ่งในระบบที่ดูเรียบง่ายและมีความหลากหลายมากที่สุด ระบบนี้ช่วยให้คุณสามารถสร้างกราฟโดย **การรวมองค์ประกอบที่เป็นอิสระเข้าด้วยกัน**\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": [
"✅ ลองคิดดูว่าเกิดอะไรขึ้นที่นี่ เส้นตรงเส้นหนึ่งกำลังผ่านจุดข้อมูลเล็กๆ หลายจุด แต่จริงๆ แล้วมันกำลังทำอะไรอยู่? คุณเห็นไหมว่าคุณควรจะสามารถใช้เส้นนี้เพื่อทำนายว่าจุดข้อมูลใหม่ที่ยังไม่เคยเห็นควรจะอยู่ตรงไหนในความสัมพันธ์กับแกน y ของกราฟ? ลองอธิบายเป็นคำพูดถึงการใช้งานจริงของโมเดลนี้\n",
"\n",
"ขอแสดงความยินดี! คุณสร้างโมเดลการถดถอยเชิงเส้นตัวแรกของคุณ สร้างการทำนายด้วยมัน และแสดงผลในกราฟ!\n"
],
"metadata": {
"id": "zrPtHIxx_tNI"
}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**ข้อจำกัดความรับผิดชอบ**: \nเอกสารนี้ได้รับการแปลโดยใช้บริการแปลภาษา AI [Co-op Translator](https://github.com/Azure/co-op-translator) แม้ว่าเราจะพยายามให้การแปลมีความถูกต้อง แต่โปรดทราบว่าการแปลอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่แม่นยำ เอกสารต้นฉบับในภาษาต้นทางควรถือเป็นแหล่งข้อมูลที่เชื่อถือได้ สำหรับข้อมูลที่สำคัญ ขอแนะนำให้ใช้บริการแปลภาษาจากผู้เชี่ยวชาญ เราไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความที่ผิดพลาดซึ่งเกิดจากการใช้การแปลนี้\n"
]
}
]
}