# clear-up the environment
rm(list = ls())

# chunk options
knitr::opts_chunk$set(
  message = FALSE,
  warning = FALSE,
  fig.align = "center",
  comment = "#>"
)
options(scipen = 99) # agar output dalam bentuk satuan biasa / tidak scientific -> e10

0.1 Introduction

Selamat Datang!

Untuk mengerjakan Learning By Building dari Algortima Academy, saat ini saya akan belajar menggunakan permodelan linier regresi. Bagi saya model ini simple tapi menarik karena bisa memprediksi variabel target yang ingin kita tentukan tapi variabel target ini hanya bisa menggunakan tipe numerik :p

Kali ini, saya akan menggunakan Data yang diambil dari data hasil scrapping dari website https://www.rumah123.com/ oleh Mba Rany Dwi Cahyaningtyas (Terima kasih banyak Mba datanya ^^). Tidak perlu waktu berlama - lama karena dikejar deadline mari kita explor!

Variabel Target pada data ini ada ‘Prices’ alias harga dari properti yang ada

0.2 Data Prepartion

0.2.1 Import Data

#Membuat Objek

house <- read.csv(file = "properti_jual.csv")

#Melihat Data

head(house)

Sekilas Data ‘house’ sudah bersih dan tidak ada perubahan yang perlu diganti, dari segi tipe data pun sudah cukup sesuai tapi mari kita terus curiga apakah masih ada hal - hal lain perlu kita check :)

0.2.2 Checking Missing Value

#Menggunakan fungsi colSums
colSums(is.na(house))
#>      K..Mandi      K..Tidur   L..Bangunan    Sertifikat Tipe.Properti 
#>             0             0             0             0             0 
#>          Kota         Price 
#>             0             0

Aman, tidak ada yang kosong!

0.2.3 Explanatory Data Analysis

#Memanggil library 'dplyr'
library(dplyr)

#mengunakan fungsi 'glimpse' untuk melihat keseluruhan data
glimpse(house)
#> Rows: 6,287
#> Columns: 7
#> $ K..Mandi      <int> 3, 3, 1, 2, 3, 1, 1, 1, 4, 3, 1, 2, 3, 1, 2, 4, 2, 1, 1,…
#> $ K..Tidur      <int> 4, 3, 1, 2, 3, 1, 1, 2, 4, 3, 2, 2, 3, 2, 2, 3, 2, 2, 1,…
#> $ L..Bangunan   <int> 294, 78, 33, 120, 130, 97, 23, 42, 160, 85, 40, 70, 110,…
#> $ Sertifikat    <chr> "SHM - Sertifikat Hak Milik", "SHM - Sertifikat Hak Mili…
#> $ Tipe.Properti <chr> "Rumah", "Apartemen", "Apartemen", "Rumah", "Rumah", "Ap…
#> $ Kota          <chr> "Jakarta Utara", "Jakarta Selatan", "Jakarta Timur", "Ja…
#> $ Price         <dbl> 3500000000, 2500000000, 265000000, 2600000000, 130000000…

0.2.4 Mengubah Tipe Data

Terdapat dua kolom yang perlu diubah menjadi data faktor yaitu Tipe.Properti dan Kota

#Mengubah tipe data menggunakan fungsi 'mutate'
house$Tipe.Properti <-  as.factor(house$Tipe.Properti)
house$Kota <- as.factor(house$Kota)

#Mengecheck kembali data yang telah diubah
glimpse(house)
#> Rows: 6,287
#> Columns: 7
#> $ K..Mandi      <int> 3, 3, 1, 2, 3, 1, 1, 1, 4, 3, 1, 2, 3, 1, 2, 4, 2, 1, 1,…
#> $ K..Tidur      <int> 4, 3, 1, 2, 3, 1, 1, 2, 4, 3, 2, 2, 3, 2, 2, 3, 2, 2, 1,…
#> $ L..Bangunan   <int> 294, 78, 33, 120, 130, 97, 23, 42, 160, 85, 40, 70, 110,…
#> $ Sertifikat    <chr> "SHM - Sertifikat Hak Milik", "SHM - Sertifikat Hak Mili…
#> $ Tipe.Properti <fct> Rumah, Apartemen, Apartemen, Rumah, Rumah, Apartemen, Ap…
#> $ Kota          <fct> Jakarta Utara, Jakarta Selatan, Jakarta Timur, Jakarta P…
#> $ Price         <dbl> 3500000000, 2500000000, 265000000, 2600000000, 130000000…

