library(rio)
## Warning: package 'rio' was built under R version 4.4.2
library("forecast")
## Warning: package 'forecast' was built under R version 4.4.3
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library("graphics")
library("TTR")
## Warning: package 'TTR' was built under R version 4.4.3
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.4.3

##Import data

library(readxl)
## Warning: package 'readxl' was built under R version 4.4.3
sales<- read_excel("C:/Users/Resea/Documents/Semester 5/MPDW/data latihan mpdw (store sales)_Chaca Alya (1).xlsx")
sales
## # A tibble: 730 × 2
##    Date                Total_Sales
##    <dttm>                    <dbl>
##  1 2022-01-01 00:00:00        185.
##  2 2022-01-02 00:00:00        193.
##  3 2022-01-03 00:00:00        213.
##  4 2022-01-04 00:00:00        250.
##  5 2022-01-05 00:00:00        224.
##  6 2022-01-06 00:00:00        222.
##  7 2022-01-07 00:00:00        200.
##  8 2022-01-08 00:00:00        213.
##  9 2022-01-09 00:00:00        222.
## 10 2022-01-10 00:00:00        203.
## # ℹ 720 more rows

##Ambil 100 data

data_tugas <- sales[1:100,]
data_tugas
## # A tibble: 100 × 2
##    Date                Total_Sales
##    <dttm>                    <dbl>
##  1 2022-01-01 00:00:00        185.
##  2 2022-01-02 00:00:00        193.
##  3 2022-01-03 00:00:00        213.
##  4 2022-01-04 00:00:00        250.
##  5 2022-01-05 00:00:00        224.
##  6 2022-01-06 00:00:00        222.
##  7 2022-01-07 00:00:00        200.
##  8 2022-01-08 00:00:00        213.
##  9 2022-01-09 00:00:00        222.
## 10 2022-01-10 00:00:00        203.
## # ℹ 90 more rows

Diubah ke time series

data.ts <- ts(data_tugas$Total_Sales)

##Eksploraasi Data

summary(data.ts)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   181.3   198.5   217.8   216.4   229.0   280.9

#Membuat plot time series

ts.plot(data.ts, xlab="Time Period ", ylab="Total Sales", 
        main = "Time Series Plot")
points(data.ts)

#Plot tersebut menunjukkan data stasioner tanpa tren sehingga cocok dengan metode Single Moving Average (SMA) dan Single Exponential Smoothing (SES).

##Single Moving Average (SMA) #Split data #Data train sebanyak 80% dan data test 20%

training_ma_prak1 <- data_tugas[1:80,]
testing_ma_prak1 <- data_tugas[81:100,]
train_ma.ts <- ts(training_ma_prak1$Total_Sales)
test_ma.ts <- ts(testing_ma_prak1$Total_Sales)

#Plot dara train

plot(train_ma.ts, col="blue",main="Plot data latih")
points(train_ma.ts)

#Plot data test

plot(test_ma.ts, col="blue",main="Plot data uji")
points(test_ma.ts)

#Plot seluruh data

ggplot() + 
  geom_line(data = training_ma_prak1, aes(x = Date, y = Total_Sales, col = "Data Latih")) +
  geom_line(data = testing_ma_prak1, aes(x = Date, y = Total_Sales, col = "Data Uji")) +
  labs(x = "Date", y = "Total Sales", color = "Legend") +
   scale_colour_manual(name="Keterangan:", breaks = c("Data Latih", "Data Uji"),
                      values = c("blue", "red")) + 
  theme_bw() + theme(legend.position = "bottom",
                     plot.caption = element_text(hjust=0.5, size=12))

