Introduction to Data Sciences

Regression I : K-nearest neighbors


Kontak \(\downarrow\)
Email
Instagram https://www.instagram.com/jeremyheriyand/
RPubs https://rpubs.com/jeremyheriyand23/

NIM | 20214920008


Project Description

  Setelah kita mempelajari bagaiamana cara memprediksi kelas klasifikasi pada sesi sebelumnya, nah pada kali ini kita akan melanjutkan proses analisa prediktif yang menfokuskan pada variabel numerikal dan akan menggunakan regresi. K-nearest neighbors akan kita gunakan untuk membuat prediksi dengan rapih. Untuk memilih nilai K, kita akan memakai teknik cross-validation.

  Dalam memprediksi variabel numerik banyak sekali metode yang dapat digunakan, sebagai contohnya adalah pohon regresi, splines, dan metode lainnya. Namun, pada kali ini kita akan fokus pada algoritma K-nearest neighbors.

The Regression Problem

  Regresi merupakan bagian dari analisa prediktif yang menggunakan informasi masa lalu untuk memprediksi masa depan. Pada metode regresi yang difokuskan adalah variabel numerikal, tidak seperti sesi sebelumnya yang fokus pada variabel kategorikal. Variabel yang akan kita analisa dapat disebut sebagai variabel respon. Untuk contohnya adalah ketika kita ingin memprediksi harga jual rumah berdasarkan ukuran rumahnya.

  Saat membuat model regresi, hal yang pertama dilakukan adalah membagi data menjadi data set dan test untuk memastikan kinerja metode berjalan dengan baik. Selanjutnya, dapat dilakukan cross-validation untuk evaluasi nilai parameter.

Exploring a Data Set

  Pada kali ini, kita akan menggunakan data 932 Real Estate Transactions in Sacramento, California yang dilaporkan oleh Sacramento Bee Newspaper. Untuk melakukan sebuah prediksi pastinya ada pertanyaan yang muncul untuk diolah dan dianalisa, jadi pada data ini kita merumuskan sebuah pertanyaan, yaitu “Apakah ukuran rumah di Sacramento dapat menentukan harga rumah?” Dengan adanya pertanyaan ini diharapkan nanti hasil prediksi kita dapat berguna untuk memberikan informasi kepada perusahaan dan kepada klien.

Import Data

  Pertama-tama kita panggil library yang akan digunakan dan kita import data yang kita ingin analisa, yaitu sacramento.csv

library(tidyverse) #menginstal tidyverse dari library
library(tidymodels) #menginstal tidymodels dari library
library(gridExtra)  #menginstal gridExstra dari library
set.seed(5)

sacramento <- read_csv("C:/Users/Public/Matkul R DLL/sacramento.csv") #Perintah untuk menunjukan atau membaca  data sacramento pada data/dokumen
## Rows: 932 Columns: 9
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## chr (3): city, zip, type
## dbl (6): beds, baths, sqft, price, latitude, longitude
## 
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.
sacramento

Kita coba untuk menvisualisasikan data dengan scatter plot untuk mengetahui secara garis besar bagaimana hubungan antara ukuran rumah dan harga jualnya.

ntaps <- ggplot(sacramento, aes(x = sqft, y = price)) + #menunjukan data dan variabel
  geom_point(alpha = 0.5) +                             #menunjukan scatter plot
  xlab("House size (square feet)") +                    #Memberikan nama pada sumbu x (horizontal)
  ylab("Price (USD)") +                                 #Memberikan nama pada sumbu y (vertikal)
  scale_y_continuous(labels = dollar_format()) +        #Mengubah label menjadi dollar 
  theme(text = element_text(size = 10))                 #mengatur ukuran text 

ntaps

Dari grafik sebaran tersebut dapat kita katakan semakin bertambahnya ukuran rumah, maka harga jualnya juga meningkat.

K-nearest neighbors Regression

  Seperti yang sudah disinggung di awal bahwa kita akan menggunakan algoritma K-nearest neighbors untuk kasus regresi ini. Dan sebagai contohnya kita akan menggunakan random sampel sebanyak 30 menggunakan fungsi slice_sample.

sacramento_kecil <- slice_sample(sacramento, n = 30) #memanggil dokumen sacramento dengan 30 data saja

