Pendahuluan

Keberadaan teknologi membuat manusia mudah menemukan kata atau istilah menggunakan mesin pencarian. Salah satu mesin pencarian yang umum digunakan adalah Google, dimana Google memiliki fitur Google trends. Melalui Google trends, dapat diketahui frekuensi data pencarian yang telah dilakukan oleh masyarakat di seluruh dunia, termasuk kata pencarian musim hujan. Pencarian kata kunci “musim hujan” pada google trends dapat mencerminkan kepedulian masyarakat terhadap fenomena musim hujan yang merupakan periode tahunan dan ditandai dengan peningkatan intensitas curah hujan. Analisis terhadap pencarian ini dapat memberikan wawasan tentang perilaku masyarakat serta membantu perencanaan informasi terhada cuaca tersebut.

Untuk menganalisis dan memprediksi tren pencarian ini, diperlukan pendekatan yang mampu menangkap pola musiman dan kompleksitas data. Metode Seasonal Autoregressive Integrated Moving Average (SARIMA) telah banyak digunakan dalam analisis deret waktu hidrologi karena kemampuannya dalam menangkap pola musiman secara statistik. Di sisi lain, pendekatan berbasis Neural Network (NN), yang merupakan bagian dari machine learning, menawarkan fleksibilitas dalam memodelkan hubungan non-linier yang sering ditemukan dalam data lingkungan dan iklim

Dengan demikian, penelitian ini bertujuan untuk menganalisis dan memprediksi tren pencarian kata kunci “musim hujan” menggunakan metode SARIMA dan Neural Network sehingga dapat memberikan gambaran mengenai pola pencarian masyarakat serta mendukung upaya penyampaian informasi cuaca yang lebih tepat sasaran dan responsif terhadap kebutuhan publik. Keberadaan teknologi membuat manusia mudah menemukan kata atau istilah menggunakan mesin pencarian. Salah satu mesin pencarian yang umum digunakan adalah Google, dimana Google memiliki fitur Google trends. Melalui Google trends, dapat diketahui frekuensi data pencarian yang telah dilakukan oleh masyarakat di seluruh dunia, termasuk kata pencarian musim hujan.

Pencarian kata kunci “musim hujan” pada google trends dapat mencerminkan kepedulian masyarakat terhadap fenomena musim hujan yang merupakan periode tahunan dan ditandai dengan peningkatan intensitas curah hujan. Analisis terhadap pencarian ini dapat memberikan wawasan tentang perilaku masyarakat serta membantu perencanaan informasi terhada cuaca tersebut. Untuk menganalisis dan memprediksi tren pencarian ini, diperlukan pendekatan yang mampu menangkap pola musiman dan kompleksitas data. Metode Seasonal Autoregressive Integrated Moving Average (SARIMA) telah banyak digunakan dalam analisis deret waktu hidrologi karena kemampuannya dalam menangkap pola musiman secara statistik. Di sisi lain, pendekatan berbasis Neural Network (NN), yang merupakan bagian dari machine learning, menawarkan fleksibilitas dalam memodelkan hubungan non-linier yang sering ditemukan dalam data lingkungan dan iklim

Dengan demikian, penelitian ini bertujuan untuk menganalisis dan memprediksi tren pencarian kata kunci “musim hujan” menggunakan metode SARIMA dan Neural Network sehingga dapat memberikan gambaran mengenai pola pencarian masyarakat serta mendukung upaya penyampaian informasi cuaca yang lebih tepat sasaran dan responsif terhadap kebutuhan publik.

Statistika Deskriptif

data=read.csv(file.choose(), sep=';')
summary(data)
##     Bulan            musim.hujan    
##  Length:173         Min.   :  5.00  
##  Class :character   1st Qu.: 19.00  
##  Mode  :character   Median : 31.00  
##                     Mean   : 34.69  
##                     3rd Qu.: 47.00  
##                     Max.   :100.00
sd(data$musim.hujan)
## [1] 20.30081
var(data$musim.hujan)
## [1] 412.1229
length(data$musim.hujan)
## [1] 173

Berdasarkan hasil analisis statistika deskriptif di atas, diketahui bahwa data pencarian kata kunci “musim hujan” Periode Januari 2011 sampai dengan Mei 2025 memiliki panjang 173 data, dengan nilai standar deviasi sebesar 20,20081 dan nilai variansi sebesar 412,1229. Data tersebut memiliki nilai rata-rata sebesar 34,69 dengan jumlah pencarian minimum sebesar 5 dan jumlah pencarian maksimum sebesar 100.

SARIMA

SARIMA adalah singkatan dari Seasonal Autoregressive Integrated Moving Average, yaitu model statistik yang digunakan untuk memprediksi data deret waktu (time series) yang memiliki pola musiman (seasonality).

Rumus Umum SARIMA:

Import Data

Memanggil data yang akan dianalisis yaitu kata pencarian “Musim Hujan”

data=read.csv(file.choose(), sep=';')
Zt<-as.data.frame(data$musim.hujan)
Zt<-ts(Zt)

Splitting Data

Sebelum melakukan tahap analisis menggunakan model Seasonal Autoregressive Integrated Moving Average (SARIMA) dilakukan tahap pembagian data atau splitting data dengan rasio 85% untuk data in-sample dan 15% untuk out-sample dapat ditulis sebagai 85:15.

in_sample <- Zt[1:floor(0.85 * NROW(Zt)), ] #1:147
out_sample <- Zt[(floor(0.85 * NROW(Zt)) + 1):NROW(Zt), ] #148:173

cat("Jumlah data in sample =", NROW(in_sample), "\n")
## Jumlah data in sample = 147
cat("Jumlah data out sample =", NROW(out_sample), "\n")
## Jumlah data out sample = 26

Import Library

library(TSA)
## 
## Attaching package: 'TSA'
## The following objects are masked from 'package:stats':
## 
##     acf, arima
## The following object is masked from 'package:utils':
## 
##     tar
library(MASS)
library(car)
## Loading required package: carData
library(forecast)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
## Registered S3 methods overwritten by 'forecast':
##   method       from
##   fitted.Arima TSA 
##   plot.Arima   TSA
library(tseries)
library(quadprog)
library(zoo)
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
library(fracdiff)
library(fUnitRoots)
library(lmtest)
library(nortest)
library(readxl)
library(MLmetrics)
## 
## 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(knitr)
library(kableExtra)
## Warning: package 'kableExtra' was built under R version 4.4.3

Time Series Plot

Time series plot digunakan untuk memvisualisasikan data berdasarkan urutan waktunya dengan tujuan mengamati pola tren, mengidentifikasi pola musiman, mendeteksi outlier atau nilai ekstrem.