data.sma<-SMA(train_ma.ts, n=4)
data.sma
## Time Series:
## Start = 1 
## End = 80 
## Frequency = 1 
##  [1]       NA       NA       NA 209.9150 219.5950 226.8875 223.8250 214.7975
##  [9] 214.5325 209.8600 214.4475 227.6375 223.1975 227.0000 218.1450 197.8425
## [17] 208.5075 208.1575 216.8925 226.1175 213.3225 205.8100 197.0625 192.4325
## [25] 198.9825 207.2575 215.6350 213.4450 214.2075 206.1600 215.8875 230.2500
## [33] 229.0925 237.0025 221.0425 205.0850 195.2225 190.4150 198.3150 208.7775
## [41] 217.5700 216.9650 207.6075 196.1025 192.8700 208.5675 220.0650 228.4700
## [49] 235.0450 224.7925 214.2575 210.8625 209.9600 213.1425 220.9150 218.5925
## [57] 216.2075 216.6000 222.0350 228.6150 231.0700 225.4000 220.5675 213.4475
## [65] 214.1400 213.3150 214.6925 231.4275 227.5550 225.9775 217.9125 208.6825
## [73] 216.8250 219.2275 228.1325 234.4150 222.4650 217.1200 212.3725 202.3700
data.ramal<-c(NA,data.sma)
data.ramal #forecast 1 periode ke depan
##  [1]       NA       NA       NA       NA 209.9150 219.5950 226.8875 223.8250
##  [9] 214.7975 214.5325 209.8600 214.4475 227.6375 223.1975 227.0000 218.1450
## [17] 197.8425 208.5075 208.1575 216.8925 226.1175 213.3225 205.8100 197.0625
## [25] 192.4325 198.9825 207.2575 215.6350 213.4450 214.2075 206.1600 215.8875
## [33] 230.2500 229.0925 237.0025 221.0425 205.0850 195.2225 190.4150 198.3150
## [41] 208.7775 217.5700 216.9650 207.6075 196.1025 192.8700 208.5675 220.0650
## [49] 228.4700 235.0450 224.7925 214.2575 210.8625 209.9600 213.1425 220.9150
## [57] 218.5925 216.2075 216.6000 222.0350 228.6150 231.0700 225.4000 220.5675
## [65] 213.4475 214.1400 213.3150 214.6925 231.4275 227.5550 225.9775 217.9125
## [73] 208.6825 216.8250 219.2275 228.1325 234.4150 222.4650 217.1200 212.3725
## [81] 202.3700
data.gab<-cbind(
  aktual=c(data.ts),
  pemulusan=c(data.sma,rep(NA,24)),
  ramalan=c(data.ramal,rep(data.ramal[length(data.ramal)],23)))