katakanlah terdapat rumah seluas 2000 meter dengan harga $350000 dan kita ingin mengetahui apakah rumah ini termasuk terlalu mahal atau murah.

plot_piyik <- ggplot(sacramento_kecil, aes(x = sqft, y = price)) + #menunjukan data dan variabel
  geom_point() +                                                   #menunjukan scatter plot
  xlab("House size (square feet)") +                               #Memberikan nama pada sumbu x (horizontal)
  ylab("Price (USD)") +                                            #Memberikan nama pada sumbu y (vertikal)
  scale_y_continuous(labels = dollar_format()) +                   #Mengubah label menjadi dollar
  geom_vline(xintercept = 2000, linetype = "dotted") +             #Memberikan titik potong pada nilai 2000 di sumbu horizontal(x)
  theme(text = element_text(size = 12))                            #mengatur ukuran text 

plot_piyik

karena tidak ada nilai yang persis dengan ukuran yang kita inginkan, maka kita dapat melakukan uji lanjut dengan mencari rata-rata dari 5 kota.a

nearest_neighbors <- sacramento_kecil |>    #memfilter data dari data sacramento_kecil
  mutate(diff = abs(2000 - sqft)) |>        #menambahkan variabel diff dengan variabel sqft 2000
  arrange(diff) |>                          #mengurutkan data diff dari terkecil ke terbesar
  slice(1:5)                                #mengambil 5 data dari data diff

nearest_neighbors #print
prediction <- nearest_neighbors |>             
  summarise(predicted = mean(price))           #memprediksi rata-rata pada summari

prediction

Kita sudah memprediksikan harga $272687 dimana harga tersebut sangat rendah dibanding harga yang ditawarkan. Keputusannya adalah kita lebih baik menawar rumah dengan ukuran dan harga tersebut. Namun, apakah langkah ini sudah benar? Jawabannya adalah kita perlu membuat smodel yang lebih baik lagi dengan regresi KNN.

Training, Evaluating, and Tuning The Model

  Kita akan membagi data sacramento menjadi dua bagian, yaitu data set dan data test dengan proporsi 0.75 dan variabel harga yang dijadikan strata.

sacramento_split <- initial_split(sacramento, prop = 0.75, strata = price) 
sacramento_train <- training(sacramento_split)
sacramento_test <- testing(sacramento_split)

Kita akan menggunakan metode cross-validation untuk mencari tahu seberapa akurat prediksi kita, untuk mencari hal itu kita gunakan RMSPE. Jika nilai RMSPE kecil, maka prediksi mendekati nilai kebenaran dan sebaliknya.

Selanjutnya kita akan membuat pra-proses data untuk mendapatkan standarisasi yang baik dalam data kita. Dan kita akan membuat spesifikasi untuk regresi kita menggunakan set_mode("regression"). Penggunaan fungsi tersebut pada dasarnya untuk mendapatkan model yang presisi untuk penyetelan dan evaluasi.

sacr_recipe <- recipe(price ~ sqft, data = sacramento_train) |>  #praproses data untuk mendapatkan standarisasi data
  step_scale(all_predictors()) |>
  step_center(all_predictors())

sacr_spec <- nearest_neighbor(weight_func = "rectangular",   
                              neighbors = tune()) |>
  set_engine("kknn") |>                                          #metode pengambilan analisis mengunakan KNN
  set_mode("regression")                                         #menentukan model pada regression

sacr_vfold <- vfold_cv(sacramento_train, v = 5, strata = price)  

sacr_wkflw <- workflow() |>
  add_recipe(sacr_recipe) |>
  add_model(sacr_spec)

sacr_wkflw #print
## == Workflow ====================================================================
## Preprocessor: Recipe
## Model: nearest_neighbor()
## 
## -- Preprocessor ----------------------------------------------------------------
## 2 Recipe Steps
## 
## * step_scale()
## * step_center()
## 
## -- Model -----------------------------------------------------------------------
## K-Nearest Neighbor Model Specification (regression)
## 
## Main Arguments:
##   neighbors = tune()
##   weight_func = rectangular
## 
## Computational engine: kknn