Yeay! sudah terubah menjadi data faktor ^^ Selanjutnya, ngapain ya?

0.2.5 Data Explanation

Oh iya, terlihat data ini memiliki 7 kolom yang berisikan :

  • K..Mandi: Jumlah kamar mandi pada suatu properti

  • K..Tidur: Jumlah kamar tidur pada suatu properti

  • L..Bangunan: Luas bangunan properti (m2)

  • Sertifikat: Jenis sertifikat atas properti yang di jual

    • Sertifikat Hak Pakai
    • Sertifikat Hak Sewa
    • Sertifikat lainnya (PPJB, Girik, Adat, dll)
    • Sertifikat PPJB
    • Sertifikat Hak Milik
  • Tipe.Properti: Jenis properti yang dijual

    • Rumah: Untuk tipe properti rumah
    • Apartemen: Untuk tipe properti apartemen
  • Kota: Lokasi kota tempat properti di jual

    • Depok
    • Jakarta Selatan
    • Jakarta Timur
    • Jakarta Utara
    • Jakarta Barat
    • Jakarta Pusat
    • Tangerang Selatan
  • Price: Nominal harga properti yang dijual

0.3 Exploratory Data Analysis

Yuhu, kita memasuki saat yang ditunggu - tunggu~ untuk mengexplor data yang kita miliki hehe

sebelum itu, saya ingin mengingatkan kembali bahwa…

Variabel Target pada data ini ada ‘Price’ alias harga dari properti yang ada

sebelum itu mari kita mengcheck terlebih dahulu hubungan dari Variabel Target dengan Variabel Prediktor

#Menggunakan Library 'GGally'
library(GGally)
ggcorr(data = house, label = TRUE)

💡 Insight : Dapat dilihat korelasi variabel tertinggi pada Price terdapat pada L..Bangunan yaitu jumlah luas bangunan dari properti tersebut.

0.3.1 Modeling & Interpretation

0.3.1.1 Modeling - Keseluruhan Prediktor

Wuhu! kita telah memasuki dalam hal modeling, kali ini kita akan membuat Modeling dengan menggunakan keseluruhan variabel prediktor terlebih dahulu ;p

#Menggunakan fungsi 'lm' untuk membuat model linier Regression
model_all <-  lm(formula = Price ~ ., data = house)
#Mengecheck model yang ada
summary(model_all) 
#> 
#> Call:
#> lm(formula = Price ~ ., data = house)
#> 
#> Residuals:
#>         Min          1Q      Median          3Q         Max 
#> -6741061107  -385104093  -112745012   261317721  3953651973 
#> 
#> Coefficients:
#>                                           Estimate Std. Error t value
#> (Intercept)                             -103500776   41061065  -2.521
#> K..Mandi                                  89422402   18268163   4.895
#> K..Tidur                                 103745234   16914121   6.134
#> L..Bangunan                               13659934     228673  59.736
#> SertifikatHP - Hak Pakai                -185644260  124504582  -1.491
#> SertifikatHS - Hak Sewa                 -295223961  318008806  -0.928
#> SertifikatLainnya (PPJB,Girik,Adat,dll)   41371839   31531506   1.312
#> SertifikatPPJB                          -161517621  502101218  -0.322
#> SertifikatSHM - Sertifikat Hak Milik     -70251816   30627540  -2.294
#> Tipe.PropertiRumah                      -323483239   30490591 -10.609
#> KotaJakarta Barat                        408778315   32866753  12.437
#> KotaJakarta Pusat                        541558140   38218742  14.170
#> KotaJakarta Selatan                      809639863   37896650  21.364
#> KotaJakarta Timur                         -2317356   30993739  -0.075
#> KotaJakarta Utara                        362759231   37698697   9.623
#> KotaTangerang Selatan                    274005320   32583828   8.409
#>                                                     Pr(>|t|)    
#> (Intercept)                                           0.0117 *  
#> K..Mandi                                      0.000001007720 ***
#> K..Tidur                                      0.000000000911 ***
#> L..Bangunan                             < 0.0000000000000002 ***
#> SertifikatHP - Hak Pakai                              0.1360    
#> SertifikatHS - Hak Sewa                               0.3533    
#> SertifikatLainnya (PPJB,Girik,Adat,dll)               0.1895    
#> SertifikatPPJB                                        0.7477    
#> SertifikatSHM - Sertifikat Hak Milik                  0.0218 *  
#> Tipe.PropertiRumah                      < 0.0000000000000002 ***
#> KotaJakarta Barat                       < 0.0000000000000002 ***
#> KotaJakarta Pusat                       < 0.0000000000000002 ***
#> KotaJakarta Selatan                     < 0.0000000000000002 ***
#> KotaJakarta Timur                                     0.9404    
#> KotaJakarta Utara                       < 0.0000000000000002 ***
#> KotaTangerang Selatan                   < 0.0000000000000002 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> Residual standard error: 708400000 on 6271 degrees of freedom
#> Multiple R-squared:  0.6817, Adjusted R-squared:  0.6809 
#> F-statistic: 895.4 on 15 and 6271 DF,  p-value: < 0.00000000000000022