## Warning in cbind(aktual = c(data.ts), pemulusan = c(data.sma, rep(NA, 24)), :
## number of rows of result is not a multiple of vector length (arg 1)
data.gab #forecast 24 periode ke depan
##        aktual pemulusan  ramalan
##   [1,] 184.78        NA       NA
##   [2,] 192.62        NA       NA
##   [3,] 212.68        NA       NA
##   [4,] 249.58  209.9150       NA
##   [5,] 223.50  219.5950 209.9150
##   [6,] 221.79  226.8875 219.5950
##   [7,] 200.43  223.8250 226.8875
##   [8,] 213.47  214.7975 223.8250
##   [9,] 222.44  214.5325 214.7975
##  [10,] 203.10  209.8600 214.5325
##  [11,] 218.78  214.4475 209.8600
##  [12,] 266.23  227.6375 214.4475
##  [13,] 204.68  223.1975 227.6375
##  [14,] 218.31  227.0000 223.1975
##  [15,] 183.36  218.1450 227.0000
##  [16,] 185.02  197.8425 218.1450
##  [17,] 247.34  208.5075 197.8425
##  [18,] 216.91  208.1575 208.5075
##  [19,] 218.30  216.8925 208.1575
##  [20,] 221.92  226.1175 216.8925
##  [21,] 196.16  213.3225 226.1175
##  [22,] 186.86  205.8100 213.3225
##  [23,] 183.31  197.0625 205.8100
##  [24,] 203.40  192.4325 197.0625
##  [25,] 222.36  198.9825 192.4325
##  [26,] 219.96  207.2575 198.9825
##  [27,] 216.82  215.6350 207.2575
##  [28,] 194.64  213.4450 215.6350
##  [29,] 225.41  214.2075 213.4450
##  [30,] 187.77  206.1600 214.2075
##  [31,] 255.73  215.8875 206.1600
##  [32,] 252.09  230.2500 215.8875
##  [33,] 220.78  229.0925 230.2500
##  [34,] 219.41  237.0025 229.0925
##  [35,] 191.89  221.0425 237.0025
##  [36,] 188.26  205.0850 221.0425
##  [37,] 181.33  195.2225 205.0850
##  [38,] 200.18  190.4150 195.2225
##  [39,] 223.49  198.3150 190.4150
##  [40,] 230.11  208.7775 198.3150
##  [41,] 216.50  217.5700 208.7775
##  [42,] 197.76  216.9650 217.5700
##  [43,] 186.06  207.6075 216.9650
##  [44,] 184.09  196.1025 207.6075
##  [45,] 203.57  192.8700 196.1025
##  [46,] 260.55  208.5675 192.8700
##  [47,] 232.05  220.0650 208.5675
##  [48,] 217.71  228.4700 220.0650
##  [49,] 229.87  235.0450 228.4700
##  [50,] 219.54  224.7925 235.0450
##  [51,] 189.91  214.2575 224.7925
##  [52,] 204.13  210.8625 214.2575
##  [53,] 226.26  209.9600 210.8625
##  [54,] 232.27  213.1425 209.9600
##  [55,] 221.00  220.9150 213.1425
##  [56,] 194.84  218.5925 220.9150
##  [57,] 216.72  216.2075 218.5925
##  [58,] 233.84  216.6000 216.2075
##  [59,] 242.74  222.0350 216.6000
##  [60,] 221.16  228.6150 222.0350
##  [61,] 226.54  231.0700 228.6150
##  [62,] 211.16  225.4000 231.0700
##  [63,] 223.41  220.5675 225.4000
##  [64,] 192.68  213.4475 220.5675
##  [65,] 229.31  214.1400 213.4475
##  [66,] 207.86  213.3150 214.1400
##  [67,] 228.92  214.6925 213.3150
##  [68,] 259.62  231.4275 214.6925
##  [69,] 213.82  227.5550 231.4275
##  [70,] 201.55  225.9775 227.5550
##  [71,] 196.66  217.9125 225.9775
##  [72,] 222.70  208.6825 217.9125
##  [73,] 246.39  216.8250 208.6825
##  [74,] 211.16  219.2275 216.8250
##  [75,] 232.28  228.1325 219.2275
##  [76,] 247.83  234.4150 228.1325
##  [77,] 198.59  222.4650 234.4150
##  [78,] 189.78  217.1200 222.4650
##  [79,] 213.29  212.3725 217.1200
##  [80,] 207.82  202.3700 212.3725
##  [81,] 226.39        NA 202.3700
##  [82,] 235.91        NA 202.3700
##  [83,] 245.15        NA 202.3700
##  [84,] 226.40        NA 202.3700
##  [85,] 257.16        NA 202.3700
##  [86,] 198.16        NA 202.3700
##  [87,] 280.91        NA 202.3700
##  [88,] 252.30        NA 202.3700
##  [89,] 231.43        NA 202.3700
##  [90,] 248.58        NA 202.3700
##  [91,] 205.63        NA 202.3700
##  [92,] 186.51        NA 202.3700
##  [93,] 192.29        NA 202.3700
##  [94,] 207.66        NA 202.3700
##  [95,] 217.99        NA 202.3700
##  [96,] 230.70        NA 202.3700
##  [97,] 219.75        NA 202.3700
##  [98,] 201.17        NA 202.3700
##  [99,] 189.20        NA 202.3700
## [100,] 187.20        NA 202.3700
## [101,] 184.78        NA 202.3700
## [102,] 192.62        NA 202.3700
## [103,] 212.68        NA 202.3700
## [104,] 249.58        NA 202.3700

#Plot peramalan

ts.plot(data.ts, xlab="Date", ylab="Total Sales", main= "SMA N=4 Data Sales")
points(data.ts)
lines(data.gab[,2],col="green",lwd=2)
lines(data.gab[,3],col="red",lwd=2)
legend("topleft",c("data aktual","data pemulusan","data peramalan"), lty=8, col=c("black","green","red"), cex=0.5)

#Menghitung keakuratan data

#Menghitung nilai keakuratan data latih
error_train.sma = train_ma.ts-data.ramal[1:length(train_ma.ts)]

SSE_train.sma = sum(error_train.sma[5:length(train_ma.ts)]^2)
MSE_train.sma = mean(error_train.sma[5:length(train_ma.ts)]^2)
MAPE_train.sma = mean(abs((error_train.sma[5:length(train_ma.ts)]/train_ma.ts[5:length(train_ma.ts)])*100))

akurasi_train.sma <- matrix(c(SSE_train.sma, MSE_train.sma, MAPE_train.sma))
row.names(akurasi_train.sma)<- c("SSE", "MSE", "MAPE")
colnames(akurasi_train.sma) <- c("Akurasi m = 4")
akurasi_train.sma
##      Akurasi m = 4
## SSE   45950.943462
## MSE     604.617677
## MAPE      9.343885