ts.plot(in_sample,type="o",ylab="Pencarian Kata Kunci 'Musim Hujan'", xlab="Periode",main="Time Series Plot Pencarian Kata Kunci 'Musim Hujan' Periode 
        Januari 2011 sampai dengan Mei 2025")
grid()

Berdasakan time series plot jumlah pencarian kata kunci Musim Hujan” di Indonesia pada periode Januari 2011 hingga Mei 2025, terlihat adanya pola musiman dan tren peningkatan dalam jumlah pencarian. Pada awal periode, volume pencarian relatif rendah dan stabil. Namun, mulai sekitar tahun 2015 hingga 2025, volume pencarian meningkat secara bertahap. Kenaikan drastis terlihat setelah periode ke-100, mengindikasikan peningkatan minat atau perhatian masyarakat terhadap topik “musim hujan” menunjukkan lonjakan signifikan dalam periode tersebut. Pola musiman juga tampak jelas, di mana pencarian cenderung meningkat pada bulan-bulan tertentu yang kemungkinan bertepatan dengan musim hujan di Indonesia.

Identifikasi Stasioneritas Data

Pada analisis runtun waktu, langkah pertama untuk mengetahui apakah data perlu distasionerkan adalah dengan membuat plot ACF dan PACF. ACF digunakan untuk melihat apakah data telah stasioner dalam rata-rata dengan memeriksa apakah ACF menurun secara perlahan atau cepat. Jika ACF menurun perlahan hingga lag tinggi dapat dikatakan data belum stasioner. Jika menurun tajam setelah beberapa lag dapat dikatakan bahwa data sudah stasioner. Sama halnya dengan PACF yang membantu mengidentifikasi lag signifikan, dan jika PACF juga cepat menurun setelah beberapa lag, data sudah stasioner. Jika pada ACF dan PACF menunjukkan data tidak stasioner maka perlu dilakukan langkah selanjutnya yaitu transformasi dan differencing (non-musiman ataupun musiman) pada data.

acf(in_sample,173, main="Plot ACF Data Aktual")

pacf(in_sample,173, main="Plot PACF Data Aktual")

Stasioneritas dalam Variansi

Dalam melakukan pemodelan SARIMA, maka tahapan awal yang harus dilakukan adalah melakukan stasioneritas pada data, hal ini dikarenakan dalam melakukan pemodelan SARIMA harus memenuhi syarat stasioneritas terhadap variansi dan stasioneritas terhadap rata-rata. Untuk mengetahui data time series telah stasioner dalam variansi dapat dilakukan dengan menggunakan transformasi Box-Cox.

boxcox(in_sample~1) #cek stasioner dalam variansi

p<-powerTransform(in_sample);p
## Estimated transformation parameter 
## in_sample 
## 0.2023421
y<-(in_sample^(p$lambda))
y1<-as.data.frame(y)
boxcox(y~1)

q<-powerTransform(y)
q
## Estimated transformation parameter 
## y 
## 1

Berdasarkan grafik boxcox data hasil transformasi, diperoleh bahwasanya nilai lambda sudah 1 dengan nilai lambda sebesar 1 Hal ini menunjukkan bahwa data sudah stasioner dalam variansi.

acf(y,106, main="Plot ACF Data Aktual Setelah Transformasi")#diesdown atau turun lambat 

pacf(y,106, main="Plot PACF Data Aktual Setelah Transformasi")

Stasioneritas dalam Rata-rata

Dalam melakukan pemodelan SARIMA (Seasonal Autoregressive Integrated Moving Average), pemeriksaan dan pencapaian stasioneritas rata-rata sangat penting. Terdapat dua tahapan utama yaitu differencing non-musiman dan differencing musiman dengan melakukan uji ADF test (Augmented Dickey-Fuller)

Stasioneritas dalam Rata-rata pada non-musiman

adfTest(y)
## 
## Title:
##  Augmented Dickey-Fuller Test
## 
## Test Results:
##   PARAMETER:
##     Lag Order: 1
##   STATISTIC:
##     Dickey-Fuller: -0.0604
##   P VALUE:
##     0.5949 
## 
## Description:
##  Tue May 13 11:29:45 2025 by user: User
 datadiff=diff(y,differences=1)
datadiff
##   [1] -0.064639873  0.064639873  0.000000000 -0.101375503 -0.086129763
##   [6] -0.052046407  0.097574041  0.170831798  0.076361721  0.139375214
##  [11] -0.116639073  0.133526301 -0.156262443 -0.049366094 -0.026995628
##  [16]  0.052382488 -0.223214286  0.040602129  0.130229670  0.141364581
##  [21]  0.056861301  0.124963665 -0.074254027  0.162649093 -0.231548079
##  [26] -0.153040907  0.093731704 -0.068344844 -0.112265245  0.059882758
##  [31]  0.026995628  0.072102235  0.080938672  0.156758085  0.026159401
##  [36]  0.163093914 -0.261334481 -0.188351732  0.000000000 -0.049366094
##  [41] -0.086878385 -0.110949041  0.403455962  0.000000000  0.016311356
##  [46]  0.277112414  0.000000000 -0.080747391 -0.022236233 -0.207327375
##  [51]  0.016887229 -0.071517522 -0.220989400  0.031028591  0.352043713
##  [56]  0.013605073  0.086269691  0.236092612 -0.079478125 -0.156614487
##  [61]  0.139301542 -0.212323225 -0.070046892 -0.099959201 -0.208890701
##  [66]  0.149581498  0.128208189  0.060269440  0.177969502 -0.075589848
##  [71] -0.102379654  0.013984587  0.193395119 -0.236588930 -0.047371572
##  [76] -0.091259583 -0.234858621  0.120489667  0.171230254  0.213358732
##  [81]  0.000000000  0.105000052 -0.116736992 -0.024300194  0.058751652
##  [86] -0.139482999  0.000000000 -0.174088801 -0.149581498  0.081236654
##  [91]  0.297660140  0.084256504  0.072656720  0.037546736 -0.121438277
##  [96]  0.102983624 -0.150500455  0.012292643 -0.107844387 -0.180897873
## [101] -0.158980620  0.239919292  0.276042662  0.069968737 -0.019092083
## [106]  0.000000000 -0.009801034  0.204963509 -0.113977778  0.024656657
## [111] -0.008101380 -0.193111211  0.105000052 -0.116736992  0.295322991
## [116]  0.148128923 -0.114169202 -0.062592792  0.160070325 -0.040767138
## [121]  0.099938579 -0.047994781 -0.330828728 -0.131408371  0.245238516
## [126] -0.356072542  0.409113390  0.123936330 -0.271715240  0.154979250
## [131] -0.076331360  0.031743688  0.137244621 -0.025059374 -0.348777085
## [136] -0.024300194 -0.052357933 -0.143153012  0.346011400  0.118062755
## [141]  0.000000000 -0.081744836 -0.045781187  0.079893549  0.098692450
## [146] -0.115491867
adfTest(datadiff)
## Warning in adfTest(datadiff): p-value smaller than printed p-value
## 
## Title:
##  Augmented Dickey-Fuller Test
## 
## Test Results:
##   PARAMETER:
##     Lag Order: 1
##   STATISTIC:
##     Dickey-Fuller: -9.3808
##   P VALUE:
##     0.01 
## 
## Description:
##  Tue May 13 11:29:45 2025 by user: User
#plot ACF data differencing 1
#karena di lag 24 signifikan sedangkan pada lag-lag kelipatan 24 selanjutnya tidak ada yang signifikan sehingga plot acf seasonal cut off after lag 1 seasonal

plot.ts(datadiff, type="o", main="Time Series Plot Data Hasil 
Transformasi Setelah Differencing Non Musiman Orde 1", xlab="Periode", ylab="Pencarian Kata Kunci 'Musim Hujan'")

acf(datadiff,105, main="Plot ACF Data Hasil Transformasi 
    Setelah di Differencing Orde 1") #cut off after lag 1
grid()#terdapat pola data musiman di data 24

pacf(datadiff,105, main="Plot PACF Data Hasil 
     Transformasi Setelah di Differencing Orde 1") #cut off after lag 1
grid()#terdapat pola data musiman di data 24

Stasioneritas dalam Rata-rata pada Musiman

datadiff2=diff(datadiff,differences=1, lag=12)
datadiff2
##   [1] -0.0916225699 -0.1140059665 -0.0269956277  0.1537579906 -0.1370845231
##   [6]  0.0926485360  0.0326556283 -0.0294672172 -0.0195004207 -0.0144115491
##  [11]  0.0423850461  0.0291227920 -0.0752856364 -0.1036748132  0.1207273312
##  [16] -0.1207273312  0.1109490408  0.0192806289 -0.1032340420 -0.0692623463
##  [21]  0.0240773712  0.0317944200  0.1004134275  0.0004448206 -0.0297864016
##  [26] -0.0353108253 -0.0937317035  0.0189787498  0.0253868599 -0.1708317984
##  [31]  0.3764603348 -0.0721022350 -0.0646273158  0.1203543294 -0.0261594009
##  [36] -0.2438413052  0.2390982479 -0.0189756428  0.0168872287 -0.0221514281
##  [41] -0.1341110145  0.1419776318 -0.0514122491  0.0136050726  0.0699583348
##  [46] -0.0410198022 -0.0794781249 -0.0758670959  0.1615377751 -0.0049958500
##  [51] -0.0869341206 -0.0284416792  0.0120986985  0.1185529068 -0.2238355244
##  [56]  0.0466643672  0.0916998109 -0.3116824602 -0.0229015287  0.1705990739
##  [61]  0.0540935767 -0.0242657050  0.0226753202  0.0086996183 -0.0259679193
##  [66] -0.0290918308  0.0430220653  0.1530892918 -0.1779695019  0.1805899005
##  [71] -0.0143573386 -0.0382847808 -0.1346434672  0.0971059310  0.0473715717
##  [76] -0.0828292184  0.0852771227 -0.0392530128  0.1264298857 -0.1291022277
##  [81]  0.0726567196 -0.0674533162 -0.0047012846  0.1272838179 -0.2092521064
##  [86]  0.1517756421 -0.1078443870 -0.0068090719 -0.0093991225  0.1586826380
##  [91] -0.0216174776 -0.0142877666 -0.0917488028 -0.0375467360  0.1116372426
##  [96]  0.1019798849  0.0365226764  0.0123640141  0.0997430066 -0.0122133376
## [101]  0.2639806725 -0.3566562844  0.0192803287  0.0781601861 -0.0950771190
## [106] -0.0625927915  0.1698713593 -0.2457306473  0.2139163570 -0.0726514382
## [111] -0.3227273474  0.0617028393  0.1402384640 -0.2393355501  0.1137903991
## [116] -0.0241925929 -0.1575460378  0.2175720412 -0.2364016848  0.0725108260
## [121]  0.0373060425  0.0229354070 -0.0179483577  0.1071081775 -0.2975964491
## [126]  0.2129195301 -0.0631019905 -0.0058735756  0.2717152400 -0.2367240861
## [131]  0.0305501727  0.0481498610 -0.0385521708 -0.0904324933
adfTest(datadiff2)
## Warning in adfTest(datadiff2): p-value smaller than printed p-value
## 
## Title:
##  Augmented Dickey-Fuller Test
## 
## Test Results:
##   PARAMETER:
##     Lag Order: 1
##   STATISTIC:
##     Dickey-Fuller: -14.7113
##   P VALUE:
##     0.01 
## 
## Description:
##  Tue May 13 11:29:45 2025 by user: User
#menampilkan plot ACF data differencing 12
plot.ts(datadiff2, type="o", main="Time Series Plot Data Hasil 
Transformasi Setelah Differencing Musiman Orde 1", xlab="Periode", ylab="Pencarian Kata Kunci 'Musim Hujan'")

Setelah melakukan differencing pada non-musiman dan musiman, diperoleh nilai ADF test sebsesar 0,01, hal ini menandakan bahwa data in-sample telah stasioner dalam rata-rata sehingga dapat dilanjutkan dengan identifikasi stasioner secara visual dengan plot ACF dan PACF.

Identififkasi Model SARIMA Sementara

#Model ARIMA Sementara
acf(datadiff2, main="Plot ACF Data Hasil Differencinf non-musiman dan musiman Orde 1",93)#cut off after lag 3
grid()#cut off setelag lag 2

pacf(datadiff2,main="Plot PACF Data Hasil Differencinf non-musiman dan musiman Orde 1",93)#cut off setelah lag 3
grid()

#Model SARIMA Sementara

Berdasarkan plot ACF dan PACF setelah dilakukan transformasi dan differencing (non-musiman dan musiman), diketahui bahwa ACF cut off setelah lag 1 pada non-musiman dan cut off setelah lag 2 pada musiman, maka terbentuk orde untuk MA(q) adalah 1 dan MA(Q) adalah 2. sedangkan PACF ACF cut off setelah lag 2 pada non-musiman dan cut off setelah lag 0 pada musiman, maka terbentuk orde untuk AR(p) adalah 2 dan AR(P) adalah 0 dengan differencing I(d) dan I(D) adalah 1 serta musiman pada kelipatan lag 12. Karena ACF dan PACF sama-sama cut off maka model yang terbentuk adalah ARI dan IMA, sehingga didapat model SARIMA, sebagai berikut:

  1. SARIMA(0,1,1)(0,1,1)^12

  2. SARIMA(1,1,0)(0,1,1)^12

  3. SARIMA(2,1,0)(0,1,1)^12

  4. SARIMA(0,1,1)(0,1,2)^12

  5. SARIMA(1,1,0)(0,1,2)^12

  6. SARIMA(2,1,0)(0,1,2)^12

Tahap Pendugaan dan Pengujian Signifikansi Parameter Model SARIMA sementara

Pada tahap ini, dilakukan pendugaan parameter model SARIMA (Seasonal AutoRegressive Integrated Moving Average) untuk menentukan nilai koefisien yang signifikan dengan keenam model SARIMA sementara berdasarkan plot ACF dan PACF

# Model 1 (SIG)
fit1 <- Arima(y, order = c(0,1,1), seasonal = list(order = c(0,1,1), period = 12))
summary(fit1)
## Series: y 
## ARIMA(0,1,1)(0,1,1)[12] 
## 
## Coefficients:
##           ma1     sma1
##       -0.6505  -0.3439
## s.e.   0.0612   0.1259
## 
## sigma^2 = 0.01025:  log likelihood = 116.72
## AIC=-227.44   AICc=-227.26   BIC=-218.75
## 
## Training set error measures:
##                      ME       RMSE        MAE        MPE    MAPE      MASE
## Training set -0.0079323 0.09594562 0.07145778 -0.5223005 3.56519 0.5935392
##                   ACF1
## Training set -0.028006
coeftest(fit1)
## 
## z test of coefficients:
## 
##       Estimate Std. Error  z value  Pr(>|z|)    
## ma1  -0.650496   0.061161 -10.6358 < 2.2e-16 ***
## sma1 -0.343895   0.125858  -2.7324  0.006287 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Model 2 (SIG)
fit2 <- Arima(y, order = c(1,1,0), seasonal = list(order = c(0,1,1), period = 12))
summary(fit2)
## Series: y 
## ARIMA(1,1,0)(0,1,1)[12] 
## 
## Coefficients:
##           ar1     sma1
##       -0.4538  -0.2860
## s.e.   0.0776   0.1303
## 
## sigma^2 = 0.0119:  log likelihood = 107.14
## AIC=-208.29   AICc=-208.1   BIC=-199.59
## 
## Training set error measures:
##                        ME      RMSE        MAE        MPE     MAPE      MASE
## Training set -0.004811447 0.1033652 0.07851358 -0.3477455 3.906348 0.6521458
##                    ACF1
## Training set -0.1759983
coeftest(fit2)
## 
## z test of coefficients:
## 
##       Estimate Std. Error z value  Pr(>|z|)    
## ar1  -0.453764   0.077567 -5.8499 4.917e-09 ***
## sma1 -0.286038   0.130322 -2.1948   0.02817 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Model 3 (SIG)
fit3 <- Arima(y, order = c(2,1,0), seasonal = list(order = c(0,1,1), period = 12))
summary(fit3)
## Series: y 
## ARIMA(2,1,0)(0,1,1)[12] 
## 
## Coefficients:
##           ar1      ar2     sma1
##       -0.6364  -0.3919  -0.2975
## s.e.   0.0812   0.0804   0.1228
## 
## sigma^2 = 0.01016:  log likelihood = 118.05
## AIC=-228.11   AICc=-227.8   BIC=-216.51
## 
## Training set error measures:
##                        ME       RMSE       MAE        MPE     MAPE      MASE
## Training set -0.006048226 0.09513391 0.0726006 -0.4092917 3.635256 0.6030317
##                       ACF1
## Training set -0.0005643188
coeftest(fit3)
## 
## z test of coefficients:
## 
##       Estimate Std. Error z value  Pr(>|z|)    
## ar1  -0.636415   0.081228 -7.8349 4.691e-15 ***
## ar2  -0.391931   0.080356 -4.8774 1.075e-06 ***
## sma1 -0.297514   0.122784 -2.4231   0.01539 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Model 4 (SIG)
fit4 <- Arima(y, order = c(0,1,1), seasonal = list(order = c(0,1,2), period = 12))
summary(fit4)
## Series: y 
## ARIMA(0,1,1)(0,1,2)[12] 
## 
## Coefficients:
##           ma1     sma1     sma2
##       -0.6412  -0.2967  -0.3311
## s.e.   0.0654   0.0934   0.1012
## 
## sigma^2 = 0.009266:  log likelihood = 122.06
## AIC=-236.13   AICc=-235.82   BIC=-224.54
## 
## Training set error measures:
##                        ME       RMSE        MAE        MPE     MAPE      MASE
## Training set -0.007630648 0.09087018 0.06791702 -0.5161217 3.401569 0.5641292
##                      ACF1
## Training set -0.007666995
coeftest(fit4)
## 
## z test of coefficients:
## 
##       Estimate Std. Error z value  Pr(>|z|)    
## ma1  -0.641153   0.065358 -9.8099 < 2.2e-16 ***
## sma1 -0.296715   0.093392 -3.1771  0.001488 ** 
## sma2 -0.331114   0.101198 -3.2719  0.001068 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Model 5 (SIG)
fit5 <- Arima(y, order = c(1,1,0), seasonal = list(order = c(0,1,2), period = 12))
summary(fit5)
## Series: y 
## ARIMA(1,1,0)(0,1,2)[12] 
## 
## Coefficients:
##           ar1     sma1     sma2
##       -0.4501  -0.2346  -0.3787
## s.e.   0.0778   0.0944   0.1021
## 
## sigma^2 = 0.01049:  log likelihood = 113.83
## AIC=-219.66   AICc=-219.35   BIC=-208.07
## 
## Training set error measures:
##                        ME      RMSE        MAE        MPE    MAPE      MASE
## Training set -0.004984201 0.0966856 0.07353446 -0.3578654 3.66955 0.6107885
##                    ACF1
## Training set -0.1481796
coeftest(fit5)
## 
## z test of coefficients:
## 
##      Estimate Std. Error z value  Pr(>|z|)    
## ar1  -0.45011    0.07778 -5.7869 7.169e-09 ***
## sma1 -0.23461    0.09438 -2.4858 0.0129247 *  
## sma2 -0.37870    0.10212 -3.7082 0.0002088 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Model 6 (SIG)
fit6 <- Arima(y, order = c(2,1,0), seasonal = list(order = c(0,1,2), period = 12))
summary(fit6)
## Series: y 
## ARIMA(2,1,0)(0,1,2)[12] 
## 
## Coefficients:
##           ar1      ar2     sma1     sma2
##       -0.6107  -0.3517  -0.2711  -0.2763
## s.e.   0.0830   0.0836   0.0919   0.0976
## 
## sigma^2 = 0.009464:  log likelihood = 122.02
## AIC=-234.05   AICc=-233.58   BIC=-219.56
## 
## Training set error measures:
##                        ME       RMSE        MAE        MPE   MAPE      MASE
## Training set -0.005981758 0.09148652 0.07027108 -0.4136504 3.5171 0.5836824
##                      ACF1
## Training set -0.002220329
coeftest(fit6)
## 
## z test of coefficients:
## 
##       Estimate Std. Error z value  Pr(>|z|)    
## ar1  -0.610750   0.082981 -7.3601 1.837e-13 ***
## ar2  -0.351692   0.083568 -4.2084 2.571e-05 ***
## sma1 -0.271116   0.091945 -2.9487  0.003191 ** 
## sma2 -0.276310   0.097602 -2.8310  0.004641 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Berdasarkan hasil pengujian signifikansi parameter pada keenam model SARIMA diketahui bahwa semuaa model signifikan sehingga dapat dilakukan pengujian selanjutnya yaitu tahap pengujian diagnostik model.

Pengujian Diagnostik Model SARIMA Sementara

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

#uji normalitas residuals dan white noise
#Model 1 (NOWN+NORMAL)
#Normalitas
res1=resid(fit1)
shapiro.test(res1)
## 
##  Shapiro-Wilk normality test
## 
## data:  res1
## W = 0.98627, p-value = 0.1533
lillie.test(res1)
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  res1
## D = 0.067948, p-value = 0.09354
ks.test(res1,"pnorm",mean(res1),sqrt(var(res1)))
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  res1
## D = 0.067948, p-value = 0.5059
## alternative hypothesis: two-sided
#White noise
x<-res1
pv2<-rep(1,length(x))
for(i in 1:length(x))
  pv2[i]=Box.test(x,lag=i,type="Ljung")$p.value
plot(pv2,type="p",main="Ljung-Box Model ARIMA(0,1,1)(0,1,1)^12",xlab="lag",ylab="p value",ylim=c(0,1))
abline(h=0.05,lty=1,col="red")

Box.test(res1, lag=11, type="Ljung" )
## 
##  Box-Ljung test
## 
## data:  res1
## X-squared = 28.821, df = 11, p-value = 0.002419
#Model 2 (NOWN+NORMAL)
#Normalitas
res2=resid(fit2)
shapiro.test(res2)
## 
##  Shapiro-Wilk normality test
## 
## data:  res2
## W = 0.99204, p-value = 0.584
lillie.test(res2)
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  res2
## D = 0.073072, p-value = 0.0528
ks.test(res2,"pnorm",mean(res2),sqrt(var(res2)))
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  res2
## D = 0.073072, p-value = 0.4124
## alternative hypothesis: two-sided
#White noise
x<-res2
pv2<-rep(1,length(x))
for(i in 1:length(x))
  pv2[i]=Box.test(x,lag=i,type="Ljung")$p.value
plot(pv2,type="p",main="Ljung-Box Model ARIMA(1,1,0)(0,1,1)^12",xlab="lag",ylab="p value",ylim=c(0,1))
abline(h=0.05,lty=1,col="red")

#Model 3 (WN+NORMAL)
#Normalitas
res3=resid(fit3)
shapiro.test(res3)
## 
##  Shapiro-Wilk normality test
## 
## data:  res3
## W = 0.99099, p-value = 0.4732
lillie.test(res3)
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  res3
## D = 0.046684, p-value = 0.6035
ks.test(res3,"pnorm",mean(res3),sqrt(var(res3)))
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  res3
## D = 0.046684, p-value = 0.9058
## alternative hypothesis: two-sided
#White noise
x<-res3
pv2<-rep(1,length(x))
for(i in 1:length(x))
  pv2[i]=Box.test(x,lag=i,type="Ljung")$p.value
plot(pv2,type="p",main="Ljung-Box Model ARIMA(2,1,0)(0,1,1)^12",xlab="lag",ylab="p value",ylim=c(0,1))
abline(h=0.05,lty=1,col="red")

#Model 4 (NOWN+NORMAL)
#Normalitas
res4=resid(fit4)
shapiro.test(res4)
## 
##  Shapiro-Wilk normality test
## 
## data:  res4
## W = 0.98586, p-value = 0.1382
lillie.test(res4)
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  res4
## D = 0.062846, p-value = 0.1665
ks.test(res4,"pnorm",mean(res4),sqrt(var(res4)))
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  res4
## D = 0.062846, p-value = 0.6071
## alternative hypothesis: two-sided
#white noise
x<-res4
pv2<-rep(1,length(x))
for(i in 1:length(x))
  pv2[i]=Box.test(x,lag=i,type="Ljung")$p.value
plot(pv2,type="p",main="Ljung-Box Model ARIMA(0,1,1)(0,1,2)^12",xlab="lag",ylab="p value",ylim=c(0,1))
abline(h=0.05,lty=1,col="red")

#Model 5 (NOWN+NORMAL)
#normalitas 
res5=resid(fit5)
shapiro.test(res5)
## 
##  Shapiro-Wilk normality test
## 
## data:  res5
## W = 0.98764, p-value = 0.2164
lillie.test(res5)
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  res5
## D = 0.075714, p-value = 0.03848
ks.test(res5,"pnorm",mean(res5),sqrt(var(res5)))
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  res5
## D = 0.075714, p-value = 0.3684
## alternative hypothesis: two-sided
#white noise
x<-res5
pv2<-rep(1,length(x))
for(i in 1:length(x))
  pv2[i]=Box.test(x,lag=i,type="Ljung")$p.value
plot(pv2,type="p",main="Ljung-Box Model ARIMA(1,1,0)(0,1,2)^12",xlab="lag",ylab="p value",ylim=c(0,1))
abline(h=0.05,lty=1,col="red")

#Model 6 (NOWN+NORMAL) (KALAU PAKAI ALPHA 0,01 MODEL 6 WN)
#Normalitas
res6=resid(fit6)
shapiro.test(res6)
## 
##  Shapiro-Wilk normality test
## 
## data:  res6
## W = 0.98964, p-value = 0.3505
lillie.test(res6)
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  res6
## D = 0.053873, p-value = 0.3717
ks.test(res6,"pnorm",mean(res6),sqrt(var(res6)))
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  res6
## D = 0.053873, p-value = 0.7871
## alternative hypothesis: two-sided
#White Noise
x<-res6
pv2<-rep(1,length(x))
for(i in 1:length(x))
  pv2[i]=Box.test(x,lag=i,type="Ljung")$p.value
plot(pv2,type="p",main="Ljung-Box Model ARIMA(2,1,0)(0,1,2)^12",xlab="lag",ylab="p value",ylim=c(0,1))
abline(h=0.05,lty=1,col="red")

Box.test(res6, lag=11, type="Ljung" )
## 
##  Box-Ljung test
## 
## data:  res6
## X-squared = 21.961, df = 11, p-value = 0.02468

Berdasarkan hasil pengujian normalitas residual, diketahui bahwa keenam model memiliki nilai p-value lebih dari taraf signifikansi sebesar 0,05. Sehingga disimpulkan bahwa keenam model memiliki residual yang mengikuti distribusi normal dan dapat dilanjutkan dengan pengujian white noise.

Berdasarkan hasil grafik Ljung Box keenam model, diperoleh bahwa hanya fit3 yang memenuhi syarat white noise karena nilai p-value pada setiap lag lebih besar dari 0,05 yang berada di atas garis batas signifikansi 0,05. Sehingga model SARIMA(2,1,0)(0,1,1)^12 merupakan model terbaik, karena model tersebut memenuhi seluruh asumsi. Maka model tersebut yang akan terpilih menjadi model untuk prediksi dan peramalan.

Pemilihan Model Terbaik

Pemilihan Model Terbaik diperoleh dari model sementara yang signifikan dan asumsi diagnostik yang terpenuhi yaitu normalitas dan white noise

summary(fit3)
## Series: y 
## ARIMA(2,1,0)(0,1,1)[12] 
## 
## Coefficients:
##           ar1      ar2     sma1
##       -0.6364  -0.3919  -0.2975
## s.e.   0.0812   0.0804   0.1228
## 
## sigma^2 = 0.01016:  log likelihood = 118.05
## AIC=-228.11   AICc=-227.8   BIC=-216.51
## 
## Training set error measures:
##                        ME       RMSE       MAE        MPE     MAPE      MASE
## Training set -0.006048226 0.09513391 0.0726006 -0.4092917 3.635256 0.6030317
##                       ACF1
## Training set -0.0005643188

Diperoleh model SARIMA(2,1,0)(0,1,1)^12 sebagai model SARIMA terbaik karena model tersebut signifikan dan memenuhi asumsi diagnostik. Sehingga model tersebut dilanjutkan untuk mencari nilai prediksi dan peramalan.

Prediksi Model SARIMA Terbaik pada Data In Sample dan Out Sample

# Gunakan model terbaik (fit3) untuk prediksi
model <- fit3  # model ARIMA(2,1,0)(0,1,1)[12]

Prediksi Data In Sample

# Prediksi in-sample
in_sample_pred <- fitted(model)
in_sample_pred_inv <- (in_sample_pred)^(1/(p$lambda))
in_sample_pred_inv
## Time Series:
## Start = 1 
## End = 147 
## Frequency = 1 
##   [1]  10.968649   8.989472  10.990083  10.992608   7.997805   6.000183
##   [7]   5.001000   6.999005  11.992846  14.989198  21.978931  16.028794
##  [13]  23.281418  18.346100  19.182423  17.421957  10.776376   8.201902
##  [19]   6.468138  10.768426  16.829217  22.121041  31.939069  23.030425
##  [25]  30.424990  22.968929  21.208487  17.558097  16.573064   8.077761
##  [31]   9.973098  14.484600  22.212087  23.779249  29.362139  22.823945
##  [37]  37.455938  25.327020  20.101296  21.533327  15.997717   9.374538
##  [43]  10.578358  10.830169  19.347908  22.917849  41.567446  40.510983
##  [49]  59.107092  31.060168  21.637676  19.631557  21.177167  14.965233
##  [55]  10.684967  24.540068  26.065404  31.718023  59.737139  60.285946
##  [61]  57.948982  40.252771  26.007104  26.611025  25.850586  13.964713
##  [67]  12.100374  32.799173  30.383973  38.022479  60.365390  45.528659
##  [73]  30.846185  29.650008  20.115002  21.490762  18.778849  10.057284
##  [79]  13.274530  22.297248  24.207462  40.331739  40.085556  37.559611
##  [85]  31.736261  48.949106  25.296726  22.888035  17.929793   9.707191
##  [91]  14.811685  22.360444  39.518849  42.409845  55.255060  39.526625
##  [97]  37.033335  48.318897  28.180419  31.319504  17.002158  11.438433
## [103]  13.341090  30.409850  43.968754  56.480972  58.480182  39.776082
## [109]  45.654831  43.419081  45.790863  44.783385  31.919200  23.104392
## [115]  49.651517  78.683411  99.647493  83.896396  83.364762  71.762468
## [121] 101.179878  73.570165  91.652116  78.174231  47.738323  42.665829
## [127]  38.099380  65.623656  94.232173  65.110888  56.792276  73.577144
## [133]  63.199003  74.260211  65.106740  40.801893  28.603899  46.243030
## [139]  19.218792  52.061541  58.387618  38.978849  56.365626  51.684002
## [145]  59.025247  65.899811  62.275568

Prediksi Data Out Sample

# Prediksi out-sample (forecast setelah in-sample)
out_sample_pred <- predict(model, n.ahead = length(out_sample))
out_sample_pred_inv <- (out_sample_pred$pred)^(1/(p$lambda))
out_sample_pred_inv 
## Time Series:
## Start = 148 
## End = 173 
## Frequency = 1 
##  [1] 28.97317 24.58662 24.29994 15.66155 38.92408 50.68166 44.23981 41.38243
##  [9] 37.62765 43.84178 55.06066 45.05304 23.02372 19.43651 19.52728 12.16664
## [17] 31.60515 41.75472 36.15305 33.73174 30.57419 35.83089 45.42211 36.87281
## [25] 18.28597 15.31079

Peramalan

Melakukan peramalan untuk 12 periode kedepan dari model terbaik. Sehingga didapatkan peramalan (forecasting ) dari model terbaik adalah sebagai berikut:

# Peramalan 12 periode ke depan
full_series <- c(in_sample, out_sample)
model_full <- Arima(full_series^(p$lambda), order = c(2,1,0), seasonal = list(order = c(0,1,1), period = 12))
forecast_12 <- predict(model_full, n.ahead = 12)
forecast_12_inv <- (forecast_12$pred)^(1/(p$lambda))
forecast_12_inv
## Time Series:
## Start = 174 
## End = 185 
## Frequency = 1 
##  [1] 25.58666 24.00663 34.24341 49.93167 41.09952 43.89049 54.02639 44.02685
##  [9] 37.31507 28.02376 23.96618 26.74545

Plot Perbandingan

Membuat plot perbandingan antara data aktual, hasil prediksi pada data In Sample dan Out Sample, serta hasil forecasting, bertujuan untuk melihat apakah model yang digunakan sudah sesuai, sehingga nilai prediksi hasil tidak jauh berbeda dengan data aktual dan menghasilkan peramalan periode kedepannya secara akurat.

# Buat vektor gabungan untuk plotting
gabungan_aktual <- c(in_sample, out_sample)
gabungan_prediksi <- c(in_sample_pred_inv, out_sample_pred_inv)
gabungan_forecast <- forecast_12_inv

# Buat indeks periode
periode_aktual <- 1:length(gabungan_aktual)
periode_prediksi <- 1:length(gabungan_prediksi)
periode_forecast <- (length(gabungan_aktual) + 1):(length(gabungan_aktual) + length(gabungan_forecast))

# Plot
plot(Zt, type = "o", col = "black", pch = 16, lwd = 2.5,
     ylim = c(0, max(c(gabungan_aktual, gabungan_prediksi, gabungan_forecast)) + 10),
     xlab = "Periode", ylab = "Jumlah Pencarian Kata Kunci 'Musim Hujan'",
     main = "Grafik Prediksi dan Peramalan Kata Pencarian Musim Hujan")

# Tambahkan komponen lainnya
points(periode_prediksi, gabungan_prediksi, type = "o", col = "blue", pch = 19, lwd = 0.5)# In-sample prediksi
points((length(in_sample)+1):length(gabungan_prediksi), out_sample_pred_inv, type = "o", col = "red", pch = 19, lwd = 2)  # Out-sample prediksi
points(periode_forecast, gabungan_forecast, type = "o", col = "green", pch = 17, lwd = 2)# Forecast 12 ke depan

# Legenda
legend("topleft",
       legend = c("Aktual", "Prediksi In sample ", "Prediksi Out sample ", "Peralaman"),
       col = c("black", "blue", "red", "green"),
       lty = 1, lwd = 2, pch = c(16, 19, 19, 19))

Berdasarkan Plot perbandingan di atas, terlihat bahwa model cukup baik dalam menangkap pola tren dan musiman pada data In Sample, meskipun terdapat sedikit deviasi pada prediksi data Out Sample. Hasil peramalan menunjukkan pola musiman yang berulang, mengindikasikan bahwa model dapat digunakan untuk prediksi jangka pendek dengan kewaspadaan terhadap potensi ketidaksesuaian pada data baru.

Akurasi Model SARIMA Terbaik

Model SARIMA terbaik yang digunakan dalam analisis ini dievaluasi berdasarkan beberapa metrik akurasi, termasuk MAPE (Mean Absolute Percentage Error), RMSE (Root Mean Square Error), dan SMAPE (Symmetric Mean Absolute Percentage Error). Digunakan untuk menilai seberapa baik model dapat menyesuaikan pola data historis serta memprediksi nilai di masa depan.

# Akurasi untuk prediksi insample
aktual_in_sample <- in_sample
prediksi_in_sample <- in_sample_pred_inv

RMSE_in_sample = RMSE(aktual_in_sample,prediksi_in_sample)
MAPE_in_sample = MAPE(aktual_in_sample,prediksi_in_sample)*100
SMAPE_in_sample = smape(prediksi_in_sample,aktual_in_sample)*100


cat("Akurasi pada data in_sample (fitted):\n")
## Akurasi pada data in_sample (fitted):
cat("RMSE =", RMSE_in_sample, "\n")
## RMSE = 9.091953
cat("MAPE =", MAPE_in_sample, "\n")
## MAPE = 18.02031
cat("SMAPE =", SMAPE_in_sample, "\n\n")
## SMAPE = 17.72477
#Akurasi untuk prediksi Outsample (forecast)
aktual_out_sample <- out_sample
prediksi_out_sample <- out_sample_pred_inv 


RMSE_out_sample = RMSE(aktual_out_sample ,prediksi_out_sample )
MAPE_out_sample  = MAPE(aktual_out_sample ,prediksi_out_sample )*100
SMAPE_out_sample  = smape(prediksi_out_sample ,aktual_out_sample )*100


cat("Akurasi pada data out_sample (fitted):\n")
## Akurasi pada data out_sample (fitted):
cat("RMSE =", RMSE_out_sample , "\n")
## RMSE = 12.72845
cat("MAPE =", MAPE_out_sample , "\n")
## MAPE = 37.66723
cat("SMAPE =", SMAPE_out_sample , "\n\n")
## SMAPE = 30.57014
# Buat Data Frame Komparasi
akurasi_df <- data.frame(
  Dataset = c("In-Sample", "Out-Sample"),
  RMSE = c(RMSE_in_sample, RMSE_out_sample),
  MAPE = c(MAPE_in_sample, MAPE_out_sample),
  SMAPE = c(SMAPE_in_sample, SMAPE_out_sample)
)

akurasi_df %>%
  kbl(caption = "📊 Tabel Komparasi Akurasi Prediksi", digits = 2) %>%
  kable_styling("striped", full_width = F) %>%
  row_spec(0, bold = TRUE,  background = "steelblue")
📊 Tabel Komparasi Akurasi Prediksi
Dataset RMSE MAPE SMAPE
In-Sample 9.09 18.02 17.72
Out-Sample 12.73 37.67 30.57

Berdasarkan Tabel Komparasi Akurasi Prediksi, model menunjukkan performa yang baik, dengan nilai error yang masih dalam batas wajar pada data In Sample dan Out Sample. Nilai RMSE, MAPE, dan SMAPE pada data In Sample masing-masing sebesar 9.09, 18.02%, dan 17.72%, sementara pada data Out Sample sebesar 12.73, 37.67%, dan 30.57%. Perbedaan ini menunjukkan bahwa model mampu menyesuaikan diri dengan baik terhadap data historis sekaligus tetap memberikan hasil prediksi yang cukup akurat saat diuji pada data baru. Dengan demikian, model yang digunakan dapat dikatakan sudah sesuai dan cukup andal untuk kebutuhan peramalan.

NEURAL NETWORK

Neural Network merupakan salah satu teknik dalam algoritma machine learning yang terinspirasi dari cara kerja otak manusia dalam memproses informasi. Secara umum, model Neural Network terdiri atas input layerhidden layer, dan output layer dengan fungsi aktiviasi di dalamnya. Metode ini menggunakan algoritma yang dapat melakukan prediksi maupun klasifikasi pada data input hingga diperoleh output yang mampu merepresentasikan keadaan sesungguhnya (Nielsen 2015).

Import Library

library(neuralnet)
## Warning: package 'neuralnet' was built under R version 4.4.3
library(forecast)

Import Data

data=read.csv(file.choose(),header = T,sep = ";")
Zt <- ts(data$musim.hujan, start = c(2011, 1), frequency = 12)

Pra-processing Data

Standarisasi Data

Standarisasi data pada tahap pra-pemrosesan dalam neural network dilakukan agar semua fitur memiliki skala yang seragam, biasanya dengan rata-rata 0 dan standar deviasi 1. Hal ini penting karena dapat mempercepat proses pelatihan, mencegah dominasi fitur dengan skala besar, dan menjaga kestabilan fungsi aktivasi seperti sigmoid atau tanh. Dengan data yang terstandarisasi, jaringan saraf dapat belajar lebih efisien dan akurat, serta menghindari masalah seperti vanishing gradient.

max_asli = max(Zt)
min_asli = min(Zt)
data_standarisasi = 2*((as.numeric(Zt) - min_asli)/(max_asli - min_asli))-1
data_standarisasi
##   [1] -0.87368421 -0.91578947 -0.87368421 -0.87368421 -0.93684211 -0.97894737
##   [7] -1.00000000 -0.95789474 -0.85263158 -0.78947368 -0.64210526 -0.76842105
##  [13] -0.62105263 -0.78947368 -0.83157895 -0.85263158 -0.81052632 -0.95789474
##  [19] -0.93684211 -0.85263158 -0.72631579 -0.66315789 -0.49473684 -0.60000000
##  [25] -0.34736842 -0.68421053 -0.83157895 -0.74736842 -0.81052632 -0.89473684
##  [31] -0.85263158 -0.83157895 -0.76842105 -0.68421053 -0.47368421 -0.43157895
##  [37] -0.11578947 -0.57894737 -0.78947368 -0.78947368 -0.83157895 -0.89473684
##  [43] -0.95789474 -0.62105263 -0.62105263 -0.60000000 -0.11578947 -0.11578947
##  [49] -0.28421053 -0.32631579 -0.64210526 -0.62105263 -0.70526316 -0.89473684
##  [55] -0.87368421 -0.49473684 -0.47368421 -0.32631579  0.22105263  0.01052632
##  [61] -0.32631579 -0.03157895 -0.45263158 -0.55789474 -0.68421053 -0.87368421
##  [67] -0.74736842 -0.60000000 -0.51578947 -0.20000000 -0.34736842 -0.51578947
##  [73] -0.49473684 -0.13684211 -0.55789474 -0.62105263 -0.72631579 -0.91578947
##  [79] -0.83157895 -0.66315789 -0.34736842 -0.34736842 -0.13684211 -0.36842105
##  [85] -0.41052632 -0.30526316 -0.53684211 -0.53684211 -0.74736842 -0.87368421
##  [91] -0.81052632 -0.45263158 -0.30526316 -0.15789474 -0.07368421 -0.32631579
##  [97] -0.11578947 -0.41052632 -0.38947368 -0.55789474 -0.76842105 -0.89473684
## [103] -0.68421053 -0.26315789 -0.11578947 -0.15789474 -0.15789474 -0.17894737
## [109]  0.34736842  0.03157895  0.09473684  0.07368421 -0.34736842 -0.13684211
## [115] -0.36842105  0.32631579  0.83157895  0.43157895  0.24210526  0.76842105
## [121]  0.62105263  1.00000000  0.81052632 -0.15789474 -0.41052632  0.11578947
## [127] -0.57894737  0.26315789  0.66315789 -0.11578947  0.28421053  0.07368421
## [133]  0.15789474  0.57894737  0.49473684 -0.36842105 -0.41052632 -0.49473684
## [139] -0.68421053 -0.11578947  0.17894737  0.17894737 -0.03157895 -0.13684211
## [145]  0.05263158  0.32631579  0.01052632 -0.55789474 -0.24210526 -0.49473684
## [151] -0.60000000 -0.28421053  0.36842105  0.36842105  0.05263158 -0.01052632
## [157]  0.13684211 -0.22105263 -0.38947368 -0.66315789 -0.47368421 -0.49473684
## [163] -0.57894737 -0.34736842 -0.05263158 -0.30526316 -0.15789474  0.15789474
## [169] -0.17894737 -0.30526316 -0.51578947 -0.53684211 -0.51578947

Penentuan Lag Signifikan

Menentukan input dan Output

acf(data_standarisasi,200)

pacf(data_standarisasi,200)

library(dplyr)
## 
## Attaching package: 'dplyr'
## The following object is masked from 'package:neuralnet':
## 
##     compute
## The following object is masked from 'package:kableExtra':
## 
##     group_rows
## 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
y <- data.frame(nilai_asli = data_standarisasi) %>%
  mutate(
    lag1 = lag(nilai_asli, 1),
    lag12 = lag(nilai_asli, 12)
  ) %>%
  na.omit()  # hapus baris dengan NA
y
##      nilai_asli        lag1       lag12
## 13  -0.62105263 -0.76842105 -0.87368421
## 14  -0.78947368 -0.62105263 -0.91578947
## 15  -0.83157895 -0.78947368 -0.87368421
## 16  -0.85263158 -0.83157895 -0.87368421
## 17  -0.81052632 -0.85263158 -0.93684211
## 18  -0.95789474 -0.81052632 -0.97894737
## 19  -0.93684211 -0.95789474 -1.00000000
## 20  -0.85263158 -0.93684211 -0.95789474
## 21  -0.72631579 -0.85263158 -0.85263158
## 22  -0.66315789 -0.72631579 -0.78947368
## 23  -0.49473684 -0.66315789 -0.64210526
## 24  -0.60000000 -0.49473684 -0.76842105
## 25  -0.34736842 -0.60000000 -0.62105263
## 26  -0.68421053 -0.34736842 -0.78947368
## 27  -0.83157895 -0.68421053 -0.83157895
## 28  -0.74736842 -0.83157895 -0.85263158
## 29  -0.81052632 -0.74736842 -0.81052632
## 30  -0.89473684 -0.81052632 -0.95789474
## 31  -0.85263158 -0.89473684 -0.93684211
## 32  -0.83157895 -0.85263158 -0.85263158
## 33  -0.76842105 -0.83157895 -0.72631579
## 34  -0.68421053 -0.76842105 -0.66315789
## 35  -0.47368421 -0.68421053 -0.49473684
## 36  -0.43157895 -0.47368421 -0.60000000
## 37  -0.11578947 -0.43157895 -0.34736842
## 38  -0.57894737 -0.11578947 -0.68421053
## 39  -0.78947368 -0.57894737 -0.83157895
## 40  -0.78947368 -0.78947368 -0.74736842
## 41  -0.83157895 -0.78947368 -0.81052632
## 42  -0.89473684 -0.83157895 -0.89473684
## 43  -0.95789474 -0.89473684 -0.85263158
## 44  -0.62105263 -0.95789474 -0.83157895
## 45  -0.62105263 -0.62105263 -0.76842105
## 46  -0.60000000 -0.62105263 -0.68421053
## 47  -0.11578947 -0.60000000 -0.47368421
## 48  -0.11578947 -0.11578947 -0.43157895
## 49  -0.28421053 -0.11578947 -0.11578947
## 50  -0.32631579 -0.28421053 -0.57894737
## 51  -0.64210526 -0.32631579 -0.78947368
## 52  -0.62105263 -0.64210526 -0.78947368
## 53  -0.70526316 -0.62105263 -0.83157895
## 54  -0.89473684 -0.70526316 -0.89473684
## 55  -0.87368421 -0.89473684 -0.95789474
## 56  -0.49473684 -0.87368421 -0.62105263
## 57  -0.47368421 -0.49473684 -0.62105263
## 58  -0.32631579 -0.47368421 -0.60000000
## 59   0.22105263 -0.32631579 -0.11578947
## 60   0.01052632  0.22105263 -0.11578947
## 61  -0.32631579  0.01052632 -0.28421053
## 62  -0.03157895 -0.32631579 -0.32631579
## 63  -0.45263158 -0.03157895 -0.64210526
## 64  -0.55789474 -0.45263158 -0.62105263
## 65  -0.68421053 -0.55789474 -0.70526316
## 66  -0.87368421 -0.68421053 -0.89473684
## 67  -0.74736842 -0.87368421 -0.87368421
## 68  -0.60000000 -0.74736842 -0.49473684
## 69  -0.51578947 -0.60000000 -0.47368421
## 70  -0.20000000 -0.51578947 -0.32631579
## 71  -0.34736842 -0.20000000  0.22105263
## 72  -0.51578947 -0.34736842  0.01052632
## 73  -0.49473684 -0.51578947 -0.32631579
## 74  -0.13684211 -0.49473684 -0.03157895
## 75  -0.55789474 -0.13684211 -0.45263158
## 76  -0.62105263 -0.55789474 -0.55789474
## 77  -0.72631579 -0.62105263 -0.68421053
## 78  -0.91578947 -0.72631579 -0.87368421
## 79  -0.83157895 -0.91578947 -0.74736842
## 80  -0.66315789 -0.83157895 -0.60000000
## 81  -0.34736842 -0.66315789 -0.51578947
## 82  -0.34736842 -0.34736842 -0.20000000
## 83  -0.13684211 -0.34736842 -0.34736842
## 84  -0.36842105 -0.13684211 -0.51578947
## 85  -0.41052632 -0.36842105 -0.49473684
## 86  -0.30526316 -0.41052632 -0.13684211
## 87  -0.53684211 -0.30526316 -0.55789474
## 88  -0.53684211 -0.53684211 -0.62105263
## 89  -0.74736842 -0.53684211 -0.72631579
## 90  -0.87368421 -0.74736842 -0.91578947
## 91  -0.81052632 -0.87368421 -0.83157895
## 92  -0.45263158 -0.81052632 -0.66315789
## 93  -0.30526316 -0.45263158 -0.34736842
## 94  -0.15789474 -0.30526316 -0.34736842
## 95  -0.07368421 -0.15789474 -0.13684211
## 96  -0.32631579 -0.07368421 -0.36842105
## 97  -0.11578947 -0.32631579 -0.41052632
## 98  -0.41052632 -0.11578947 -0.30526316
## 99  -0.38947368 -0.41052632 -0.53684211
## 100 -0.55789474 -0.38947368 -0.53684211
## 101 -0.76842105 -0.55789474 -0.74736842
## 102 -0.89473684 -0.76842105 -0.87368421
## 103 -0.68421053 -0.89473684 -0.81052632
## 104 -0.26315789 -0.68421053 -0.45263158
## 105 -0.11578947 -0.26315789 -0.30526316
## 106 -0.15789474 -0.11578947 -0.15789474
## 107 -0.15789474 -0.15789474 -0.07368421
## 108 -0.17894737 -0.15789474 -0.32631579
## 109  0.34736842 -0.17894737 -0.11578947
## 110  0.03157895  0.34736842 -0.41052632
## 111  0.09473684  0.03157895 -0.38947368
## 112  0.07368421  0.09473684 -0.55789474
## 113 -0.34736842  0.07368421 -0.76842105
## 114 -0.13684211 -0.34736842 -0.89473684
## 115 -0.36842105 -0.13684211 -0.68421053
## 116  0.32631579 -0.36842105 -0.26315789
## 117  0.83157895  0.32631579 -0.11578947
## 118  0.43157895  0.83157895 -0.15789474
## 119  0.24210526  0.43157895 -0.15789474
## 120  0.76842105  0.24210526 -0.17894737
## 121  0.62105263  0.76842105  0.34736842
## 122  1.00000000  0.62105263  0.03157895
## 123  0.81052632  1.00000000  0.09473684
## 124 -0.15789474  0.81052632  0.07368421
## 125 -0.41052632 -0.15789474 -0.34736842
## 126  0.11578947 -0.41052632 -0.13684211
## 127 -0.57894737  0.11578947 -0.36842105
## 128  0.26315789 -0.57894737  0.32631579
## 129  0.66315789  0.26315789  0.83157895
## 130 -0.11578947  0.66315789  0.43157895
## 131  0.28421053 -0.11578947  0.24210526
## 132  0.07368421  0.28421053  0.76842105
## 133  0.15789474  0.07368421  0.62105263
## 134  0.57894737  0.15789474  1.00000000
## 135  0.49473684  0.57894737  0.81052632
## 136 -0.36842105  0.49473684 -0.15789474
## 137 -0.41052632 -0.36842105 -0.41052632
## 138 -0.49473684 -0.41052632  0.11578947
## 139 -0.68421053 -0.49473684 -0.57894737
## 140 -0.11578947 -0.68421053  0.26315789
## 141  0.17894737 -0.11578947  0.66315789
## 142  0.17894737  0.17894737 -0.11578947
## 143 -0.03157895  0.17894737  0.28421053
## 144 -0.13684211 -0.03157895  0.07368421
## 145  0.05263158 -0.13684211  0.15789474
## 146  0.32631579  0.05263158  0.57894737
## 147  0.01052632  0.32631579  0.49473684
## 148 -0.55789474  0.01052632 -0.36842105
## 149 -0.24210526 -0.55789474 -0.41052632
## 150 -0.49473684 -0.24210526 -0.49473684
## 151 -0.60000000 -0.49473684 -0.68421053
## 152 -0.28421053 -0.60000000 -0.11578947
## 153  0.36842105 -0.28421053  0.17894737
## 154  0.36842105  0.36842105  0.17894737
## 155  0.05263158  0.36842105 -0.03157895
## 156 -0.01052632  0.05263158 -0.13684211
## 157  0.13684211 -0.01052632  0.05263158
## 158 -0.22105263  0.13684211  0.32631579
## 159 -0.38947368 -0.22105263  0.01052632
## 160 -0.66315789 -0.38947368 -0.55789474
## 161 -0.47368421 -0.66315789 -0.24210526
## 162 -0.49473684 -0.47368421 -0.49473684
## 163 -0.57894737 -0.49473684 -0.60000000
## 164 -0.34736842 -0.57894737 -0.28421053
## 165 -0.05263158 -0.34736842  0.36842105
## 166 -0.30526316 -0.05263158  0.36842105
## 167 -0.15789474 -0.30526316  0.05263158
## 168  0.15789474 -0.15789474 -0.01052632
## 169 -0.17894737  0.15789474  0.13684211
## 170 -0.30526316 -0.17894737 -0.22105263
## 171 -0.51578947 -0.30526316 -0.38947368
## 172 -0.53684211 -0.51578947 -0.66315789
## 173 -0.51578947 -0.53684211 -0.47368421

Splitting Data

Sama halnya dengan model SARIMA, pada neural network dilakukan tahap splitting data dengan rasio 85% untuk data training dan 15% untuk testing dapat ditulis sebagai 85:15.

nn_insample = y[1:length(in_sample),]
nn_insample = na.omit(nn_insample)
nn_outsample = y[length(in_sample)+1:173,]
nn_outsample = nn_outsample[1:14,]
cat("In-sample (85%) :", NROW(nn_insample), "\n")
## In-sample (85%) : 147
cat("Out-sample (15%):", NROW(nn_outsample), "\n")
## Out-sample (15%): 14

Pemodelan Neural Network

Model Neural Network dengan 1 Hidden layer dan 1 Neuron (N(1))

### *Neural network* 1 *hidden layer*
attach(nn_insample)
attach(nn_outsample)
## The following objects are masked from nn_insample:
## 
##     lag1, lag12, nilai_asli
set.seed(1231)
mlp_1_1 = neuralnet(nilai_asli~lag1+lag12, data=nn_insample, hidden=1, act.fct="tanh", linear.output = TRUE, learningrate = 0.005, stepmax = 10000, startweights = NULL, threshold = 0.005, algorithm = "rprop+")
plot(mlp_1_1)

Model Neural Network dengan 1 Hidden layer dan 2 Neuron (N(2))

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

Model Neural Network dengan 1 Hidden layer dan 3 Neuron (N(3))

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

Model Neural Network dengan 2 Hidden layer dan 1 Neuron pada Hidden Layer 1 dan 1 Neuron pada Hidden Layer 2 (N(1,1))

### *Neural network* 2 *hidden layer*
set.seed(1233)
mlp_2_1_1 = neuralnet(nilai_asli~lag1+lag12, data=nn_insample, 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)

Model Neural Network dengan 2 Hidden layer dan 1 Neuron pada Hidden Layer 1 dan 1 Neuron pada Hidden Layer 2 (N(1,1))

set.seed(1234)
mlp_2_1_2 = neuralnet(nilai_asli~lag1+lag12, data=nn_insample, 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)

Model Neural Network dengan 2 Hidden layer dan 1 Neuron pada Hidden Layer 1 dan 3 Neuron pada Hidden Layer 2 (N(1,3))

set.seed(1235)
mlp_2_1_3 = neuralnet(nilai_asli~lag1+lag12, data=nn_insample, 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)

Model Neural Network dengan 2 Hidden layer dan 2 Neuron pada Hidden Layer 1 dan 1 Neuron pada Hidden Layer 2 (N(2,1))

set.seed(1236)
mlp_2_2_1 = neuralnet(nilai_asli~lag1+lag12, data=nn_insample, hidden=c(2,1), act.fct="tanh", linear.output = TRUE, learningrate = 0.05, stepmax = 10000, startweights = NULL, threshold = 0.05, algorithm = "rprop+")
plot(mlp_2_2_1)

Model Neural Network dengan 2 Hidden layer dan 2 Neuron pada Hidden Layer 1 dan 2 Neuron pada Hidden Layer 2 (N(2,2))

set.seed(1237)
mlp_2_2_2 = neuralnet(nilai_asli~lag1+lag12, data=nn_insample, hidden=c(2,2), act.fct="tanh", linear.output = TRUE, learningrate = 0.05, stepmax = 10000, startweights = NULL, threshold = 0.05, algorithm = "rprop+")
plot(mlp_2_2_2)

Model Neural Network dengan 2 Hidden layer dan 2 Neuron pada Hidden Layer 1 dan 3 Neuron pada Hidden Layer 2 (N(2,3))

set.seed(1238)
mlp_2_2_3 = neuralnet(nilai_asli~lag1+lag12, data=nn_insample, hidden=c(2,3), act.fct="tanh", linear.output = TRUE, learningrate = 0.05, stepmax = 10000, startweights = NULL, threshold = 0.05, algorithm = "rprop+")
plot(mlp_2_2_3)

Prediksi Model Neural Network

Model N(1)

## Tahap Prediksi
### 1 *hidden layer*
#### NN(1)
predict_NN1 = ts(mlp_1_1$net.result[[1]])
kembali_NN1 = ((predict_NN1 + 1) / 2) * (max(Zt) - min(Zt)) + min(Zt)
head(kembali_NN1)
## Time Series:
## Start = 1 
## End = 6 
## Frequency = 1 
##          [,1]
## [1,] 15.18481
## [2,] 17.09205
## [3,] 14.73814
## [4,] 13.84714
## [5,] 11.58230
## [6,] 11.25406

Model N(2)

#### NN(2)
predict_NN2 = ts(mlp_1_2$net.result[[1]])
kembali_NN2 = ((predict_NN2 + 1) / 2) * (max(Zt) - min(Zt)) + min(Zt)
head(kembali_NN2)
## Time Series:
## Start = 1 
## End = 6 
## Frequency = 1 
##          [,1]
## [1,] 15.97399
## [2,] 18.92208
## [3,] 15.48342
## [4,] 14.50387
## [5,] 13.27581
## [6,] 13.75917

Model N(3)

#### NN(3)
predict_NN3 = ts(mlp_1_3$net.result[[1]])
kembali_NN3 = ((predict_NN3 + 1) / 2) * (max(Zt) - min(Zt)) + min(Zt)
head(kembali_NN3)
## Time Series:
## Start = 1 
## End = 6 
## Frequency = 1 
##          [,1]
## [1,] 14.69560
## [2,] 15.00592
## [3,] 14.42520
## [4,] 13.87917
## [5,] 11.28663
## [6,] 10.33710

Model N(1,1)

### 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(Zt) - min(Zt)) + min(Zt)
head(kembali_NN_1_1)
## Time Series:
## Start = 1 
## End = 6 
## Frequency = 1 
##          [,1]
## [1,] 15.18972
## [2,] 17.08087
## [3,] 14.74595
## [4,] 13.86079
## [5,] 11.60496
## [6,] 11.27499

Model N(1,2)

#### 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(Zt) - min(Zt)) + min(Zt)
head(kembali_NN_1_2)
## Time Series:
## Start = 1 
## End = 6 
## Frequency = 1 
##          [,1]
## [1,] 15.16591
## [2,] 17.08294
## [3,] 14.71645
## [4,] 13.81958
## [5,] 11.53634
## [6,] 11.20445

Model N(1,3)

#### 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(Zt) - min(Zt)) + min(Zt)
head(kembali_NN_1_3)
## Time Series:
## Start = 1 
## End = 6 
## Frequency = 1 
##          [,1]
## [1,] 15.00089
## [2,] 16.99298
## [3,] 14.53736
## [4,] 13.61656
## [5,] 11.30775
## [6,] 10.97873

Model N(2,1)

#### 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(Zt) - min(Zt)) + min(Zt)
head(kembali_NN_2_1)
## Time Series:
## Start = 1 
## End = 6 
## Frequency = 1 
##          [,1]
## [1,] 14.90497
## [2,] 15.28549
## [3,] 14.67250
## [4,] 14.22563
## [5,] 11.86566
## [6,] 10.92915

Model N(2,2)

#### 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(Zt) - min(Zt)) + min(Zt)
head(kembali_NN_2_2)
## Time Series:
## Start = 1 
## End = 6 
## Frequency = 1 
##           [,1]
## [1,] 14.726740
## [2,] 14.634235
## [3,] 14.454362
## [4,] 13.920779
## [5,] 10.567410
## [6,]  8.758607

Model N(2,3)

#### 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(Zt) - min(Zt)) + min(Zt)
head(kembali_NN_2_3)
## Time Series:
## Start = 1 
## End = 6 
## Frequency = 1 
##          [,1]
## [1,] 14.64444
## [2,] 14.85666
## [3,] 14.45096
## [4,] 14.07523
## [5,] 12.13310
## [6,] 11.47520

Pemilihan Model Neural Network Terbaik

Pemilihan model Neural Network terbaik ditentukan oleh nilai akurasi terkcecil, yaitu nilai MAPE, RMSE, dan SMAPE.

## Pemilihan Model NN Terbaik
cat("================ MAPE =============")
## ================ MAPE =============
cat("\nMAPE Neural Network (1) = ",MAPE(ts(kembali_NN1),ts(in_sample[13:147]))*100)
## 
## MAPE Neural Network (1) =  23.3005
cat("\nMAPE Neural Network (2) = ",MAPE(ts(kembali_NN2),ts(in_sample[13:147]))*100)
## 
## MAPE Neural Network (2) =  23.83139
cat("\nMAPE Neural Network (3) = ",MAPE(ts(kembali_NN3),ts(in_sample[13:147]))*100)
## 
## MAPE Neural Network (3) =  22.13881
cat("\nMAPE Neural Network (1,1) = ",MAPE(ts(kembali_NN_1_1),ts(in_sample[13:147]))*100)
## 
## MAPE Neural Network (1,1) =  23.29479
cat("\nMAPE Neural Network (1,2) = ",MAPE(ts(kembali_NN_1_2),ts(in_sample[13:147]))*100)
## 
## MAPE Neural Network (1,2) =  23.30222
cat("\nMAPE Neural Network (1,3) = ",MAPE(ts(kembali_NN_1_3),ts(in_sample[13:147]))*100)
## 
## MAPE Neural Network (1,3) =  23.27264
cat("\nMAPE Neural Network (2,1) = ",MAPE(ts(kembali_NN_2_1),ts(in_sample[13:147]))*100)
## 
## MAPE Neural Network (2,1) =  22.50643
cat("\nMAPE Neural Network (2,2) = ",MAPE(ts(kembali_NN_2_2),ts(in_sample[13:147]))*100)
## 
## MAPE Neural Network (2,2) =  22.94342
cat("\nMAPE Neural Network (2,3) = ",MAPE(ts(kembali_NN_2_3),ts(in_sample[13:147]))*100)
## 
## MAPE Neural Network (2,3) =  22.47273
cat("\n================ RMSE =============")
## 
## ================ RMSE =============
cat("\nRMSE Neural Network (1) = ",RMSE(ts(kembali_NN1),ts(in_sample[13:147])))
## 
## RMSE Neural Network (1) =  10.55482
cat("\nRMSE Neural Network (2) = ",RMSE(ts(kembali_NN2),ts(in_sample[13:147])))
## 
## RMSE Neural Network (2) =  10.2071
cat("\nRMSE Neural Network (3) = ",RMSE(ts(kembali_NN3),ts(in_sample[13:147])))
## 
## RMSE Neural Network (3) =  9.819301
cat("\nRMSE Neural Network (1,1) = ",RMSE(ts(kembali_NN_1_1),ts(in_sample[13:147])))
## 
## RMSE Neural Network (1,1) =  10.5552
cat("\nRMSE Neural Network (1,2) = ",RMSE(ts(kembali_NN_1_2),ts(in_sample[13:147])))
## 
## RMSE Neural Network (1,2) =  10.55455
cat("\nRMSE Neural Network (1,3) = ",RMSE(ts(kembali_NN_1_3),ts(in_sample[13:147])))
## 
## RMSE Neural Network (1,3) =  10.55335
cat("\nRMSE Neural Network (2,1) = ",RMSE(ts(kembali_NN_2_1),ts(in_sample[13:147])))
## 
## RMSE Neural Network (2,1) =  10.34456
cat("\nRMSE Neural Network (2,2) = ",RMSE(ts(kembali_NN_2_2),ts(in_sample[13:147])))
## 
## RMSE Neural Network (2,2) =  10.46104
cat("\nRMSE Neural Network (2,3) = ",RMSE(ts(kembali_NN_2_3),ts(in_sample[13:147])))
## 
## RMSE Neural Network (2,3) =  10.33875
cat("\n================ SMAPE =============")
## 
## ================ SMAPE =============
cat("\nSMAPE Neural Network (1) = ",smape(ts(in_sample[13:147]),ts(kembali_NN1))*100)
## 
## SMAPE Neural Network (1) =  21.87771
cat("\nSMAPE Neural Network (2) = ",smape(ts(in_sample[13:147]),ts(kembali_NN2))*100)
## 
## SMAPE Neural Network (2) =  22.19925
cat("\nSMAPE Neural Network (3) = ",smape(ts(in_sample[13:147]),ts(kembali_NN3))*100)
## 
## SMAPE Neural Network (3) =  20.91628
cat("\nSMAPE Neural Network (1,2) = ",smape(ts(in_sample[13:147]),ts(kembali_NN_1_1))*100)
## 
## SMAPE Neural Network (1,2) =  21.86948
cat("\nSMAPE Neural Network (1,2) = ",smape(ts(in_sample[13:147]),ts(kembali_NN_1_2))*100)
## 
## SMAPE Neural Network (1,2) =  21.88827
cat("\nSMAPE Neural Network (1,2) = ",smape(ts(in_sample[13:147]),ts(kembali_NN_1_3))*100)
## 
## SMAPE Neural Network (1,2) =  21.91541
cat("\nSMAPE Neural Network (2,1) = ",smape(ts(in_sample[13:147]),ts(kembali_NN_2_1))*100)
## 
## SMAPE Neural Network (2,1) =  21.02146
cat("\nSMAPE Neural Network (2,2) = ",smape(ts(in_sample[13:147]),ts(kembali_NN_2_2))*100)
## 
## SMAPE Neural Network (2,2) =  21.64251
cat("\nSMAPE Neural Network (2,3) = ",smape(ts(in_sample[13:147]),ts(kembali_NN_2_3))*100)
## 
## SMAPE Neural Network (2,3) =  21.06888
## Evaluasi model NN terbaik
# Simpan semua hasil evaluasi ke dalam list
mape_list <- c(
  NN1 = MAPE(ts(kembali_NN1), ts(in_sample[13:147])) * 100,
  NN2 = MAPE(ts(kembali_NN2), ts(in_sample[13:147])) * 100,
  NN3 = MAPE(ts(kembali_NN3), ts(in_sample[13:147])) * 100,
  NN_1_1 = MAPE(ts(kembali_NN_1_1), ts(in_sample[13:147])) * 100,
  NN_1_2 = MAPE(ts(kembali_NN_1_2), ts(in_sample[13:147])) * 100,
  NN_1_3 = MAPE(ts(kembali_NN_1_3), ts(in_sample[13:147])) * 100,
  NN_2_1 = MAPE(ts(kembali_NN_2_1), ts(in_sample[13:147])) * 100,
  NN_2_2 = MAPE(ts(kembali_NN_2_2), ts(in_sample[13:147])) * 100,
  NN_2_3 = MAPE(ts(kembali_NN_2_3), ts(in_sample[13:147])) * 100
)

rmse_list <- c(
  NN1 = RMSE(ts(kembali_NN1), ts(in_sample[13:147])),
  NN2 = RMSE(ts(kembali_NN2), ts(in_sample[13:147])),
  NN3 = RMSE(ts(kembali_NN3), ts(in_sample[13:147])),
  NN_1_1 = RMSE(ts(kembali_NN_1_1), ts(in_sample[13:147])),
  NN_1_2 = RMSE(ts(kembali_NN_1_2), ts(in_sample[13:147])),
  NN_1_3 = RMSE(ts(kembali_NN_1_3), ts(in_sample[13:147])),
  NN_2_1 = RMSE(ts(kembali_NN_2_1), ts(in_sample[13:147])),
  NN_2_2 = RMSE(ts(kembali_NN_2_2), ts(in_sample[13:147])),
  NN_2_3 = RMSE(ts(kembali_NN_2_3), ts(in_sample[13:147]))
)

smape_list <- c(
  NN1 = smape(ts(in_sample[13:147]), ts(kembali_NN1)) * 100,
  NN2 = smape(ts(in_sample[13:147]), ts(kembali_NN2)) * 100,
  NN3 = smape(ts(in_sample[13:147]), ts(kembali_NN3)) * 100,
  NN_1_1 = smape(ts(in_sample[13:147]), ts(kembali_NN_1_1)) * 100,
  NN_1_2 = smape(ts(in_sample[13:147]), ts(kembali_NN_1_2)) * 100,
  NN_1_3 = smape(ts(in_sample[13:147]), ts(kembali_NN_1_3)) * 100,
  NN_2_1 = smape(ts(in_sample[13:147]), ts(kembali_NN_2_1)) * 100,
  NN_2_2 = smape(ts(in_sample[13:147]), ts(kembali_NN_2_2)) * 100,
  NN_2_3 = smape(ts(in_sample[13:147]), ts(kembali_NN_2_3)) * 100
)

# Cari model terbaik berdasarkan masing-masing metrik
#Cari model terbaik berdasarkan masing-masing metrik
best_mape_model <- names(which.min(mape_list))
best_rmse_model <- names(which.min(rmse_list))
best_smape_model <- names(which.min(smape_list))

# Cetak hasil
cat("\n========== Pemilihan Model NN Terbaik ============\n")
## 
## ========== Pemilihan Model NN Terbaik ============
cat("Model terbaik berdasarkan MAPE  : ", best_mape_model, "(", round(min(mape_list), 2), "% )\n")
## Model terbaik berdasarkan MAPE  :  NN3 ( 22.14 % )
cat("Model terbaik berdasarkan RMSE  : ", best_rmse_model, "(", round(min(rmse_list), 2), ")\n")
## Model terbaik berdasarkan RMSE  :  NN3 ( 9.82 )
cat("Model terbaik berdasarkan SMAPE : ", best_smape_model, "(", round(min(smape_list), 2), "% )\n")
## Model terbaik berdasarkan SMAPE :  NN3 ( 20.92 % )

Berdasarkan nilai akurasi, diketahui bahwa model N(3) atau Model Neural Network dengan 1 Hidden layer dan 3 Neuron (N(3)) adalah model terbaik dikarenakan nilai MAPE sebesar 22,14%, nilai RMSE sebesar 9,82%, dan nilai SMAPE sebesar 20,92% lebih kecil dibandingkan model Neural Network lainnya. Sehingga model N(3) dapat dilanjutkan untuk menentukan nilai prediksi dan peramalan.

Prediki Model Neural Network Terbaik

predict_NN3 = ts(mlp_1_3$net.result[[1]])
kembali_NN3 = ((predict_NN3 + 1) / 2) * (max(Zt) - min(Zt)) + min(Zt)
head(kembali_NN3)
## Time Series:
## Start = 1 
## End = 6 
## Frequency = 1 
##          [,1]
## [1,] 14.69560
## [2,] 15.00592
## [3,] 14.42520
## [4,] 13.87917
## [5,] 11.28663
## [6,] 10.33710

Peramalan Model Neural Network Terbaik

Dilakukan proses peramalan selama 12 periode ke depan menggunakan model Neural Network terbaik yang telah diperoleh sebelumnya. Nilai-nilai input terakhir (lag 1 dan lag 12) dari data in-sample digunakan sebagai dasar peramalan

## Peramalan NN(mlp_1_3)
last_lag1 = tail(nn_insample$lag1, 1)
last_lag12 = tail(nn_insample$lag12, 1)

forecast_normalized <- numeric(12)

current_lag1 = last_lag1
current_lag12 = last_lag12

for (i in 1:12) {
  # Create the correct input data frame for the network
  new_data = data.frame(lag1 = current_lag1, lag12 = current_lag12)
  
  # Predict the next value
  pred = neuralnet::compute(mlp_1_3, new_data)
  forecast_normalized[i] = pred$net.result[1, 1]
  
  # Update the lags
  current_lag12 = current_lag1
  current_lag1 = forecast_normalized[i]
}

# Denormalize the forecasted values
forecast_denormalized = ((forecast_normalized + 1) / 2) * (max_asli - min_asli) + min_asli
forecast_denormalized
##  [1] 40.30950 48.99519 49.42992 57.99482 60.33222 68.33267 71.97829 58.70742
##  [9] 59.10971 56.15668 48.83858 44.73405

Prediksi In Sample

Prediksi in sample dilakukan terhadap data yang digunakan untuk melatih model, dengan tujuan untuk melihat seberapa baik model mampu menangkap pola yang sudah dikenalnya. Hasil prediksi in sample ini kemudian dibandingkan dengan nilai aktual untuk mengevaluasi kecocokan model terhadap data in sample

# Prediksi In-sample
pred_in_sample = ts(mlp_1_3$net.result[[1]])
pred_in_sample_denorm = ((pred_in_sample + 1) / 2) * (max_asli - min_asli) + min_asli
head(pred_in_sample_denorm)
## Time Series:
## Start = 1 
## End = 6 
## Frequency = 1 
##          [,1]
## [1,] 14.69560
## [2,] 15.00592
## [3,] 14.42520
## [4,] 13.87917
## [5,] 11.28663
## [6,] 10.33710

Prediksi Out Sample

Prediksi out-sample dilakukan terhadap data yang tidak digunakan selama proses pelatihan (data uji). Tujuannya adalah untuk mengukur kemampuan generalisasi model dalam memprediksi data baru yang belum pernah dilihat sebelumnya.

# Prediksi Out-sample
out_sample_nn <- data.frame(
  lag1 = nn_outsample$lag1[1:14],
  lag12 = nn_outsample$lag12[1:14]
  %>%
  na.omit()
)

new_data_out = out_sample_nn
pred_out_sample = neuralnet::compute(mlp_1_3, covariate = new_data_out)$net.result
pred_out_sample_denorm = ((pred_out_sample[1:14,] + 1) / 2) * (max_asli - min_asli) + min_asli
head(pred_out_sample_denorm)
## [1] 31.99479 30.10212 33.76805 28.92859 42.17516 53.85219

Plot Perbandingan

Membuat plot perbandingan antara data aktual, hasil prediksi pada data in sample dan out sample, serta hasil forecasting, bertujuan untuk melihat apakah model yang digunakan sudah sesuai, sehingga nilai prediksi hasil tidak jauh berbeda dengan data aktual dan menghasilkan peramalan periode kedepannya secara akurat.

# Plot Hasil Prediksi dan Peramalan
# Plot data aktual
plot(1:length(Zt), Zt, type = "l", col = "black", xlab = "Periode", ylab = "Nilai Aktual",
     main = "Grafik Prediksi dan Peramalan Kata Pencarian Musim Hujan di Google Trends Metode Neural Network")
points(1:length(Zt), Zt, col = "black", pch = 19)

# In-Sample
x_in = seq_along(pred_in_sample_denorm) + 12
lines(x_in, pred_in_sample_denorm, col = "blue", lwd = 2)
points(x_in, pred_in_sample_denorm, col = "blue", pch = 19)

# Out-Sample
x_out = seq_along(pred_out_sample_denorm) + 12 + length(pred_in_sample_denorm)
lines(x_out, pred_out_sample_denorm, col = "red", lwd = 2)
points(x_out, pred_out_sample_denorm, col = "red", pch = 19)

# Peramalan 12 bulan ke depan
x_forecast = (length(Zt) + 1):(length(Zt) + 12)
lines(x_forecast, forecast_denormalized, col = "green", lwd = 2)
points(x_forecast, forecast_denormalized, col = "green", pch = 19)


# Keterangan
legend("topleft", legend = c("Aktual", "Prediksi In-Sample", "Prediksi Out-Sample", "Peramalan"),
       col = c("black", "blue", "red", "green"),
       lty = 1, lwd = 2, pch = 19)

# Grid
grid()

Berdasarkan plot di atas, dapat diketahui bahwa model Neural Network mampu menangkap pola tren dan musiman pada data in sample dengan cukup baik, terlihat dari prediksi in sample yang mengikuti pola data aktual secara konsisten. Ini menunjukkan bahwa model berhasil mengenali pola historis dalam data pelatihan. Namun, pada data out-sample, terdapat sedikit deviasi yang mengindikasikan penurunan akurasi saat model dihadapkan pada data yang belum pernah dilihat sebelumnya. Meskipun demikian, peramalan memperlihatkan kecenderungan pola musiman yang konsisten, menandakan model memiliki potensi untuk memberikan prediksi yang cukup baik.

Akurasi Model Neural Network Terbaik

Model Neural Network terbaik yang digunakan dalam analisis ini dievaluasi berdasarkan beberapa metrik akurasi, termasuk Mean Absolute Percentage Error (MAPE), Root Mean Square Error (RMSE), dan Symmetric Mean Absolute Percentage Error (SMAPE) yang digunakan untuk menilai seberapa baik model dapat menyesuaikan pola data historis serta memprediksi nilai di masa depan. Model terbaik dipilih berdasarkan hasil evaluasi pada data in sample dan out sample.

## Evaluasi model NN terbaik
#In Sample
MAPE_in<-MAPE(ts(pred_in_sample_denorm), ts(in_sample[13:147])) * 100
RMSE_in<-RMSE(ts(pred_in_sample_denorm), ts(in_sample[13:147]))
SMAPE_in<-smape(ts(in_sample[13:147]), ts(pred_in_sample_denorm)) * 100

#Out Sample
MAPE_out<-MAPE(ts(pred_out_sample_denorm), ts(out_sample)) * 100
RMSE_out<-RMSE(ts(pred_out_sample_denorm), ts(out_sample))
SMAPE_out<-smape(ts(out_sample), ts(pred_out_sample_denorm)) * 100


# Buat Data Frame Komparasi
akurasi_df <- data.frame(
  Dataset = c("In-Sample", "Out-Sample"),
  MAPE = c(MAPE_in, MAPE_out),
  RMSE = c(RMSE_in, RMSE_out),
  SMAPE = c(SMAPE_in, SMAPE_out)
)

akurasi_df$MAPE <- sprintf("%.2f%%", akurasi_df$MAPE)
akurasi_df$RMSE <- round(akurasi_df$RMSE, 2)
akurasi_df$SMAPE <- sprintf("%.2f%%", akurasi_df$SMAPE)


akurasi_df %>%
  kbl(caption = "📊 Tabel Komparasi Akurasi Prediksi Model NN", digits = 2) %>%
  kable_styling("striped", full_width = F) %>%
  row_spec(0, bold = TRUE,  background = "steelblue")
📊 Tabel Komparasi Akurasi Prediksi Model NN
Dataset MAPE RMSE SMAPE
In-Sample 22.14% 9.82 20.92%
Out-Sample 17.24% 8.44 17.26%

Berdasarkan Tabel Komparasi Akurasi Prediksi, model menunjukkan performa yang baik, dengan nilai error yang masih dalam batas wajar pada data In Sample dan Out Sample. Nilai RMSE, MAPE, dan SMAPE pada data In Sample masing-masing sebesar 9,82, 22,145%, dan 20,92%%, sementara pada data Out Sample masing-masing sebesar 8,44, 17,24%, dan 17,26%. Perbedaan ini menunjukkan bahwa model mampu menyesuaikan diri dengan baik terhadap data historis sekaligus tetap memberikan hasil prediksi yang cukup akurat saat diuji pada data baru. Dengan demikian, model yang digunakan dapat dikatakan sudah sesuai dan cukup andal untuk kebutuhan peramalan.

Evaluasi Model SARIMA dan Neural Network

Evaluasi model SARIMA (Seasonal Autoregressive Integrated Moving Average) dan Neural Network (NN) dilakukan untuk mengukur seberapa baik kedua pendekatan ini dalam memahami pola historis data dan memprediksi nilai masa depan. Evaluasi dilakukan pada dua jenis dataset, yaitu in-sample dan out-sample. Metrik yang digunakan dalam evaluasi ini mencakup Mean Absolute Percentage Error (MAPE), Root Mean Square Error (RMSE) dan Symmetric Mean Absolute Percentage Error (SMAPE).

#Evaluasi Model SARIMA Terbaik
#In Sample
aktual_in_sample <- in_sample
prediksi_in_sample <- in_sample_pred_inv

RMSE_in_sample = RMSE(aktual_in_sample,prediksi_in_sample)
MAPE_in_sample = MAPE(aktual_in_sample,prediksi_in_sample)*100
SMAPE_in_sample = smape(prediksi_in_sample,aktual_in_sample)*100

#Out Sample
aktual_out_sample <- out_sample
prediksi_out_sample <- out_sample_pred_inv 


RMSE_out_sample = RMSE(aktual_out_sample ,prediksi_out_sample )
MAPE_out_sample  = MAPE(aktual_out_sample ,prediksi_out_sample )*100
SMAPE_out_sample  = smape(prediksi_out_sample ,aktual_out_sample )*100


#Evaluasi model NN terbaik
#In Sample
MAPE_in<-MAPE(ts(pred_in_sample_denorm), ts(in_sample[13:147])) * 100
RMSE_in<-RMSE(ts(pred_in_sample_denorm), ts(in_sample[13:147]))
SMAPE_in<-smape(ts(in_sample[13:147]), ts(pred_in_sample_denorm)) * 100

#Out Sample
MAPE_out<-MAPE(ts(pred_out_sample_denorm), ts(out_sample)) * 100
RMSE_out<-RMSE(ts(pred_out_sample_denorm), ts(out_sample))
SMAPE_out<-smape(ts(out_sample), ts(pred_out_sample_denorm)) * 100

# ===== TABEL KOMPARASI =====
akurasi_total <- data.frame(
  Model = rep(c("SARIMA", "Neural Network"), each = 2),
  Dataset = rep(c("In-Sample", "Out-Sample"), 2),
  MAPE = c(MAPE_in_sample, MAPE_out_sample, MAPE_in, MAPE_out),
  RMSE = c(RMSE_in_sample, RMSE_out_sample, RMSE_in, RMSE_out),
  SMAPE = c(SMAPE_in_sample, SMAPE_out_sample, SMAPE_in, SMAPE_out)
)

#Format angka
akurasi_total$MAPE <- sprintf("%.2f%%", akurasi_total$MAPE)
akurasi_total$RMSE <- round(akurasi_total$RMSE, 2)
akurasi_total$SMAPE <- sprintf("%.2f%%", akurasi_total$SMAPE)

# Tampilkan tabel
akurasi_total %>%
  kbl(caption = "📊 Tabel Perbandingan Akurasi Model SARIMA dan Neural Network", digits = 2) %>%
  kable_styling("striped", full_width = F) %>%
  row_spec(0, bold = TRUE, background = "steelblue")
📊 Tabel Perbandingan Akurasi Model SARIMA dan Neural Network
Model Dataset MAPE RMSE SMAPE
SARIMA In-Sample 18.02% 9.09 17.72%
SARIMA Out-Sample 37.67% 12.73 30.57%
Neural Network In-Sample 22.14% 9.82 20.92%
Neural Network Out-Sample 17.24% 8.44 17.26%

Berdasarkan hasil evaluasi dari kedua model yaitu model SARIMA dan Neural Network, diketahui bahwa model Neural Network lebih baik dibandingkan dengan model SARIMA dikarenakan nilai akurasi yang terbilang rendah baik pada in-sample maupun out-sample.

Kesimpulan

Berdasarkan hasil analisis data pencarian kata kunci “Musim Hujan” dengan menggunakan model terbaik SARIMA dan Neural Network diperoleh model yang cocok untuk data tersebut berdasarkan nilai MAPE, RMSE, dan SMAPE baik pada in-sample maupun out-sample adalah model Neural Network. Hal ini dikarenakan model Neural Network pada out-sample memiliki nilai MAPE sebesar 17,24% ,RMSE sebesar 8,44 , dan SMAPE sebesar 17,26% lebih kecil dibandingkan dengan model SARIMA yang menandakan bahwa model mampu memprediksi data baru (out-sample) secara akurat dan tidak terjadi over fitting pada model tersebut.

Berdasarkan tabel perbandingan akurasi model SARIMA dan Neural Network, dapat disimpulkan bahwa model Neural Network memberikan performa yang lebih baik dibandingkan SARIMA, khususnya pada data out-sample. Meskipun SARIMA memiliki nilai pada data in-sample MAPE sebesar 18,02%, RMSE sebesar 9,09, dan SMAPE sebesar 17,72% , performanya menurun drastis pada data out-sample dengan MAPE sebesar 37.67%, RMSE 12.73, dan SMAPE 30.57%. Sebaliknya, Neural Network menunjukkan performa yang lebih stabil dan akurat, dengan nilai MAPE, RMSE, dan SMAPE pada data out-sample masing-masing sebesar 17.24%, 8.44, dan 17.26%. Hal ini menunjukkan bahwa model Neural Network memiliki kemampuan generalisasi yang lebih baik dan lebih andal dalam melakukan prediksi terhadap data yang belum pernah dilihat sebelumnya.

Saran

Sebaiknya pada penelitian selanjutnya dapat menggunakan data sentimen terhadap pencarian mengenai “Musim Hujan” untuk memahami persepsi dan kekhawatiran masyarakat dengan menggunakan SARIMAX (SARIMA dengan Variabel Eksogen)