Pendahuluan

Nilai tukar, atau kurs, adalah perbandingan nilai antara mata uang suatu negara dengan mata uang negara lain, yang berfungsi sebagai jembatan untuk menyamakan harga barang dan jasa dalam berbagai mata uang.

Belakangan ini, pelemahan rupiah terhadap dolar AS terus berlanjut, sehingga setiap satuan valuta asing menjadi lebih mahal jika dikonversi ke rupiah. Puncak dari melemah nya kurs rupiah terhadap dolar AS terjadi pada tanggal 8 sampai 9 April 2025 ini, dengan nilai tukar 1 USD sebesar Rp 16.860,-

Kondisi ini menimbulkan kekhawatiran di banyak pihak, mulai dari pemerintah yang harus mengatur kebijakan moneter dan fiskal, pelaku usaha yang menghadapi biaya impor bahan baku yang meningkat, hingga masyarakat umum yang merasakan dampak kenaikan harga barang sehari-hari. Investor pun turut mencermati pergerakan ini karena berpotensi memengaruhi aliran modal dan prospek investasi di dalam negeri. Dengan demikian, stabilitas kurs rupiah menjadi isu sentral yang menuntut perhatian dan langkah antisipatif dari semua pihak.

Berdasarkan latar belakang tersebut, diperlukan analisis lebih lanjut untuk memproyeksikan pergerakan nilai tukar rupiah dalam beberapa periode ke depan, sehingga pemerintah dapat merumuskan kebijakan yang tepat, dan investor maupun pelaku usaha dapat mengambil keputusan strategis yang lebih matang. Adapun analisis pada penelitian ini menggunakan model ARIMA, Neural Network, dan Moving Average.


1. import library

library(MASS)
library(hms)
library(car)
## Loading required package: carData
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(tseries)
library(timeSeries)
## Loading required package: timeDate
## 
## Attaching package: 'timeSeries'
## The following objects are masked from 'package:graphics':
## 
##     lines, points
library(quadprog)
library(zoo)
## Warning: package 'zoo' was built under R version 4.4.3
## 
## Attaching package: 'zoo'
## The following object is masked from 'package:timeSeries':
## 
##     time<-
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
library(fracdiff)
library(fUnitRoots)
library(lmtest)
library(nortest)
library(MLmetrics)
## Warning: package 'MLmetrics' was built under R version 4.4.3
## 
## Attaching package: 'MLmetrics'
## The following object is masked from 'package:base':
## 
##     Recall
library(Metrics)
## Warning: package 'Metrics' was built under R version 4.4.3
## 
## Attaching package: 'Metrics'
## The following object is masked from 'package:forecast':
## 
##     accuracy
library(neuralnet)
## Warning: package 'neuralnet' was built under R version 4.4.3
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following object is masked from 'package:neuralnet':
## 
##     compute
## The following objects are masked from 'package:timeSeries':
## 
##     filter, lag
## The following object is masked from 'package:car':
## 
##     recode
## The following object is masked from 'package:MASS':
## 
##     select
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(tensorflow)
## Warning: package 'tensorflow' was built under R version 4.4.3
library(keras3)
## 
## Attaching package: 'keras3'
## The following objects are masked from 'package:tensorflow':
## 
##     set_random_seed, shape
library(TTR)

2. import data

Data yang digunakan dalam penelitian ini adalah data harian nilai tukar rupiah terhadap dolar AS periode 1 April 2024 hingga 30 April 2025. Adapun sumber data diperoleh dari laman website : https://www.investing.com/currencies/usd-idr-historical-data

import_data = read.csv(file.choose(), header = T, sep = ",")
head(import_data)
##       Date Price    Open    High     Low Vol. Change..
## 1 9/2/2024 15520 15497.5 15555.0 15492.5   NA    0.45%
## 2 9/3/2024 15520 15547.5 15583.5 15522.5   NA    0.00%
## 3 9/4/2024 15470 15530.0 15542.5 15470.0   NA   -0.32%
## 4 9/5/2024 15395 15422.5 15432.5 15394.0   NA   -0.48%
## 5 9/6/2024 15360 15390.0 15398.5 15352.0   NA   -0.23%
## 6 9/9/2024 15450 15475.0 15485.0 15416.0   NA    0.59%
kurs_rupiah = ts(data = import_data$Price)
cat("total data :",length(kurs_rupiah))
## total data : 172

3. Time Series Plot

ts.plot(kurs_rupiah, main = "Nilai Tukar Rupiah Terhadap Dolar AS", ylab = "Nilai Tukar")
points(kurs_rupiah, cex = 0.8, pch = 21)
grid()

Berdasarkan time series plot diatas dapat diketahui bahwa nilai tukar rupiah mengalami fluktuasi di tiap periode nya dan cenderung mengalami trend naik.

4. Tahap Splitting Data

Sebelum melakukan tahap analisis menggunakan model Autoregressive Integrated Moving Average (ARIMA), Moving Average (MA) dan Neural Network (NN) dilakukan tahap pembagian data atau splitting data dengan rasio 85% untuk data training dan 15% untuk data testing atau dapat ditulis sebagai 85:15

jumlah_train = round(NROW(kurs_rupiah)*0.85,0)
jumlah_test = NROW(kurs_rupiah)-jumlah_train

data_train = kurs_rupiah[1:jumlah_train]
data_test  = kurs_rupiah[(jumlah_train+1):(jumlah_test+jumlah_train)]

cat("Jumlah data train =",jumlah_train,"\nJumlah data test =",jumlah_test)
## Jumlah data train = 146 
## Jumlah data test = 26

5. Pemodelan ARIMA (Autoregressive Integrated Moving Average)

Model ARIMA merupakan salah satu model statistik yang digunakan untuk menganalisis (memprediksi serta meramalkan) data runtun waktu. Model ini merupakan gabungan dari model Autoregressive (AR), model Integrated (I), dan model Moving Average (MA). Adapun persamaan dari model ARIMA dapat ditulis sebagai berikut.

\[\phi_p(B)(1-B)^dZ_t=\theta_q(B)\varepsilon_t\]

Berikut langkah-langkah dalam melakukan pemodelan ARIMA

Tahap stasioneritas data

Dalam melakukan pemodelan ARIMA, maka tahapan awal yang harus dilakukan adalah melakukan stasioneritas pada data, hal ini dikarenakan dalam melakukan pemodelan ARIMA harus memenuhi syarat stasioneritas data. Terdapat dua tahapan dalam stasioneritas yaitu stasioneritas terhadap variansi dan stasioneritas terhadap rata-rata.

Stasioneritas dalam variansi

boxcox(data_train~1,lambda = seq(-9,32,by=1))

nilai = powerTransform(data_train)
nilai$lambda
## data_train 
##   10.84763

Karena nilai \(\lambda\) yang dihasilkan adalah 10,847 dimana nilai tersebut tidak mendekati 1 maka dapat dilakukan tahapan transformasi.

\(\lambda\) Transformasi
-2 \(y^-2\)
-1 \(y^-1\)
-0,5 \(\frac{1}{\sqrt{y}}\)
0 \(log(y)\)
0,5 \(\sqrt{y}\)
1 \(y\)
2 \(y^2\)

dikarenakan jika kita memangkatkan data dengan 10,847 akan membuat data lebih besar maka kita dapat melakukan proses transformasi data dengan cara log.

data_trans = log(data_train)
head(data_trans)
## [1] 9.649885 9.649885 9.646658 9.641798 9.639522 9.645364

Stasioneritas dalam rata-rata

Setelah melakukan tahap transformasi maka dilakukan tahap stasioneritas rata-rata. Pengecekan stasioneritas rata-rata dapat dilakukan dengan melihat grafik Autocorrelation Function (ACF) dan uji Augmented Dickey Fuller (ADF).

acf(data_trans, lag.max = 1/4*NROW(data_trans), main = "Grafik ACF Data Transformasi")

Berdasarkan grafik diatas dapat diketahui bahwa nilai ACF mengalami turun secara eksponensial, maka dapat disimpulkan bahwa data transformasi belum stasioner dalam rata-rata. Untuk dapat menguatkan keputusan, maka dilakukan pengujian ADF sebagai berikut.

adfTest(data_trans)
## 
## Title:
##  Augmented Dickey-Fuller Test
## 
## Test Results:
##   PARAMETER:
##     Lag Order: 1
##   STATISTIC:
##     Dickey-Fuller: 1.3578
##   P VALUE:
##     0.9549 
## 
## Description:
##  Tue May 13 12:33:42 2025 by user: ASUS

Dikarenakan nilai p-value ADF test lebih dari taraf signifikansi, maka diputuskan \(H_0\) gagal ditolak. Sehingga disimpulkan data belum stasioner dalam rata-rata. Kemudian dilakukan tahap differencing sebagai berikut.

diff_1 = diff(data_trans, differences = 1, lag = 1)
head(diff_1)
## [1]  0.000000000 -0.003226850 -0.004859883 -0.002276054  0.005842276
## [6] -0.000323677
adfTest(diff_1)
## Warning in adfTest(diff_1): p-value smaller than printed p-value
## 
## Title:
##  Augmented Dickey-Fuller Test
## 
## Test Results:
##   PARAMETER:
##     Lag Order: 1
##   STATISTIC:
##     Dickey-Fuller: -7.8593
##   P VALUE:
##     0.01 
## 
## Description:
##  Tue May 13 12:33:42 2025 by user: ASUS

Setelah dilakukan proses differencing, maka dapat disimpulkan bahwa data sudah stasioner dalam rata-rata.