#MAPE data train pada metode pemulusan SMA sekitar 9% atau 9.343885. Nilai akurasi tersebut termasuk sangat akurat.

# Ambil data aktual (baris 81-104, kolom 1)
actual_test <- data.gab[81:104, 1]

# Ambil data ramalan (baris 81-104, kolom 3)
forecast_test <- data.gab[81:104, 3]

# Hitung error
error_test.sma <- actual_test - forecast_test

# Hitung metrik
SSE_test.sma <- sum(error_test.sma^2)
MSE_test.sma <- mean(error_test.sma^2)
MAPE_test.sma <- mean(abs(error_test.sma / actual_test * 100))

# Simpan dalam matrix
akurasi_test.sma <- matrix(c(SSE_test.sma, MSE_test.sma, MAPE_test.sma))
row.names(akurasi_test.sma) <- c("SSE", "MSE", "MAPE")
colnames(akurasi_test.sma) <- c("Akurasi m = 4")

akurasi_test.sma
##      Akurasi m = 4
## SSE    23655.47770
## MSE      985.64490
## MAPE      10.60234

#MAPE : 10.60234, maka nilai akurasi termasuk baik.

##Single Exponential Smoothing #Split data #Data train 80% dan data test

training_ma_prak1 <- data_tugas[1:80,]
testing_ma_prak1 <- data_tugas[81:100,]
train_ma.ts <- ts(training_ma_prak1$Total_Sales)
test_ma.ts <- ts(testing_ma_prak1$Total_Sales)

#Plot data train

plot(train_ma.ts, col="blue",main="Plot data latih")
points(train_ma.ts)

#Plot data test

plot(test_ma.ts, col="blue",main="Plot data uji")
points(test_ma.ts)

#Plot digabung

library(ggplot2)
ggplot() + 
  geom_line(data = training_ma_prak1, aes(x = Date, y = Total_Sales, col = "Data Latih")) +
  geom_line(data = testing_ma_prak1, aes(x = Date, y = Total_Sales, col = "Data Uji")) +
  labs(x = "Date", y = "Tota Sales", color = "Legend") +
  scale_colour_manual(name="Keterangan:", breaks = c("Data Latih", "Data Uji"),
                      values = c("blue", "red")) + 
  theme_bw() + theme(legend.position = "bottom",
                     plot.caption = element_text(hjust=0.5, size=12))

#Cara 1 (fungsi ses)
ses.1_prak1 <- ses(train_ma.ts, h = 10, alpha = 0.2)
plot(ses.1_prak1)

ses.2_prak1<- ses(train_ma.ts, h = 10, alpha = 0.7)
plot(ses.2_prak1)

autoplot(ses.1_prak1) +
  autolayer(fitted(ses.1_prak1), series="Fitted") +
  ylab("Total Sales") + xlab("Date")

#Cara 2 (fungsi Holtwinter)
ses1_prak1<- HoltWinters(train_ma.ts, gamma = FALSE, beta = FALSE, alpha = 0.2)
plot(ses1_prak1)

#Ramalan 1

ramalan1<- forecast(ses1_prak1, h=10)
ramalan1
##    Point Forecast    Lo 80    Hi 80    Lo 95    Hi 95
## 81       213.6022 184.9455 242.2590 169.7755 257.4290
## 82       213.6022 184.3779 242.8265 168.9075 258.2970
## 83       213.6022 183.8212 243.3832 168.0561 259.1484
## 84       213.6022 183.2747 243.9297 167.2203 259.9841
## 85       213.6022 182.7379 244.4665 166.3994 260.8051
## 86       213.6022 182.2103 244.9942 165.5924 261.6121
## 87       213.6022 181.6914 245.5131 164.7988 262.4057
## 88       213.6022 181.1808 246.0237 164.0179 263.1866
## 89       213.6022 180.6781 246.5264 163.2491 263.9554
## 90       213.6022 180.1830 247.0215 162.4919 264.7126
ses2_prak1<- HoltWinters(train_ma.ts, gamma = FALSE, beta = FALSE, alpha = 0.7)
plot(ses2_prak1)

#Ramalan 2

