Melakukan cross validation untuk menghasilkan pemodelan antara
tingkat efisiensi penggunaan bahan bakar (direpresentasikan oleh mpg
atau miles per gallon) versus kekuatan mesin (horsepower) pada data
ISLR::Auto dengan metode:
Pemodelan dilakukan untuk masing-masing subset data berdasarkan asal negara produsennya (Amerika, Eropa, Jepang).
Mendapatkan model non-linear yang optimal berdasarkan masing-masing data.
10-fold cross validation dengan meminimumkan RMSE (Root Mean Squared Error).
Pilihan k biasanya 5 atau 10, tetapi tidak ada aturan formal. Ketika k semakin besar, perbedaan ukuran antara himpunan pelatihan dan himpunan sampel ulang semakin kecil. Ketika perbedaan ini berkurang, bias dari teknik ini menjadi lebih kecil. (Page 70, Applied Predictive Modeling, 2013)
Polynomial Regression
Derajat/degree polinomial awal: 2:4
d (derajat polinomial) yang digunakan biasanya hingga 4 karena d yang terlalu besar akan membuat kurva berbentuk tidak teratur dan tampak “liar” terutama pada bagian ujungnya.
Piecewise Constant
Jumlah breaks awal: 2:10data Auto,
2:6 untuk Data AutoEropa, dan 2:5
untuk Data AutoJepang
Natural Cubic Spline
Jumlah dan lokasi knots awal ditentukan berdasarkan basis yang
terpilih 2:10
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.2.3
## Warning: package 'tibble' was built under R version 4.2.3
## Warning: package 'readr' was built under R version 4.2.3
## Warning: package 'dplyr' was built under R version 4.2.3
## Warning: package 'stringr' was built under R version 4.2.3
## Warning: package 'forcats' was built under R version 4.2.3
## Warning: package 'lubridate' was built under R version 4.2.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.3 ✔ readr 2.1.4
## ✔ forcats 1.0.0 ✔ stringr 1.5.0
## ✔ ggplot2 3.4.3 ✔ tibble 3.2.1
## ✔ lubridate 1.9.2 ✔ tidyr 1.3.0
## ✔ purrr 1.0.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(splines)
library(rsample)
## Warning: package 'rsample' was built under R version 4.2.3
library(ISLR)
## Warning: package 'ISLR' was built under R version 4.2.3
library(cowplot)
## Warning: package 'cowplot' was built under R version 4.2.3
##
## Attaching package: 'cowplot'
##
## The following object is masked from 'package:lubridate':
##
## stamp
library(caret) # cross-validation
## Warning: package 'caret' was built under R version 4.2.3
## Loading required package: lattice
##
## Attaching package: 'caret'
##
## The following object is masked from 'package:purrr':
##
## lift
library(gridExtra) # combining graphs
##
## Attaching package: 'gridExtra'
##
## The following object is masked from 'package:dplyr':
##
## combine
library(ggplot2)
library(dplyr)
library(purrr)
library(dplyr)
library(knitr)
## Warning: package 'knitr' was built under R version 4.2.3
library(DT)
## Warning: package 'DT' was built under R version 4.2.3
library(kableExtra)
## Warning: package 'kableExtra' was built under R version 4.2.3
##
## Attaching package: 'kableExtra'
##
## The following object is masked from 'package:dplyr':
##
## group_rows
library(gam) # generalized additive models
## Warning: package 'gam' was built under R version 4.2.3
## Loading required package: foreach
## Warning: package 'foreach' was built under R version 4.2.3
##
## Attaching package: 'foreach'
##
## The following objects are masked from 'package:purrr':
##
## accumulate, when
##
## Loaded gam 1.22-2
library(rstatix) #Deteksi Outlier
## Warning: package 'rstatix' was built under R version 4.2.3
##
## Attaching package: 'rstatix'
##
## The following object is masked from 'package:stats':
##
## filter
Auto MPG merupaka dataset mengenai penggunaan bahan bakar yang dihitung dengan satuan miles per gallon (mpg). mpg merupakan satuan nilai penggunaan bahan bakar sekaligus sebagai peubah respon pada dataset tersebut. Terdapat tujuh peubah prediktor yang memengaruhi penggunaan bahan bakar yakni sebagai berikut.
| No | Variabel | Keterangan |
|---|---|---|
| 1 | Cylinder | Silinder yang digunakan pada kendaraan |
| 2 | Displacement | Besarnya perpindahan |
| 3 | Horsepower | Tenaga kendaraan (Kekuatan Mesin) |
| 4 | Weight | Berat kendaraan |
| 5 | Acceleration | Percepatan kendaraan |
| 6 | Year Model | Tahun Keluaran Kendaraan |
| 7 | Origin | Asal Kendaraan |
head(Auto)
## mpg cylinders displacement horsepower weight acceleration year origin
## 1 18 8 307 130 3504 12.0 70 1
## 2 15 8 350 165 3693 11.5 70 1
## 3 18 8 318 150 3436 11.0 70 1
## 4 16 8 304 150 3433 12.0 70 1
## 5 17 8 302 140 3449 10.5 70 1
## 6 15 8 429 198 4341 10.0 70 1
## name
## 1 chevrolet chevelle malibu
## 2 buick skylark 320
## 3 plymouth satellite
## 4 amc rebel sst
## 5 ford torino
## 6 ford galaxie 500
Data yang digunakan adalah Auto dari package ISLR yang terdiri dari 392 observasi dan 9 variabel. Namun, variabel yang digunakan kali ini hanya 3, yaitu:
Auto = Auto %>% select(mpg, horsepower, origin)
datatable(Auto)
summary(Auto)
## mpg horsepower origin
## Min. : 9.00 Min. : 46.0 Min. :1.000
## 1st Qu.:17.00 1st Qu.: 75.0 1st Qu.:1.000
## Median :22.75 Median : 93.5 Median :1.000
## Mean :23.45 Mean :104.5 Mean :1.577
## 3rd Qu.:29.00 3rd Qu.:126.0 3rd Qu.:2.000
## Max. :46.60 Max. :230.0 Max. :3.000
Visualisasi Hubungan mpg terhadap
horsepower
plotmpg <- function(x){
ggplot(Auto) +
geom_point(aes_string(x = tolower(x), y = "mpg"), color="dodgerblue2", alpha = 0.8) +
ggtitle(paste0("Miles per Gallon vs ", x)) +
xlab(x) + ylab("Miles per Gallon") +
theme_bw()
}
p <- plotmpg("horsepower")
## Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
## ℹ Please use tidy evaluation idioms with `aes()`.
## ℹ See also `vignette("ggplot2-in-packages")` for more information.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
p
Ini merupakan scatter plot dari 392 kendaraan dimana dari masing-masing kendaraan diukur dua peubah/variabel, yaitu kekuatan mesin (horse power pada sumbu X) dan berapa jarak yang ditempuh kendaraan tersebut untuk setiap galon bahan bakarnya (mile per gallon pada sumbu y).
Berdasarkan scatter plot ini, secara umum terlihat bahwa semakin besar kekuatan mesin (horsepower) suatu kendaraan, semakin pendek jarak yang ditempuh kendaraan itu per galon bahan bakarnya. Artinya semakin kuat mesinnya, maka semakin boros. Dapat dilihat juga bahwa hubungan antara kekuatan mesin kendaraan (pada sumbu X) dan jarak yang dapat ditempuh oleh kendaraan per galon bahan bakarnya (pada sumbu Y) cenderung bersifat tidak linear.
Beberapa hal yang kurang menyenangkan dari model linier pada kasus ini, yaitu:
Model linier yang kita gunakan tidak mengikuti pola hubungan pada data. Sebelah kiri curam, sebelah kanan cenderung landai sehingga prediksinya tidak cukup baik.
Dapat diperoleh nilai penduga peubah respon yang “tidak masuk akal”. Jika garis linier diteruskan, untuk kekuatan mesin tertentu, akan diperoleh respon yang negatif sehingga tidak mungkin terjadi.
Sifat dan perilaku sisaan cenderung tidak sesuai harapan. Jika wilayah dibagi menjadi tiga bagian, bagian yang tengah, eror cenderung negatif karena garis cenderung ada di atas titik-titik yang sebenarnya. Sedangkan wilayah yang kanan sisaan cenderung positif karena garis cenderung ada di bawah titik-titik yang sebenarnya. Padahal biasanya lebih disukai error dari model ada yang positif dan negatif dengan nilai harapan nol. Di kasus ini, jika disekat, ada wilayah yang nilai harapan positif dan negatif sehingga tidak sesuai harapan.
Secara Empiris dengan Cross Validation
Cross validation untuk menghasilkan pemodelan mpg vs
horsepower optimal dengan Polynomial Regression.
set.seed(123)
cv.poly1 <- function(dataset){
set.seed(123)
cross_val <- vfold_cv(dataset,v=10,strata = "mpg")
metric_poly1 <- map_dfr(cross_val$splits,
function(x){
mod <- lm(mpg ~ poly(horsepower,1,raw = T),
data=dataset[x$in_id,])
pred <- predict(mod,
newdata=dataset[-x$in_id,])
truth <- dataset[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,response = pred)
metric <- rmse
names(metric) <- "RMSE"
return(metric)
}
)
RegLin<- colMeans(metric_poly1) #menghitung rmse dan mae rata-rata untuk 10 folds
return(RegLin)
}
cv.poly2 <- function(dataset){
set.seed(123)
cross_val <- vfold_cv(dataset,v=10,strata = "mpg")
metric_poly2 <- map_dfr(cross_val$splits,
function(x){
mod <- lm(mpg ~ poly(horsepower,2,raw = T),
data=dataset[x$in_id,])
pred <- predict(mod,
newdata=dataset[-x$in_id,])
truth <- dataset[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,response = pred)
metric <- rmse
names(metric) <- "RMSE"
return(metric)
}
)
poly2<- colMeans(metric_poly2) #menghitung rmse dan mae rata-rata untuk 10 folds
return(poly2)
}
cv.poly3 <- function(dataset){
set.seed(123)
cross_val <- vfold_cv(dataset,v=10,strata = "mpg")
metric_poly3 <- map_dfr(cross_val$splits,
function(x){
mod <- lm(mpg ~ poly(horsepower,3,raw = T),
data=dataset[x$in_id,])
pred <- predict(mod,
newdata=dataset[-x$in_id,])
truth <- dataset[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,response = pred)
metric <- rmse
names(metric) <- "RMSE"
return(metric)
}
)
poly3<- colMeans(metric_poly3) #menghitung rmse dan mae rata-rata untuk 10 folds
return(poly3)
}
cv.poly4 <- function(dataset){
set.seed(123)
cross_val <- vfold_cv(dataset,v=10,strata = "mpg")
metric_poly4 <- map_dfr(cross_val$splits,
function(x){
mod <- lm(mpg ~ poly(horsepower,4,raw = T),
data=dataset[x$in_id,])
pred <- predict(mod,
newdata=dataset[-x$in_id,])
truth <- dataset[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,response = pred)
metric <- rmse
names(metric) <- "RMSE"
return(metric)
}
)
poly4<- colMeans(metric_poly4) #menghitung rmse dan mae rata-rata untuk 10 folds
return(poly4)
}
cvpoly <- rbind (cv.poly1(Auto),cv.poly2(Auto),cv.poly3(Auto),cv.poly4(Auto))
cvpoly
## RMSE
## [1,] 4.889086
## [2,] 4.351129
## [3,] 4.355430
## [4,] 4.367009
Secara empiris jika dilihat dari RMSE terlihat bahwa polinomial derajat 2 memberikan nilai RMSE yang terkecil sehingga dipilih Polynomial Regression derajat 2.
Secara Visual
poly2 <- ggplot(Auto,aes(x=horsepower, y=mpg)) +
geom_point(alpha=0.8, color="black") +
stat_smooth(method = "lm",
formula = y~poly(x,2,raw=T),
lty = 1, col = "blue",se = F)+
ggtitle("Polynomial Regression Derajat 2 (RMSE=4.35)") +
theme_bw()
poly2
Secara Empiris dengan Cross Validation
Cross validation untuk menghasilkan pemodelan mpg vs
horsepower optimal dengan Piecewise Constant.
set.seed(123)
cv.pc <- function(dataset){
set.seed(123)
cross_val <- vfold_cv(dataset,v=10,strata = "mpg")
breaks <- 2:10
best_tangga <- map_dfr(breaks, function(i){
metric_tangga <- map_dfr(cross_val$splits,
function(x){
training <- dataset[x$in_id,]
training$horsepower <- cut(training$horsepower,i)
mod <- lm(mpg ~ horsepower,
data=training)
labs_x <- levels(mod$model[,2])
labs_x_breaks <- cbind(lower = as.numeric( sub("\\((.+),.*", "\\1", labs_x) ),
upper = as.numeric( sub("[^,]*,([^]]*)\\]", "\\1", labs_x) ))
testing <- dataset[-x$in_id,]
horsepower_new <- cut(testing$horsepower,c(labs_x_breaks[1,1],labs_x_breaks[,2]))
pred <- predict(mod,
newdata=list(horsepower=horsepower_new))
truth <- testing$mpg
data_eval <- na.omit(data.frame(truth,pred))
rmse <- mlr3measures::rmse(truth = data_eval$truth,
response = data_eval$pred
)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
colMeans(metric_tangga) # menghitung rata-rata untuk 10 folds
}
)
best_tangga <- cbind(breaks=breaks,best_tangga) # menampilkan hasil all breaks
return(best_tangga)
}
cv.pc(Auto)
## breaks rmse
## 1 2 6.147626
## 2 3 5.775792
## 3 4 4.985270
## 4 5 4.712623
## 5 6 4.644383
## 6 7 4.554116
## 7 8 4.437597
## 8 9 4.549668
## 9 10 4.589172
Secara empiris berdasarkan nilai RMSE, banyaknya interval yang terbaik adalah 8 interval sehingga dipilih Piecewise Constant dengan 8 interval.
Secara Visual
pc8 <- ggplot(Auto,aes(x=horsepower, y=mpg)) +
geom_point(alpha=0.8, color="black") +
stat_smooth(method = "lm",
formula = y~cut(x,8),
lty = 1, col = "blue",se = F)+
ggtitle("Piecewise Constant 8 Interval (RMSE=4.44)") +
theme_bw()
pc8
Secara Empiris dengan Cross Validation
Menentukan Banyaknya Fungsi Basis, sebagai berikut:
set.seed(123)
cross.val <- vfold_cv(Auto,v=10,strata = "mpg")
df <- 2:10
best.spline3 <- map_dfr(df, function(i){
metric.spline3 <- map_dfr(cross.val$splits,
function(x){
mod <- lm(mpg ~ ns(horsepower,df=i),data=Auto[x$in_id,])
pred <- predict(mod,newdata=Auto[-x$in_id,])
truth <- Auto[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,response = pred)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
metric.spline3
mean.metric.spline3 <- colMeans(metric.spline3) #rata-rata untuk 10 folds
mean.metric.spline3
}
)
best.spline3 <- cbind(df=df,best.spline3)
basis<-best.spline3 %>% slice_min(rmse) #berdasarkan rmse
basis
## df rmse
## 1 10 4.260316
Banyaknya fungsi basis yang terpilih adalah 10. Selanjutnya adalah menentukan knot berdasarkan banyaknya fungsi basis yang terpilih.
df_10<-attr(ns(Auto$horsepower, df=10),"knots")
df_10
## 10% 20% 30% 40% 50% 60% 70% 80% 90%
## 67.0 72.0 80.0 88.0 93.5 100.0 110.0 140.0 157.7
Cross Validation
set.seed(123)
cross.val <- vfold_cv(Auto,v=10,strata = "mpg")
metric.spline3.ns4 <- map_dfr(cross.val$splits,
function(x){
mod <- lm(mpg ~ ns(horsepower, knots = c(80, 120, 160, 200)),
data=Auto[x$in_id,])
pred <- predict(mod,
newdata=Auto[-x$in_id,])
truth <- Auto[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,
response = pred
)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
mean.metric.spline3.ns4 <- colMeans(metric.spline3.ns4)# menghitung rata-rata untuk 10 folds
metric.spline3.ns9 <- map_dfr(cross.val$splits,
function(x){
mod <- lm(mpg ~ ns(horsepower, knots = c(67,72,80,88,93.5,100,110,140,157.7)),
data=Auto[x$in_id,])
pred <- predict(mod,
newdata=Auto[-x$in_id,])
truth <- Auto[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,
response = pred
)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
mean.metric.spline3.ns9 <- colMeans(metric.spline3.ns9)# menghitung rata-rata untuk 10 folds
nilai.cv.ns <- rbind("NCS4" = mean.metric.spline3.ns4,
"NCS9" = mean.metric.spline3.ns9)
nama.model.ncs <- c("4 - NCS Knots 80, 120, 160, 200",
"9 - NCS (df=10)")
model.ncs<-data.frame(Model = nama.model.ncs, nilai.cv.ns)
model.ncs
## Model rmse
## NCS4 4 - NCS Knots 80, 120, 160, 200 4.359156
## NCS9 9 - NCS (df=10) 4.261893
Secara empiris berdasarkan nilai RMSE, banyaknya knot terbaik adalah 9 knots, yaitu knot 67,72,80,88,93.5,100,110,140,157.7 sehingga dipilih Natural Cubic Splines dengan 9 knots.
Secara Visual
nc9 <- ggplot(Auto, aes(x = horsepower, y = mpg)) +
geom_point(alpha = 0.8, color="black") +
stat_smooth(method = "lm", formula = y~ns(x, knots = c(67,72,80,88,93.5,100,110,140,157.7)), col = "blue", se = F)+
ggtitle("Natural Cubic Splines 9 Knots (RMSE=4.26)") +
theme_bw()
nc9
Secara Empiris
poly2.a <- cv.poly2(Auto)
pc.a <- cv.pc(Auto)[1,-1]
ncs.a <- model.ncs[2,-1]
# Membuat dataframe
df <- data.frame("Metode" = c("Polinomial Derajat 2", "Piecewise Constant 8", "NCS 9 Knots"), "RMSE" = c(poly2.a, pc.a, ncs.a))
df
## Metode RMSE
## 1 Polinomial Derajat 2 4.351129
## 2 Piecewise Constant 8 6.147626
## 3 NCS 9 Knots 4.261893
Berdasarkan hasil analisis, model terbaik untuk data Auto adalah Natural Cubic Splines dengan 9 knots.
Secara Visual
# Membuat plot gabungan
combined_plot <- ggplot(Auto, aes(x = horsepower, y = mpg)) +
ggtitle("Comparison of Best Model") +
geom_point(alpha = 0.8, color="black") +
stat_smooth(method = "lm",
formula = y~poly(x,2,raw=T), aes(col = "Polinomial Derajat 2"), se = F,
linetype = "solid") +
stat_smooth(method = "lm",
formula = y~cut(x,8), aes(col = "Piecewise Constant 8"), se = F,
linetype = "solid") +
stat_smooth(method = "lm",
formula = y~ns(x, knots = c(67,72,80,88,93.5,100,110,140,157.7)),
aes(col = "NCS 9 Knots"), se = F, linetype = "solid") +
labs(color="Model")+
scale_color_manual(values=c("Polinomial Derajat 2"="blue", "Piecewise Constant 8"="red","NCS 9 Knots"= "green")) +
theme_bw()
combined_plot
Secara umum, model Natural Cubic Splines 9 Knots tampaknya paling akurat dalam memodelkan hubungan ini. Model ini tampaknya paling akurat dalam memprediksi mpg berdasarkan horsepower. Garis biru mewakili model ini dan tampaknya paling dekat dengan titik data, menunjukkan bahwa model ini memiliki kesalahan prediksi yang paling rendah.
Secara Empiris dengan Cross Validation
Cross validation untuk menghasilkan pemodelan mpg vs
horsepower optimal dengan polynomial regression.
cvpoly <- rbind (cv.poly1(AutoAmerika),cv.poly2(AutoAmerika),cv.poly3(AutoAmerika),cv.poly4(AutoAmerika))
cvpoly
## RMSE
## [1,] 4.237175
## [2,] 3.799433
## [3,] 3.804542
## [4,] 3.823584
Secara empiris jika dilihat dari nilai RMSE terlihat bahwa polinomial derajat 2 memberikan nilai RMSE yang terkecil sehingga dipilih Polynomial Regression derajat 2.
Secara Visual
poly2 <- ggplot(AutoAmerika,aes(x=horsepower, y=mpg)) +
geom_point(alpha=0.8, color="black") +
stat_smooth(method = "lm",
formula = y~poly(x,2,raw=T),
lty = 1, col = "coral2",se = F)+
theme_bw()+
labs(title = "Polynomial Derajat 2 (RMSE=3.80)",
subtitle = "Amerika")
poly2
Secara Empiris dengan Cross Validation
Cross validation untuk menghasilkan pemodelan mpg vs
horsepower optimal dengan Piecewise Constant.
cv.pc(AutoAmerika)
## breaks rmse
## 1 2 4.997476
## 2 3 4.759908
## 3 4 4.139362
## 4 5 3.966889
## 5 6 4.222039
## 6 7 4.150320
## 7 8 3.945534
## 8 9 3.737522
## 9 10 3.816464
Secara empiris berdasarkan RMSE, banyaknya interval yang terbaik adalah 9 sehingga model yang dipilih adalah Piecewise Constant dengan 9 Interval
pc9 <- ggplot(AutoAmerika,aes(x=horsepower, y=mpg)) +
geom_point(alpha=0.55, color="black") +
stat_smooth(method = "lm",
formula = y~cut(x,9),
lty = 1, col = "coral2",se = F)+
theme_bw()+
labs(title = "Piecewise Constant 9 Interval (RMSE=3.74)",
subtitle = "Amerika")
pc9
Secara Empiris dengan Cross Validation
Menentukan Banyaknya Fungsi Basis, sebagai berikut
set.seed(123)
cross.val <- vfold_cv(AutoAmerika,v=10,strata = "mpg")
df <- 2:10
best.spline3 <- map_dfr(df, function(i){
metric.spline3 <- map_dfr(cross.val$splits,
function(x){
mod <- lm(mpg ~ ns(horsepower,df=i),data=AutoAmerika[x$in_id,])
pred <- predict(mod,newdata=AutoAmerika[-x$in_id,])
truth <- AutoAmerika[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,response = pred)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
metric.spline3
mean.metric.spline3 <- colMeans(metric.spline3) #rata-rata untuk 10 folds
mean.metric.spline3
}
)
best.spline3 <- cbind(df=df,best.spline3)
basis<-best.spline3 %>% slice_min(rmse) #berdasarkan rmse
basis
## df rmse
## 1 7 3.769022
Diperoleh df atau banyaknya fungsi basis terpilih sebesar 7. Selanjutnya menentukan knot berdasarkan banyaknya fungsi basis yang terpilih.
df_7 <-attr(ns(AutoAmerika$horsepower, df=7),"knots")
df_7
## 14.28571% 28.57143% 42.85714% 57.14286% 71.42857% 85.71429%
## 82.85714 90.00000 100.00000 110.00000 145.00000 165.00000
Cross Validation
set.seed(123)
cross.val <- vfold_cv(AutoAmerika,v=10,strata = "mpg")
metric.spline3.ns4 <- map_dfr(cross.val$splits,
function(x){
mod <- lm(mpg ~ ns(horsepower, knots = c(80, 120, 160, 200)),
data=AutoAmerika[x$in_id,])
pred <- predict(mod,
newdata=AutoAmerika[-x$in_id,])
truth <- AutoAmerika[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,
response = pred
)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
mean.metric.spline3.ns4 <- colMeans(metric.spline3.ns4)# menghitung rata-rata untuk 10 folds
metric.spline3.ns7 <- map_dfr(cross.val$splits,
function(x){
mod <- lm(mpg ~ ns(horsepower, knots = c(82.85714,90,100,110,145,165)),
data=AutoAmerika[x$in_id,])
pred <- predict(mod,
newdata=AutoAmerika[-x$in_id,])
truth <- AutoAmerika[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,
response = pred
)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
mean.metric.spline3.ns7 <- colMeans(metric.spline3.ns7)# menghitung rata-rata untuk 10folds
nilai.cv.ns <- rbind("NCS4" = mean.metric.spline3.ns4,
"NCS6" = mean.metric.spline3.ns7)
nama.model.ncs <- c("4 - NCS Knots 80, 120, 160, 200",
"6 - NCS (df=7)")
model.ncs<-data.frame(Model = nama.model.ncs, nilai.cv.ns)
model.ncs
## Model rmse
## NCS4 4 - NCS Knots 80, 120, 160, 200 3.823310
## NCS6 6 - NCS (df=7) 3.761205
Secara empiris berdasarkan RMSE, banyaknya knot terbaik adalah 6 knots sehingga model yang dipilih adalah Natural Cubic Splines dengan 6 Knots.
Secara Visual
nc6 <- ggplot(AutoAmerika, aes(x = horsepower, y = mpg)) +
geom_point(alpha = 0.8, color="black") +
stat_smooth(method = "lm", formula = y~ns(x, knots = c(82.85714,90,100,110,145,165)), col = "coral2", se = F)+
theme_bw()+
labs(title = "Natural Cubic Splines 6 Knots (RMSE=3.76)",
subtitle = "Amerika")
nc6
Secara Empiris
poly2.b <- cv.poly2(AutoAmerika)
pc.b <- cv.pc(AutoAmerika)[1,-1]
ncs.b <- model.ncs[2,-1]
# Membuat dataframe
df <- data.frame("Metode" = c("Polinomial Derajat 2", "Piecewise Constant 9", "NCS 6 Knots"), "RMSE" = c(poly2.b, pc.b, ncs.b))
df
## Metode RMSE
## 1 Polinomial Derajat 2 3.799433
## 2 Piecewise Constant 9 4.997476
## 3 NCS 6 Knots 3.761205
Berdasarkan hasil analisis, model terbaik untuk data Auto Amerika adalah Piecewise Constant dengan 9 interval.
Secara Visual
# Membuat plot gabungan
combined_plot <- ggplot(AutoAmerika,aes(x=horsepower, y=mpg)) +
ggtitle("Comparison of Best Model") +
geom_point(alpha = 0.8, color="black") +
stat_smooth(method = "lm",
formula = y~poly(x,2,raw=T), aes(col = "Polinomial Derajat 2"), se = F,
linetype = "solid") +
stat_smooth(method = "lm",
formula = y~cut(x,9), aes(col = "Piecewise Constant 9"), se = F,
linetype = "solid") +
stat_smooth(method = "lm",
formula = y~ns(x, knots = c(82.85714,90,100,110,145,165)),
aes(col = "NCS 6 Knots"), se = F, linetype = "solid") +
labs(color="Model")+
scale_color_manual(values=c("Polinomial Derajat 2"="blue", "Piecewise Constant 9"="red","NCS 6 Knots"= "green")) +
theme_bw()
combined_plot
Secara keseluruhan, plot ini menunjukkan bahwa ada hubungan
non-linear antara horsepower dan mpg. Model
Piecewise Constant 9, sebagai model terbaik berdasarkan hasil Cross
Validation, membagi data menjadi 9 segmen dan mengasumsikan fungsi
konstan di setiap segmen. Ini memungkinkan model untuk menangkap pola
non-linear dalam data tanpa harus memperkirakan fungsi yang rumit.
Secara Empiris dengan Cross Validation
Cross validation untuk menghasilkan pemodelan mpg vs
horsepower optimal dengan Polynomial Regression.
set.seed(123)
cv.poly2 <- function(dataset){
set.seed(123)
cross_val <- vfold_cv(dataset,v=10,strata = "mpg")
metric_poly2 <- map_dfr(cross_val$splits,
function(x){
mod <- lm(mpg ~ poly(horsepower,2,raw = T),
data=dataset[x$in_id,])
pred <- predict(mod,
newdata=dataset[-x$in_id,])
truth <- dataset[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,response = pred)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
poly2<- colMeans(metric_poly2) #menghitung rmse dan mae rata-rata untuk 10 folds
return(poly2)
}
cv.poly3 <- function(dataset){
set.seed(123)
cross_val <- vfold_cv(dataset,v=10,strata = "mpg")
metric_poly3 <- map_dfr(cross_val$splits,
function(x){
mod <- lm(mpg ~ poly(horsepower,3,raw = T),
data=dataset[x$in_id,])
pred <- predict(mod,
newdata=dataset[-x$in_id,])
truth <- dataset[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,response = pred)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
poly3<- colMeans(metric_poly3) #menghitung rmse dan mae rata-rata untuk 10 folds
return(poly3)
}
cv.poly4 <- function(dataset){
set.seed(123)
cross_val <- vfold_cv(dataset,v=10,strata = "mpg")
metric_poly4 <- map_dfr(cross_val$splits,
function(x){
mod <- lm(mpg ~ poly(horsepower,4,raw = T),
data=dataset[x$in_id,])
pred <- predict(mod,
newdata=dataset[-x$in_id,])
truth <- dataset[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,response = pred)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
poly4<- colMeans(metric_poly4) #menghitung rmse dan mae rata-rata untuk 10 folds
return(poly4)
}
cvpoly <- rbind (cv.poly2(AutoEropa),cv.poly3(AutoEropa),cv.poly4(AutoEropa))
## Warning: The number of observations in each quantile is below the recommended threshold of 20.
## • Stratification will use 3 breaks instead.
## The number of observations in each quantile is below the recommended threshold of 20.
## • Stratification will use 3 breaks instead.
## The number of observations in each quantile is below the recommended threshold of 20.
## • Stratification will use 3 breaks instead.
cvpoly
## rmse
## [1,] 4.805676
## [2,] 4.832309
## [3,] 4.878846
Secara empiris jika dilihat dari nilai RMSE terlihat bahwa polinomial derajat 2 memberikan nilai RMSE yang terkecil sehingga dipilih Polynomial Regression derajat 2.
Secara Visual
poly2 <- ggplot(AutoEropa,aes(x=horsepower, y=mpg)) +
geom_point(alpha=0.8, color="black") +
stat_smooth(method = "lm",
formula = y~poly(x,2,raw=T),
lty = 1, col = "blue",se = F)+
theme_bw()+
labs(title = "Polynomial Derajat 2 (RMSE=4.805)",
subtitle = "Eropa")
poly2
Secara Empiris dengan Cross Validation
Cross validation untuk menghasilkan pemodelan mpg vs
horsepower optimal dengan Piecewise Constant.
set.seed(123)
cv.pc2 <- function(dataset){
set.seed(123)
cross_val <- vfold_cv(dataset,v=10,strata = "mpg")
breaks <- 2:6
best_tangga <- map_dfr(breaks, function(i){
metric_tangga <- map_dfr(cross_val$splits,
function(x){
training <- dataset[x$in_id,]
training$horsepower <- cut(training$horsepower,i)
mod <- lm(mpg ~ horsepower,
data=training)
labs_x <- levels(mod$model[,2])
labs_x_breaks <- cbind(lower = as.numeric( sub("\\((.+),.*", "\\1", labs_x) ),
upper = as.numeric( sub("[^,]*,([^]]*)\\]", "\\1", labs_x) ))
testing <- dataset[-x$in_id,]
horsepower_new <- cut(testing$horsepower,c(labs_x_breaks[1,1],labs_x_breaks[,2]))
pred <- predict(mod,
newdata=list(horsepower=horsepower_new))
truth <- testing$mpg
data_eval <- na.omit(data.frame(truth,pred))
rmse <- mlr3measures::rmse(truth = data_eval$truth,
response = data_eval$pred
)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
colMeans(metric_tangga) # menghitung rata-rata untuk 10 folds
}
)
best_tangga <- cbind(breaks=breaks,best_tangga) # menampilkan hasil all breaks
return(best_tangga)
}
cv.pc2(AutoEropa)
## Warning: The number of observations in each quantile is below the recommended threshold of 20.
## • Stratification will use 3 breaks instead.
## breaks rmse
## 1 2 5.462277
## 2 3 5.395409
## 3 4 5.226264
## 4 5 4.963259
## 5 6 5.133934
Secara empiris berdasarkan nilai RMSE, banyaknya interval yang terbaik adalah 5 interval sehingga model yang dipilih adalah Piecewise Contants dengan 5 interval.
pc5 <- ggplot(AutoEropa,aes(x=horsepower, y=mpg)) +
geom_point(alpha=0.8, color="black") +
stat_smooth(method = "lm",
formula = y~cut(x,5),
lty = 1, col = "blue",se = F)+
theme_bw()+
labs(title = "Piecewise Constant 5 (RMSE=4.963)",
subtitle = "Eropa")
pc5
Secara Empiris dengan Cross Validation
Menentukan Banyaknya Fungsi Basis
set.seed(123)
cross.val <- vfold_cv(AutoEropa,v=10,strata = "mpg")
## Warning: The number of observations in each quantile is below the recommended threshold of 20.
## • Stratification will use 3 breaks instead.
df <- 2:10
best.spline3 <- map_dfr(df, function(i){
metric.spline3 <- map_dfr(cross.val$splits,
function(x){
mod <- lm(mpg ~ ns(horsepower,df=i),data=AutoEropa[x$in_id,])
pred <- predict(mod,newdata=AutoEropa[-x$in_id,])
truth <- AutoEropa[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,response = pred)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
metric.spline3
mean.metric.spline3 <- colMeans(metric.spline3) #rata-rata untuk 10 folds
mean.metric.spline3
}
)
best.spline3 <- cbind(df=df,best.spline3)
basis<-data.frame(best.spline3 %>% slice_min(rmse)) #berdasarkan rmse
basis
## df rmse
## 1 2 4.807144
Diperoleh basis yang terbaik adalah 2, selanjutnya menentukan knot berdasarkan banyaknya fungsi basis yang terpilih
df_2<-attr(ns(AutoEropa$horsepower, df=2),"knots")
df_2
## 50%
## 76.5
Cross Validation
metric.spline3.ns1 <- map_dfr(cross.val$splits,
function(x){
mod <- lm(mpg ~ ns(horsepower, knots = c(76.5)),
data=AutoEropa[x$in_id,])
pred <- predict(mod,
newdata=AutoEropa[-x$in_id,])
truth <- AutoEropa[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,
response = pred
)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
mean.metric.spline3.ns1 <- colMeans(metric.spline3.ns1)# menghitung rata-rata untuk 10 folds
metric.spline3.ns2 <- map_dfr(cross.val$splits,
function(x){
mod <- lm(mpg ~ ns(horsepower, knots = c(88, 105)),
data=AutoEropa[x$in_id,])
pred <- predict(mod,
newdata=AutoEropa[-x$in_id,])
truth <- AutoEropa[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,
response = pred
)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
mean.metric.spline3.ns2 <- colMeans(metric.spline3.ns2)# menghitung rata-rata untuk 10 folds
nilai.cv.ns <- rbind("NCS1" = mean.metric.spline3.ns1,
"NCS2" = mean.metric.spline3.ns2)
nama.model.ncs <- c("1 - NCS Knots 76.5",
"2 - NCS Knots 88, 105")
model.ncs<-data.frame(Model = nama.model.ncs, nilai.cv.ns)
model.ncs
## Model rmse
## NCS1 1 - NCS Knots 76.5 4.806982
## NCS2 2 - NCS Knots 88, 105 4.825955
Secara empiris berdasarkan nilai RMSE, banyaknya knot terbaik adalah 1 knot sehingga model yang dipilih adalah Natural Cubic Splines dengan 1 knot.
Secara Visual
nc1 <- ggplot(AutoEropa, aes(x = horsepower, y = mpg)) +
geom_point(alpha = 0.8, color="black") +
stat_smooth(method = "lm", formula = y~ns(x, knots = c(76.5)), col = "blue", se = F) +
theme_bw()+
labs(title = "Natural Cubic Splines 1 Knot (RMSE=4.806)",
subtitle = "Eropa")
nc1
Secara Empiris
poly2.c <- cv.poly2(AutoEropa)
## Warning: The number of observations in each quantile is below the recommended threshold of 20.
## • Stratification will use 3 breaks instead.
pc.c <- cv.pc2(AutoEropa)[1,-1]
## Warning: The number of observations in each quantile is below the recommended threshold of 20.
## • Stratification will use 3 breaks instead.
ncs.c <- model.ncs[1,-1]
# Membuat dataframe
df <- data.frame("Metode" = c("Polinomial Derajat 2", "Piecewise Constant 5", "NCS 1 Knot"), "RMSE" = c(poly2.c, pc.c, ncs.c))
df
## Metode RMSE
## 1 Polinomial Derajat 2 4.805676
## 2 Piecewise Constant 5 5.462277
## 3 NCS 1 Knot 4.806982
Berdasarkan hasil analisis, model terbaik untuk data Auto Eropa adalah Polynomial Regression derajat 2.
Secara Visual
# Membuat plot gabungan
combined_plot <- ggplot(AutoEropa,aes(x=horsepower, y=mpg)) +
ggtitle("Comparison of Best Model") +
geom_point(alpha = 0.8, color="black") +
stat_smooth(method = "lm",
formula = y~poly(x,2,raw=T), aes(col = "Polinomial Derajat 2"), se = F,
linetype = "solid") +
stat_smooth(method = "lm",
formula = y~cut(x,5), aes(col = "Piecewise Constant 5"), se = F,
linetype = "solid") +
stat_smooth(method = "lm",
formula = y~ns(x, knots = c(76.5)),
aes(col = "NCS 1 Knot"), se = F, linetype = "solid") +
labs(color="Model")+
scale_color_manual(values=c("Polinomial Derajat 2"="blue", "Piecewise Constant 5"="red","NCS 1 Knot"= "green")) +
theme_bw()
combined_plot
Secara keseluruhan, plot ini menunjukkan bahwa ada hubungan non-linear antara tenaga kuda dan efisiensi bahan bakar, dan model Polynomial Derajat 2 tampaknya paling akurat dalam memodelkan hubungan ini.
Berdasarkan model Polynomial Derajat 2, dapat disimpulkan bahwa ada hubungan non-linear (horsepower) dan efisiensi bahan bakar (mpg). Model ini tampaknya memberikan perkiraan yang baik tentang hubungan antara tenaga kuda dan efisiensi bahan bakar, meskipun ada beberapa penyimpangan dari titik data.
Secara Empiris dengan Cross Validation
Cross validation untuk menghasilkan pemodelan mpg vs
horsepower optimal dengan Polynomial Regression.
set.seed(123)
cv.poly2 <- function(dataset){
set.seed(123)
cross_val <- vfold_cv(dataset,v=10,strata = "mpg")
metric_poly2 <- map_dfr(cross_val$splits,
function(x){
mod <- lm(mpg ~ poly(horsepower,2,raw = T),
data=dataset[x$in_id,])
pred <- predict(mod,
newdata=dataset[-x$in_id,])
truth <- dataset[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,response = pred)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
poly2<- colMeans(metric_poly2) #menghitung rmse dan mae rata-rata untuk 10 folds
return(poly2)
}
cv.poly3 <- function(dataset){
set.seed(123)
cross_val <- vfold_cv(dataset,v=10,strata = "mpg")
metric_poly3 <- map_dfr(cross_val$splits,
function(x){
mod <- lm(mpg ~ poly(horsepower,3,raw = T),
data=dataset[x$in_id,])
pred <- predict(mod,
newdata=dataset[-x$in_id,])
truth <- dataset[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,response = pred)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
poly3<- colMeans(metric_poly3) #menghitung rmse dan mae rata-rata untuk 10 folds
return(poly3)
}
cv.poly4 <- function(dataset){
set.seed(123)
cross_val <- vfold_cv(dataset,v=10,strata = "mpg")
metric_poly4 <- map_dfr(cross_val$splits,
function(x){
mod <- lm(mpg ~ poly(horsepower,4,raw = T),
data=dataset[x$in_id,])
pred <- predict(mod,
newdata=dataset[-x$in_id,])
truth <- dataset[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,response = pred)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
poly4<- colMeans(metric_poly4) #menghitung rmse dan mae rata-rata untuk 10 folds
return(poly4)
}
cvpoly <- rbind (cv.poly2(AutoJepang),cv.poly3(AutoJepang),cv.poly4(AutoJepang))
## Warning: The number of observations in each quantile is below the recommended threshold of 20.
## • Stratification will use 3 breaks instead.
## The number of observations in each quantile is below the recommended threshold of 20.
## • Stratification will use 3 breaks instead.
## The number of observations in each quantile is below the recommended threshold of 20.
## • Stratification will use 3 breaks instead.
cvpoly
## rmse
## [1,] 4.522705
## [2,] 3.962162
## [3,] 4.380986
Secara empiris jika dilihat dari nilai RMSE terlihat bahwa polinomial derajat 2 memberikan nilai rmse yang terkecil sehingga dipilih Polynomial Regression derajat 3.
Secara Visual
poly3 <- ggplot(AutoJepang,aes(x=horsepower, y=mpg)) +
geom_point(alpha=0.8, color="black") +
stat_smooth(method = "lm",
formula = y~poly(x,3,raw=T),
lty = 1, col = "blue",se = F)+
theme_bw()+
labs(title = "Polinomial Derajat 3 (RMSE=3.96)",
subtitle = "Jepang")
poly3
Secara Empiris dengan Cross Validation
Cross validation untuk menghasilkan pemodelan mpg vs
horsepower optimal dengan Piecewise Constant.
set.seed(123)
cv.pc2 <- function(dataset){
set.seed(123)
cross_val <- vfold_cv(dataset,v=10,strata = "mpg")
breaks <- 2:5
best_tangga <- map_dfr(breaks, function(i){
metric_tangga <- map_dfr(cross_val$splits,
function(x){
training <- dataset[x$in_id,]
training$horsepower <- cut(training$horsepower,i)
mod <- lm(mpg ~ horsepower,
data=training)
labs_x <- levels(mod$model[,2])
labs_x_breaks <- cbind(lower = as.numeric( sub("\\((.+),.*", "\\1", labs_x) ),
upper = as.numeric( sub("[^,]*,([^]]*)\\]", "\\1", labs_x) ))
testing <- dataset[-x$in_id,]
horsepower_new <- cut(testing$horsepower,c(labs_x_breaks[1,1],labs_x_breaks[,2]))
pred <- predict(mod,
newdata=list(horsepower=horsepower_new))
truth <- testing$mpg
data_eval <- na.omit(data.frame(truth,pred))
rmse <- mlr3measures::rmse(truth = data_eval$truth,
response = data_eval$pred
)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
colMeans(metric_tangga) # menghitung rata-rata untuk 10 folds
}
)
best_tangga <- cbind(breaks=breaks,best_tangga) # menampilkan hasil all breaks
return(best_tangga)
}
cv.pc2(AutoJepang)
## Warning: The number of observations in each quantile is below the recommended threshold of 20.
## • Stratification will use 3 breaks instead.
## breaks rmse
## 1 2 4.306154
## 2 3 4.201949
## 3 4 4.072662
## 4 5 4.226607
Secara empiris berdasarkan nilai RMSE, banyaknya interval yang terbaik adalah 4 interval sehingga model yang dipilih adalah Piecewiseconstant dengan 4 interval,
Secara Visual
pc4 <- ggplot(AutoJepang,aes(x=horsepower, y=mpg)) +
geom_point(alpha=0.8, color="black") +
stat_smooth(method = "lm",
formula = y~cut(x,4),
lty = 1, col = "blue",se = F)+
theme_bw()+
labs(title = "Picewise Constant 4 (RMSE=4.07)",
subtitle = "Jepang")
pc4
Secara Empiris dengan Cross Validation
Menentukan Banyaknya Fungsi Basis
set.seed(123)
cross.val <- vfold_cv(AutoJepang,v=10,strata = "mpg")
## Warning: The number of observations in each quantile is below the recommended threshold of 20.
## • Stratification will use 3 breaks instead.
df <- 2:10
best.spline3 <- map_dfr(df, function(i){
metric.spline3 <- map_dfr(cross.val$splits,
function(x){
mod <- lm(mpg ~ ns(horsepower,df=i),data=AutoJepang[x$in_id,])
pred <- predict(mod,newdata=AutoJepang[-x$in_id,])
truth <- AutoJepang[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,response = pred)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
metric.spline3
mean.metric.spline3 <- colMeans(metric.spline3) #rata-rata untuk 10 folds
mean.metric.spline3
}
)
best.spline3 <- cbind(df=df,best.spline3)
basis<-best.spline3 %>% slice_min(rmse) #berdasarkan rmse
basis
## df rmse
## 1 3 4.143445
Diperoleh basis yang terbaik adalah 3, selanjutnya menentukan knot berdasarkan banyaknya fungsi basis yang terpilih.
df_3<-attr(ns(AutoJepang$horsepower, df=3),"knots")
df_3
## 33.33333% 66.66667%
## 68 90
Cross Validation
set.seed(123)
cross.val <- vfold_cv(AutoJepang,v=10,strata = "mpg")
## Warning: The number of observations in each quantile is below the recommended threshold of 20.
## • Stratification will use 3 breaks instead.
metric.spline3.ns2 <- map_dfr(cross.val$splits,
function(x){
mod <- lm(mpg ~ ns(horsepower, knots = c(68,90)),
data=AutoJepang[x$in_id,])
pred <- predict(mod,
newdata=AutoJepang[-x$in_id,])
truth <- AutoJepang[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,
response = pred
)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
mean.metric.spline3.ns2 <- colMeans(metric.spline3.ns2) # menghitung rata-rata untuk 10 folds
metric.spline3.ns3 <- map_dfr(cross.val$splits,
function(x){
mod <- lm(mpg ~ ns(horsepower, knots = c(60, 88, 105)),
data=AutoJepang[x$in_id,])
pred <- predict(mod,
newdata=AutoJepang[-x$in_id,])
truth <- AutoJepang[-x$in_id,]$mpg
rmse <- mlr3measures::rmse(truth = truth,
response = pred
)
metric <- rmse
names(metric) <- "rmse"
return(metric)
}
)
mean.metric.spline3.ns3 <- colMeans(metric.spline3.ns3) # menghitung rata-rata untuk 10 folds
nilai.cv.ns <- rbind("NCS2" = mean.metric.spline3.ns2,
"NCS3" = mean.metric.spline3.ns3)
nama.model.ncs <- c("2 - NCS Knots 68,90",
"3 - NCS Knots 60, 88, 105")
model.ncs<-data.frame(Model = nama.model.ncs, nilai.cv.ns)
model.ncs
## Model rmse
## NCS2 2 - NCS Knots 68,90 4.140871
## NCS3 3 - NCS Knots 60, 88, 105 4.217066
Secara empiris berdasarkan nilai RMSE, banyaknya knots terbaik adalah 2 knots sehingga model yang terpilih adalah Natural Cubic Splines dengan 2 knots.
Secara Visual
nc2 <- ggplot(AutoJepang, aes(x = horsepower, y = mpg)) +
geom_point(alpha = 0.8, color="black") +
stat_smooth(method = "lm", formula = y~ns(x, knots = c(68,90)), col = "blue", se = F) +
theme_bw()+
labs(title = "Natural Cubic Splines 2 Knots (RMSE=4.14)",
subtitle = "Jepang")
nc2
Secara Empiris
poly2.d <- cv.poly3(AutoJepang)
## Warning: The number of observations in each quantile is below the recommended threshold of 20.
## • Stratification will use 3 breaks instead.
pc.d <- cv.pc2(AutoJepang)[1,-1]
## Warning: The number of observations in each quantile is below the recommended threshold of 20.
## • Stratification will use 3 breaks instead.
ncs.d <- model.ncs[1,-1]
# Membuat dataframe
df <- data.frame("Metode" = c("Polinomial Derajat 2", "Piecewise Constant 4", "NCS 2 Knots"), "RMSE" = c(poly2.d, pc.d, ncs.d))
df
## Metode RMSE
## 1 Polinomial Derajat 2 3.962162
## 2 Piecewise Constant 4 4.306154
## 3 NCS 2 Knots 4.140871
Berdasarkan hasil analisis, model terbaik untuk data Auto Eropa adalah Polynomial Regression derajat 2.
Secara Visual
# Membuat plot gabungan
combined_plot <- ggplot(AutoJepang,aes(x=horsepower, y=mpg)) +
ggtitle("Comparison of Best Model") +
geom_point(alpha = 0.8, color="black") +
stat_smooth(method = "lm",
formula = y~poly(x,3,raw=T), aes(col = "Polinomial Derajat 3"), se = F,
linetype = "solid") +
stat_smooth(method = "lm",
formula = y~cut(x,4), aes(col = "Piecewise Constant 4"), se = F,
linetype = "solid") +
stat_smooth(method = "lm",
formula = y~ns(x, knots = c(68,90)),
aes(col = "NCS 2 Knots"), se = F, linetype = "solid") +
labs(color="Model")+
scale_color_manual(values=c("Polinomial Derajat 3"="blue", "Piecewise Constant 4"="red","NCS 2 Knots"= "green")) +
theme_bw()
combined_plot
Polynomial Derajat 3: Model ini, yang diwakili oleh garis biru, tampaknya paling akurat dalam memprediksi efisiensi bahan bakar berdasarkan tenaga kuda. Garis ini tampaknya paling dekat dengan titik data, menunjukkan bahwa model ini memiliki kesalahan prediksi yang paling rendah.
Secara keseluruhan, plot ini menunjukkan bahwa ada hubungan
non-linear antara horsepower dan mpg.
Berdasarkan hasil modeling non linier, pemilihan tuning parameter menggunakan 10-fold cross validation, dan evaluasi diperoleh model terbaik untuk masing-masing data sebagai berikut:
mod.auto <- model.ncs[2,-1]
mod.Amerika <- cv.pc(AutoAmerika)[1,-1]
mod.Eropa <- cv.poly2(AutoEropa)
## Warning: The number of observations in each quantile is below the recommended threshold of 20.
## • Stratification will use 3 breaks instead.
mod.Jepang <- cv.poly3(AutoJepang)
## Warning: The number of observations in each quantile is below the recommended threshold of 20.
## • Stratification will use 3 breaks instead.
df <- data.frame("Metode" = c("NCS 9 Knots", "Piecewise Constant 9", "Polynomial Derajat 2", "Polynomial Derajat 3"), "RMSE" = c(mod.auto, mod.Amerika, mod.Eropa, mod.Jepang))
df$Negara <- c("Global", "Amerika", "Eropa", "Jepang")
df
## Metode RMSE Negara
## 1 NCS 9 Knots 4.217066 Global
## 2 Piecewise Constant 9 4.997476 Amerika
## 3 Polynomial Derajat 2 4.805676 Eropa
## 4 Polynomial Derajat 3 3.962162 Jepang
Plot Model Terbaik Berdasarkan Asal Negara
Hasil modeling dapat disajikan dalam diagram pencar dan kurva prediksi sebagai berikut:
pc9 <- ggplot(AutoAmerika,aes(x=horsepower, y=mpg)) +
geom_point(alpha=0.8, color="black") +
stat_smooth(method = "lm",
formula = y~cut(x,9),
lty = 1, col = "blue",se = F)+
theme_bw()+
labs(title = "Piecewise Constant 9 Interval",
subtitle = "Amerika")
poly2 <- ggplot(AutoEropa,aes(x=horsepower, y=mpg)) +
geom_point(alpha=0.8, color="black") +
stat_smooth(method = "lm",
formula = y~poly(x,2,raw=T),
lty = 1, col = "blue",se = F)+
theme_bw()+
labs(title = "Polynomial Derajat 2",
subtitle = "Eropa")
poly3 <- ggplot(AutoJepang,aes(x=horsepower, y=mpg)) +
geom_point(alpha=0.8, color="black") +
stat_smooth(method = "lm",
formula = y~poly(x,3,raw=T),
lty = 1, col = "blue",se = F)+
theme_bw()+
labs(title = "Polinomial Derajat 3",
subtitle = "Jepang")
plot_grid(pc9, poly2, poly3)
Berdasarkan model terbaik, ada beberapa kesimpulan yang diperoleh yaitu sebagai berikut:
Model non linear terbaik yang terpilih untuk data Auto adalah Natural Cubic Splines dengan 9 knots, sedangkan untuk data berdasarkan asal negara model non linear terbaik yang terpilih adalah: Amerika (Piecewise Constant dengan 9 Interval), Eropa (Polynomial Regression derajat 2), dan Jepang (Polynomial Regression derajat 2).
Secara umum, model terbaik yang terpilih untuk semua data baik itu secara keseluruhan ataupun berdasarkan asal negara menunjukkan bahwa peningkatan tenaga kuda tidak selalu berarti penurunan efisiensi bahan bakar yang signifikan. Sebaliknya, ada titik di mana peningkatan tenaga kuda mulai memiliki dampak negatif yang lebih besar pada efisiensi bahan bakar. Namun, perlu diingat bahwa model ini hanyalah perkiraan dan mungkin tidak selalu berlaku untuk setiap kendaraan atau situasi.
Saran yang dapat diberikan berdasarkan analisis adalah:
Terdapat hubungan non-linear antara kekuatan mesin
horsepower dan efisiensi bahan bakar mpg.
Secara umum, peningkatan kekuatan mesin dapat mengakibatkan penurunan
efisiensi bahan bakar. Oleh karena itu, jika efisiensi bahan bakar
adalah prioritas, pertimbangkan untuk memilih kendaraan dengan tenaga
kuda yang lebih rendah.
Model yang digunakan dalam analisis ini memberikan perkiraan yang
baik tentang hubungan antara kekuatan mesin horsepower dan
efisiensi bahan bakar mpg. Namun, model ini hanyalah
perkiraan dan mungkin tidak selalu berlaku untuk setiap kendaraan atau
situasi. Oleh karena itu, selalu baik untuk memvalidasi model dengan
data tes atau data baru sebelum membuat keputusan berdasarkan prediksi
model.
Pertimbangkan Model yang Lebih Sederhana: Model yang lebih sederhana bisa lebih berguna jika mereka cukup akurat dan lebih mudah diinterpretasikan.
Sartono, B. (November 1, 2020). Moving Beyond Linearity. Retrieved from: https://rpubs.com/bagusco/taklinear
Amalia, R. (April 23, 2021). Moving Beyond Linearity. Retrieved from: https://rpubs.com/reniamelia/MovingBeyondLinearity
Setiabudi, N.A. (November 3, 2021). Moving Beyond Linearity. Retrieved from: https://rpubs.com/nurandi/moving-beyond-linearity
Kuhn, M., & Johnson, K. (2013). Applied Predictive Modeling. New York, NY: Springer.
Mahasiswa Pascasarjana Statistika dan Sains Data, IPB University, ummulsyam@apps.ipb.ac.id