Tahap identifikasi model ARIMA

Identifikasi model ARIMA dapat dilakukan dengan melihat grafik Autocorrelation Function (ACF) dan Partial Autocorrelation Function (PACF)

acf(diff_1, 1/4*NROW(diff_1), main = "ACF diff 1")
grid()

pacf(diff_1, 1/4*NROW(diff_1), main = "PACF diff 1")
grid()

Dikarenakan saat melakukan tahap identifikasi model pada grafik ACF dan PACF nya tidak ada nilai ACF yang keluar maka akan dilakukan tahap differencing kedua

diff_2 = diff(data_trans, differences = 2, lag = 1)
head(diff_2)
## [1] -0.003226850 -0.001633033  0.002583830  0.008118329 -0.006165953
## [6] -0.002918868
acf(diff_2, 1/4*NROW(diff_2), main = "ACF diff 2")
grid()

pacf(diff_2, 1/4*NROW(diff_2), main = "PACF diff 2")
grid()

Berdasarkan grafik ACF dan PACF data differencing kedua maka diketahui bahwa nilai ACF cut off setelah lag kedua, maka orde untuk MA (q) adalah 2. Sedangkan nilai PACF cut off setelah lag keempat sehingga diketahui bahwa orde AR (p) adalah 4. Oleh karena itu, terdapat

  1. ARIMA (0,2,1)

  2. ARIMA (0,2,2)

  3. ARIMA (1,2,0)

  4. ARIMA (2,2,0)

  5. ARIMA (3,2,0)

  6. ARIMA (4,2,0)

  7. ARIMA (1,2,1)

  8. ARIMA (2,2,1)

  9. ARIMA (3,2,1)

  10. ARIMA (4,2,1)

  11. ARIMA (1,2,2)

  12. ARIMA (2,2,2)

  13. ARIMA (3,2,2)

  14. ARIMA (4,2,2)

Tahap Estimasi dan Pengujian Signifikansi Parameter Model ARIMA

model1 = Arima(data_trans, order = c(0,2,1))
model2 = Arima(data_trans, order = c(0,2,2))
model3 = Arima(data_trans, order = c(1,2,0))
model4 = Arima(data_trans, order = c(2,2,0))
model5 = Arima(data_trans, order = c(3,2,0))
model6 = Arima(data_trans, order = c(4,2,0))
model7 = Arima(data_trans, order = c(1,2,1))
model8 = Arima(data_trans, order = c(2,2,1))
model9 = Arima(data_trans, order = c(3,2,1))
model10 = Arima(data_trans, order = c(4,2,1))
model11 = Arima(data_trans, order = c(1,2,2))
model12 = Arima(data_trans, order = c(2,2,2))
model13 = Arima(data_trans, order = c(3,2,2))
model14 = Arima(data_trans, order = c(4,2,2))

db = NROW(data_trans)
cat("========== MODEL 1 ==========")
## ========== MODEL 1 ==========
coeftest(model1, df = db-1)
## 
## t test of coefficients:
## 
##      Estimate Std. Error t value  Pr(>|t|)    
## ma1 -0.999999   0.020836 -47.994 < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
cat("========== MODEL 2 ==========")
## ========== MODEL 2 ==========
coeftest(model2, df = db-2)
## 
## t test of coefficients:
## 
##      Estimate Std. Error  t value Pr(>|t|)    
## ma1 -0.963997   0.082772 -11.6465   <2e-16 ***
## ma2 -0.036002   0.080195  -0.4489   0.6542    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
cat("========== MODEL 3 ==========")
## ========== MODEL 3 ==========
coeftest(model3, df = db-1)
## 
## t test of coefficients:
## 
##      Estimate Std. Error t value Pr(>|t|)    
## ar1 -0.497446   0.071918 -6.9168 1.37e-10 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
cat("========== MODEL 4 ==========")
## ========== MODEL 4 ==========
coeftest(model4, df = db-2)
## 
## t test of coefficients:
## 
##      Estimate Std. Error t value  Pr(>|t|)    
## ar1 -0.641753   0.080067 -8.0152 3.434e-13 ***
## ar2 -0.284209   0.079916 -3.5563 0.0005094 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
cat("========== MODEL 5 ==========")
## ========== MODEL 5 ==========
coeftest(model5, df = db-3)
## 
## t test of coefficients:
## 
##      Estimate Std. Error t value  Pr(>|t|)    
## ar1 -0.701137   0.081478 -8.6052 1.241e-14 ***
## ar2 -0.420483   0.093916 -4.4772 1.534e-05 ***
## ar3 -0.213099   0.081672 -2.6092   0.01004 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
cat("========== MODEL 6 ==========")
## ========== MODEL 6 ==========
coeftest(model6,df = db-4)
## 
## t test of coefficients:
## 
##      Estimate Std. Error t value  Pr(>|t|)    
## ar1 -0.743000   0.081537 -9.1124 6.905e-16 ***
## ar2 -0.504074   0.098126 -5.1370 9.052e-07 ***
## ar3 -0.356438   0.098760 -3.6091  0.000425 ***
## ar4 -0.204274   0.082737 -2.4690  0.014737 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
cat("========== MODEL 7 ==========")
## ========== MODEL 7 ==========
coeftest(model7, df = db-2)
## 
## t test of coefficients:
## 
##      Estimate Std. Error  t value Pr(>|t|)    
## ar1  0.038782   0.083486   0.4645    0.643    
## ma1 -0.999999   0.020470 -48.8527   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
cat("========== MODEL 8 ==========")
## ========== MODEL 8 ==========
coeftest(model8, df = db-3)
## 
## t test of coefficients:
## 
##      Estimate Std. Error  t value Pr(>|t|)    
## ar1  0.037958   0.083475   0.4547   0.6500    
## ar2  0.036141   0.083499   0.4328   0.6658    
## ma1 -0.999996   0.020219 -49.4575   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
cat("========== MODEL 9 ==========")
## ========== MODEL 9 ==========
coeftest(model9, df = db-4)
## 
## t test of coefficients:
## 
##      Estimate Std. Error  t value Pr(>|t|)    
## ar1  0.038956   0.083402   0.4671   0.6412    
## ar2  0.036568   0.083404   0.4384   0.6617    
## ar3 -0.037238   0.083964  -0.4435   0.6581    
## ma1 -0.999999   0.020422 -48.9661   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
cat("========== MODEL 10 ==========")
## ========== MODEL 10 ==========
coeftest(model10, df = db-5)
## 
## t test of coefficients:
## 
##      Estimate Std. Error  t value Pr(>|t|)    
## ar1  0.035744   0.083366   0.4288   0.6687    
## ar2  0.037721   0.083301   0.4528   0.6514    
## ar3 -0.036161   0.083795  -0.4315   0.6667    
## ar4 -0.053985   0.084429  -0.6394   0.5236    
## ma1 -0.999993   0.020668 -48.3847   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
cat("========== MODEL 11 ==========")
## ========== MODEL 11 ==========
coeftest(model11, df = db-3)
## Warning in sqrt(diag(se)): NaNs produced
## 
## t test of coefficients:
## 
##     Estimate Std. Error t value Pr(>|t|)
## ar1 -0.76169        NaN     NaN      NaN
## ma1 -0.23767        NaN     NaN      NaN
## ma2 -0.76233        NaN     NaN      NaN
cat("========== MODEL 12 ==========")
## ========== MODEL 12 ==========
coeftest(model12, df = db-4)
## 
## t test of coefficients:
## 
##      Estimate Std. Error t value Pr(>|t|)  
## ar1 -0.791633   0.475210 -1.6659  0.09795 .
## ar2  0.050019   0.084019  0.5953  0.55257  
## ma1 -0.169223   0.468480 -0.3612  0.71847  
## ma2 -0.830770   0.468340 -1.7739  0.07823 .
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
cat("========== MODEL 13 ==========")
## ========== MODEL 13 ==========
coeftest(model13, df = db-5)
## 
## t test of coefficients:
## 
##      Estimate Std. Error  t value  Pr(>|t|)    
## ar1  0.959744   0.103560   9.2675 2.938e-16 ***
## ar2 -0.010023   0.114102  -0.0878    0.9301    
## ar3 -0.091822   0.085550  -1.0733    0.2850    
## ma1 -1.957489   0.069262 -28.2621 < 2.2e-16 ***
## ma2  0.957533   0.069144  13.8484 < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
cat("========== MODEL 14 ==========")
## ========== MODEL 14 ==========
coeftest(model14, df = db-6)
## 
## t test of coefficients:
## 
##        Estimate  Std. Error  t value  Pr(>|t|)    
## ar1  0.93576636  0.10988792   8.5156  2.33e-14 ***
## ar2 -0.00041231  0.11331871  -0.0036    0.9971    
## ar3 -0.06960022  0.11330101  -0.6143    0.5400    
## ar4 -0.03396384  0.08708066  -0.3900    0.6971    
## ma1 -1.93550453  0.07952193 -24.3393 < 2.2e-16 ***
## ma2  0.93561176  0.07941843  11.7808 < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Berdasarkan hasil pengujian signifikansi parameter terdapat 5 model ARIMA yang signifikan yaitu model ARIMA (0,2,1), ARIMA (1,2,0), ARIMA (2,2,0), ARIMA (3,2,0), dan ARIMA (4,2,0). Kemudian dari keempat model yang terbentuk akan dilakukan tahap pengujian diagnostik model

Pengujian diagnostik model ARIMA

