Introduction to Data Science
Regression I : K-Nearest Neighbor
Kontak | : \(\downarrow\) |
: ferd.widjaya@gmail.com | |
: https://www.instagram.com/ferd_nw/ | |
RPubs | : https://rpubs.com/ferdnw/ |
Introduction
Pada Chapter ini, untuk membuat suatu prediktif dari suatu variabel menggunakan regression. . Namun, regression memiliki persamaan dengan classification : sebagai contoh, dalam kasus klasifikasi, kita akan membagi data menjadi training, validation, dan test sets, kita akan menggunakan tidymodels
workflows, kita akan menggunakan KNN untuk membuat prediksi, dan kita akan menggunakan cross-validation untuk memilih K.
Objectives
Setelah mempelajari bab ini, diharapkan untuk :
• Mengenali situasi di mana analisis regresi yang mudah dapat sesuai dengan prediksi.
• Menjelaskan algoritma regresi KNN dan mendeskripsikan bagaimana ini berbeda dari klasifikasi KNN.
• Menafsirkan output dari regresi KNN.
• Dalam dataset dengan dua atau lebih variabel, menampilkan regresi KNN dengan R menggunakan tidymodels
workflow.
• Menjalankan cross-validation dalam R untuk memilih jumlah dari neighbors.
• Mengevaluasi prediksi regresi KNN akurasi dalam R menggunakan test dataset dan the root mean squared prediction error (RMSPE).
• Dalam konteks dari regresi KNN, bandingkan dan kontraskan kebaikan dari kesesuaian dan prediksi properti (bernama RMPE vs RMSPE).
• Mendeskripsikan keuntungan dan kerugian dari regresi KNN.
The Regression Problem
Regresi, seperti klasifikasi, adalah prediksi masalah pengaturan di mana kita akan menggunakan informasi sebelumnya untuk memprediksi observasi selanjutnya. Namun dalam kasus regresi, targetnya yaitu memprediksi nilai numerical sebagai gantinya dari nilai categorical. Variabel yang kita akan prediksikan yang sering disebut response variable. Seperti padan klasifikasi, ada banyak kemungkinan metode yang kita akan gunakan untuk prediksi respon variabel numerical. Pada bab ini kita akan fokus pada algoritma KNN (Fix and Hodges 1951; Cover and Hart 1967). Regresi memprediksi variabel respon pengamatan baru berdasarkan variabel respon serupa dalam dataset dari observasi sebelumnya. Saat membuat model regresi, kita mulai dari membagi data ke training dan test sets sama seperti pada melakukan classifications , untuk memastikan bahwa kita menilai kinerja dari metode kami pada observasi bukan melihat selama training. Dan akhirnya, kita bisa menggunakan cross-validation untuk evaluasi pilihan yang berbeda dari model parameters (seperti, K pada model KNN). Perbedaan utama adalah kita sekarang memprediksi variabel numerical bukan variabel categorical.
Exploring a Data Set
Menggunakan data set dari Transaksi Real Estate di Sacramento, California . Pertama kita perlu memformulasi pertanyaan yang tepat yang ingin kita jawab. Contohnya, pertanyaan kita bersifat prediksi : Bisakah kita menggunakan ukuran rumah di area Sacramento, CA untuk memprediksi harga jualnya?
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.1.2
## -- Attaching packages --------------------------------------- tidyverse 1.3.1 --
## v ggplot2 3.3.5 v purrr 0.3.4
## v tibble 3.1.4 v dplyr 1.0.7
## v tidyr 1.2.0 v stringr 1.4.0
## v readr 2.0.1 v forcats 0.5.1
## Warning: package 'tidyr' was built under R version 4.1.2
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
library(tidymodels)
## Warning: package 'tidymodels' was built under R version 4.1.2
## Registered S3 method overwritten by 'tune':
## method from
## required_pkgs.model_spec parsnip
## -- Attaching packages -------------------------------------- tidymodels 0.1.4 --
## v broom 0.7.9 v rsample 0.1.1
## v dials 0.1.0 v tune 0.1.6
## v infer 1.0.0 v workflows 0.2.4
## v modeldata 0.1.1 v workflowsets 0.1.0
## v parsnip 0.1.7 v yardstick 0.0.9
## v recipes 0.1.17
## Warning: package 'dials' was built under R version 4.1.2
## Warning: package 'infer' was built under R version 4.1.2
## Warning: package 'modeldata' was built under R version 4.1.2
## Warning: package 'parsnip' was built under R version 4.1.2
## Warning: package 'recipes' was built under R version 4.1.2
## Warning: package 'rsample' was built under R version 4.1.2
## Warning: package 'tune' was built under R version 4.1.2
## Warning: package 'workflows' was built under R version 4.1.2
## Warning: package 'workflowsets' was built under R version 4.1.2
## Warning: package 'yardstick' was built under R version 4.1.2
## -- Conflicts ----------------------------------------- tidymodels_conflicts() --
## x scales::discard() masks purrr::discard()
## x dplyr::filter() masks stats::filter()
## x recipes::fixed() masks stringr::fixed()
## x dplyr::lag() masks stats::lag()
## x yardstick::spec() masks readr::spec()
## x recipes::step() masks stats::step()
## * Dig deeper into tidy modeling with R at https://www.tmwr.org
library(gridExtra)
##
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
##
## combine
set.seed(5)
<- read_csv("C:/Users/5/Documents/Semester2/Input/sacramento.txt") sacramento
## 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
Kolom yang dibutuhkan untuk menjawab pertanyaan kita adalah sqft (ukuran rumah, in square foot) dan price (house sale price (USD)). Langkah pertama yaitu memvisualisasi data sebagai scatter plot dimana kita menempatkan variabel prediktor (house size) pada sumbu x, dan kita menempatkan variabel target/repons yang kita ingin prediksikan (sale price) pada sumbu y.
Note -> Pada figure 7.1, unit sumbu y adalah dolar, kita memformat label sumb y untuk meletakkan tanda dolar di depan house price, serta koma untuk meningkatkan keterbacaan angka yang lebih besar. Kita bisa melakukan ini di R dengan meneruskan fungsi dollar_format (dari paket scales) ke argumen label dari fungsi scale_y_continuous
<- ggplot(sacramento, aes(x = sqft, y = price)) +
eda geom_point(alpha = 0.4) +
xlab("House size (square feet)") +
ylab("Price (USD)") +
scale_y_continuous(labels = dollar_format()) +
theme(text = element_text(size = 12))
eda
Scatter Plot menunjukkan bahwa di Sacramento, CA, semakin besar ukuran rumah, maka harga jualnya juga semakin meningkat. Dengan demikian, kita mungkin dapat menggunakan ukuran rumah yang belum terjual (yang kita tidak tahu harga jualnya) untuk memprediksi harga jual akhirnya.
K-Nearest Neighbor Regression
Sama seperti klasifikasi, kita dapat menggunakan pendekatan berbasis K-nearest neighbor dalam regresi untuk membuat prediksi. Untuk mengetahui cara kerja Regression dari KNN kita akan mencobanya dengan sample untuk menggambarkan cara kerjanya. Menggunakan command slice_sample
untuk mengambil 30 data sampel secara acak.
<- slice_sample(sacramento, n = 30) small_sacramento
Dalam suatu kondisi, andaikan ada rumah dengan luas 2000 sqft di Sacramento dengan harga $350.000 APakah harga tersebut sudah pas? atau seharusnya terlalu mahal dan harus di tawar? Kita bisa tahu jawabannya walau tidak ada data observasi dengan nilai yang sama.
<- ggplot(small_sacramento, aes(x = sqft, y = price)) +
small_plot geom_point() +
xlab("House size (square feet)") +
ylab("Price (USD)") +
scale_y_continuous(labels = dollar_format()) +
geom_vline(xintercept = 2000, linetype = "dotted") +
theme(text = element_text(size = 12))
small_plot
Kita akan menggunakan metode yang sama dari bab klasifikasi, dan menggunakan titik-titik tetangga ke prediksi titik yang baru untuk menyarankan/memprediksi berapa harga jualnya. Kita menemukan dan memberi label 5 tetangga terdekat dengan pengamatan kami terhadap sebuah rumah seluas 2.000 kaki persegi.
<- small_sacramento |>
nearest_neighbors mutate(diff = abs(2000 - sqft)) |>
arrange(diff) |>
slice(1:5) #subset the first 5 rows
nearest_neighbors
Chunk di atas mengilustrasikan perbedaan antara ukuran rumah dari 5 tetangga terdekat (dalam hal ukuran rumah) dengan rumah baruseluas 2.000 sqft . Sekarang setelah kita mendapatkan tetangga terdekat ini, kita dapat menggunakan nilainya untuk memprediksi harga jual rumah baru. Secara khusus, kita dapat mengambil mean (atau rata-rata) dari 5 nilai ini
<- nearest_neighbors |>
prediction summarise(predicted = mean(price))
prediction
Rumah yang harga nilai jualnya di prediksi ditandai dengan titik merah dengan nilai $326,324 , dibawah harga yang diajukan. Salah satu kekuatan dari algoritma regresi KNN yang ingin kami perhatikan pada saat ini adalah kemampuannya untuk bekerja dengan baik dengan hubungan non-linier (yaitu, jika hubungannya bukan garis lurus). Ini berasal dari penggunaan tetangga terdekat untuk memprediksi nilai.
Training Eavluating and Tuning the Model
Seperti bab sebelumnya, dataset dibagi menjadi training set dan test set dengan ratio 75-25
<- initial_split(sacramento, prop = 0.75, strata = price)
sacramento_split <- training(sacramento_split)
sacramento_train <- testing(sacramento_split) sacramento_test
Selanjutnya, kita akan menggunakan validasi silang untuk memilih K. Dalam klasifikasi KNN, kita menggunakan akurasi untuk melihat seberapa baik prediksi kami cocok dengan label sebenarnya. Kita tidak dapat menggunakan metrik yang sama dalam pengaturan regresi, karena prediksi kita hampir tidak akan pernah sama persis dengan nilai variabel respons yang sebenarnya. Oleh karena itu dalam konteks regresi KNN kita akan menggunakan root mean square prediksi error (RMSPE) sebagai gantinya. Jika prediksi sangat mendekati nilai sebenarnya, maka RMSPE akan kecil. Sebaliknya, jika prediksi sangat berbeda dari nilai sebenarnya, maka RMSPE akan cukup besar. Saat kami menggunakan validasi silang, kami akan memilih K yang memberi kita RMSPE terkecil.
Note -> Saat menggunakan banyak paket kode (termasuk model rapi), keluaran evaluasi yang akan kami peroleh untuk menilai kualitas prediksi model regresi KNN kami diberi label “RMSE,” atau “root mean squared error.”
Sekarang kita tahu bagaimana kita dapat menilai seberapa baik model kita memprediksi nilai numerik, mari kita gunakan R untuk melakukan validasi silang dan untuk memilih K yang optimal . Pertama, kita akan membuat resep untuk preprocessing data kita. Perhatikan bahwa kami menyertakan standarisasi dalam prapemrosesan kami untuk membangun kebiasaan yang baik, tetapi karena kami hanya memiliki satu prediktor, secara teknis hal itu tidak diperlukan; tidak ada risiko membandingkan dua prediktor dari skala yang berbeda.
Selanjutnya kita membuat spesifikasi model untuk regresi K-nearest neighbor. Kemudian kita membuatcross validation 5 kali , dan menyatukan recipe dan spesifikasi model dalam workflow .
<- recipe(price ~ sqft, data = sacramento_train) |>
sacr_recipe step_scale(all_predictors()) |>
step_center(all_predictors())
<- nearest_neighbor(weight_func = "rectangular",
sacr_spec neighbors = tune()) |>
set_engine("kknn") |>
set_mode("regression")
<- vfold_cv(sacramento_train, v = 5, strata = price)
sacr_vfold
<- workflow() |>
sacr_wkflw add_recipe(sacr_recipe) |>
add_model(sacr_spec)
sacr_wkflw
## == 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
Selanjutnya kita menjalankan validasi silang untuk kisi jumlah tetangga mulai dari 1 hingga 200. Kode berikut menyetel model dan mengembalikan RMSPE untuk setiap jumlah tetangga. Dalam output dari frame data hasil sacr_results, kita melihat bahwa variabel tetangga berisi nilai K, mean (mean) berisi nilai RMSPE yang diperkirakan melalui validasi silang, dan kesalahan standar (std_err) berisi nilai yang sesuai dengan ukuran seberapa tidak pasti kita dalam nilai mean. Penjelasan rinci tentang hal ini berada di luar cakupan bab ini; tetapi secara kasar, jika perkiraan rata-rata Anda adalah 100.000 dan kesalahan standar adalah 1.000, Anda dapat mengharapkan RMSPE yang sebenarnya berada di suatu tempat kira-kira antara 99.000 dan 101.000 (meskipun mungkin berada di luar kisaran ini). Anda dapat mengabaikan kolom lain dalam kerangka data metrik
<- tibble(neighbors = seq(from = 1, to = 200, by = 3))
gridvals
<- sacr_wkflw |>
sacr_results tune_grid(resamples = sacr_vfold, grid = gridvals) |>
collect_metrics() |>
filter(.metric == "rmse")
## Warning: package 'kknn' was built under R version 4.1.2
# show the results
sacr_results
Mengambil RMSPE Terkecil
# show only the row of minimum RMSPE
<- sacr_results |>
sacr_min filter(mean == min(mean))
sacr_min
RMSPE terkecil ada di K=37.
Underfitting dan overfitting
sama seperti klasifikasi, pemilihan jumlah k yang salah juga bisa merusak model regresi yang kita buat, nilai RSMPE Meroket. Nilai akan terlalu dipengaruhi atau kurang dipengaruhi oleh data lainnya sehingga prediksi menjadi tidak jelas.
Idealnya, yang kita inginkan bukanlah kedua situasi yang dibahas di atas. Sebagai gantinya, kita ingin model yang (1) mengikuti “tren” keseluruhan dalam training datan, sehingga model tersebut benar-benar menggunakan training data untuk mempelajari sesuatu yang berguna, dan (2) tidak mengikuti fluktuasi , sehingga kami dapat yakinlah bahwa model kami akan mentransfer/menggeneralisasi dengan baik ke data baru lainnya. Jika kita menjelajahi nilai-nilai lain untuk K, khususnya K = 37 (seperti yang disarankan oleh cross validation ), kita dapat melihatnya mencapai tujuan ini: mengikuti tren kenaikan harga rumah versus ukuran rumah, tetapi tidak terlalu dipengaruhi oleh variasi harga yang istimewa. Semua ini mirip dengan bagaimana pilihan K mempengaruhi klasifikasi K-tetangga terdekat, seperti yang dibahas dalam bab sebelumnya.
Evaluating on Test Set
Untuk menilai seberapa baik model kami dalam memprediksi data yang tidak terlihat, kami akan menilai RMSPE-nya pada data uji. Untuk melakukan ini, pertama-tama kita akan melatih kembali model regresi KNN kita di seluruh kumpulan data pelatihan, menggunakan K=37 Kemudian kita akan menggunakan prediksi untuk membuat prediksi pada test set, dan menggunakan fungsi metrik lagi untuk menghitung ringkasan kualitas regresi
<- sacr_min |> pull(neighbors)
kmin
<- nearest_neighbor(weight_func = "rectangular", neighbors = kmin) |>
sacr_spec set_engine("kknn") |>
set_mode("regression")
<- workflow() |>
sacr_fit add_recipe(sacr_recipe) |>
add_model(sacr_spec) |>
fit(data = sacramento_train)
<- sacr_fit |>
sacr_summary predict(sacramento_test) |>
bind_cols(sacramento_test) |>
metrics(truth = price, estimate = .pred) |>
filter(.metric == 'rmse')
sacr_summary
kami memperkirakan kesalahan dalam prediksi kami kira-kira USD89.279. Dari satu perspektif, ini adalah kabar baik: ini hampir sama dengan estimasi RMSPE validasi silang dari model kami yang disetel (yaitu USD85.227), jadi kami dapat mengatakan bahwa model tersebut tampaknya digeneralisasi dengan baik ke data baru yang belum pernah dilihatnya sebelum. Namun, seperti halnya klasifikasi KNN, apakah nilai untuk RMSPE ini baik—yaitu, apakah kesalahan sekitar USD89.279 dapat diterima—bergantung sepenuhnya pada aplikasi. Dalam aplikasi ini, kesalahan ini tidak terlalu besar, tetapi juga tidak dapat diabaikan; USD89.279 mungkin mewakili sebagian besar anggaran pembeli rumah
Grafik menunjukkan prediksi yang dibuat model akhir kami di berbagai ukuran rumah yang mungkin kami temui di area Sacramento—dari 500 hingga 5000 kaki persegi
<- tibble(sqft = seq(from = 500, to = 5000, by = 10))
sacr_preds
<- sacr_fit |>
sacr_preds predict(sacr_preds) |>
bind_cols(sacr_preds)
<- ggplot(sacramento_train, aes(x = sqft, y = price)) +
plot_final geom_point(alpha = 0.4) +
geom_line(data = sacr_preds,
mapping = aes(x = sqft, y = .pred),
color = "blue") +
xlab("House size (square feet)") +
ylab("Price (USD)") +
scale_y_continuous(labels = dollar_format()) +
ggtitle(paste0("K = ", kmin)) +
theme(text = element_text(size = 12))
plot_final
Multivariable KNN Regression
Seperti pada klasifikasi KNN, kita dapat menggunakan beberapa prediktor dalam regresi KNN. Dalam pengaturan ini, Sekali lagi, prediksi dibuat dengan mengidentifikasi K pengamatan yang paling dekat dengan titik baru yang ingin kita prediksi. Dalam regresi KNN seperti pada klasifikasi KNN: memiliki lebih banyak prediktor tidak selalu lebih akurat , dan pilihan prediktor mana yang akan digunakan berpotensi besar mempengaruhi kualitas prediksi.
Kami sekarang akan mendemonstrasikan analisis regresi KNN multivariabel dari data real estate Sacramento menggunakan tidymodels
. Kali ini kami akan menggunakan ukuran rumah (diukur dalam kaki persegi) serta jumlah kamar tidur sebagai prediktor kami, dan terus menggunakan harga jual rumah sebagai variabel hasil/target yang kami coba prediksi.
<- sacramento |>
plot_beds ggplot(aes(x = beds, y = price)) +
geom_point(alpha = 0.4) +
labs(x = 'Number of Bedrooms', y = 'Price (USD)') +
theme(text = element_text(size = 12))
plot_beds
Grafik menunjukkan bahwa dengan bertambahnya jumlah kamar tidur, harga jual rumah juga cenderung meningkat, tetapi hubungannya cukup lemah. Apakah menambahkan jumlah kamar tidur ke model sebelumnya daoat meningkatkan kemampuan untuk memprediksi harga? Untuk menjawab pertanyaan itu, kita harus membuat model regresi KNN baru menggunakan ukuran rumah dan jumlah kamar tidur, dan kemudian kita dapat membandingkannya dengan model yang sebelumnya
<- recipe(price ~ sqft + beds, data = sacramento_train) |>
sacr_recipe step_scale(all_predictors()) |>
step_center(all_predictors())
<- nearest_neighbor(weight_func = "rectangular",
sacr_spec neighbors = tune()) |>
set_engine("kknn") |>
set_mode("regression")
Mencari nilai K dimana RMPSE paling kecil menggunakan 5 Kali Cross Validation
<- tibble(neighbors = seq(1, 200))
gridvals
<- workflow() |>
sacr_multi add_recipe(sacr_recipe) |>
add_model(sacr_spec) |>
tune_grid(sacr_vfold, grid = gridvals) |>
collect_metrics() |>
filter(.metric == "rmse") |>
filter(mean == min(mean))
<- sacr_multi |>
sacr_k pull(neighbors)
sacr_multi
Di sini kita melihat bahwa estimasi RMSPE terkecil dari validasi silang terjadi ketika K=12. kita ingin membandingkan model regresi KNN multivariabel ini dengan model dengan hanya satu prediktor sebagai bagian dari proses penyetelan model. Cross Validation untuk model prediktor tunggal adalah 85.227. Perkiraan akurasi Cross Validation untuk model multivariabel adalah 82.648. Jadi dalam hal ini, kami tidak meningkatkan model dalam tingkat akurasi yang signifikan besarnya dengan menambahkan prediktor tambahan ini. Melanjutkan analisis untuk melihat bagaimana prediksi dengan model regresi KNN multivariabel dan mengevaluasi kinerjanya pada Test set dengan K=12 .
<- nearest_neighbor(weight_func = "rectangular",
sacr_spec neighbors = sacr_k) |>
set_engine("kknn") |>
set_mode("regression")
<- workflow() |>
knn_mult_fit add_recipe(sacr_recipe) |>
add_model(sacr_spec) |>
fit(data = sacramento_train)
<- knn_mult_fit |>
knn_mult_preds predict(sacramento_test) |>
bind_cols(sacramento_test)
<- metrics(knn_mult_preds, truth = price, estimate = .pred) |>
knn_mult_mets filter(.metric == 'rmse')
knn_mult_mets
Kali ini, ketika dilakukan regresi KNN pada kumpulan data test, tetapi memasukkan jumlah kamar tidur sebagai prediktor, kami memperoleh kesalahan uji RMSPE sebesar 90.953.
Karena prediktor yang baru ditambahkan (jumlah kamar tidur) terkait dengan harga (adanya perubahan harga, demikian juga jumlah kamar tidur) dan tidak sepenuhnya ditentukan oleh ukuran rumah (prediktor yang lain), kami mendapatkan informasi tambahan dan berguna untuk membuat prediksi lainnya. Misalnya, dalam model ini kami akan memprediksi bahwa biaya rumah dengan ukuran 2.500 kaki persegi umumnya sedikit meningkat seiring dengan peningkatan jumlah kamar tidur. Tanpa tambahan prediktor jumlah kamar tidur, kami akan memprediksi harga yang sama untuk kedua rumah ini.
Plus Minus dari Regression with KNN
Plus Side
1. Algortima yang simple
2. Bekerja dengan baik bahkan pasa hubungan non-linear
Minus Side
1. Melambat ketika data semakin membesar
2. Tidak terlalu optimal dnegan jumlah prediktor yang banyak
3. Mungkin tidak terlalu bisa memprediksi dengan baik di luar range input dalam data.