💡 Interpretasi Model

1. Significant Predictor

  • variabel signifikan (p-value < 0.05) : K..Mandi, K..Tidur, L..Bangunan,Tipe.PropertiRumah,SertifikatSHM - Sertifikat Hak Milik,KotaJakarta Barat,KotaJakarta Pusat, KotaJakarta Selatan, KotaJakarta Utara, KotaTangerang Selatan
  • variabel tidak signifikan (p-value < 0.05) : SertifikatHP - Hak Pakai, SertifikatHS - Hak Sewa, SertifikatLainnya (PPJB,Girik,Adat,dll), SertifikatPPJB

2. Interpretasi Coefficient

  • Untuk Variabel numerik
    • Interpretasi L..Bangunan : L..Bangunan punya koefisien 13659934 -> setiap kenaikan 1 satuan tingkat L..Bangunan, efeknya akan meningkatkan Price, dengan catatan variabel lainnya tetap
  • Untuk variabel kategorik
    • Interpretasi Kota Tangerang Selatan : 274005320, artinya ketika suatu properti berasal dari Kota Tanggerang Selatan maka Price/harga bertambah sebesar 274005320

3. Goodness of fit (adj R-Squared)

  • 0.6809
    • Interpretasi artinya 68% mampu menjelaskan variansi dari variabel target Price

0.3.1.2 Modeling - 1 Prediktor

Selanjutnya, kita akan membuat model dengan menggunakan 1 prediktor yaitu L..Bangunan

#Menggunakan fungsi 'lm' untuk membuat model linier Regression
model_1 <- lm(formula = Price ~ L..Bangunan , data = house)
#Mengecheck model yang ada
summary(model_1)
#> 
#> Call:
#> lm(formula = Price ~ L..Bangunan, data = house)
#> 
#> Residuals:
#>         Min          1Q      Median          3Q         Max 
#> -6964733519  -427072759  -191152667   247469197  4135696585 
#> 
#> Coefficients:
#>              Estimate Std. Error t value            Pr(>|t|)    
#> (Intercept) 321092368   16875936   19.03 <0.0000000000000002 ***
#> L..Bangunan  14903015     148042  100.67 <0.0000000000000002 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> Residual standard error: 776000000 on 6285 degrees of freedom
#> Multiple R-squared:  0.6172, Adjusted R-squared:  0.6171 
#> F-statistic: 1.013e+04 on 1 and 6285 DF,  p-value: < 0.00000000000000022

💡 Interpretasi Model

1. Significant Predictor

  • L..Bangunan menunjukan variabel prediktor yang signifikan sebesar (p-value < 0.05)

2. Interpretasi Coefficient + Interpretasi L..Bangunan : L..Bangunan punya koefisien 14903015 -> setiap kenaikan 1 satuan tingkat L..Bangunan, efeknya akan meningkatkan Price, dengan catatan variabel lainnya tetap

3. Goodness of fit (Multiple R-squared)

  • 0.6172
    • Interpretasi artinya 61% mampu menjelaskan variansi dari variabel target Price