ramalan2<- forecast(ses2_prak1, h=10)
ramalan2
##    Point Forecast    Lo 80    Hi 80     Lo 95    Hi 95
## 81       207.9343 177.3096 238.5590 161.09790 254.7708
## 82       207.9343 170.5521 245.3165 150.76318 265.1055
## 83       207.9343 164.8416 251.0271 142.02963 273.8390
## 84       207.9343 159.8038 256.0648 134.32510 281.5436
## 85       207.9343 155.2456 260.6231 127.35389 288.5148
## 86       207.9343 151.0515 264.8172 120.93952 294.9292
## 87       207.9343 147.1460 268.7226 114.96667 300.9020
## 88       207.9343 143.4768 272.3919 109.35505 306.5136
## 89       207.9343 140.0055 275.8632 104.04610 311.8226
## 90       207.9343 136.7031 279.1656  98.99557 316.8731

#SES

ses.opt <- ses(train_ma.ts, h = 10, alpha = NULL)
plot(ses.opt)

ses.opt
##    Point Forecast    Lo 80   Hi 80    Lo 95    Hi 95
## 81        214.869 188.4191 241.319 174.4173 255.3208
## 82        214.869 188.4191 241.319 174.4173 255.3208
## 83        214.869 188.4191 241.319 174.4173 255.3208
## 84        214.869 188.4191 241.319 174.4173 255.3208
## 85        214.869 188.4191 241.319 174.4173 255.3208
## 86        214.869 188.4191 241.319 174.4173 255.3208
## 87        214.869 188.4191 241.319 174.4173 255.3208
## 88        214.869 188.4191 241.319 174.4173 255.3208
## 89        214.869 188.4191 241.319 174.4173 255.3208
## 90        214.869 188.4191 241.319 174.4173 255.3208

#Lamda optimum holt winter

HWopt<- HoltWinters(train_ma.ts, gamma = FALSE, beta = FALSE,alpha = NULL)
HWopt
## Holt-Winters exponential smoothing without trend and without seasonal component.
## 
## Call:
## HoltWinters(x = train_ma.ts, alpha = NULL, beta = FALSE, gamma = FALSE)
## 
## Smoothing parameters:
##  alpha: 0.1505943
##  beta : FALSE
##  gamma: FALSE
## 
## Coefficients:
##       [,1]
## a 215.1085
plot(HWopt)

ramalanopt<- forecast(HWopt, h=10)
ramalanopt
##    Point Forecast    Lo 80    Hi 80    Lo 95    Hi 95
## 81       215.1085 186.6135 243.6035 171.5292 258.6878
## 82       215.1085 186.2922 243.9248 171.0378 259.1792
## 83       215.1085 185.9744 244.2426 170.5518 259.6652
## 84       215.1085 185.6601 244.5569 170.0711 260.1459
## 85       215.1085 185.3491 244.8679 169.5954 260.6216
## 86       215.1085 185.0413 245.1757 169.1247 261.0923
## 87       215.1085 184.7366 245.4804 168.6587 261.5583
## 88       215.1085 184.4350 245.7820 168.1974 262.0196
## 89       215.1085 184.1363 246.0807 167.7406 262.4764
## 90       215.1085 183.8404 246.3766 167.2881 262.9289

#Keakuratan data train

#Pada data training

# SES alpha = 0.2
SSE1<-ses1_prak1$SSE
MSE1<-ses1_prak1$SSE/length(train_ma.ts)
RMSE1<-sqrt(MSE1)

akurasi1 <- matrix(c(SSE1,MSE1,RMSE1))
row.names(akurasi1)<- c("SSE", "MSE", "RMSE")
colnames(akurasi1) <- c("Akurasi lamda=0.2")
akurasi1
##      Akurasi lamda=0.2
## SSE        39264.04244
## MSE          490.80053
## RMSE          22.15402
# SES dengan alpha = 0.7
SSE2<-ses2_prak1$SSE
MSE2<-ses2_prak1$SSE/length(train_ma.ts)
RMSE2<-sqrt(MSE2)

akurasi2 <- matrix(c(SSE2,MSE2,RMSE2))
row.names(akurasi2)<- c("SSE", "MSE", "RMSE")
colnames(akurasi2) <- c("Akurasi lamda=0.7")
akurasi2
##      Akurasi lamda=0.7
## SSE        44555.47498
## MSE          556.94344
## RMSE          23.59965