Kemudian, kita akan menjalankan cross-validation dengan jarak neighbors antara 1 sampai 200 yang nantinya akan menyetel dan mengembalikan RMSPE untuk setiap jumlah neighborsnya. Untuk mengetahui hasilnya, kita dapat menggunakan sacr_results dan akan terlihat nilai K, mean, nilai RMSPE, dan standar error.y

gridvals <- tibble(neighbors = seq(from = 1, to = 200, by = 3)) #Membuat masing-masing dari nilai K untuk menentukan RMSP terkecil dan standar error

sacr_results <- sacr_wkflw |>
  tune_grid(resamples = sacr_vfold, grid = gridvals) |>
  collect_metrics() |>
  filter(.metric == "rmse")
## Warning: package 'kknn' was built under R version 4.1.2
sacr_results

Kita ambil nilai terkecil dari RMSPE untuk mencari setelan nilai neighbors

sacr_min <- sacr_results |> 
  filter(mean == min(mean)) #untuk memfilter dari RMSPE kecil  

sacr_min #print

Dapat disimpulkan babhwa nilai K untuk disetting adalah 34

Underfitting and Overfitting

  Kita akan menggunakan model yang mengikuti tren keseluruhan dalam data test, sehingga dapat digunakan untuk mempelajari sesuatu yang berguna dan modelnya tidak mengikuti fluktuasi yang bising agar model yang dibuat dapat menggeneralisasi dengan baik ke data baru yang lain. Jika kita menelusuri nilai lain, terkhusus K = 34 dan kita dapat melihat tren peningkatan harga rumah berdasarkan ukuran rumah yang tidak terlalu dipengaruhi oleh variasi harga yang khas.

Evaluating on The Test Set

  Dalam menilai seberapa efektif rancangan yang kita buat, maka kita akan menilai RMSPE pada data test. Pertama-tama kita akan menguji kembali model yang kita buat menggunakan nilai K = 34 dan selanjutnya kita akan membuat prediksi pada data test. Karena kami menetapkan untuk melakukan regresi dengan set_mode nantinya kita akan mengetahui ringkasan kualitas yang terkait dengan regresi dan klasifikasi.

kmin <- sacr_min |> pull(neighbors)

sacr_spec <- nearest_neighbor(weight_func = "rectangular", neighbors = kmin) |>
  set_engine("kknn") |>                              #metode pengambilan analisis mengunakan KNN
  set_mode("regression")                             #menentukan model pada regrission

sacr_fit <- workflow() |>                            
  add_recipe(sacr_recipe) |>
  add_model(sacr_spec) |>
  fit(data = sacramento_train)
                                     
sacr_summary <- sacr_fit |>
  predict(sacramento_test) |>
  bind_cols(sacramento_test) |>
  metrics(truth = price, estimate = .pred) |>
  filter(.metric == 'rmse')
#mengunakan Metric RMSPE untuk menemukan standar prediksinya
sacr_summary #print

Dari hasil tersebut didapat bahwa tingkat error pada pengujian ini sekitar $89472.32 nilai ini hampir sama dengan estimasi RMSPE dengan cross-validation yang bernilai sekitar 85ribuan. Tingkat kesalahan ini dapat diterima tergantung pada aplikasinya saja, dalam kasus ini tidak terlalu besar, tetapi tidka boleh diabaikan.

sacr_preds <- tibble(sqft = seq(from = 500, to = 5000, by = 10)) 

sacr_preds <- sacr_fit |>
  predict(sacr_preds) |>
  bind_cols(sacr_preds)

plot_final <- ggplot(sacramento_train, aes(x = sqft, y = price)) +
  geom_point(alpha = 0.4) +
  geom_line(data = sacr_preds, 
            mapping = aes(x = sqft, y = .pred), 
            color = "blue") +
  xlab("House size (square feet)") +             #sumbuh x (horizontal)menampilkan ukuran rumah
  ylab("Price (USD)") +                          # sumbuh y (vertikal)menampilkan  harga rumah
  scale_y_continuous(labels = dollar_format()) + #Mengubah label tanda centang pada sumbu y
  ggtitle(paste0("K = ", kmin)) +                #membuat judul plot               
  theme(text = element_text(size = 12))

plot_final