Terdapat dua pengujian diagnostik model, yakni pengujian normalitas residual model ARIMA dan pengujian independensi residual model ARIMA (white noise)

Pengujian normalitas residual

Pengujian normalitas residual model ARIMA dilakukan menggunakan uji

lillie.test(resid(model1))
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  resid(model1)
## D = 0.056696, p-value = 0.2997
lillie.test(resid(model3))
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  resid(model3)
## D = 0.05716, p-value = 0.288
lillie.test(resid(model4))
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  resid(model4)
## D = 0.053589, p-value = 0.3854
lillie.test(resid(model5))
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  resid(model5)
## D = 0.042326, p-value = 0.7535
lillie.test(resid(model6))
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  resid(model6)
## D = 0.036209, p-value = 0.9109

Berdasarkan pengujian normalitas menggunakan uji Kolmogorov-Smirnov maka dapat disimpulkan bahwa seluruh model ARIMA memenuhi asumsi normalitas residual.

Independensi Residual (white noise)

##### MODEL 3 ########
p_val_model1 = NROW(resid(model1))
for (i in 1:p_val_model1) {
  model1_box = Box.test(resid(model1), lag = i, type = "Ljung-Box")
  p_val_model1[i] = model1_box$p.value
}
# Plot p-value
plot(1:NROW(resid(model1)), p_val_model1, type = "p", pch = 1 ,xlab = "Lag", ylab = "p-value", main = "Ljung-Box Model 1 ARIMA(0,2,1)", ylim = c(0,1))
abline(h = 0.05, col = "blue", lty = 2)

##### MODEL 3 ########
p_val_model3 = NROW(resid(model3))
for (i in 1:p_val_model3) {
  model3_box = Box.test(resid(model3), lag = i, type = "Ljung-Box")
  p_val_model3[i] = model3_box$p.value
}
# Plot p-value
plot(1:NROW(resid(model3)), p_val_model3, type = "p", pch = 1 ,xlab = "Lag", ylab = "p-value", main = "Ljung-Box Model 3 ARIMA(1,2,0)", ylim = c(0,1))
abline(h = 0.05, col = "blue", lty = 2)

##### MODEL 4 ########
p_val_model4 = NROW(resid(model4))
for (i in 1:p_val_model4) {
  model4_box = Box.test(resid(model4), lag = i, type = "Ljung-Box")
  p_val_model4[i] = model4_box$p.value
}
# Plot p-value
plot(1:NROW(resid(model4)), p_val_model4, type = "p", pch = 1 ,xlab = "Lag", ylab = "p-value", main = "Ljung-Box Model 4 ARIMA(2,2,0)", ylim = c(0,1))
abline(h = 0.05, col = "blue", lty = 2)

##### MODEL 5 ########
p_val_model5 = NROW(resid(model5))
for (i in 1:p_val_model5) {
  model5_box = Box.test(resid(model5), lag = i, type = "Ljung-Box")
  p_val_model5[i] = model5_box$p.value
}
# Plot p-value
plot(1:NROW(resid(model5)), p_val_model5, type = "p", pch = 1 ,xlab = "Lag", ylab = "p-value", main = "Ljung-Box Model 5 ARIMA(3,2,0)", ylim = c(0,1))
abline(h = 0.05, col = "blue", lty = 2)

##### MODEL  ########
p_val_model6 = NROW(resid(model6))
for (i in 1:p_val_model6) {
  model6_box = Box.test(resid(model6), lag = i, type = "Ljung-Box")
  p_val_model6[i] = model6_box$p.value
}
# Plot p-value
plot(1:NROW(resid(model6)), p_val_model6, type = "p", pch = 1 ,xlab = "Lag", ylab = "p-value", main = "Ljung-Box Model 6 ARIMA(4,2,0)", ylim = c(0,1))
abline(h = 0.05, col = "blue", lty = 2)

Menggunakan uji Ljung-Box Test model yang memenuhi asumsi normalitas dan independensi residual adalah model ARIMA (4,2,0).

Tahap Prediksi dan Peramalan Model ARIMA (4,2,0)

Setelah didapatkan model ARIMA yang memenuhi asumsi normalitas residual dan independensi residual, kemudian pada tahapan ini akan dilakukan prediksi dan peramalan menggunakan model ARIMA (4,2,0).

prediksi_arima = exp(fitted.values(model6))
head(prediksi_arima)
## Time Series:
## Start = 1 
## End = 6 
## Frequency = 1 
## [1] 15453.17 15722.24 15510.03 15441.00 15350.86 15321.26
ramal_arima = exp(predict(model6, n.ahead =28)$pred)
head(ramal_arima)
## Time Series:
## Start = 147 
## End = 152 
## Frequency = 1 
## [1] 16583.22 16621.64 16641.21 16673.99 16709.27 16741.86

Grafik Prediksi dan Peramalan ARIMA

Berdasarkan tahapan prediksi dan peramalan, berikut disajikan grafik prediksi dan peramalan model ARIMA (4,2,0).

plot(1:172,kurs_rupiah, type = "l", main = "Grafik Prediksi dan Peramalan ARIMA", ylab = "Nilai Kurs IDR", xlab = "Time", ylim = c(15000,17500))
  points(kurs_rupiah, cex = 0.9, pch = 21)
  lines(1:146,prediksi_arima, col = "blue")
  lines(147:172,ramal_arima[1:26], col = "red")
  lines(173:174,ramal_arima[27:28], col = "green")
  abline(v = 146, lty = 2)
  abline(v = 172, lty = 2)
legend("topleft", legend = c("Data aktual","Prediksi In sample", "Prediksi Out Sample", "Peramalan"), 
       col = c("black","blue","red","green"), lty = 1, pch = 20, lwd = 3, bty = "o", cex = 0.8)
grid()

Berdasarkan grafik time series nilai tukar Rupiah terhadap Dolar AS, tampak bahwa hasil prediksi dari model ARIMA mampu mengikuti pola data historis dengan cukup baik. Prediksi dalam in-sample menunjukkan kesesuaian yang tinggi terhadap data aktual, sementara prediksi out-sample juga masih mencerminkan arah tren yang serupa. Peramalan jangka pendek yang dilakukan menunjukkan kecenderungan peningkatan nilai tukar, meskipun hanya untuk dua hari ke depan. Secara keseluruhan, model ARIMA menunjukkan performa yang baik dalam memodelkan dan memproyeksikan pergerakan nilai tukar, khususnya dalam jangka pendek.

Evaluasi Model ARIMA

Evaluasi model ARIMA dilakukan dengan menggunakan tiga metrik utama, yaitu MAPE (Mean Absolute Percentage Error), SMAPE (Symmetric Mean Absolute Percentage Error), dan RMSE (Root Mean Squared Error). Berikut adala hasil evaluasi untuk model ARIMA yang dibangun:

in_sample_arima = c(
  MAPE_Arima_in = MAPE(prediksi_arima,data_train)*100,
  SMAPE_Arima_in = smape(data_train, prediksi_arima)*100,
  RMSE_Arima_in = RMSE(prediksi_arima, data_train)
)

out_sample_arima = c(
  MAPE_Arima_out = MAPE(ramal_arima[1:26], data_test) * 100,
  SMAPE_Arima_out = smape(data_test, ramal_arima[1:26]) * 100,
  RMSE_Arima_out = RMSE(ramal_arima[1:26], data_test)
)

hasil_evaluasi_arima = data.frame(
  Metrik = c("MAPE (%)", "SMAPE (%)", "RMSE"),
  In_Sample = round(in_sample_arima, 3),
  Out_Sample = round(out_sample_arima, 3),
  row.names = NULL
)

# Menampilkan tabel
hasil_evaluasi_arima
##      Metrik In_Sample Out_Sample
## 1  MAPE (%)     0.343      1.599
## 2 SMAPE (%)     0.343      1.582
## 3      RMSE    68.279    312.756

Berdasarkan hasil evaluasi model ARIMA, dapat disimpulkan bahwa model ini menunjukkan akurasi yang sangat baik pada data pelatihan dengan nilai MAPE dan SMAPE yang rendah, yaitu 0.343%, serta RMSE sebesar 68.279. Namun, pada data uji, akurasi model menurun dengan MAPE sebesar 1.599%, SMAPE 1.582%, dan RMSE 312.756, yang menunjukkan adanya peningkatan kesalahan prediksi. Meskipun model ARIMA cukup baik untuk meramalkan nilai tukar rupiah terhadap dolar AS pada data yang telah ada, performanya perlu ditingkatkan agar lebih robust dalam menghadapi fluktuasi nilai tukar di periode mendatang.

6. Neural Network

Neural network merupakan model komputasi yang merupakan bagian dari kecerdasan buatan dan terinspirasi dari jaringan saraf dan struktur otak manusia.

Model ini dapat digunakan untuk mempelajari pola-pola kompleks dalam data termasuk untuk melakukan prediksi dan peramalan. Struktur neural network terdiri dari beberapa lapisan yaitu input layer, hidden layer,output layer dan fungsi aktivasi.

  1. Input layer yaitu lapisan masukan yang memiliki beberapa neuron input yang tidak memiliki fungsi transfer, namun memiliki faktor skala di setiap input untuk mentransimisikan sinyal pada faktor skala di setiap input.

  2. Hidden layer merupakan lapisan yang menghubungkan input dan output layer dengan melalui bobot yang dihitung ke lapisan keluaran.

  3. Output layer merupakan lapisan keluaran yang terdiri dari satu atau beberapa neuron yang mewakili sebuah kelas dari kumpulan data keluaran.

  4. Fungsi aktivasi merupakan fungsi yang menentukan bagaimana neuron memproses sinyal input dan mengirimkannya ke lapisan berikutnya.