0.3.2 Modeling - Beberapa Prediktor

Selanjutnya, kita akan membuat model dengan beberapa prediktor saja. Kita akan membuat Model dengan Predikotr numerik yaitu terdiri dari L..Bangunan ,K..Tidur, dan K..Mandi.

#Menggunakan fungsi 'lm' untuk membuat model linier Regression
model_3 <-  lm(formula = Price ~ L..Bangunan + K..Tidur + K..Mandi , data = house)
#Mengecheck model yang ada
summary(model_3) 
#> 
#> Call:
#> lm(formula = Price ~ L..Bangunan + K..Tidur + K..Mandi, data = house)
#> 
#> Residuals:
#>         Min          1Q      Median          3Q         Max 
#> -7275215787  -415197661  -199687047   238353706  4272258780 
#> 
#> Coefficients:
#>              Estimate Std. Error t value            Pr(>|t|)    
#> (Intercept) 408169317   26778040  15.243 <0.0000000000000002 ***
#> L..Bangunan  15671995     235390  66.579 <0.0000000000000002 ***
#> K..Tidur    -41638492   17348284  -2.400              0.0164 *  
#> K..Mandi    -30445057   18962891  -1.606              0.1084    
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> Residual standard error: 775000000 on 6283 degrees of freedom
#> Multiple R-squared:  0.6183, Adjusted R-squared:  0.6181 
#> F-statistic:  3393 on 3 and 6283 DF,  p-value: < 0.00000000000000022

💡 Interpretasi Model

Nilai R-squared dari model di atas adalah 0.6181 atau 61% mampu menjelaskan variansi dari variabel target Price

0.3.3 Prediction

Selanjutnya, kita akan melakukan prediksi, tetapi sebelum itu berhubung belum ada data baru yang dibuat, maka kita akan melihat performa model di data training.

Beberapa model yang telah dibuat :

  1. model_all : semua prediktor (ada numerik, ada kategorik)
  2. model_1 : satu prediktor (L..Bangunan)
  3. model_3 : semua prediktor numerik

0.3.4 Model Evaluation

Setelah membuat model yang ingin digunakan dan terlihat outputnya, kita perlu mengevaluasi terlebih dahulu apakah model yang kita buat sudah cukup bagus untuk digunakan

Menggunakan predict() untuk melihat hasil prediksi model pada data training.

# Simpan hasil prediksi ke kolom baru 
house_pred <- house

#hasil prediksi model 1 variabel
house_pred$pred_1 <- predict(model_1, newdata = house)
#hasil prediksi keseluruhan variabel
house_pred$pred_all <- predict(model_all, newdata = house)
# hasil prediksi model semua variabel numerik
house_pred$pred_3 <- predict(model_3, newdata = house)

#Mengcheck kembali
head(house_pred)

0.3.5 Model Comparison

Karena kita ingin mengetahui mana model terbaik yang memprediksi variabel target ada beberapa hal bisa kita lakukan.

0.3.5.1 Goodness of Fit (R-Squared)

kita dapat melihat goodness of fit berdasarkan nilai R-squarednya.

# cek r-squared untuk masing-masing model
summary(model_1)$r.squared
#> [1] 0.617209
summary(model_all)$adj.r.squared
#> [1] 0.6809434
summary(model_3)$adj.r.squared
#> [1] 0.6181464

💡 Kesimpulan : Model terbaik berdasarkan R-squared adalah model_all

0.3.5.2 Error/Residual

Selain itu, kita bisa melihat berdasarkan dengan error terkecilnya. Kali ini saya akan menggunakan metriks RMSE aka (Root Mean Squared Error).

#Menggunakan library `MLmetrics`
library(MLmetrics)

# Menghitung RMSE dari library MLmetrics
MAE(y_pred = house_pred$pred_all, y_true = house_pred$Price)
#> [1] 486136046
RMSE(y_pred = house_pred$pred_all, y_true = house_pred$Price)
#> [1] 707517644
range(house$Price)
#> [1]  205000000 5970000000

Interpretasi RMSE: Error kita masih cukup kecil, berada pada luar range data target kita

0.3.6 Asumsi Linear Regression

