| itle: “Regresi Polinomial dengan R” |
| ubtitle: “Contoh Penerapan dan Pemilihan Derajat via Cross-Validation” |
| uthor: “Nadia” |
| ate: “2026-10-05” |
| utput: |
| html_document: |
| toc: true |
| toc_float: true |
| theme: flatly |
Data disimulasikan dengan hubungan non-linier (kuadratik) antara
x dan y.
set.seed(123)
n <- 100
x <- seq(0, 10, length.out = n)
y <- 5 + 2*x - 0.3*x^2 + rnorm(n, mean = 0, sd = 2)
data <- data.frame(x = x, y = y)
head(data)
## x y
## 1 0.0000000 3.879049
## 2 0.1010101 4.738604
## 3 0.2020202 8.509213
## 4 0.3030303 5.719529
## 5 0.4040404 6.017682
## 6 0.5050505 9.363708
#Interpretasi: #Data pada tahap ini dibuat secara simulasi untuk menggambarkan hubungan yang tidak berbentuk garis lurus antara variabel x dan y. Penggunaan set.seed(123) bertujuan agar proses pembangkitan data menghasilkan nilai yang sama ketika kode dijalankan kembali. Sebanyak 100 data dibentuk dengan nilai x mulai dari 0 hingga 10. Nilai y kemudian diperoleh berdasarkan fungsi kuadratik (y = 5 + 2x - 0.3x^2) yang diberi tambahan variasi acak. Dengan demikian, data yang terbentuk memiliki pola melengkung sehingga sesuai untuk penerapan regresi polinomial. Fungsi head(data) digunakan untuk melihat beberapa observasi pertama dari data yang telah dibuat.
Tiga model dicocokkan sebagai pembanding: linier, polinomial derajat 2, dan derajat 3.
model_linier <- lm(y ~ x, data = data)
model_poli2 <- lm(y ~ poly(x, 2, raw = TRUE), data = data)
model_poli3 <- lm(y ~ poly(x, 3, raw = TRUE), data = data)
summary(model_poli2)
##
## Call:
## lm(formula = y ~ poly(x, 2, raw = TRUE), data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -4.8136 -1.1977 -0.0533 1.3549 4.3891
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 5.33982 0.53777 9.929 <2e-16 ***
## poly(x, 2, raw = TRUE)1 1.80266 0.24855 7.253 1e-10 ***
## poly(x, 2, raw = TRUE)2 -0.27529 0.02405 -11.447 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.829 on 97 degrees of freedom
## Multiple R-squared: 0.788, Adjusted R-squared: 0.7837
## F-statistic: 180.3 on 2 and 97 DF, p-value: < 2.2e-16
#Interpretasi: #Pada tahap pencocokan model, tiga bentuk regresi digunakan untuk melihat model mana yang paling mampu menggambarkan pola data, yaitu regresi linier, polinomial derajat 2, dan polinomial derajat 3. Model polinomial derajat 2 memasukkan komponen (x^2), sedangkan derajat 3 menambahkan komponen (x^3). Penggunaan raw = TRUE membuat koefisien yang diperoleh dapat dibaca secara langsung sebagai koefisien dari masing-masing pangkat x. Berdasarkan hasil summary(model_poli2), model kuadratik menunjukkan hasil yang baik dengan koefisien yang signifikan dan nilai R-squared yang tinggi. Hasil tersebut sesuai dengan karakteristik data yang sejak awal dibentuk menggunakan pola kuadratik.
anova(model_linier, model_poli2, model_poli3)
## Analysis of Variance Table
##
## Model 1: y ~ x
## Model 2: y ~ poly(x, 2, raw = TRUE)
## Model 3: y ~ poly(x, 3, raw = TRUE)
## Res.Df RSS Df Sum of Sq F Pr(>F)
## 1 98 762.42
## 2 97 324.33 1 438.09 129.6931 <2e-16 ***
## 3 96 324.28 1 0.05 0.0155 0.9012
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#Interpretasi: #Perbandingan melalui uji ANOVA bertingkat digunakan untuk mengetahui apakah penambahan derajat polinomial memberikan perbaikan yang berarti pada model. Hasil perbandingan menunjukkan bahwa model derajat 2 memberikan peningkatan yang signifikan dibandingkan model linier. Sebaliknya, penambahan komponen hingga derajat 3 tidak memberikan peningkatan yang cukup berarti dibandingkan model derajat 2. Oleh karena itu, penggunaan model derajat 2 sudah mampu menggambarkan pola hubungan x dan y tanpa perlu menambah tingkat kompleksitas model.
AIC(model_linier, model_poli2, model_poli3)
## df AIC
## model_linier 3 492.9204
## model_poli2 4 409.4469
## model_poli3 5 411.4307
#Interpretasi: #AIC digunakan untuk membandingkan kualitas ketiga model dengan mempertimbangkan ketepatan model sekaligus kompleksitasnya. Semakin kecil nilai AIC, semakin baik model tersebut dalam memberikan keseimbangan antara kecocokan dan jumlah parameter. Berdasarkan hasil perhitungan, model polinomial derajat 2 memperoleh nilai AIC sebesar 409.4469, lebih rendah dibandingkan derajat 3 sebesar 411.4307 dan model linier sebesar 492.9204. Dengan demikian, berdasarkan kriteria AIC, model derajat 2 menjadi model yang paling sesuai di antara ketiga model yang dibandingkan.
data$pred_linier <- predict(model_linier)
data$pred_poli2 <- predict(model_poli2)
data$pred_poli3 <- predict(model_poli3)
ggplot(data, aes(x = x, y = y)) +
geom_point(alpha = 0.5) +
geom_line(aes(y = pred_linier, color = "Linier"), linewidth = 1) +
geom_line(aes(y = pred_poli2, color = "Polinomial derajat 2"), linewidth = 1) +
geom_line(aes(y = pred_poli3, color = "Polinomial derajat 3"), linewidth = 1) +
labs(title = "Perbandingan Regresi Linier vs Polinomial",
x = "X", y = "Y", color = "Model") +
theme_minimal()
#Interpretasi: #Visualisasi memperlihatkan posisi data aktual bersama
dengan garis prediksi dari masing-masing model. Garis regresi linier
belum mampu mengikuti pola lengkung yang terlihat pada data sehingga
terdapat penyimpangan yang cukup jelas. Berbeda dengan model linier,
kurva polinomial derajat 2 mengikuti pola sebaran data dengan lebih
baik. Kurva derajat 3 juga memiliki bentuk yang hampir sama dengan
derajat 2. Kedekatan kedua kurva tersebut menunjukkan bahwa penambahan
komponen kubik hanya memberikan perubahan kecil terhadap hasil
prediksi.
rmse <- function(actual, predicted) sqrt(mean((actual - predicted)^2))
data.frame(
Model = c("Linier", "Polinomial derajat 2", "Polinomial derajat 3"),
RMSE = c(rmse(data$y, data$pred_linier),
rmse(data$y, data$pred_poli2),
rmse(data$y, data$pred_poli3))
)
## Model RMSE
## 1 Linier 2.761195
## 2 Polinomial derajat 2 1.800917
## 3 Polinomial derajat 3 1.800772
#Interpretasi: #RMSE digunakan untuk melihat tingkat kesalahan prediksi yang dihasilkan oleh masing-masing model. Nilai yang lebih kecil menunjukkan bahwa hasil prediksi model semakin dekat dengan nilai sebenarnya. Berdasarkan hasil perhitungan, model polinomial memiliki kesalahan prediksi yang jauh lebih rendah dibandingkan model linier. Nilai RMSE antara model derajat 2 dan derajat 3 juga sangat berdekatan, sehingga peningkatan kompleksitas dari derajat 2 menjadi derajat 3 tidak memberikan keuntungan prediksi yang berarti.
Skema 10-fold cross-validation diulang 5 kali untuk menguji derajat polinomial 1 sampai 6.
names(data)
## [1] "x" "y" "pred_linier" "pred_poli2" "pred_poli3"
library(caret)
set.seed(42)
kontrol <- trainControl(
method = "repeatedcv",
number = 10,
repeats = 5
)
derajat_max <- 6
hasil_cv <- data.frame(
derajat = integer(),
RMSE = numeric()
)
for (d in 1:derajat_max) {
data_cv <- data
# Membuat variabel polynomial
if (d == 1) {
data_cv$x_poly <- data_cv$x
} else {
poly_x <- poly(data_cv$x, degree = d, raw = TRUE)
data_cv$x_poly <- poly_x[, 1]
for (j in 2:d) {
data_cv[[paste0("x_poly", j)]] <- poly_x[, j]
}
}
# Formula sesuai derajat
if (d == 1) {
formula_model <- y ~ x_poly
} else {
variabel <- paste0("x_poly", 2:d)
formula_model <- as.formula(
paste("y ~ x_poly +", paste(variabel, collapse = " + "))
)
}
model_cv <- train(
formula_model,
data = data_cv,
method = "lm",
trControl = kontrol
)
hasil_cv <- rbind(
hasil_cv,
data.frame(
derajat = d,
RMSE = min(model_cv$results$RMSE)
)
)
}
hasil_cv
## derajat RMSE
## 1 1 2.757805
## 2 2 1.825068
## 3 3 1.859968
## 4 4 1.877628
## 5 5 1.871701
## 6 6 1.880719
#Interpretasi: #Cross-validation dilakukan untuk menentukan derajat polinomial yang memberikan kinerja prediksi terbaik. Proses validasi menggunakan 10-fold cross-validation yang diulang sebanyak 5 kali untuk masing-masing derajat polinomial dari 1 hingga 6. Hasilnya menunjukkan penurunan RMSE yang cukup besar ketika model berubah dari derajat 1 menjadi derajat 2. Setelah mencapai derajat 2, perubahan nilai RMSE relatif kecil dan cenderung meningkat pada derajat yang lebih tinggi. Kondisi tersebut menunjukkan bahwa penambahan derajat setelah derajat 2 tidak lagi memberikan peningkatan kinerja yang berarti.
derajat_optimal <- hasil_cv$derajat[which.min(hasil_cv$RMSE)]
cat("Derajat optimal berdasarkan CV:", derajat_optimal, "\n")
## Derajat optimal berdasarkan CV: 2
#Interpretasi: #Berdasarkan proses cross-validation, derajat yang menghasilkan nilai RMSE paling rendah dipilih sebagai derajat optimal. Hasil yang diperoleh menunjukkan bahwa model polinomial derajat 2 merupakan pilihan terbaik. Hal ini juga sejalan dengan hasil perbandingan menggunakan ANOVA, AIC, maupun visualisasi sebelumnya. Dengan demikian, model kuadratik sudah cukup untuk menggambarkan hubungan antara x dan y pada data yang digunakan.
ggplot(hasil_cv, aes(x = derajat, y = RMSE)) +
geom_line(
color = "steelblue",
linewidth = 1
) +
geom_point(
size = 3,
color = "steelblue"
) +
geom_vline(
xintercept = derajat_optimal,
linetype = "dashed",
color = "firebrick"
) +
scale_x_continuous(
breaks = 1:derajat_max
) +
labs(
title = "Pemilihan Derajat Optimal via 10-Fold Cross-Validation",
x = "Derajat Polinomial",
y = "RMSE Rata-rata (Validasi Silang)"
) +
theme_minimal()
#Interpretasi: #Grafik cross-validation memperlihatkan perubahan nilai
RMSE ketika derajat polinomial dinaikkan. Penurunan paling terlihat
terjadi dari derajat 1 menuju derajat 2. Setelah itu, nilai RMSE tidak
mengalami perbaikan yang berarti dan justru cenderung meningkat pada
beberapa derajat yang lebih tinggi. Garis vertikal menunjukkan derajat
yang dipilih sebagai model optimal, yaitu derajat 2. Pola tersebut
menunjukkan bahwa model linier masih terlalu sederhana untuk menangkap
hubungan data, sedangkan penggunaan derajat yang terlalu tinggi dapat
membuat model menjadi lebih kompleks tanpa menghasilkan peningkatan
prediksi yang sebanding.
model_final <- lm(y ~ poly(x, derajat_optimal, raw = TRUE), data = data)
summary(model_final)
##
## Call:
## lm(formula = y ~ poly(x, derajat_optimal, raw = TRUE), data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -4.8136 -1.1977 -0.0533 1.3549 4.3891
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 5.33982 0.53777 9.929 <2e-16 ***
## poly(x, derajat_optimal, raw = TRUE)1 1.80266 0.24855 7.253 1e-10 ***
## poly(x, derajat_optimal, raw = TRUE)2 -0.27529 0.02405 -11.447 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.829 on 97 degrees of freedom
## Multiple R-squared: 0.788, Adjusted R-squared: 0.7837
## F-statistic: 180.3 on 2 and 97 DF, p-value: < 2.2e-16
#Interpretasi: #Setelah derajat optimal ditentukan, model akhir dibentuk menggunakan regresi polinomial derajat 2. Persamaan model yang diperoleh adalah ( = 5.34 + 1.80x - 0.275x^2). Koefisien pada model menunjukkan adanya pengaruh dari komponen linier dan kuadratik terhadap nilai y. Seluruh koefisien menunjukkan hasil yang signifikan secara statistik dengan nilai p kurang dari 0,001. Nilai (R^2 = 0.788) menunjukkan bahwa sekitar 78,8% variasi pada y dapat dijelaskan oleh model, sedangkan sisanya dipengaruhi oleh faktor lain di luar model. Uji F yang signifikan juga menunjukkan bahwa model secara keseluruhan memiliki kemampuan yang bermakna dalam menjelaskan variabel y.
poly(x, derajat, raw = TRUE) digunakan agar koefisien
dapat diinterpretasi langsung sebagai \(\beta_1 x + \beta_2 x^2 + \dots\)x distandardisasi terlebih dahulu
(scale(x)) agar model lebih stabil secara numerik.data$Y_topi_linier <- predict(model_linier)
data$Y_topi_poli2 <- predict(model_poli2)
data$Y_topi_poli3 <- predict(model_poli3)
data.frame(
Y = data$y,
Y_topi_linier = data$Y_topi_linier,
Y_topi_poli2 = data$Y_topi_poli2,
Y_topi_poli3 = data$Y_topi_poli3
)
## Y Y_topi_linier Y_topi_poli2 Y_topi_poli3
## 1 3.87904871 9.8817094 5.33982287 5.28280126
## 2 4.73860431 9.7857215 5.51910079 5.46899089
## 3 8.50921338 9.6897335 5.69276104 5.64921021
## 4 5.71952918 9.5937456 5.86080361 5.82346649
## 5 6.01768168 9.4977577 6.02322852 5.99176701
## 6 9.36370818 9.4017697 6.18003576 6.15411903
## 7 7.02376079 9.3057818 6.33122532 6.31052982
## 8 3.73403425 9.2097939 6.47679722 6.46100666
## 9 5.04655753 9.1138060 6.61675145 6.60555682
## 10 5.67892399 9.0178180 6.75108800 6.74418756
## 11 9.16227440 8.9218301 6.87980689 6.87690616
## 12 7.57147951 8.8258422 7.00290810 7.00371990
## 13 7.78501398 8.7298542 7.12039165 7.12463603
## 14 7.33033390 8.6338663 7.23225752 7.23966183
## 15 6.11666178 8.5378784 7.33850572 7.34880458
## 16 10.91542407 8.4418904 7.43913626 7.45207154
## 17 8.44443068 8.3459025 7.53414912 7.54946998
## 18 3.61650551 8.2499146 7.62354431 7.64100717
## 19 9.04733990 8.1539266 7.70732183 7.72669040
## 20 6.78781174 8.0579387 7.78548168 7.80652691
## 21 5.68039177 7.9619508 7.85802386 7.88052400
## 22 7.45661215 7.8659628 7.92494837 7.94868893
## 23 5.91095407 7.7699749 7.98625521 8.01102896
## 24 6.56945966 7.6739870 8.04194438 8.06755137
## 25 6.83532091 7.5779990 8.09201588 8.11826344
## 26 4.76404833 7.4820111 8.13646971 8.16317242
## 27 9.85892273 7.3860232 8.17530587 8.20228560
## 28 8.52988673 7.2900352 8.20852436 8.23561024
## 29 5.98053666 7.1940473 8.23612517 8.26315362
## 30 10.79198858 7.0980594 8.25810832 8.28492300
## 31 9.15871357 7.0020714 8.27447380 8.30092566
## 32 7.73094672 6.9060835 8.28522160 8.31116887
## 33 10.12052374 6.8100956 8.29035174 8.31565989
## 34 10.08960031 6.7141076 8.28986420 8.31440601
## 35 9.97343458 6.6181197 8.28375900 8.30741448
## 36 9.69837019 6.5221318 8.27203612 8.29469258
## 37 9.41362043 6.4261439 8.25469558 8.27624759
## 38 8.16053532 6.3301559 8.23173736 8.25208677
## 39 7.64488520 6.2341680 8.20316147 8.22221739
## 40 7.46219849 6.1381801 8.16896791 8.18664672
## 41 6.79393468 6.0421921 8.12915669 8.14538204
## 42 7.72160040 5.9462042 8.08372779 8.09843062
## 43 5.55460675 5.8502163 8.03268122 8.04579973
## 44 12.36515405 5.7542283 7.97601698 7.98749663
## 45 10.37888696 5.6582404 7.91373507 7.92352860
## 46 5.64634482 5.5622525 7.84583549 7.85390291
## 47 7.01026951 5.4662645 7.77231824 7.77862683
## 48 6.80008384 5.3702766 7.69318332 7.69770763
## 49 9.20455834 5.2742887 7.60843073 7.61115259
## 50 7.38300169 5.1783007 7.51806047 7.51896896
## 51 7.95536675 5.0823128 7.42207253 7.42116404
## 52 7.28450429 4.9863249 7.32046693 7.31774507
## 53 7.14260313 4.8903369 7.21324366 7.20871935
## 54 9.84617304 4.7943490 7.10040271 7.09409413
## 55 6.53192910 4.6983611 6.98194410 6.97387668
## 56 9.88479306 4.6023731 6.85786782 6.84807429
## 57 3.61660520 4.5063852 6.72817386 6.71669421
## 58 7.73947543 4.4103973 6.59286224 6.57974373
## 59 6.66797173 4.3144093 6.45193294 6.43723011
## 60 6.69603986 4.2184214 6.30538598 6.28916062
## 61 6.86120734 4.1224335 6.15322134 6.13554253
## 62 4.92893130 4.0264455 5.99543903 5.97638312
## 63 5.09269145 3.9304576 5.83203905 5.81168965
## 64 3.54136163 3.8344697 5.66302141 5.64146939
## 65 3.24821430 3.7384818 5.48838609 5.46572963
## 66 5.80601657 3.6424938 5.30813310 5.28447762
## 67 5.89641956 3.5465059 5.12226244 5.09772064
## 68 4.90092734 3.4505180 4.93077411 4.90546596
## 69 6.42825088 3.3545300 4.73366811 4.70772084
## 70 8.46656056 3.2585421 4.53094444 4.50449257
## 71 3.16088227 3.1625542 4.32260310 4.29578842
## 72 -0.70496157 3.0665662 4.10864409 4.08161564
## 73 5.68916300 2.9705783 3.88906741 3.86198152
## 74 2.01747237 2.8745904 3.66387306 3.63689332
## 75 1.81192277 2.7786024 3.43306103 3.40635832
## 76 4.98502704 2.6826145 3.19663134 3.17038378
## 77 2.10416075 2.5866266 2.95458398 2.92897699
## 78 -0.03402802 2.4906386 2.70691894 2.68214520
## 79 2.49759319 2.3946507 2.45363624 2.42989569
## 80 1.57866050 2.2986628 2.19473586 2.17223573
## 81 1.58330676 2.2026748 1.93021782 1.90917259
## 82 2.05155254 2.1066869 1.66008210 1.64071354
## 83 0.24276319 2.0106990 1.38432872 1.36686585
## 84 1.96980605 1.9147110 1.10295766 1.08763680
## 85 -0.06907230 1.8187231 0.81596894 0.80303366
## 86 0.72019080 1.7227352 0.52336254 0.51306368
## 87 1.92890913 1.6267472 0.22513847 0.21773416
## 88 0.27807648 1.5307593 -0.07870327 -0.08294765
## 89 -1.57778910 1.4347714 -0.38816268 -0.38897447
## 90 1.03192806 1.3387834 -0.70323975 -0.70033903
## 91 0.37543746 1.2427955 -1.02393450 -1.01703406
## 92 -0.86678123 1.1468076 -1.35024692 -1.33905229
## 93 -1.84423840 1.0508196 -1.68217701 -1.66638645
## 94 -3.94176257 0.9548317 -2.01972477 -1.99902927
## 95 -0.33501589 0.8588438 -2.36289021 -2.33697348
## 96 -4.63333215 0.7628559 -2.71167331 -2.68021179
## 97 0.55923899 0.6668679 -3.06607408 -3.02873696
## 98 -1.13894159 0.5708800 -3.42609252 -3.38254170
## 99 -5.07042123 0.4748921 -3.79172863 -3.74161874
## 100 -7.05284180 0.3789041 -4.16298242 -4.10596081
#Interpretasi: #Tabel terakhir digunakan untuk membandingkan nilai aktual y dengan nilai prediksi yang dihasilkan oleh model linier, polinomial derajat 2, dan polinomial derajat 3. Hasil perbandingan menunjukkan bahwa prediksi model linier memiliki selisih yang lebih besar terhadap nilai aktual. Sementara itu, hasil prediksi dari model derajat 2 dan derajat 3 berada lebih dekat dengan data sebenarnya. Kedua model polinomial juga menghasilkan nilai prediksi yang relatif serupa. Temuan ini semakin memperkuat bahwa hubungan antara x dan y lebih tepat direpresentasikan menggunakan bentuk polinomial, dengan derajat 2 sebagai pilihan yang lebih sederhana dan sudah mampu memberikan hasil yang baik.