Pada penelitian ini tahapan training model neural network dimulai dari tahap standarisasi data, kemudian menentukan variabel masukan, pelatihan algoritma yang digunakan yang pada penelitian ini menggunakan resilient backpropagation, kemudian dilakukan destandarisasi data, lalu pemilihan neural network terbaik, lalu melakukan peramalan.

Tahap standarisasi

Dilakukan standarisasi data dikarenakan data observasi memiliki perbedaan nilai yang cukup besar, dapat dilihat juga dari  grafik time series plot diawal analisis yang cenderung menunjukkan pola trend. Standarisasi dilakukan sehingga data observasi dapat berfluktuasi disekitar rata-rata

max_asli = max(kurs_rupiah)
min_asli = min(kurs_rupiah)
data_standarisasi = 2*((as.numeric(kurs_rupiah) - min_asli)/(max_asli - min_asli))-1
head(data_standarisasi)
## [1] -0.5197740 -0.5197740 -0.5762712 -0.6610169 -0.7005650 -0.5988701

Grafik PACF Data Standarisasi

Setelah mendapatkan data yang terstandarisasi kemudian dilakukan tahapan pembentukan data input pada model Neural Network dengan melihat nilai PACF yang signifikan.

pacf(data_standarisasi, main = "PACF Data Standarisasi", lag.max = 80)
grid()

Variabel masukan dipilih berdasarkan pada lag yang signifikan pada grafik PACF, dan berdasarkan output yang terlihat, dapat diketahui bahwa nilai PACF signifikan pada lag ke-1 sehingga lag ini menjadi variabel masukannya. Selanjutnya, data keluaran yang digunakan dilambangkan dengan Y. Data Y ini yaitu data kurs nilai tukar rupiah terhadap dollar setelah standarisasi yang selanjutnya data masukan dan keluaran dimulai dari t=2.  

Tahap Pembentukan model NN

Kemudian dilakukan proses pelatihan Resilient Backpropagation dengan maksimal  2 hidden layer proses dengan 1 neuron, 2 neuron dan 3 neuron. Kondisi pemberhentian yang digunakan adalah maksimum iterasi sebesar 10.000 target dan target eror sebesar 0,005. Diperoleh hasil pelatihan sebagai berikut:

Input data

y = data.frame(
  nilai_asli = data_standarisasi
) %>% 
  mutate(
    nilai_lag = dplyr::lag(nilai_asli, n = 1, default = NA)
  )
head(y)
##   nilai_asli  nilai_lag
## 1 -0.5197740         NA
## 2 -0.5197740 -0.5197740
## 3 -0.5762712 -0.5197740
## 4 -0.6610169 -0.5762712
## 5 -0.7005650 -0.6610169
## 6 -0.5988701 -0.7005650
trainy = y[1:length(data_train),]
trainy = na.omit(trainy)
testy = y[length(data_train)+1:172,]

head(trainy)
##   nilai_asli  nilai_lag
## 2 -0.5197740 -0.5197740
## 3 -0.5762712 -0.5197740
## 4 -0.6610169 -0.5762712
## 5 -0.7005650 -0.6610169
## 6 -0.5988701 -0.7005650
## 7 -0.6045198 -0.5988701
head(testy)
##     nilai_asli nilai_lag
## 147  0.6892655 0.6440678
## 148  0.6723164 0.6892655
## 149  0.6497175 0.6723164
## 150  0.6497175 0.6497175
## 151  0.6497175 0.6497175
## 152  0.6497175 0.6497175
attach(trainy)
attach(testy)
## The following objects are masked from trainy:
## 
##     nilai_asli, nilai_lag

Neural network 1 hidden layer

set.seed(1234)
mlp_1_1 = neuralnet(nilai_asli~nilai_lag, data=trainy, hidden=1, act.fct="tanh", linear.output = TRUE, learningrate = 0.005, stepmax = 10000, startweights = NULL, threshold = 0.005, algorithm = "rprop+")
plot(mlp_1_1)

set.seed(1234)
mlp_1_2 = neuralnet(nilai_asli~nilai_lag, data=trainy, hidden=2, act.fct="tanh", linear.output = T, learningrate = 0.005, stepmax = 10000, startweights = NULL, threshold = 0.005, algorithm = "rprop+")
plot(mlp_1_2)

set.seed(1234)
mlp_1_3 = neuralnet(nilai_asli~nilai_lag, data=trainy, hidden=3, act.fct="tanh", linear.output = TRUE, learningrate = 0.005, stepmax = 10000, startweights = NULL, threshold = 0.005, algorithm = "rprop+")
plot(mlp_1_3)

Neural network 2 hidden layer

set.seed(1234)
mlp_2_1_1 = neuralnet(nilai_asli~nilai_lag, data=trainy, hidden=c(1,1), act.fct="tanh", linear.output = TRUE, learningrate = 0.005, stepmax = 10000, startweights = NULL, threshold = 0.005, algorithm = "rprop+")
plot(mlp_2_1_1)

set.seed(1234)
mlp_2_1_2 = neuralnet(nilai_asli~nilai_lag, data=trainy, hidden=c(1,2), act.fct="tanh", linear.output = TRUE, learningrate = 0.005, stepmax = 10000, startweights = NULL, threshold = 0.005, algorithm = "rprop+")
plot(mlp_2_1_2)

set.seed(1234)
mlp_2_1_3 = neuralnet(nilai_asli~nilai_lag, data=trainy, hidden=c(1,3), act.fct="tanh", linear.output = TRUE, learningrate = 0.005, stepmax = 10000, startweights = NULL, threshold = 0.005, algorithm = "rprop+")
plot(mlp_2_1_3)

set.seed(1234)
mlp_2_2_1 = neuralnet(nilai_asli~nilai_lag, data=trainy, hidden=c(2,1), act.fct="tanh", linear.output = TRUE, learningrate = 0.005, stepmax = 10000, startweights = NULL, threshold = 0.005, algorithm = "rprop+")
plot(mlp_2_2_1)

set.seed(1234)
mlp_2_2_2 = neuralnet(nilai_asli~nilai_lag, data=trainy, hidden=c(2,2), act.fct="tanh", linear.output = TRUE, learningrate = 0.005, stepmax = 10000, startweights = NULL, threshold = 0.005, algorithm = "rprop+")
plot(mlp_2_2_2)

set.seed(1234)
mlp_2_2_3 = neuralnet(nilai_asli~nilai_lag, data=trainy, hidden=c(2,3), act.fct="tanh", linear.output = TRUE, learningrate = 0.005, stepmax = 10000, startweights = NULL, threshold = 0.005, algorithm = "rprop+")
plot(mlp_2_2_3)

Tahap Prediksi Neural Network

Selanjutnya yaitu melakukan destandarisasi data dari hasil pelatihan algoritma Resilient Backpropagation dengan menggunakan 1 neuron, 2 neuron dan 3 neuron pada kedua hidden layer. 1 hidden layer

NN(1)

predict_NN1 = ts(mlp_1_1$net.result[[1]])
kembali_NN1 = ((predict_NN1 + 1) / 2) * (max(kurs_rupiah) - min(kurs_rupiah)) + min(kurs_rupiah)

NN(2)

predict_NN2 = ts(mlp_1_2$net.result[[1]])
kembali_NN2 = ((predict_NN2 + 1) / 2) * (max(kurs_rupiah) - min(kurs_rupiah)) + min(kurs_rupiah)

NN(3)

predict_NN3 = ts(mlp_1_3$net.result[[1]])
kembali_NN3 = ((predict_NN3 + 1) / 2) * (max(kurs_rupiah) - min(kurs_rupiah)) + min(kurs_rupiah)

2 hidden layer

NN(1,1)

predict_NN_1_1 = ts(mlp_2_1_1$net.result[[1]])
kembali_NN_1_1 = ((predict_NN_1_1 + 1) / 2) * (max(kurs_rupiah) - min(kurs_rupiah)) + min(kurs_rupiah)

NN(1,2)

predict_NN_1_2 = ts(mlp_2_1_2$net.result[[1]])
kembali_NN_1_2 = ((predict_NN_1_2 + 1) / 2) * (max(kurs_rupiah) - min(kurs_rupiah)) + min(kurs_rupiah)

NN(1,3)

predict_NN_1_3 = ts(mlp_2_1_3$net.result[[1]])
kembali_NN_1_3 = ((predict_NN_1_3 + 1) / 2) * (max(kurs_rupiah) - min(kurs_rupiah)) + min(kurs_rupiah)

NN(2,1)

predict_NN_2_1 = ts(mlp_2_2_1$net.result[[1]])
kembali_NN_2_1 = ((predict_NN_2_1 + 1) / 2) * (max(kurs_rupiah) - min(kurs_rupiah)) + min(kurs_rupiah)

NN(2,2)

predict_NN_2_2 = ts(mlp_2_2_2$net.result[[1]])
kembali_NN_2_2 = ((predict_NN_2_2 + 1) / 2) * (max(kurs_rupiah) - min(kurs_rupiah)) + min(kurs_rupiah)

NN(2,3)

predict_NN_2_3 = ts(mlp_2_2_3$net.result[[1]])
kembali_NN_2_3 = ((predict_NN_2_3 + 1) / 2) * (max(kurs_rupiah) - min(kurs_rupiah)) + min(kurs_rupiah)

Pemilihan Model NN Terbaik