Sebagai salah satu model statistik, linear regression adalah model yang ketat asumsi.Berarti beberapa asumsi yang harus dicek untuk memastikan apakah model yang kita buat dianggap sebagai Best Linear Unbiased Estimator (BLUE) model, yaitu model yang dapat memprediksi data baru secara konsisten.

Homoscedasticity of Residuals dan No Multicollinearity

Kita akan mengechek hanya dengan model_all

0.3.6.1 Homoscedasticity of Residuals

plot(model_all, which = 1)

# scatter plot
plot(x = model_all$fitted.values, y = model_all$residuals)
abline(h = 0, col = "red")

Uji statistik dengan bptest() dari package lmtest

Breusch-Pagan hypothesis test:

  • H0: error menyebar konstan atau homoscedasticity
  • H1: error menyebar TIDAK konstan atau heteroscedasticity

Kondisi yang diharapkan: H0

H0 ditolak apabila nilai p-value < alpha

# bptest dari model
library(lmtest)
#install.packages("lmtest")
bptest(model_all)
#> 
#>  studentized Breusch-Pagan test
#> 
#> data:  model_all
#> BP = 836.6, df = 15, p-value < 0.00000000000000022

Kesimpulan: nilai p-value 0.00000000000000022 < alpha = 0.05, sehingga erorr kita tidak menyebar konstan. Asumsi tidak terpenuhi.

Mencoba model lain :

#Menggunakan model 1 prediktor
plot(model_1, which = 1)

bptest(model_1)
#> 
#>  studentized Breusch-Pagan test
#> 
#> data:  model_1
#> BP = 522.11, df = 1, p-value < 0.00000000000000022
bptest(model_3)
#> 
#>  studentized Breusch-Pagan test
#> 
#> data:  model_3
#> BP = 685.31, df = 3, p-value < 0.00000000000000022

Kesimpulan : Untuk semua model yang dibuat tidak memenuhi asumsi.

0.3.6.2 No Multicollinearity

Multicollinearity adalah kondisi adanya korelasi antar prediktor yang kuat. Hal ini tidak diinginkan karena menandakan prediktor redundan pada model, yang seharusnya dapat dipilih salah satu saja dari variable yang hubungannya amat kuat tersebut. Harapannya tidak terjadi multicollinearity

# vif dari model
library(car)
vif(model_all)
#>                   GVIF Df GVIF^(1/(2*Df))
#> K..Mandi      3.755235  1        1.937843
#> K..Tidur      3.403945  1        1.844978
#> L..Bangunan   2.862982  1        1.692035
#> Sertifikat    1.608076  5        1.048650
#> Tipe.Properti 2.878646  1        1.696657
#> Kota          1.440847  6        1.030904

Kesimpulan : Dari output VIF, model kita bebas multikolinearity (hubungan korelasi kuat antar prediktor)

#Menguji Model dengan variabel Numerik
vif(model_3)
#> L..Bangunan    K..Tidur    K..Mandi 
#>    2.534773    2.992041    3.380861

Kesimpulan: Dari output VIF, model kita bebas multikolinearity (hubungan korelasi kuat antar prediktor)

0.4 Conclusion

Variabel - variabel yang berguna untuk menjelaskan variasi Price atau harga properti adalah K..Mandi, K..Tidur, L..Bangunan,Tipe.PropertiRumah,SertifikatSHM - Sertifikat Hak Milik,KotaJakarta Barat,KotaJakarta Pusat, KotaJakarta Selatan, KotaJakarta Utara, KotaTangerang Selatan.

Model akhir kita telah memenuhi asumsi-asumsi klasik. R-squared dari model tersebut tinggi adalah model_all, dengan 68% variabel dapat menjelaskan variasi dalam harga properti. Walaupun, bagi saya model ini belum terlalu cukup baik dalam menjelaskan variasi tersebut.

Akurasi model dalam memprediksi harga properti diukur dengan RMSE sebesar 707517644, yang dimana Error kita masih cukup kecil, berada pada luar range data target yang ada.

Untuk model evaluasi yang lain perlu diperbaiki dan dikaji terlebih jauh karena menunjukan hasil yang tidak memenuhi asumsi yang ada.