Dengan menggunakan data Auto
dari package
ISLR (pastikan sudah diinstall),
gunakan peubah respon mpg
dan pilih tiga kolom lainnya
untuk dijadikan peubah prediktor.
Apakah ada bukti bahwa peubah-peubah yang dipilih tersebut memiliki pola hubungan non linear. Buktikan dengan visualisasi untuk mendukung jawaban tersebut.
Lakukan pendekatan Smoothing Spline da Local Regression untuk mengenal dengan baik pola hubungan ketiga pasangan peubah yang telah dipilih sebelumnya.
library(tidyverse)
## -- 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.1.3 v stringr 1.4.0
## v readr 2.0.1 v forcats 0.5.1
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
library(splines) # Natural Cubic Spline
library(rsample) # validasi silang k fold (vfold_cv)
library(cowplot) # plot_grid
library(DT) # datatable
library(mlr3measures)
## In order to avoid name clashes, do not attach 'mlr3measures'. Instead, only load the namespace with `requireNamespace("mlrmeasures")` and access the measures directly via `::`, e.g. `mlr3measures::auc()`.
library(ISLR)
library(grid)
<- Auto
Auto data("Auto",package = "ISLR")
datatable(Auto)
Tabel di atas adalah data frame dengan 392 observasi yang terdiri
dari 9 peubah. Pada pembahasan ini, dipilih 3 kolom yang akan menjadi
peubah prediktor yaitu horsepower
, weight
, dan
displacement
. Pola hubungan antara peubah respon
mpg
dan masing-peubah prediktor akan disajikan secara
visual pada penjelasan di bawah ini.
mpg
vs
horsepower
ggplot(Auto,aes(x=horsepower, y=mpg)) +
geom_point(alpha=0.55, color="black") +
ggtitle("Horse Power VS mile per gallon") +
xlab("Horse Power")+
ylab("mile per gallon")+
theme_grey()
Dari scatter plot di atas, secara umum terlihat bahwa semakin besar kekuatan mesin (horsepower) suatu mobil, semakin pendek jarak yang ditempuh kendaraan itu per galon bahan bakarnya. Artinya semakin kuat mesinnya, maka semakin boros. Dapat dilihat pula bahwa hubungan antara kekuatan mesin kendaraan (pada sumbu X) dan jarak yang dapat ditempuh oleh kendaraan per galon bahan bakarnya (pada sumbu Y) bersifat tidak linear.
mpg
vs weight
ggplot(Auto,aes(x=weight, y=mpg)) +
geom_point(alpha=0.55, color="black") +
ggtitle("Weight VS mile per gallon") +
xlab("Weight")+
ylab("mile per gallon")+
theme_grey()
Dari scatter plot di atas, secara umum terlihat bahwa semakin besar berat (weight) suatu mobil, semakin banyak bahan bakar yang dikonsumsi, namun jarak yang ditempuh kendaraan itu per galon bahan bakarnya semakin pendek. Artinya semakin berat mesinnya, maka semakin boros. Dapat dilihat pula bahwa hubungan antara berat mobil (pada sumbu X) dan jarak yang dapat ditempuh oleh kendaraan per galon bahan bakarnya (pada sumbu Y) bersifat tidak linear.
mpg
vs
displacement
ggplot(Auto,aes(x=displacement, y=mpg)) +
geom_point(alpha=0.55, color="black") +
ggtitle("displacement VS mile per gallon") +
xlab("displacement")+
ylab("mile per gallon")+
theme_grey()
Dari scatter plot di atas, hubungan antara displacement (pada sumbu X) dan jarak yang dapat ditempuh oleh kendaraan per galon bahan bakarnya (pada sumbu Y) bersifat tidak linear.
Jika hubungan masing-masing ketiga peubah prediktor tersebut dengan
peubah respon mpg
dipaksakan dengan regresi linear
sederhana, maka akan terlihat seperti berikut.
<- ggplot(Auto,aes(x=horsepower, y=mpg)) +
plot_hp geom_point(alpha=0.55, color="black") +
ggtitle("Horse Power VS mile per gallon") +
xlab("Horse Power")+
ylab("mile per gallon")+
stat_smooth(method = "lm",
formula = y~x,lty = 1,
col = "blue",se = F)+
theme_grey()
<- ggplot(Auto,aes(x=weight, y=mpg)) +
plot_weight geom_point(alpha=0.55, color="black") +
ggtitle("Weight VS mile per gallon") +
xlab("Weight")+
ylab("mile per gallon")+
stat_smooth(method = "lm",
formula = y~x,lty = 1,
col = "blue",se = F)+
theme_grey()
<- ggplot(Auto,aes(x=displacement, y=mpg)) +
plot_displacement geom_point(alpha=0.55, color="black") +
ggtitle("Displacement VS mile per gallon") +
xlab("Displacement")+
ylab("mile per gallon")+
stat_smooth(method = "lm",
formula = y~x,lty = 1,
col = "blue",se = F)+
theme_grey()
plot_grid(plot_hp, plot_weight, plot_displacement)
Tampak bahwa hubungan linear tidak masuk akal karena seolah jika
mengikuti garis linearnya maka kendaraan dengan kekuatan mesin yang
lebih besar lagi akan menempuh jarak nol atau bahkan negatif per galon
bahan bakarnya. Ini jelas tidak mungkin. Demikian halnya untuk hubungan
antara peubah mpg
vs weight
dan
mpg
vs displacement
.
Oleh karena itu, untuk memetakan data dengan baik agar dapat
digunakan dalam analisis lanjutan, akan dilakukan pendekatan
Smoothing Spline dan Local Regression
pada data mpg
vs horsepower
, mpg
vs weight
dan mpg
vs displacement
agar dapat mengenali pola hubungan data yang tidak linear tersebut.
Metode Smoothing Spline pada R dilakukan dengan menggunakan fungsi
smooth.spline()
. Fungsi smooth.spline()
tersebut secara otomatis memilih parameter lambda
terbaik
dengan menggunakan Cross-Validation (CV) dan
Generalized Cross-Validation (GCV).
Perbedaan utama antara keduanya adalah pada ukuran kebaikan model yang digunakan. Kalau CV menggunakan MSE sebagai ukuran kebaikan model, sedangkan GCV menggunakan Weighted-MSE. Banyaknya folds (lipatan) pada CV dan GCV ini adalah sejumlah observasinya.
mpg
vs
horsepower
<- with(data = Auto,smooth.spline(horsepower,mpg))
model_sms_hp model_sms_hp
## Call:
## smooth.spline(x = horsepower, y = mpg)
##
## Smoothing Parameter spar= 0.2648644 lambda= 5.101567e-07 (12 iterations)
## Equivalent Degrees of Freedom (Df): 42.14987
## Penalized Criterion (RSS): 1117.657
## GCV: 18.64132
Output data di atas menunjukkan bahwa dengan pendekatan
Smoothing Spline pada data mpg
vs
horsepower
diperoleh secara otomatis dengan GCV nilai
lambda yang sangat kecil yaitu mendekati 0 dengan 12 kali iterasi
sebagai parameter lambda terbaik. Dari hasil penentuan model smoothing
splines terbaik tersebut, berikut diperlihatkan secara visual hasil
Smoothing Spline pada data mpg
vs
horsepower
.
<- broom::augment(model_sms_hp)
pred_data
ggplot(pred_data,aes(x=x,y=y))+
geom_point(alpha=0.55, color="black")+
geom_line(aes(y=.fitted),col="blue",
lty=1)+
xlab("horsepower")+
ylab("mpg")+
theme_bw()
Plot data di atas menunjukkan bahwa model smoothing spline yang
diperoleh masih terlihat “jumpy” atau masih belum mulus, sehingga
berikut akan dilakukan simulasi dengen mengubah parameter lambda agar
diproleh model yang lebih mulus dan mampu menggambarkan pola hubungan
data antara mpg
vs horsepower
dengan sangat
baik.
<- data.frame(lambda=seq(0,5,by=0.5)) %>%
model_sms_lambda group_by(lambda) %>%
do(broom::augment(with(data = Auto,smooth.spline(horsepower,mpg,lambda = .$lambda))))
<- ggplot(model_sms_lambda,
p aes(x=x,y=y))+
geom_line(aes(y=.fitted),
col="blue",
lty=1
+
)facet_wrap(~lambda)
p
Ilustrasi di atas menunjukkan bahwa semakin besar parameter lambda maka model regresi yang dihasilkan akan semakin mulus, bahkan cenderung linear.
Jika kita tentukan df=5
, maka hasil kurva model
smooth.spline
akan lebih merepresentasikan data
<- with(data = Auto,smooth.spline(horsepower,mpg,df=5))
model_sms_hp model_sms_hp
## Call:
## smooth.spline(x = horsepower, y = mpg, df = 5)
##
## Smoothing Parameter spar= 0.8891706 lambda= 0.01650666 (14 iterations)
## Equivalent Degrees of Freedom (Df): 5.000611
## Penalized Criterion (RSS): 2564.889
## GCV: 19.02216
<- broom::augment(model_sms_hp)
pred_data
ggplot(pred_data,aes(x=x,y=y))+
geom_point(alpha=0.55, color="black")+
geom_line(aes(y=.fitted),col="blue",
lty=1)+
xlab("horsepower")+
ylab("mpg")+
theme_bw()
mpg
vs weight
<- with(data = Auto,smooth.spline(weight,mpg))
model_sms_weight model_sms_weight
## Call:
## smooth.spline(x = weight, y = mpg)
##
## Smoothing Parameter spar= 1.138481 lambda= 0.08299391 (16 iterations)
## Equivalent Degrees of Freedom (Df): 3.674305
## Penalized Criterion (RSS): 6000.624
## GCV: 17.63865
Output data di atas menunjukkan bahwa dengan pendekatan
Smoothing Spline pada data mpg
vs
weight
diperoleh secara otomatis dengan GCV nilai lambda
terbaik yaitu 0,083 dengan 16 kali iterasi. Dari hasil penentuan model
smoothing splines terbaik tersebut, berikut diperlihatkan secara visual
hasil Smoothing Spline pada data mpg
vs
weight
.
<- broom::augment(model_sms_weight)
pred_data
ggplot(pred_data,aes(x=x,y=y))+
geom_point(alpha=0.55, color="black")+
geom_line(aes(y=.fitted),col="blue",
lty=1)+
xlab("weight")+
ylab("mpg")+
theme_bw()
Plot data di atas menunjukkan bahwa model smoothing spline yang
diperoleh sudah cukup mulus untuk dapat mereprentasikan pola hubungan
data antara mpg
vs weight
.
mpg
vs
displacement
<- with(data = Auto,smooth.spline(displacement,mpg))
model_sms_displacement model_sms_displacement
## Call:
## smooth.spline(x = displacement, y = mpg)
##
## Smoothing Parameter spar= 0.08978477 lambda= 6.674266e-09 (13 iterations)
## Equivalent Degrees of Freedom (Df): 52.73308
## Penalized Criterion (RSS): 471.1873
## GCV: 16.58384
Output data di atas menunjukkan bahwa dengan pendekatan
Smoothing Spline pada data mpg
vs
displacement
diperoleh secara otomatis dengan GCV nilai
lambda terbaik yaitu 0 dengan 13 kali iterasi. Dari hasil penentuan
model smoothing splines terbaik tersebut, berikut diperlihatkan secara
visual hasil Smoothing Spline pada data
mpg
vs displacement
.
<- broom::augment(model_sms_displacement)
pred_data
ggplot(pred_data,aes(x=x,y=y))+
geom_point(alpha=0.55, color="black")+
geom_line(aes(y=.fitted),col="blue",
lty=1)+
xlab("displacement")+
ylab("mpg")+
theme_bw()
Plot data di atas menunjukkan bahwa model smoothing spline yang
diperoleh masih terlihat “jumpy” atau masih belum mulus, sehingga
berikut akan dilakukan simulasi dengen mengubah parameter lambda agar
diproleh model yang lebih mulus dan mampu menggambarkan pola hubungan
data antara mpg
vs displacement
dengan sangat
baik.
<- data.frame(lambda=seq(0,5,by=0.5)) %>%
model_sms_lambda1 group_by(lambda) %>%
do(broom::augment(with(data = Auto,smooth.spline(displacement,mpg,lambda = .$lambda))))
<- ggplot(model_sms_lambda1,
p aes(x=x,y=y))+
geom_line(aes(y=.fitted),
col="blue",
lty=1
+
)facet_wrap(~lambda)
p
Ilustrasi di atas menunjukkan bahwa semakin besar parameter lambda maka model regresi yang dihasilkan akan semakin mulus, bahkan cenderung linear.
Jika kita tentukan df=5
, maka hasil kurva model
smooth.spline
akan lebih merepresentasikan data dengan
baik.
<- with(data = Auto,smooth.spline(displacement,mpg,df=5))
model_sms_displacement model_sms_displacement
## Call:
## smooth.spline(x = displacement, y = mpg, df = 5)
##
## Smoothing Parameter spar= 0.9815859 lambda= 0.01851043 (12 iterations)
## Equivalent Degrees of Freedom (Df): 5.000745
## Penalized Criterion (RSS): 2936.755
## GCV: 19.19855
<- broom::augment(model_sms_displacement)
pred_data1
ggplot(pred_data1,aes(x=x,y=y))+
geom_point(alpha=0.55, color="black")+
geom_line(aes(y=.fitted),col="blue",
lty=1)+
xlab("displacement")+
ylab("mpg")+
theme_bw()
Masih menggunakan data Auto
seperti pada ilustrasi
sebelumnya, kali ini kita akan mencoba melakukan pendekatan
local regression dengan fungsi
loess()
.
mpg
vs
horsepower
<- loess(mpg~horsepower,
Model_loess_hp data = Auto)
summary(Model_loess_hp)
## Call:
## loess(formula = mpg ~ horsepower, data = Auto)
##
## Number of Observations: 392
## Equivalent Number of Parameters: 4.97
## Residual Standard Error: 4.32
## Trace of smoother matrix: 5.43 (exact)
##
## Control settings:
## span : 0.75
## degree : 2
## family : gaussian
## surface : interpolate cell = 0.2
## normalize: TRUE
## parametric: FALSE
## drop.square: FALSE
Pengaruh parameter span
terhadap tingkat smoothness
kurva bisa dilihat dari ilustrasi berikut:
<- data.frame(span=seq(0.1,5,by=0.5)) %>%
model_loess_span_hp group_by(span) %>%
do(broom::augment(loess(mpg~horsepower,
data = Auto,span=.$span)))
<- ggplot(model_loess_span_hp,
p2 aes(x=horsepower,y=mpg))+
geom_line(aes(y=.fitted),
col="blue",
lty=1
+
)facet_wrap(~span)
p2
Tuning span
dapat dilakukan dengan menggunakan
cross-validation
set.seed(123)
<- vfold_cv(Auto,v=5,strata = "mpg")
cross_val
<- seq(0.1,1,length.out=50)
span
<- map_dfr(span, function(i){
best_loess <- map_dfr(cross_val$splits,
metric_loess function(x){
<- loess(mpg ~ horsepower,span = i,
mod data=Auto[x$in_id,])
<- predict(mod,
pred newdata=Auto[-x$in_id,])
<- Auto[-x$in_id,]$mpg
truth
<- na.omit(data.frame(pred=pred,
data_eval truth=truth))
<- mlr3measures::rmse(truth = data_eval$truth,
rmse response = data_eval$pred
)<- mlr3measures::mae(truth = data_eval$truth,
mae response = data_eval$pred
)<- c(rmse,mae)
metric names(metric) <- c("rmse","mae")
return(metric)
}
)
head(metric_loess,20)
# menghitung rata-rata untuk 10 folds
<- colMeans(metric_loess)
mean_metric_loess
mean_metric_loess
}
)
<- cbind(span=span,best_loess)
best_loess # menampilkan hasil all breaks
best_loess
#berdasarkan rmse
%>% slice_min(rmse) best_loess
#berdasarkan mae
%>% slice_min(mae) best_loess
library(ggplot2)
ggplot(Auto, aes(horsepower,mpg)) +
geom_point(alpha=0.5,color="black") +
stat_smooth(method='loess',
formula=y~x,
span = 0.3769231,
col="blue",
lty=1,
se=F)
mpg
vs weight
<- loess(mpg~weight,
Model_loess_weight data = Auto)
summary(Model_loess_weight)
## Call:
## loess(formula = mpg ~ weight, data = Auto)
##
## Number of Observations: 392
## Equivalent Number of Parameters: 4.57
## Residual Standard Error: 4.188
## Trace of smoother matrix: 4.98 (exact)
##
## Control settings:
## span : 0.75
## degree : 2
## family : gaussian
## surface : interpolate cell = 0.2
## normalize: TRUE
## parametric: FALSE
## drop.square: FALSE
Pengaruh parameter span
terhadap tingkat smoothness
kurva bisa dilihat dari ilustrasi berikut:
<- data.frame(span=seq(0.1,5,by=0.5)) %>%
model_loess_span_weight group_by(span) %>%
do(broom::augment(loess(mpg~weight,
data = Auto,span=.$span)))
<- ggplot(model_loess_span_weight,
p2 aes(x=weight,y=mpg))+
geom_line(aes(y=.fitted),
col="blue",
lty=1
+
)facet_wrap(~span)
p2
Tuning span
dapat dilakukan dengan menggunakan
cross-validation
set.seed(123)
<- vfold_cv(Auto,v=5,strata = "mpg")
cross_val
<- seq(0.1,1,length.out=50)
span
<- map_dfr(span, function(i){
best_loess <- map_dfr(cross_val$splits,
metric_loess function(x){
<- loess(mpg ~ weight,span = i,
mod data=Auto[x$in_id,])
<- predict(mod,
pred newdata=Auto[-x$in_id,])
<- Auto[-x$in_id,]$mpg
truth
<- na.omit(data.frame(pred=pred,
data_eval truth=truth))
<- mlr3measures::rmse(truth = data_eval$truth,
rmse response = data_eval$pred
)<- mlr3measures::mae(truth = data_eval$truth,
mae response = data_eval$pred
)<- c(rmse,mae)
metric names(metric) <- c("rmse","mae")
return(metric)
}
)
head(metric_loess,20)
# menghitung rata-rata untuk 10 folds
<- colMeans(metric_loess)
mean_metric_loess
mean_metric_loess
}
)
<- cbind(span=span,best_loess)
best_loess # menampilkan hasil all breaks
best_loess
#berdasarkan rmse
%>% slice_min(rmse) best_loess
#berdasarkan mae
%>% slice_min(mae) best_loess
library(ggplot2)
ggplot(Auto, aes(weight,mpg)) +
geom_point(alpha=0.5,color="black") +
stat_smooth(method='loess',
formula=y~x,
span = 1,
col="blue",
lty=1,
se=F)
mpg
vs
displacement
<- loess(mpg~displacement,
Model_loess_displacement data = Auto)
summary(Model_loess_displacement)
## Call:
## loess(formula = mpg ~ displacement, data = Auto)
##
## Number of Observations: 392
## Equivalent Number of Parameters: 4.42
## Residual Standard Error: 4.372
## Trace of smoother matrix: 4.82 (exact)
##
## Control settings:
## span : 0.75
## degree : 2
## family : gaussian
## surface : interpolate cell = 0.2
## normalize: TRUE
## parametric: FALSE
## drop.square: FALSE
Pengaruh parameter span
terhadap tingkat smoothness
kurva bisa dilihat dari ilustrasi berikut:
<- data.frame(span=seq(0.1,5,by=0.5)) %>%
model_loess_span_displacement group_by(span) %>%
do(broom::augment(loess(mpg~displacement,
data = Auto,span=.$span)))
<- ggplot(model_loess_span_displacement,
p2 aes(x=displacement,y=mpg))+
geom_line(aes(y=.fitted),
col="blue",
lty=1
+
)facet_wrap(~span)
p2
Tuning span
dapat dilakukan dengan menggunakan
cross-validation
set.seed(123)
<- vfold_cv(Auto,v=5,strata = "mpg")
cross_val
<- seq(0.1,1,length.out=50)
span
<- map_dfr(span, function(i){
best_loess <- map_dfr(cross_val$splits,
metric_loess function(x){
<- loess(mpg ~ displacement,span = i,
mod data=Auto[x$in_id,])
<- predict(mod,
pred newdata=Auto[-x$in_id,])
<- Auto[-x$in_id,]$mpg
truth
<- na.omit(data.frame(pred=pred,
data_eval truth=truth))
<- mlr3measures::rmse(truth = data_eval$truth,
rmse response = data_eval$pred
)<- mlr3measures::mae(truth = data_eval$truth,
mae response = data_eval$pred
)<- c(rmse,mae)
metric names(metric) <- c("rmse","mae")
return(metric)
}
)
head(metric_loess,20)
# menghitung rata-rata untuk 10 folds
<- colMeans(metric_loess)
mean_metric_loess
mean_metric_loess
}
)
<- cbind(span=span,best_loess)
best_loess # menampilkan hasil all breaks
best_loess
#berdasarkan rmse
%>% slice_min(rmse) best_loess
#berdasarkan mae
%>% slice_min(mae) best_loess
library(ggplot2)
ggplot(Auto, aes(displacement,mpg)) +
geom_point(alpha=0.5,color="black") +
stat_smooth(method='loess',
formula=y~x,
span = 0.3020408,
col="blue",
lty=1,
se=F)
IPB University-Prodi Statistika dan Sains Data 2021↩︎