Tahap selanjutnya yaitu melakukan pemilihan neural network terbaik dengan menggunakan kriteria MAPE, RMSE, dan SMAPE. Adapun hasil analisis diperoleh sebagai berikut:

MAPE_pemilihan_nn = c(
  MAPE_NN1 = MAPE(ts(kembali_NN1),ts(data_train[2:146]))*100,
  MAPE_NN2 = MAPE(ts(kembali_NN2),ts(data_train[2:146]))*100,
  MAPE_NN3 = MAPE(ts(kembali_NN3),ts(data_train[2:146]))*100,
  MAPE_NN_11 = MAPE(ts(kembali_NN_1_1),ts(data_train[2:146]))*100,
  MAPE_NN_12 = MAPE(ts(kembali_NN_1_2),ts(data_train[2:146]))*100,
  MAPE_NN_13 = MAPE(ts(kembali_NN_1_3),ts(data_train[2:146]))*100,
  MAPE_NN_21 = MAPE(ts(kembali_NN_2_1),ts(data_train[2:146]))*100,
  MAPE_NN_22 = MAPE(ts(kembali_NN_2_2),ts(data_train[2:146]))*100,
  MAPE_NN_23 = MAPE(ts(kembali_NN_2_3),ts(data_train[2:146]))*100
)

RMSE_pemilihan_nn = c(
  RMSE_NN1 = RMSE(ts(data_train[2:146]),ts(kembali_NN1)),
  RMSE_NN2 = RMSE(ts(kembali_NN2),ts(data_train[2:146])),
  RMSE_NN3 = RMSE(ts(kembali_NN3),ts(data_train[2:146])),
  RMSE_NN_11 = RMSE(ts(kembali_NN_1_1),ts(data_train[2:146])),
  RMSE_NN_12 = RMSE(ts(kembali_NN_1_2),ts(data_train[2:146])),
  RMSE_NN_13 = RMSE(ts(kembali_NN_1_3),ts(data_train[2:146])),
  RMSE_NN_21 = RMSE(ts(kembali_NN_2_1),ts(data_train[2:146])),
  RMSE_NN_22 = RMSE(ts(kembali_NN_2_2),ts(data_train[2:146])),
  RMSE_NN_23 = RMSE(ts(kembali_NN_2_3),ts(data_train[2:146]))
)

SMAPE_pemilihan_nn = c(
  SMAPE_NN1 = smape(ts(data_train[2:146]),ts(kembali_NN1))*100,
  SMAPE_NN2 = smape(ts(data_train[2:146]),ts(kembali_NN2))*100,
  SMAPE_NN3 = smape(ts(data_train[2:146]),ts(kembali_NN3))*100,
  SMAPE_NN_11 = smape(ts(data_train[2:146]),ts(kembali_NN_1_1))*100,
  SMAPE_NN_12 = smape(ts(data_train[2:146]),ts(kembali_NN_1_2))*100,
  SMAPE_NN_13 = smape(ts(data_train[2:146]),ts(kembali_NN_1_3))*100,
  SMAPE_NN_21 = smape(ts(data_train[2:146]),ts(kembali_NN_2_1))*100,
  SMAPE_NN_22 = smape(ts(data_train[2:146]),ts(kembali_NN_2_2))*100,
  SMAPE_NN_23 = smape(ts(data_train[2:146]),ts(kembali_NN_2_3))*100
)

Nama_baris_pemilihan_NN = c(
  "NN (1)",
  "NN (2)",
  "NN (3)",
  "NN (1,1)",
  "NN (1,2)",
  "NN (1,3)",
  "NN (2,1)",
  "NN (2,2)",
  "NN (2,3)"
)

pemilihan_nn_terbaik = data.frame(
  pilih_mape = round(MAPE_pemilihan_nn, 3),
  pilih_rmse = round(RMSE_pemilihan_nn, 3),
  pilih_smape = round(SMAPE_pemilihan_nn, 3),
  row.names = Nama_baris_pemilihan_NN
)

colnames(pemilihan_nn_terbaik) = c("MAPE", "RMSE", "SMAPE")

pemilihan_nn_terbaik
##           MAPE   RMSE SMAPE
## NN (1)   0.294 59.071 0.294
## NN (2)   0.294 59.127 0.294
## NN (3)   0.295 59.125 0.295
## NN (1,1) 0.293 59.104 0.294
## NN (1,2) 0.292 58.992 0.292
## NN (1,3) 0.294 59.103 0.294
## NN (2,1) 0.291 59.105 0.292
## NN (2,2) 0.295 59.195 0.295
## NN (2,3) 0.292 59.026 0.292

Berdasarkan hasil evaluasi, dapat dilihat bahwa dari 1 neuron, 2 neuron dan 3 neuron pada kedua hidden layer cenderung menghasilkan nilai akurasi yang mirip, yang kemampuan peramalan yang sangat baik karena mengahasilkan MAPE dibawah 10% dan SMAPE yang juga dibawah 10%, selain itu nilai RMSE yang dihasilkan juga cukup kecil dimana keseluruhan modek Neural Network yang dibentuk memiliki error berkisar disekitar Rp 59. Sehingga dapat diambil kesimpulan bahwa model Neural Network terbaik adalah model NN dengan 1 neuron pada hidden layer pertama dan 2 neuron pada hidden layer kedua.

Peramalan NN(1,2)

Setelah diperoleh NN terbaik, selanjutnya yaitu melakukan prediksi pada outsample untuk 26 hari serta peramalan untuk 2 hari kedepannya menggunakan model NN dengan 1 neuron pada hidden layer pertama dan 2 neuron pada hidden layer kedua.

last_lag = tail(trainy$nilai_asli, 1)

forecast_normalized <- numeric(28)

current_lag = last_lag

for (i in 1:28) {
  new_data = data.frame(nilai_lag = current_lag)
  pred = neuralnet::compute(mlp_2_1_2, covariate = new_data)
  forecast_normalized[i] = pred$net.result[1, 1]
  current_lag = forecast_normalized[i]
}

forecast_denormalized = ((forecast_normalized + 1) / 2) * (max_asli - min_asli) + min_asli

head(forecast_denormalized)
## [1] 16495.95 16461.67 16438.36 16421.80 16409.67 16400.60

Grafik prediksi dan Peramalan Neural Network

Setelah diperoleh NN terbaik, selanjutnya yaitu melakukan prediksi pada outsample untuk 26 hari serta peramalan untuk 2 hari kedepannya dengan menggunakan metode NN 2 neuron dengan hidden layer pertama menggunakan 1 neuron dan hidden layer kedua menggunakan 2 neuron.

Hasil_NN = ts(c(NA,kembali_NN_1_2,forecast_denormalized[1:26],forecast_denormalized[27:28]))

plot(1:172,kurs_rupiah, type = "l", main = "Grafik Prediksi dan Peramalan NN", ylab = "Nilai Kurs IDR", xlab = "Time")
  points(kurs_rupiah, cex = 0.9, pch = 21)
  lines(1:146,Hasil_NN[1:146], col = "blue")
  lines(147:172,Hasil_NN[147:172], col = "red")
  lines(173:174,Hasil_NN[173:174], col = "green")
  abline(v = 146, lty = 2)
  abline(v = 172, lty = 2)
legend("topleft", legend = c("Data aktual","Prediksi In sample", "Prediksi Out Sample", "Peramalan"), 
       col = c("black","blue","red","green"), lty = 1, pch = 20, lwd = 3, bty = "o", cex = 0.8)
grid()

Berdasarkan hasil grafik berikut, dapat dilihat bahwa pola data aktual dan hasil peramalan periode 25 Maret 2025 hingga 29 April 2025 cenderung tidak mengikuti pola data aktual. Hasil peramalan untuk 2 periode selanjutnya juga cenderung tidak mengikuti pola aktual dan harga kurs uang yang menurun.

Evaluasi model NN terbaik

Dilakukan kembali evaluasi model nn untuk melihat perbandingan akurasi dari ketiga perhitungan yang digunakan pada insample dan outsample.

in_sample_nn = c(
  MAPE_NN_in = MAPE(ts(kembali_NN_1_2),ts(data_train[2:146]))*100,
  SMAPE_NN_in = smape(ts(data_train[2:146]),ts(kembali_NN_1_2)) * 100,
  RMSE_NN_in = RMSE(ts(kembali_NN_1_2), ts(data_train[2:146]))
)

out_sample_nn = c(
  MAPE_NN_out = MAPE(forecast_denormalized[1:26], data_test) * 100,
  SMAPE_NN_out = smape(data_test, forecast_denormalized[1:26]) * 100,
  RMSE_NN_out = RMSE(forecast_denormalized[1:26], data_test)
)

hasil_evaluasi_nn = data.frame(
  Metrik = c("MAPE (%)", "SMAPE (%)", "RMSE"),
  In_Sample = round(in_sample_nn, 3),
  Out_Sample = round(out_sample_nn, 3),
  row.names = NULL
)

hasil_evaluasi_nn
##      Metrik In_Sample Out_Sample
## 1  MAPE (%)     0.292      1.965
## 2 SMAPE (%)     0.292      1.989
## 3      RMSE    58.992    362.889

Berdasarkan hasil evaluasi model Neural Network, dapat disimpulkan bahwa model ini menunjukkan akurasi yang sangat baik pada data training dengan nilai MAPE dan SMAPE yang rendah, yaitu 0.292%, serta RMSE sebesar 58.992. Sedangkan akurasi pada data testing nilai MAPE, SMAPE, dan RMSE model mengalami penuruanan akurasi, dimana nilai MAPE yang dihasilkan menjadi sebesar 1.965%%, SMAPE sebesar 1.989%, dan RMSE sebesar 362.88.