Multivariable KNN Regression

  Kita dapat menggunakan beberapa prediktor pada regresi KNN. Hal yang patut diperhatikan adalah pemilihan prediktor harus yang memiliki potensi besar untuk memengaruhi prediksi kita. Kita akan menggunakan ukuran rumah dan jumlah kamar tidur sebagai prediktornya dan tentunya akan tetap menggunakan harga rumah sebagai targetnya.

plot_beds <- sacramento |>
  ggplot(aes(x = beds, y = price)) +                   #Membuat visualisasi data
  geom_point(alpha = 0.4) +                            #Menunjukan scatter plot
  labs(x = 'Number of Bedrooms', y = 'Price (USD)') +  #memberikan nama Pada sumbu x dan sumbu y
  theme(text = element_text(size = 12))                #Mengatur ukuran text 

plot_beds #print

Dari grafik tersebut semakin banyak jumlah kamar tidur, maka harga rumah juga semakin meningkat. Namun, kita harus perhatikan bahwa relasinya sangat lemah. Pertanyaannya adalah ketika kita menambahkan jumlah kamar tidur pada model yang kita buat apakah akan meningkatkan kemampuan untuk memprediksi harga? Untuk menjawabnya kita dapat membuat regresi KNN yang baru dengan prediktor yang baru juga.d

sacr_recipe <- recipe(price ~ sqft + beds, data = sacramento_train) |>  #melakukan preprosesing data
  step_scale(all_predictors()) |>                                       
  step_center(all_predictors())

sacr_spec <- nearest_neighbor(weight_func = "rectangular", 
                              neighbors = tune()) |>
  set_engine("kknn") |>                                                #metode pengambilan analisis mengunakan KNN
  set_mode("regression")                                               #menentukan model pada regression

selanjutnya, kita mencari nilai K berdasarkan nilai terkecil dari RMSPE.

gridvals <- tibble(neighbors = seq(1, 200))

sacr_multi <- workflow() |>
  add_recipe(sacr_recipe) |>
  add_model(sacr_spec) |>
  tune_grid(sacr_vfold, grid = gridvals) |>
  collect_metrics() |>
  filter(.metric == "rmse") |>
  filter(mean == min(mean))

sacr_k <- sacr_multi |>
              pull(neighbors)

sacr_multi #print

Terlihat bahwa nilai K = 25 dan kita bisa bandingkan ketika akurasi dengan satu prediksi dengan dua prediktor yang memiliki perbedaan. Selanjutnya, mari kita coba untuk analisa lanjut dengan nilai K yang sudah diketahui.

sacr_spec <- nearest_neighbor(weight_func = "rectangular", 
                              neighbors = sacr_k) |>
  set_engine("kknn") |>                                                        #metode pengambilan analisis mengunakan KNN
  set_mode("regression")                                                       #menentukan model pada regression


knn_mult_fit <- workflow() |>                                                  #menampilkan alurkerja dari knn_mult_fit  
  add_recipe(sacr_recipe) |>
  add_model(sacr_spec) |>                                                      
  fit(data = sacramento_train)

knn_mult_preds <- knn_mult_fit |>
  predict(sacramento_test) |>
  bind_cols(sacramento_test)

knn_mult_mets <- metrics(knn_mult_preds, truth = price, estimate = .pred) |>
                     filter(.metric == 'rmse')                                #Memfilter metric
knn_mult_mets #print

Dari hasil tersebut terdapat perbedaan ketika kita menambahkan prediktor baru, sehingga nilai akurasinya menjadi 88799.73 dan nilai ini berbedan ketika prediktornya hanya satu. Hal ini dapat kita simpulkan bahwa jumlah kamar tidur berhubungan dengan harga dan ukuran rumah.

Strengths and Limitations of KKN Regression

i  Dalam menggunakan metode ini, terdapat beberapa kelebihan dan kekurangan sebagai berikut ini.

Kelebihan


1. Simple dan Intuitif
2. Butuh asumsi data yang seharusnya seperti apa
3. Cara kerja yang baik dengan hubungan non-linear

Kekurangan


1. Data Training yang besar akan menjadi lama prosesnya
2. Tidak dapat berjalan baik ketika prediktornya banyak
3. Tidak dapat memprediksi dengan baik di luar nilai yang diinput pada data training