Linear Regression Tutorial

tutorial นี้เราจะมาลองเขียนโค้ด R ง่ายๆเพื่อเทรน linear regression ทำนายราคาบ้าน medv ของ Boston dataset

  • load dataset
  • split dataset into train (80%) test (20%)
  • train model
  • test model

เราใช้ mean absolute error หรือ MAE ในการ evaluate โมเดล

In [2]:
list.files()
  1. 'Boston.csv'
  2. 'Intro to R.ipynb'
  3. 'Linear Regression with Boston Data.ipynb'
  4. 'README.md'

Load dataset

ใช้ฟังชั่น read.csv() ในการ import csv เข้าสู่ notebook

In [2]:
df <- read.csv("Boston.csv")
In [3]:
head(df) # print first 6 rows
A data.frame: 6 x 14
crimzninduschasnoxrmagedisradtaxptratioblacklstatmedv
<dbl><dbl><dbl><int><dbl><dbl><dbl><dbl><int><int><dbl><dbl><dbl><dbl>
0.00632182.3100.5386.57565.24.0900129615.3396.904.9824.0
0.02731 07.0700.4696.42178.94.9671224217.8396.909.1421.6
0.02729 07.0700.4697.18561.14.9671224217.8392.834.0334.7
0.03237 02.1800.4586.99845.86.0622322218.7394.632.9433.4
0.06905 02.1800.4587.14754.26.0622322218.7396.905.3336.2
0.02985 02.1800.4586.43058.76.0622322218.7394.125.2128.7
In [4]:
dim(df) # dimension of dataframe
  1. 506
  2. 14
In [5]:
mean(complete.cases(df)) # clean dataset should have score =1
1

Summary Statistics

In [6]:
summary(df)
      crim                zn             indus            chas        
 Min.   : 0.00632   Min.   :  0.00   Min.   : 0.46   Min.   :0.00000  
 1st Qu.: 0.08204   1st Qu.:  0.00   1st Qu.: 5.19   1st Qu.:0.00000  
 Median : 0.25651   Median :  0.00   Median : 9.69   Median :0.00000  
 Mean   : 3.61352   Mean   : 11.36   Mean   :11.14   Mean   :0.06917  
 3rd Qu.: 3.67708   3rd Qu.: 12.50   3rd Qu.:18.10   3rd Qu.:0.00000  
 Max.   :88.97620   Max.   :100.00   Max.   :27.74   Max.   :1.00000  
      nox               rm             age              dis        
 Min.   :0.3850   Min.   :3.561   Min.   :  2.90   Min.   : 1.130  
 1st Qu.:0.4490   1st Qu.:5.886   1st Qu.: 45.02   1st Qu.: 2.100  
 Median :0.5380   Median :6.208   Median : 77.50   Median : 3.207  
 Mean   :0.5547   Mean   :6.285   Mean   : 68.57   Mean   : 3.795  
 3rd Qu.:0.6240   3rd Qu.:6.623   3rd Qu.: 94.08   3rd Qu.: 5.188  
 Max.   :0.8710   Max.   :8.780   Max.   :100.00   Max.   :12.127  
      rad              tax           ptratio          black       
 Min.   : 1.000   Min.   :187.0   Min.   :12.60   Min.   :  0.32  
 1st Qu.: 4.000   1st Qu.:279.0   1st Qu.:17.40   1st Qu.:375.38  
 Median : 5.000   Median :330.0   Median :19.05   Median :391.44  
 Mean   : 9.549   Mean   :408.2   Mean   :18.46   Mean   :356.67  
 3rd Qu.:24.000   3rd Qu.:666.0   3rd Qu.:20.20   3rd Qu.:396.23  
 Max.   :24.000   Max.   :711.0   Max.   :22.00   Max.   :396.90  
     lstat            medv      
 Min.   : 1.73   Min.   : 5.00  
 1st Qu.: 6.95   1st Qu.:17.02  
 Median :11.36   Median :21.20  
 Mean   :12.65   Mean   :22.53  
 3rd Qu.:16.95   3rd Qu.:25.00  
 Max.   :37.97   Max.   :50.00  
In [10]:
plot(df$rm, df$medv, col="red")
In [9]:
plot(df[, c("medv", "rm", "tax", "lstat")]) # need to adjust the fig size

Split Data

แบ่งข้อมูลออกเป็น train (80%) และ test (20%)

machine learning rule: สร้างโมเดลด้วย train ทดสอบโมเดลด้วย test (หรืออีกชื่อคือ validate)

In [10]:
set.seed(99)
n <- nrow(df)
id <- sample(1:n, size = n*0.8, replace = FALSE)
train_df <- df[id, ]
test_df <- df[-id, ]
In [11]:
# quick sanity check
dim(train_df)
dim(test_df)
  1. 404
  2. 14
  1. 102
  2. 14

Train Model

R ใช้ฟังชั่น lm() ในการเทรน linear regression

argument แรกของฟังชั่นคือ formula: medv ~ . เราสั่งให้ R ใช้ตัวแปรทั้งหมดใน dataframe ทำนาย medv

In [13]:
lm_model <- lm(medv ~ ., data = train_df)
print(lm_model)
Call:
lm(formula = medv ~ ., data = train_df)

Coefficients:
(Intercept)         crim           zn        indus         chas          nox  
  38.244000    -0.120009     0.055663     0.002338     2.850636   -17.233528  
         rm          age          dis          rad          tax      ptratio  
   3.501261     0.006681    -1.510574     0.331114    -0.011767    -0.927444  
      black        lstat  
   0.008853    -0.594635  

Predict and Evaluate

ทำนาย test data ด้วยฟังชั่น predict() และคำนวณ mae ด้วยสูตรด้านล่าง

In [14]:
p <- predict(lm_model, newdata = test_df)
print(p[1:10])
        2         7        11        12        19        25        43        49 
25.065157 23.022033 18.484817 21.622602 16.350415 15.659708 25.113569  8.025409 
       57        61 
25.634466 18.166264 
In [16]:
mae <- mean(abs(p - test_df$medv))
cat(paste0("Test MAE: ", round(mae, 4)))
Test MAE: 3.4408