7. Neural Network (package keras3)

sama seperti pengerjaan model Neural Network dengan package neuralnet, berikut pengerjaan Neural Network menggunakan package keras.

Persiapan Data

x_train = as.matrix(trainy$nilai_lag)
y_train = as.matrix(trainy$nilai_asli)

y_test = as.matrix(testy$nilai_asli[1:26])
x_test = as.matrix(testy$nilai_lag[1:26])
tensorflow::tf$random$set_seed(2)

Pembentukan Model

model_nn = keras_model_sequential() %>%
  layer_dense(units = 3, activation = "tanh", input_shape = 1,
              kernel_regularizer = regularizer_l2(0.008)) %>%
  layer_layer_normalization() %>%
  layer_dense(units = 2, activation = "tanh",
              kernel_regularizer = regularizer_l2(0.002)) %>%
  layer_dense(units = 1, activation = "linear")

Tahap Training

model_nn %>% compile(
  optimizer = optimizer_adam(learning_rate = 0.005),
  loss = "mse",
  metrics = list("mae")
)
history = model_nn %>% fit(
  x = x_train,
  y = y_train,
  epochs = 800,
  batch_size = 8,
  validation_data = list(x_test, y_test),
  callbacks = list(
    callback_early_stopping(
      monitor = "val_loss",
      min_delta = 0.005,
      patience = 10,
      restore_best_weights = TRUE
    ),
    callback_reduce_lr_on_plateau(
      monitor = "val_loss",
      factor = 0.1,
      patience = 10
    )
  )
)
## Epoch 1/800
## 19/19 - 1s - 76ms/step - loss: 0.0736 - mae: 0.1770 - val_loss: 0.2357 - val_mae: 0.4421 - learning_rate: 0.0050
## Epoch 2/800
## 19/19 - 0s - 6ms/step - loss: 0.0581 - mae: 0.1616 - val_loss: 0.3239 - val_mae: 0.5336 - learning_rate: 0.0050
## Epoch 3/800
## 19/19 - 0s - 7ms/step - loss: 0.0512 - mae: 0.1507 - val_loss: 0.3217 - val_mae: 0.5325 - learning_rate: 0.0050
## Epoch 4/800
## 19/19 - 0s - 7ms/step - loss: 0.0487 - mae: 0.1477 - val_loss: 0.3120 - val_mae: 0.5242 - learning_rate: 0.0050
## Epoch 5/800
## 19/19 - 0s - 7ms/step - loss: 0.0467 - mae: 0.1463 - val_loss: 0.3214 - val_mae: 0.5339 - learning_rate: 0.0050
## Epoch 6/800
## 19/19 - 0s - 7ms/step - loss: 0.0440 - mae: 0.1426 - val_loss: 0.3206 - val_mae: 0.5337 - learning_rate: 0.0050
## Epoch 7/800
## 19/19 - 0s - 7ms/step - loss: 0.0411 - mae: 0.1381 - val_loss: 0.3227 - val_mae: 0.5364 - learning_rate: 0.0050
## Epoch 8/800
## 19/19 - 0s - 6ms/step - loss: 0.0374 - mae: 0.1312 - val_loss: 0.3177 - val_mae: 0.5323 - learning_rate: 0.0050
## Epoch 9/800
## 19/19 - 0s - 6ms/step - loss: 0.0334 - mae: 0.1229 - val_loss: 0.3059 - val_mae: 0.5219 - learning_rate: 0.0050
## Epoch 10/800
## 19/19 - 0s - 6ms/step - loss: 0.0291 - mae: 0.1130 - val_loss: 0.2860 - val_mae: 0.5035 - learning_rate: 0.0050
## Epoch 11/800
## 19/19 - 0s - 6ms/step - loss: 0.0251 - mae: 0.1032 - val_loss: 0.2600 - val_mae: 0.4784 - learning_rate: 0.0050

dikarenakan bobot yang dapat berubah dan learning rate yang dapat berubah pada tahap training, maka peneliti melakukan save terlebih dahulu model awal yang telah terbentuk. sehingga diperoleh grafik pelatihan sebagai berikut.

Save Model

#save_model(model_nn, "model_final.keras")

Tahap load model

model = load_model("model_final.keras")

Tahap prediksi dan peramalan

Prediksi

train_pred_norm = predict(model, x_train)
## 5/5 - 0s - 23ms/step
test_pred_norm = predict(model, x_test)
## 1/1 - 0s - 26ms/step
kembali_NN_keras_in = ((train_pred_norm + 1) / 2) * (max(kurs_rupiah) - min(kurs_rupiah)) + min(kurs_rupiah)

head(kembali_NN_keras_in)
##          [,1]
## [1,] 15516.16
## [2,] 15516.16
## [3,] 15466.20
## [4,] 15394.52
## [5,] 15362.52
## [6,] 15446.68

Peramalan

last_window = tail(x_train, 1)
forecasts_nn_keras = numeric(28)

for (i in 1:28) {
  pred_nn_keras = predict(model, last_window)
  forecasts_nn_keras[i] = pred_nn_keras
  last_window = cbind(last_window[, -1], pred_nn_keras)
}
## 1/1 - 0s - 31ms/step
## 1/1 - 0s - 32ms/step
## 1/1 - 0s - 37ms/step
## 1/1 - 0s - 31ms/step
## 1/1 - 0s - 35ms/step
## 1/1 - 0s - 29ms/step
## 1/1 - 0s - 32ms/step
## 1/1 - 0s - 31ms/step
## 1/1 - 0s - 31ms/step
## 1/1 - 0s - 31ms/step
## 1/1 - 0s - 32ms/step
## 1/1 - 0s - 18ms/step
## 1/1 - 0s - 32ms/step
## 1/1 - 0s - 32ms/step
## 1/1 - 0s - 21ms/step
## 1/1 - 0s - 24ms/step
## 1/1 - 0s - 27ms/step
## 1/1 - 0s - 29ms/step
## 1/1 - 0s - 31ms/step
## 1/1 - 0s - 32ms/step
## 1/1 - 0s - 33ms/step
## 1/1 - 0s - 39ms/step
## 1/1 - 0s - 33ms/step
## 1/1 - 0s - 31ms/step
## 1/1 - 0s - 31ms/step
## 1/1 - 0s - 31ms/step
## 1/1 - 0s - 32ms/step
## 1/1 - 0s - 31ms/step
balik_fcst_nn_keras = ((forecasts_nn_keras + 1) / 2) * (max(kurs_rupiah) - min(kurs_rupiah)) + min(kurs_rupiah)

head(balik_fcst_nn_keras)
## [1] 16466.64 16447.09 16433.22 16423.20 16415.86 16410.44

Grafik Prediksi dan Peramalan NN

hasil_nn_keras = ts(c(NA,kembali_NN_keras_in,balik_fcst_nn_keras))

plot(1:172,kurs_rupiah, type = "l", main = "Grafik Prediksi dan Peramalan NN", ylab = "Nilai Kurs IDR", xlab = "Time")
  points(kurs_rupiah, cex = 0.9, pch = 21)
  lines(1:146,hasil_nn_keras[1:146], col = "blue") 
  lines(147:172,hasil_nn_keras[147:172], col = "red")
  lines(173:174,hasil_nn_keras[173:174],col = "green")
  abline(v = 146, lty = 2)
  abline(v = 172, lty = 2)
legend("topleft", legend = c("Data aktual","Prediksi In sample", "Prediksi Out Sample","Peramalan"), 
       col = c("black","blue","red","green"), lty = 1, pch = 20, lwd = 3, bty = "o", cex = 0.8)
grid()

Evaluasi Model NN Keras

in_sample_nn_keras = c(
  MAPE_NN_keras_in = MAPE(hasil_nn_keras[2:146],data_train[2:146])*100,
  SMAPE_NN_keras_in = smape(data_train[2:146], hasil_nn_keras[2:146]) * 100,
  RMSE_NN_keras_in = RMSE(hasil_nn_keras[2:146], data_train[2:146])
)

out_sample_nn_keras = c(
  MAPE_NN_keras_out = MAPE(hasil_nn_keras[147:172], data_test) * 100,
  SMAPE_NN_keras_out = smape(data_test, hasil_nn_keras[147:172]) * 100,
  RMSE_NN_keras_out = RMSE(hasil_nn_keras[147:172], data_test)
)

hasil_evaluasi_nn_keras = data.frame(
  Metrik = c("MAPE (%)", "SMAPE (%)", "RMSE"),
  In_Sample = round(in_sample_nn_keras, 3),
  Out_Sample = round(out_sample_nn_keras, 3),
  row.names = NULL
)

hasil_evaluasi_nn_keras
##      Metrik In_Sample Out_Sample
## 1  MAPE (%)     0.302      1.874
## 2 SMAPE (%)     0.302      1.895
## 3      RMSE    60.179    344.625

8. Pemodelan Moving Average

Moving Average (MA) adalah salah satu metode peramalan yang paling sederhana namun efektif dalam menganalisis data deret waktu. Pada dasarnya, MA digunakan untuk meratakan fluktuasi jangka pendek dalam data dan menyoroti tren atau pola yang lebih besar. Dalam pemodelan MA, prediksi masa depan didasarkan pada rata-rata nilai data sebelumnya dalam suatu periode tertentu. Tujuan utama dari penggunaan Moving Average adalah untuk mempermudah identifikasi tren dan siklus yang ada dalam data deret waktu.

