ทำนายราคาบ้าน Boston ด้วย Linear Regression

บทความที่แล้วเราเขียนอธิบายขั้นตอนการสร้าง ML model ใน 4 ขั้นตอน และสอนเขียนโค้ด R สำหรับแก้ปัญหา Binary Classification (Titanic) วันนี้เราจะมาลองเขียน ML แก้ปัญหา Regression กันบ้าง

Regression Problem

แอดดาวน์โหลด dataset มาจาก Kaggle ชื่อว่า Boston (Housing Values in Suburbs of Boston) มีตัวแปรทั้งหมด 14 ตัว โดย target ที่เราต้องการทำนายคือ medv หรือราคาบ้านเฉลี่ยหน่วยเป็น $1000

ML เรียกปัญหานี้ว่า Regression เพราะ target ที่เราต้องการทำนายเป็นตัวเลขแบบ numeric/ continuous และ algorithm ที่เราจะสอนวันนี้คือ Linear Regression (อ่านบทความอธิบายเรื่อง LR ได้ในลิ้ง)

Load Data

ดาวน์โหลดข้อมูล Boston เพื่อทำตาม tutorial นี้หรือดู Notebook ของเราได้ที่นี่

เปิดโปรแกรม RStudio ขึ้นมาแล้ว import Boston.csv ด้วยฟังชั่น read.csv() เราสามารถเรียกดู 6 แถวบนสุดของ dataframe ด้วยฟังชั่น head() หรือดูจำนวนแถวและคอลั่มด้วยฟังชั่น dim() โค้ดด้านล่างแอดใช้ฟังชั่น complete.cases() เพื่อตรวจสอบว่าข้อมูลมี missing value หรือเปล่า? ถ้าออกมาเท่ากับ 1 แปลว่า clean 100%

df <- read.csv("Boston.csv")
mean(complete.cases(df)) # should be one for clean dataset

Split Data

เราใช้ฟังชั่น sample() เพื่อสร้าง random ID สำหรับแบ่งข้อมูลเป็น train (80%) และ test (20%) ส่วนฟังชั่น set.seed() ในไลน์แรกใช้ล็อคผลแรนดอม เพื่อนๆที่ทำตาม tutorial นี้เวลารันโค้ดจะได้ผลเหมือนในตัวอย่าง

set.seed(99)
id <- sample(1:nrow(df), size = 0.8, replace = FALSE)
train_df <- df[id, ] 
test_df <- df[-id, ]

กฎเหล็กของ Machine Learning คือเราต้องแบ่งข้อมูลก่อนเทรนโมเดลเสมอ !! โดยทั่วไปเราอาจทำ split train/test ง่ายๆ หรือที่นิยมกว่าคือการแบ่งข้อมูลเป็นสามส่วน train/validate/test ทำ cross validation

Train and Validate

โค้ด 3 ไลน์ด้านล่างเขียนขึ้นเพื่อทำ task ต่อไปนี้

  • line 1 สร้างโมเดล linear regression ด้วยฟังชั่น lm()
  • line 2 ทำนาย test data ด้วยฟังชั่น predict()
  • line 3 คำนวณค่า mean absolute error (MAE) สำหรับวัดผลโมเดล
lm_model <- lm(medv ~ ., data = train_df)
p <- predict(lm_model, newdata = test_df)
mae <- mean(abs(p - test_df$medv))

เวลาเทรนโมเดล เราต้องมี metrics ที่ใช้วัด performance ว่าโมเดลเราทำงานได้ดีหรือยัง? สำหรับ regression metric ตัวพื้นฐานคือ MAE ถ้าใครยังไม่คุ้นกับ metric นี้ อ่านเพิ่มเติมได้ที่บทความแนะนำด้านล่าง

10 Metrics พื้นฐานสำหรับวัดผลโมเดล ML

รู้จักกับ MAE, MSE, RMSE, R2 สำหรับ regression problem

Reusable Function

Tasks ที่เราต้องทำบ่อยๆ ปกติเราจะเขียนเป็นฟังชั่นไว้เลย ตัวอย่างด้านล่าง แอดเขียนฟังชั่น LinearRegression() รับ 4 arguments เอาไว้เทรน Linear Regression กับข้อมูลอื่นๆได้เลย ง่ายอะไรเบอร์นี้!

Line 26-27 เราสั่งปริ้น train MAE และ test MAE เพื่อดูว่าโมเดลของเรา generalize ดีไหม i.e. เจอปัญหา overfitting หรือเปล่า ถ้า train และ test MAE มีค่าใกล้เคียงกัน ถือว่าโมเดลเราทำงานได้ OK!

## this function takes four inputs
## formula such as "mpg ~ wt + hp" (character)
## dataset
## train_size ratio between 0-1 (numeric)
## target such as "mpg" (character)
LinearRegression <- function(formula, data, train_size, target){
## split dataset into train and test
set.seed(99)
n <- nrow(data)
id <- sample(1:n, size = train_size*n, replace = FALSE)
train_df <- data[id, ]
test_df <- data[-id, ]
## train model
train_form <- as.formula(formula)
lm_model <- lm(train_form, data = train_df)
## predictions
train_p <- predict(lm_model)
test_p <- predict(lm_model, newdata = test_df)
## evaluate and print result
train_mae <- mean(abs(train_p - train_df[[target]]))
test_mae <- mean(abs(test_p - test_df[[target]]))
cat("Train MAE:", train_mae)
cat("\nTest MAE:", test_mae)
}
view raw LinearReg.R hosted with ❤ by GitHub

Awesome Work

ทดสอบฟังชั่น LinearRegression() กับข้อมูล Boston อีกครั้ง โดยกำหนด train_size = 0.80 และใช้ตัวแปร X ทุกตัวใน dataframe ทำนาย medv จะได้ค่า test MAE เท่ากับ 3.4408 not bad!!

LinearRegression("medv ~ .", df, 0.80, "medv")
## Train MAE: 3.327476
## Test MAE: 3.4408

MAE = 3.4408 อธิบายได้ว่า linear regression ของเราโดยเฉลี่ยทำนาย medv ผิดไปประมาณ 3.4408 จุด (หน่วยเป็น $1000) tutorial นี้เรายังไม่ได้ทำ preprocessing data เช่น การ scale/ normalize features หรือการทำ log/ box cox transformation ที่ (ส่วนใหญ่) จะช่วยให้ algorithm เรียนรู้และทำนายผลได้ดีขึ้น

6 thoughts on “ทำนายราคาบ้าน Boston ด้วย Linear Regression

  1. ขอบคุณมากคะ ทำตามโดย key code เอง เหมือนของแอด บาง line run แลัว error แต่ copy code ของแอดมาวาง run ได้ งงคะ

  2. สอบถามครับ กรณีผมมีตัวอย่างข้อมูลหนึ่งชุด ทดลองรันโดยปรับค่าการสุ่ม
    – set seed(99) => train_mae = 97, test_mae = 83
    – set seed(123) => train_mae = 91, test_mae = 110
    เราจะมีเกณฑ์พิจารณาอย่างไร ว่าโมเดลนี้ของเราใช้ได้แล้วครับ

    1. train test ต้องได้ค่า mae ใกล้เคียงกันครับ ไม่ overfit ปกติ test mae จะต่ำกว่า train นิดหน่อย ไม่ได้มีกฏตายตัว ของแอดใช้ +/- 3-5% ครับ

Leave a Reply