#Keakuratan data test

# Split data yang lebih fleksible
set.seed(123) # untuk reproducibility
n <- nrow(data_tugas)
train_size <- round(0.8 * n)

# Random sampling (jika data tidak time-dependent)
train_indices <- sample(1:n, train_size)
training_ma_prakl <- data_tugas[train_indices, ]
testing_ma_prakl <- data_tugas[-train_indices, ]

# Atau sequential split (untuk time series)
training_ma_prakl <- data_tugas[1:train_size, ]
testing_ma_prakl <- data_tugas[(train_size+1):n, ]

# Convert to time series
train_ma.ts <- ts(training_ma_prakl$Total_Sales)
test_ma.ts <- ts(testing_ma_prakl$Total_Sales)
# Jumlah observasi uji
n_test <- nrow(testing_ma_prakl)

# Error (ramalan - aktual), samakan panjang dan tipe numeric
e1 <- as.numeric(ramalan1$mean)[1:n_test] - as.numeric(testing_ma_prakl$Total_Sales)
e2 <- as.numeric(ramalan2$mean)[1:n_test] - as.numeric(testing_ma_prakl$Total_Sales)
eopt <- as.numeric(ramalanopt$mean)[1:n_test] - as.numeric(testing_ma_prakl$Total_Sales)

# SSE / MSE / RMSE untuk masing-masing model
SSEtesting1 <- sum(e1^2, na.rm = TRUE)
MSEtesting1 <- mean(e1^2, na.rm = TRUE)
RMSEtesting1 <- sqrt(MSEtesting1)

SSEtesting2 <- sum(e2^2, na.rm = TRUE)
MSEtesting2 <- mean(e2^2, na.rm = TRUE)
RMSEtesting2 <- sqrt(MSEtesting2)

SSEtestingopt <- sum(eopt^2, na.rm = TRUE)
MSEtestingopt <- mean(eopt^2, na.rm = TRUE)
RMSEtestingopt <- sqrt(MSEtestingopt)

# Tabel ringkas akurasi
akurasitesting_SSE <- matrix(c(SSEtesting1, SSEtesting2, SSEtestingopt), nrow = 3, 
                            dimnames = list(c("SSE1", "SSE2", "SSEopt"), "Nilai"))
akurasitesting_MSE <- matrix(c(MSEtesting1, MSEtesting2, MSEtestingopt), nrow = 3,
                            dimnames = list(c("MSE1", "MSE2", "MSEopt"), "Nilai"))
akurasitesting_RMSE <- matrix(c(RMSEtesting1, RMSEtesting2, RMSEtestingopt), nrow = 3,
                             dimnames = list(c("RMSE1", "RMSE2", "RMSEopt"), "Nilai"))

# Gabungkan semua metrik dalam satu dataframe
hasil_akurasi <- data.frame(
  Model = c("Model 1", "Model 2", "Model Optimal"),
  SSE = c(SSEtesting1, SSEtesting2, SSEtestingopt),
  MSE = c(MSEtesting1, MSEtesting2, MSEtestingopt),
  RMSE = c(RMSEtesting1, RMSEtesting2, RMSEtestingopt)
)

print(hasil_akurasi)
##           Model      SSE      MSE     RMSE
## 1       Model 1 11525.07 1152.507 33.94860
## 2       Model 2 14865.81 1486.581 38.55621
## 3 Model Optimal 10745.32 1074.532 32.78006

#Dapat dilihat bahwa SSE model 1 lebih kecil dibanding SSE model 2, maka model 1 dikatakan lebih baik dibanding model 2. #SSEopt (model optimal) tidak jauh berbeda dengan SSE model 1, maka model 1 sudah dapat dikatakan bagus.

#MSE model 1 lebih kecil dibanding MSE model 2, maka model 2 dikatakan lebih baik dibanding model 2. #MSEopt (model optimal) juga tidak jauh berbeda dengan model 1, maka model 1 dapat dikatakan cukup bagus.

#Model Optimal menunjukkan performa terbaik dengan nilai error terendah pada semua metrik (SSE, MSE, RMSE).

#Model 1 sudah cukup bagus karena performanya sangat mendekati model optimal. #Selisih error Model 1 dan Model Optimal sangat kecil, sehingga Model 1 dapat dianggap memadai. #Model 2 secara signifikan lebih buruk dari kedua model lainnya