Single Moving Average

Single Moving Average adalah suatu metode peramalan dengan menggunakan data-data pada masa lalu, kemudian di jumlahkan dan melakukan perhitungan rata rata untuk mengetahui suatu informasi yang mungkin akan terjadi. Untuk menentukan ramalan pada periode yang akan datang, diperlukan data historis dengan jang ka waktu tertentu . Metode single moving average memiliki karater khusus yaitu memerlukan data historis dengan jangka waktu tertentu dan semakin pajang waktunya maka moving average yang akan dihasilkan akan semakin halus. Persamaan matematis single moving average dapat dilihat dibawah ini:

\[ M_t=\frac{X_t+X_{t-1}+X_{t-2}+...+X_{t-n+1}}{n} \]

kererangan:

\(M_t\): Moving Average Periode ke-t

\(X_t\): Nilai rill periode ke-t

\(n\): Jumlah batas dalam Moving Average

Orde 2

SMA_order_2 = SMA(data_train, n = 2)
head(SMA_order_2)
## [1]      NA 15520.0 15495.0 15432.5 15377.5 15405.0

Orde 3

SMA_order_3 = SMA(data_train, n = 3)
head(SMA_order_3)
## [1]       NA       NA 15503.33 15461.67 15408.33 15401.67

Double Moving Average

Double moving average adalah metode yang mencari rata-rata bergerak kemudian dicari rata rata bergerak dari rata-rata bergerak dan dibuat peramalannya. Rata-rata bergerak artinya rata-rata dicari menggunakan data terbaru dan menghilangkan data yang lama. Banyaknya data yang digunakan untuk mencari rata-rata bergerak adalah ordo. Langkah peramalan rata-rata bergerak meliputi tiga aspek yaitu penentuan rata-rata bergerak tunggal pada periode 𝑡, penyesuaian terhadap perbedaan rata-rata bergerak tunggal dan ganda pada periode 𝑡, dan penyesuaian untuk trend dari periode 𝑡 ke 𝑡 + 1. Langkah-langkah peramalan double moving average sebagai berikut:

  1. Menghitung rata-rata bergerak pertama \(S_t^`=\frac{Y_t+Y_{t-1}+...+Y_{t-n+1}}{n}\)

  2. Menghitung rata-rata bergerak kedua \(S_t^{''}=\frac{S_t^`+S_{t-1}^`+...+S_{t-n+1}^`}{n}\)

  3. Menghitung besarnya konstanta \(a_t=2S_t^`-S_t^{``}\)

  4. Menghitung besarnya koefisien trend \(b_t=\frac{2}{n-1}(S_t^`-S_t^{``})\)

  5. Menghitung besarnya peramalan \(F_{t+m}=a_t+b_t\)

Orde 2

sma_dma_2 = SMA(data_train,  n=2)

dma_2 = SMA(sma_dma_2, n=2)

At_2 = 2*sma_dma_2-dma_2
Bt_2 = sma_dma_2-dma_2
pemulusan_dma_2 = At_2+Bt_2

head(pemulusan_dma_2)
## [1]      NA      NA 15470.0 15370.0 15322.5 15432.5

Orde 3

sma_dma_3 = SMA(data_train,  n=3)

dma_3 = SMA(sma_dma_3, n=3)

At_3 = 2*sma_dma_3-dma_3
Bt_3 = sma_dma_3-dma_3
pemulusan_dma_3 = At_3+Bt_3

head(pemulusan_dma_3)
## [1]       NA       NA       NA       NA 15309.44 15357.22

Peramalan

Pada bagian ini, dilakukan peramalan nilai tukar rupiah terhadap dolar AS menggunakan metode Moving Average, yang terdiri dari Single Moving Average (SMA) dan Double Moving Average (DMA):

Single Moving Average

forecast_sma2 = function(data, last_n, horizon) {
  forecasts = numeric(horizon)
  n = length(data)
  
  # Ambil 2 nilai terakhir dari data
  last_two = tail(data, last_n)
  
  for (i in 1:horizon) {
    # Hitung SMA untuk periode berikutnya
    next_forecast = mean(last_two)
    forecasts[i] = next_forecast
    
    # Update last_two: geser nilai dan tambahkan ramalan terbaru
    last_two = c(last_two[-1], next_forecast)
  }
  
  return(forecasts)
}

forecast_sma3 = function(data, last_n, horizon) {
  forecasts = numeric(horizon)
  n <- length(data)
  
  # Ambil 3 nilai terakhir dari data
  last_three = tail(data, last_n)
  
  for (i in 1:horizon) {
    # Hitung SMA untuk periode berikutnya
    next_forecast = mean(last_three)
    forecasts[i] = next_forecast
    
    # Update last_three: geser nilai dan tambahkan ramalan terbaru
    last_three = c(last_three[-1], next_forecast)
  }
  
  return(forecasts)
}
fcst_sma2 = forecast_sma2(data_train, last_n = 2, horizon = 26)
fcst_sma3 = forecast_sma3(data_train, last_n = 3, horizon = 26)

head(fcst_sma2)
## [1] 16522.50 16536.25 16529.38 16532.81 16531.09 16531.95
head(fcst_sma3)
## [1] 16505.00 16516.67 16523.89 16515.19 16518.58 16519.22

Double Moving Average

dma_forecast <- function(data, order = 2, horizon = 17) {
  # Hitung moving average pertama
  sma = SMA(data, n = order)
  
  # Hitung moving average kedua
  dma = SMA(sma, n = order)
  
  # Hitung komponen dasar
  At = 2 * sma - dma
  Bt = (sma - dma) * (2 / (order - 1))
  
  # Ambil nilai terakhir yang valid
  last_valid = max(which(!is.na(At)))
  last_At = At[last_valid]
  last_Bt = Bt[last_valid]
  
  # Generate ramalan
  ramalan = last_At + last_Bt * (1:horizon)
  
  return(list(
    data_asli = data,
    ramalan = ramalan,
    parameter = c(At = last_At, Bt = last_Bt),
    horizon = horizon
  ))
}
fcst_dma_2 = dma_forecast(data_train, order = 2, horizon = 26)$ramalan
fcst_dma_3 = dma_forecast(data_train, order = 3, horizon = 26)$ramalan

head(fcst_dma_2)
## [1] 16582.5 16622.5 16662.5 16702.5 16742.5 16782.5
head(fcst_dma_3)
## [1] 16535 16550 16565 16580 16595 16610

Pemilihan SMA dan DMA

Untuk menentukan metode peramalan terbaik antara Single Moving Average (SMA) dan Double Moving Average (DMA), dilakukan evaluasi kinerja masing-masing metode berdasarkan tiga metrik akurasi, yaitu MAPE, RMSE, dan SMAPE. Hasilnya dapat dilihat dibawah ini:

MAPE_SMA_DMA = c(
  MAPE_SMA2 = MAPE(SMA_order_2[2:146],data_train[2:146])*100,
  MAPE_SMA3 = MAPE(SMA_order_3[3:146],data_train[3:146])*100,
  MAPE_DMA2 = MAPE(pemulusan_dma_2[3:146],data_train[3:146])*100,
  MAPE_DMA3 = MAPE(pemulusan_dma_3[5:146],data_train[5:146])*100
)

RMSE_SMA_DMA = c(
  RMSE_SMA2 = RMSE(SMA_order_2[2:146],data_train[2:146]),
  RMSE_SMA3 = RMSE(SMA_order_3[3:146],data_train[3:146]),
  RMSE_DMA2 = RMSE(pemulusan_dma_2[3:146],data_train[3:146]),
  RMSE_DMA3 = RMSE(pemulusan_dma_3[5:146],data_train[5:146])
)

SMAPE_SMA_DMA = c(
  SMAPE_SMA2 = smape(data_train[2:146],SMA_order_2[2:146])*100,
  SMAPE_SMA3 = smape(data_train[3:146],SMA_order_3[3:146])*100,
  SMAPE_DMA2 = smape(data_train[3:146],pemulusan_dma_2[3:146])*100,
  SMAPE_DMA3 = smape(data_train[5:146],pemulusan_dma_3[5:146])*100
)

baris_pemilihan_SMA_DMA = c(
  "SMA 2",
  "SMA 3",
  "DMA 2",
  "DMA 3"
)

pemilihan_SMA_DMA_Terbaik = data.frame(
  pilih_mape = round(MAPE_SMA_DMA, 3),
  pilih_rmse = round(RMSE_SMA_DMA, 3),
  pilih_smape = round(SMAPE_SMA_DMA, 3),
  row.names = baris_pemilihan_SMA_DMA
)

colnames(pemilihan_SMA_DMA_Terbaik) = c("MAPE", "RMSE", "SMAPE")

pemilihan_SMA_DMA_Terbaik
##        MAPE   RMSE SMAPE
## SMA 2 0.146 30.138 0.147
## SMA 3 0.226 45.769 0.226
## DMA 2 0.146 30.155 0.146
## DMA 3 0.248 49.878 0.248

berdasarkan hasil tersebut maka dapat diketahui bahwa double moving avarage orde 2 merupakan model yang memiliki nilai MAPE, RMSE, dan SMAPE terkecil.

Grafik Prediksi dan Peraman Model DMA Orde 2

Grafik berikut menunjukkan hasil prediksi dan peramalan nilai tukar rupiah terhadap dolar AS menggunakan model DMA orde 2. Grafik ini menggambarkan bagaimana model mengikuti pola data historis dan memperkirakan nilai ke depan. Hasilnya ditampilkan sebagai berikut:

hasil_dma_2 = ts(c(pemulusan_dma_2,fcst_dma_2))

plot(1:172,kurs_rupiah, type = "l", main = "Grafik Prediksi dan Peramalan DMA", ylab = "Nilai Kurs IDR", xlab = "Time", ylim = c(15000,17600))
  points(kurs_rupiah, cex = 0.9, pch = 21)
  lines(1:146,hasil_dma_2[1:146], col = "blue")
  lines(147:172,hasil_dma_2[147:172], col = "red")
  abline(v = 146, lty = 2)
  abline(v = 172, lty = 2)
legend("topleft", legend = c("Data aktual","Prediksi In sample", "Prediksi Out Sample"), 
       col = c("black","blue","red"), lty = 1, pch = 20, lwd = 3, bty = "o", cex = 0.8)
grid()

(Berdasarkan grafik time series nilai tukar Rupiah terhadap Dolar AS, model Double Moving Average (DMA) orde 2 mampu mengikuti pola data historis dengan cukup baik. Prediksi in-sample yang ditunjukkan oleh garis biru mendekati data aktual, menandakan kecocokan model terhadap pola yang telah terjadi. Sementara itu, prediksi out-sample yang digambarkan dengan garis merah menunjukkan kecenderungan naik, meskipun mulai menyimpang dari data aktual. Hal ini menunjukkan bahwa model cukup efektif dalam memodelkan data historis, namun akurasi peramalan cenderung menurun seiring waktu. Secara umum, DMA orde 2 memberikan hasil yang layak untuk prediksi jangka pendek.

Evaluasi Model DMA

Evaluasi dilakukan untuk menilai akurasi dan kinerja model Double Moving Average (DMA) orde 2 dalam memprediksi nilai tukar Rupiah terhadap Dolar AS. Hasil evaluasi model disajikan sebagai berikut:

in_sample_dma = c(
  MAPE_DMA2_in = MAPE(pemulusan_dma_2[3:146],data_train[3:146])*100,
  SMAPE_DMA2_in = smape(data_train[3:146],pemulusan_dma_2[3:146])*100,
  RMSE_DMA2_in = RMSE(pemulusan_dma_2[3:146],data_train[3:146])
)

out_smaple_dma = c(
  MAPE_DMA2_out = MAPE(fcst_dma_2, data_test) * 100,
  SMAPE_DMA2_out = smape(data_test, fcst_dma_2) * 100,
  RMSE_DMA2_out = RMSE(fcst_dma_2, data_test)
)

hasil_evaluasi_dma = data.frame(
  Metrik = c("MAPE (%)", "SMAPE (%)", "RMSE"),
  In_Sample = round(in_sample_dma, 3),
  Out_Sample = round(out_smaple_dma, 3),
  row.names = NULL
)

hasil_evaluasi_dma
##      Metrik In_Sample Out_Sample
## 1  MAPE (%)     0.146      2.171
## 2 SMAPE (%)     0.146      2.140
## 3      RMSE    30.155    420.695

Model DMA orde 2 menunjukkan akurasi yang sangat baik pada data in-sample, dengan nilai MAPE dan SMAPE sebesar 0,146% dan RMSE 30,155, yang menandakan kesalahan prediksi sangat kecil. Pada data out-sample, akurasi menurun dengan MAPE sebesar 2,171%, SMAPE 2,140%, dan RMSE meningkat menjadi 420,695. Meskipun terjadi penurunan, model tetap cukup baik untuk peramalan jangka pendek.

9. Evaluasi Model ARIMA, NN, dan MA

Setelah dilakukan analisis data kurs rupiah menggunakan model ARIMA, NN, dan MA. Kemudian dilakukan tahap evaluasi untuk melihat model manakah yang menghasilkan MAPE, RMSE, dan SMAPE terkecil bagi data in sampledan out sample.

mape_in_sample_seluruh = c(
  MAPE_Arima_in = MAPE(prediksi_arima,data_train)*100,
  MAPE_NN_in = MAPE(ts(kembali_NN_1_2),ts(data_train[2:146]))*100,
  MAPE_NN_keras_in = MAPE(hasil_nn_keras[2:146],data_train[2:146])*100,
  MAPE_DMA2_in = MAPE(pemulusan_dma_2[3:146],data_train[3:146])*100
)

mape_out_sample_seluruh = c(
  MAPE_Arima_out = MAPE(ramal_arima[1:26], data_test) * 100,
  MAPE_NN_out = MAPE(forecast_denormalized[1:26], data_test) * 100,
  MAPE_NN_keras_out = MAPE(hasil_nn_keras[147:172], data_test) * 100,
  MAPE_DMA2_out = MAPE(fcst_dma_2, data_test) * 100
)

smape_in_sample_seluruh = c(
  SMAPE_Arima_in = smape(data_train, prediksi_arima)*100,
  SMAPE_NN_in = smape(ts(data_train[2:146]),ts(kembali_NN_1_2)) * 100,
  SMAPE_NN_keras_in = smape(data_train[2:146], hasil_nn_keras[2:146]) * 100,
  SMAPE_DMA2_in = smape(data_train[3:146],pemulusan_dma_2[3:146])*100
)

smape_out_sample_seluruh = c(
  SMAPE_Arima_out = smape(data_test, ramal_arima[1:26]) * 100,
  SMAPE_NN_out = smape(data_test, forecast_denormalized[1:26]) * 100,
  SMAPE_NN_keras_out = smape(data_test, hasil_nn_keras[147:172]) * 100,
  SMAPE_DMA2_out = smape(data_test, fcst_dma_2) * 100
)

rmse_in_sample_seluruh = c(
  RMSE_Arima_in = RMSE(prediksi_arima, data_train),
  RMSE_NN_in = RMSE(ts(kembali_NN_1_2), ts(data_train[2:146])),
  RMSE_NN_keras_in = RMSE(hasil_nn_keras[2:146], data_train[2:146]),
  RMSE_DMA2_in = RMSE(pemulusan_dma_2[3:146],data_train[3:146])
)

rmse_out_sample_seluruh = c(
  RRMSE_Arima_out = RMSE(ramal_arima[1:26], data_test),
  RMSE_NN_out = RMSE(forecast_denormalized[1:26], data_test),
  RMSE_NN_keras_out = RMSE(hasil_nn_keras[147:172], data_test),
  RMSE_DMA2_out = RMSE(fcst_dma_2, data_test)
)

hasil_evaluasi_keseluruhan <- data.frame(
  MAPE_In = round(mape_in_sample_seluruh, 3),
  MAPE_Out = round(mape_out_sample_seluruh, 3),
  SMAPE_In = round(smape_in_sample_seluruh, 3),
  SMAPE_Out = round(smape_out_sample_seluruh, 3),
  RMSE_In = round(rmse_in_sample_seluruh, 3),
  RMSE_Out = round(rmse_out_sample_seluruh, 3),
  row.names = c("ARIMA", "NN (Neural Net)", "NN (Keras)", "DMA Orde 2")
)

# Menambahkan nama kolom yang lebih deskriptif
colnames(hasil_evaluasi_keseluruhan) <- c(
  "MAPE In Sample (%)",
  "MAPE Out Sample (%)",
  "SMAPE In Sample (%)",
  "SMAPE Out Sample (%)",
  "RMSE In Sample",
  "RMSE Out Sample"
)

# Menampilkan hasil
hasil_evaluasi_keseluruhan
##                 MAPE In Sample (%) MAPE Out Sample (%) SMAPE In Sample (%)
## ARIMA                        0.343               1.599               0.343
## NN (Neural Net)              0.292               1.965               0.292
## NN (Keras)                   0.302               1.874               0.302
## DMA Orde 2                   0.146               2.171               0.146
##                 SMAPE Out Sample (%) RMSE In Sample RMSE Out Sample
## ARIMA                          1.582         68.279         312.756
## NN (Neural Net)                1.989         58.992         362.889
## NN (Keras)                     1.895         60.179         344.625
## DMA Orde 2                     2.140         30.155         420.695

Berdasarkan hasil evaluasi matriks keseluruhan model yang digunakan, maka model Neural Network merupakan model terbaik yang dapat digunakan untuk menganalis nilai tukar rupiah terhadap dolar AS periode 1 April 2024 hingga 30 April 2025.

10. Kesimpulan dan Saran

Kesimpulan

Berdasarkan ketiga model yang digunakan, model neural network dengan menggunakan bantuan pacakage keras merupakan model terbaik yang dapat digunakan untuk menganalisis data nilai tukar rupiah terhadap dolar AS periode 1 April 2024 hingga 30 April 2025. Hal ini dikarenakan model tersebut memiliki nilai MAPE, SMAPE, dan RMSE in sample terkecil, selain itu hasil nilai MAPE, SMAPE, dan RMSE dari out sample juga tidak terlalu jauh dengan in sample nya yang menandakan tidak terjadi over fitting pada model tersebut.

Saran

Sebaiknya peneliti selanjutnya dapat melakuakn hybrid pada model ARIMA dengan Neural Network untuk dapat meningkatkan akurasi dan menangkap pola-pola data yang belum bisa ditangkap model ARIMA atau Neural Network.


Penulis

Nama Penulis : Yusri Abdul Fahmi, Mochamad Afif Nurdiansyah, Nabila Aulia, Felicia Joy Rotua Tamba
Email Penulis :
fahmi2004.bukitpinang@gmail.com, ,
,