Air merupakan kebutuhan vital bagi kehidupan makhluk hidup, baik untuk memenuhi kebutuhan sehari-hari, transportasi, maupun sebagai sumber energi pada pembangkit listrik tenaga air (PLTA). Hilangnya kejernihan air akibat adanya partikel/zat yang tidak terlarut disebut kekeruhan (turbidity). Air dapat dikategorikan menjadi dua jenis, yaitu air bersih dan air tercemar, yang masing-masing memiliki karakteristik berbeda. Air bersih didefinisikan sebagai sumber air yang memenuhi standar kualitas baik untuk dikonsumsi manusia maupun mendukung aktivitas harian. Namun, saat ini pencemaran air semakin meningkat baik secara langsung maupun tidak langsung mengganggu kualitas air dan meningkatkan tingkat kekeruhan. Air yang keruh umumnya menjadi indikator air yang tidak layak digunakan karena mengandung partikel berbahaya dan berpotensi menimbulkan risiko kesehatan. Karakteristik yang penting dalam memenuhi kualitas air ditentukan oleh bahan padat keseluruhan yang terpaung maupun yang terlarut, kekeruhan, warna, bau, rasa, dan juga suhu air yang sebaiknya berada dibawah suhu udara sedemikian sehingga menimbulkan rasa nyaman (Fahril, Ida, & Nurhafiz., 2022).
Menurut UNESCO (2024), Saat ini sekitar separuh dari populasi penduduk dunia mengalami kelangkaan air yang parah. Seperempat penduduk dunia menghadapi tingkat tekanan kebutuhan air yang “sangat tinggi”, dan menggunakan lebih dari 80% pasokan air bersih terbarukan tahunan mereka. Selain itu, pada 2022, sebanyak 2,2 miliar orang tidak memiliki akses untuk air minum yang dikelola dengan aman. Empat dari lima orang yang tidak memperoleh akses pelayanan air minum tinggal di daerah terpencil. Kondisi terkait sanitasi yang dikelola dengan aman masih memprihatinkan, dengan sebanyak 3,5 miliar orang tidak memiliki akses ke layanan tersebut. Untuk mendukung pengelolaan air yang berkelanjutan, pemantauan dan peramalan kualitas air menjadi sangat penting. Hal ini disebabkan oleh tingkat tekanan yang tinggi terhadap sumber daya air bersih dan fakta bahwa banyak orang tidak memiliki akses ke air minum yang aman. Salah satu parameter utama yang mencerminkan kualitas air adalah tingkat kekeruhan, yang dapat memberikan indikasi awal terhadap potensi pencemaran. Oleh karena itu, penelitian ini betujuan untuk menemukan model terbaik dalam memprediksi perubahan tingkat kekeruhan air di masa mendatang dengan membandingkan kinerja berbagai metode peramalan, seperti ARIMA, Naïve, dan Neural Network (NN).
Pada analisis ini, data yang digunakan ialah data Turbidity of Water in the Johnstone River, Northern Queensland, Australia atau Kekeruhan Air di Sungai Johnstone, Queensland Utara, Australia pada periode harian dari tanggal 01 Januari 2020 hingga 01 April 2020.
Library yang digunakan pada analisis ini adalah sebagai berikut:
library(MASS)
library(hms)
library(car)
library(forecast)
library(tseries)
library(timeSeries)
library(quadprog)
library(zoo)
library(fracdiff)
library(fUnitRoots)
library(lmtest)
library(Metrics)
library(neuralnet)
Memanggil Data Turbidity dan membuat Time Serie Plot
data<-read.csv(file.choose(),header=TRUE, sep = ";")
head(data)
## t Zt
## 1 2020-01-01 2.162500
## 2 2020-01-02 2.516875
## 3 2020-01-03 2.288125
## 4 2020-01-04 2.122500
## 5 2020-01-05 3.383750
## 6 2020-01-06 2.571250
datat<-ts(data$Zt)
plot(datat)
Berdasarkan plot deret waktu diatas, terlihat bahwa data cenderung memiliki pola tren.
Pada analisis ini data dibagi menjadi out sample dan in sample untuk melihat akurasi dari setiap metode. Data dibagi dengan proporsi 90%:10%.
#In Sample - Out Sample
Yt<-data$Zt[1:83]
outsam<-data$Zt[84:92]
t=data$t[1:83]
Selanjutnya setelah dilakukan pembagian data out sample dan in sample, maka dilakukan analisis untuk setiap metode.
Analisis time series adalah suatu metode untuk meramalkan atau melakukan estimasi masa yang akan datang dengan menggunakan data masa lalu. Dalam analisis time series terdapat beberapa metode salah satunya. metode Autoregressive Integrated Moving Average (ARIMA). Metode ARIMA yang biasa disebut dengan metode Box-Jenkins adalah metode yang digunakan untuk peramalan jangka pendek dengan asumsi bahwa data deret waktu yang digunakan harus stasioner yang artinya rata rata variasi dari data yang dimaksud bersifat konstan.
Berikut adalah analisis data Turbidity of Water in Johnstone River, Queensland Utara, Australia menggunakan metode ARIMA
acf(Yt)
pacf(Yt)
Berdasarkan grafik ACF di atas terlihat bahwa nilai autokorelasi turun secara perlahan yang mengindikasikan bahwa data tidak stasioner. Sedangkan pada grafik PACF memiliki pola cut off setelah lag 1. Karena data belum stasioner pada rata-rata, maka dilakukan transformasi data dan differencing
boxcox(Yt~1)
p<-powerTransform(Yt)
p
## Estimated transformation parameter
## Yt
## -0.5413512
Berdasarkan nilai lambda (λ) dari transformasi Box-Cox dapat diketahui pula bahwa nilai masih jauh dari 1. Hal ini dapat dikatakan bahwa data belum stasioner dalam variansi dan diperlukan pula transformasi
y<-(Yt^(-0.5413512))
p1<-powerTransform(y)
p1
## Estimated transformation parameter
## y
## 1
Berdasarkan nilai lambda (λ) dari transformasi Box-Cox dapat diketahui pula bahwa nilai \(\lambda=1\). Hal ini dapat dikatakan bahwa data sudah stasioner dalam variansi
adfTest(y)
##
## Title:
## Augmented Dickey-Fuller Test
##
## Test Results:
## PARAMETER:
## Lag Order: 1
## STATISTIC:
## Dickey-Fuller: -1.2749
## P VALUE:
## 0.2066
##
## Description:
## Mon May 12 21:19:06 2025 by user: User
Berdasarkan hasil uji ADF diperoleh p-value sebesar \(0.2066 > 0.05\) yang berarti bahwa \(H_0\) gagal ditolak atau data tidak stasioner dalam rata-rata. Karena data tidak stasioner maka selanjutnya dilakukan differencing
datadiff=diff(y,differences=1)
datadiff
## [1] -0.051948242 0.032117927 0.026521431 -0.148462336 0.082843064
## [6] -0.051796821 -0.181697718 0.080263264 -0.101393203 -0.031660386
## [11] 0.115032480 0.062790627 0.036150138 -0.172929574 0.320826963
## [16] -0.073444113 0.069602652 -0.065334569 -0.005539835 -0.116770754
## [21] 0.037240327 0.032561050 -0.255021877 0.160066632 -0.031524928
## [26] -0.183764636 0.119691343 -0.085654503 -0.061682653 0.050737561
## [31] 0.043381515 0.073254828 0.051959121 0.079298938 -0.044466493
## [36] 0.047914295 -0.074156913 0.028025384 0.050388926 -0.025449631
## [41] -0.179655363 0.160635501 0.099770821 0.051202629 -0.081985689
## [46] 0.009820280 0.040103342 0.079239832 -0.109338924 -0.007049499
## [51] -0.007927120 0.001497191 -0.123946862 -0.064394893 0.042529846
## [56] 0.028642189 -0.017594445 -0.227746921 0.040524575 0.077267870
## [61] 0.090022252 0.079487383 0.076528583 0.009759906 -0.136659195
## [66] -0.030536270 -0.043110347 0.011729240 -0.001607743 -0.079571023
## [71] -0.113196056 0.031368800 0.119538713 0.056780934 0.026601282
## [76] 0.069020263 -0.126241078 -0.107626997 -0.011412485 0.004317823
## [81] -0.001565148 -0.008365815
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: -7.7796
## P VALUE:
## 0.01
##
## Description:
## Mon May 12 21:19:06 2025 by user: User
Berdasarkan hasil uji ADF setelah differencing, diperoleh p-value sebesar \(0.01 < 0.05\) yang berarti bahwa \(H_0\) ditolak atau data telah stasioner dalam rata-rata. Karena data telah stasioner, maka selanjutnya dapat mengidentifikasi model ARIMA melalui plot ACF dan PACF
acf(datadiff)
grid()
pacf(datadiff)
grid()
Berdasarkan plot ACF (cut off setelah lag ke-1), PACF (cut off setelah lag ke-1), diperoleh kandidat model: 1. ARIMA (0,1,1) 2. ARIMA (1,1,0) 3. ARIMA (1,1,1)
fit1=arima(x=y,order=c(0,1,1))
fit1
##
## Call:
## arima(x = y, order = c(0, 1, 1))
##
## Coefficients:
## ma1
## -0.2528
## s.e. 0.1132
##
## sigma^2 estimated as 0.008581: log likelihood = 78.7, aic = -153.4
coeftest(fit1)
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## ma1 -0.25283 0.11320 -2.2336 0.02551 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
fit2=arima(x=y,order=c(1,1,0))
fit2
##
## Call:
## arima(x = y, order = c(1, 1, 0))
##
## Coefficients:
## ar1
## -0.2100
## s.e. 0.1074
##
## sigma^2 estimated as 0.008669: log likelihood = 78.29, aic = -152.59
coeftest(fit2)
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## ar1 -0.21002 0.10743 -1.955 0.05058 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
fit3=arima(x=y,order=c(1,1,1))
fit3
##
## Call:
## arima(x = y, order = c(1, 1, 1))
##
## Coefficients:
## ar1 ma1
## 0.7061 -0.9373
## s.e. 0.1108 0.0619
##
## sigma^2 estimated as 0.008216: log likelihood = 80.2, aic = -154.4
coeftest(fit3)
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## ar1 0.706138 0.110753 6.3758 1.82e-10 ***
## ma1 -0.937291 0.061901 -15.1417 < 2.2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Berdasarkan output di atas dapat dilihat bahwa ke-tiga model sementara ARIMA memiliki parameter yang signifikan.
#White Noise
tsdiag(fit1,92)
tsdiag(fit2,92)
tsdiag(fit3,92)
Berdasarkan ke-tiga grafik Ljung-Box di atas dapat dilihat bahwa ke-tiga model sementara ARIMA memenuhi asumsi white noise karena titik-titik data cenderung berada di atas garis dan tidak keluar pada garis batas signifikan
#kenormalan residual
res1=resid(fit1)
res2=resid(fit2)
res3=resid(fit3)
ks.test(res1,"pnorm",mean(res1),sd(res1))
##
## Exact one-sample Kolmogorov-Smirnov test
##
## data: res1
## D = 0.095657, p-value = 0.4077
## alternative hypothesis: two-sided
ks.test(res2,"pnorm",mean(res2),sd(res2))
##
## Exact one-sample Kolmogorov-Smirnov test
##
## data: res2
## D = 0.091803, p-value = 0.4592
## alternative hypothesis: two-sided
ks.test(res2,"pnorm",mean(res2),sd(res2))
##
## Exact one-sample Kolmogorov-Smirnov test
##
## data: res2
## D = 0.091803, p-value = 0.4592
## alternative hypothesis: two-sided
Berdasarkan output normalitas residual di atas, dapat diketahui bahwa ke-tiga model sementara ARIMA memiliki residual yang berdistribusi normal
AIC(fit1)
## [1] -153.4041
AIC(fit2)
## [1] -152.5887
AIC(fit3)
## [1] -154.4018
Berdasarkan hasil di atas dapat disimpulkan bahwa ARIMA (1,1,1) merupakan model terbaik karena model tersebut memiliki nilai AIC terkecil yaitu -154.4018. Selain itu, apabila dilihat dari hasil uji signifikansi penduga parameter, bahwa seluruh koefisien telah signifikan terhadap model. Berikut model ARIMA (1,1,1) secara matematis:
\[ z_t=0.706138z_{t-1}+z_{t-1}-0.706138z_{t-2}+a_t+0.937291a_{t-1} \]
kembaliarima<-arima(x=(y^(1/(-0.5413512))),order=c(1,1,1))
kembaliarima
##
## Call:
## arima(x = (y^(1/(-0.5413512))), order = c(1, 1, 1))
##
## Coefficients:
## ar1 ma1
## 0.6099 -0.9357
## s.e. 0.1102 0.0537
##
## sigma^2 estimated as 13.65: log likelihood = -223.94, aic = 453.88
predinar<-fitted(kembaliarima)
fcastinar<-forecast(kembaliarima,h=9)
dffcasrar=as.data.frame(fcastinar)
knitr::kable(dffcasrar$`Point Forecast`, digits = 3, caption = "Forecasting Data In Sample Turbidity Metode ARIMA 9 Hari Kedepan")
| x |
|---|
| 13.737 |
| 12.403 |
| 11.590 |
| 11.094 |
| 10.791 |
| 10.607 |
| 10.494 |
| 10.425 |
| 10.384 |
lambda <- -0.5413512
y_inv <- (lambda * y + 1)^(1/lambda)
predfcastin <- ts(c(predinar, dffcasrar$`Point Forecast`), start = start(y_inv), frequency = frequency(y_inv))
fcastarima2<-as.data.frame(forecast(kembaliarima,h=20))
fcastar=ts(fcastarima2$`Point Forecast`[10:20])
#Grafik Perbandingan
aktual=ts(data$Zt)
data_out = ts(outsam, start=84)
data_fcast=ts(fcastar,start = 93)
# Kemudian plotnya bisa tetap sama
plot(predfcastin, main="ARIMA Forecast vs Actual", xlab="waktu", ylab="Jumlah", col="#d1d0ce")
grid()
# Garis & titik prediksi
points(predfcastin[1:92], cex=1, col="steelblue2", pch=19)
lines(predfcastin, col="steelblue2", lwd=1)
# Garis & titik aktual
points(aktual[1:92], cex=1, col="darkorange", pch=19)
lines(aktual, col="darkorange", lwd=1)
# Garis & titik out-sample
points(data_out, cex=1, col="blue3", pch=19)
lines(data_out, col="blue3", lwd=1)
# Garis & titik Forecast
points(data_fcast, cex=1, col="green", pch=19)
lines(data_fcast, col="green", lwd=1)
legend("topleft",
legend = c("Aktual", "Prediksi In-Sample", "Forecast Out-of-Sample", "out sample"),
col = c("darkorange", "steelblue2", "green", "blue3"),
lty = 1,
pch = 10,
cex = 1)
Metode Naïve merupakan metode yang hanya memerlukan jumlah data latih (training data) yang kecil untuk memilih parameter yang dibutuhkan selama proses klasifikasian. Dengan menggunakan beberapa atribut Dengan atribut saling berhubungan untuk penentuan kelayakan. Metode ini paling sederhana di mana nilai ramalan pada waktu ke-\(t+h\) diasumsikan sama dengan nilai terakhir yang tersedia pada waktu ke-\(t\)
Berikut adalah analisis data Turbidity of Water in Johnstone River, Queensland Utara, Australia menggunakan metode Naïve:
ts_naive <- ts(Yt)
naive_model <- naive(ts_naive, h=9)
summary(naive_model)
##
## Forecast method: Naive method
##
## Model Information:
## Call: naive(y = ts_naive, h = 9)
##
## Residual sd: 3.9925
##
## Error measures:
## ME RMSE MAE MPE MAPE MASE ACF1
## Training set 0.1678125 3.9925 2.42263 -7.609526 34.57439 1 -0.08143166
##
## Forecasts:
## Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
## 84 15.92313 10.8065298 21.03972 8.0979679 23.74828
## 85 15.92313 8.6871667 23.15908 4.8566817 26.98957
## 86 15.92313 7.0609222 24.78533 2.3695554 29.47669
## 87 15.92313 5.6899346 26.15632 0.2728109 31.57344
## 88 15.92313 4.4820703 27.36418 -1.5744581 33.42071
## 89 15.92313 3.3900776 28.45617 -3.2445170 35.09077
## 90 15.92313 2.3858866 29.46036 -4.7802946 36.62654
## 91 15.92313 1.4512084 30.39504 -6.2097615 38.05601
## 92 15.92313 0.5733394 31.27291 -7.5523462 39.39860
fcinn=as.data.frame(naive_model)
naive_fcast2<- naive(ts_naive, h=20)
naive_fcast2
## Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
## 84 15.92313 10.8065298 21.03972 8.0979679 23.74828
## 85 15.92313 8.6871667 23.15908 4.8566817 26.98957
## 86 15.92313 7.0609222 24.78533 2.3695554 29.47669
## 87 15.92313 5.6899346 26.15632 0.2728109 31.57344
## 88 15.92313 4.4820703 27.36418 -1.5744581 33.42071
## 89 15.92313 3.3900776 28.45617 -3.2445170 35.09077
## 90 15.92313 2.3858866 29.46036 -4.7802946 36.62654
## 91 15.92313 1.4512084 30.39504 -6.2097615 38.05601
## 92 15.92313 0.5733394 31.27291 -7.5523462 39.39860
## 93 15.92313 -0.2569697 32.10322 -8.8221944 40.66844
## 94 15.92313 -1.0467015 32.89295 -10.0299849 41.87623
## 95 15.92313 -1.8012807 33.64753 -11.1840143 43.03026
## 96 15.92313 -2.5250213 34.37127 -12.2908801 44.13713
## 97 15.92313 -3.2214212 35.06767 -13.3559318 45.20218
## 98 15.92313 -3.8933630 35.73961 -14.3835780 46.22983
## 99 15.92313 -4.5432558 36.38951 -15.3775033 47.22375
## 100 15.92313 -5.1731374 37.01939 -16.3408241 48.18707
## 101 15.92313 -5.7847499 37.63100 -17.2762048 49.12245
## 102 15.92313 -6.3795964 38.22585 -18.1859439 50.03219
## 103 15.92313 -6.9589843 38.80523 -19.0720413 50.91829
naive_fcast_df <- as.data.frame(naive_fcast2)
fcastnaive <- ts(naive_fcast_df$`Point Forecast`[10:20])
prednaive <- ts(c(fitted(naive_model), naive_fcast_df$`Point Forecast`), start=start(ts_naive), frequency=frequency(ts_naive))
fcastna=ts(fcastnaive,start = 93)
plot(prednaive, main="Naive Forecast vs Aktual", xlab="Waktu", ylab="Jumlah", col="#d1d0ce")
grid()
points(prednaive[1:92], col="steelblue2", pch=19)
lines(prednaive, col="steelblue2")
points(aktual[1:92], col="darkorange", pch=19)
lines(aktual, col="darkorange")
points(data_out, col="blue3", pch=19)
lines(data_out, col="blue3")
points(fcastna, col="green", pch=19)
lines(fcastna, col="green")
legend("topleft",
legend = c("Aktual", "Prediksi In-Sample (Naive)", "Forecast Out-of-Sample", "out sample"),
col = c("darkorange", "steelblue2", "green", "blue3"),
lty = 1, pch = 10, cex = 1)
Berdasarkan visualisasi di atas terlihat bahwa prediksi in sample mengikuti pola data aktual, tetapi pada data out sampel tidak mengikuti pola data prediksi. Sehingga dapat disimpulkan bahwa metode Naïve tidak mampu menangkap perubahan atau fluktuasi data di masa depan, sehingga akurasi prediksi menurun secara signifikan untuk data forecast out-of-sample (peramalan 11 periode ke depan).
Jaringan Syaraf Tiruan atau Artificial Neural Network (NN) adalah teknik dalam Machine Learning (ML) yang menirukan syaraf manusia yang merupakan bagian fundamental dari otak. NN terdiri atas lapis masukan (input layer) dan lapis keluaran (output layer). Setiap lapis terdiri atas satu atau beberapa unit neuron yang mempunyai sebuah fungsi aktivasi yang menentukan keluaran dari unit tersebut. Kita bisa menambahkan lapis tersembunyi (hidden layer) untuk menambah kemampuan dari NN tersebut. NN bisa dilatih dengan menggunakan data training. Semakin banyak data training maka akan semakin bagus unjuk kerja dari NN tersebut.
Berikut adalah analisis data Turbidity of Water in Johnstone River, Queensland Utara, Australia menggunakan metode Neural Network
Zt <- ts(data$Zt)
maxZ <- max(Zt)
minZ <- min(Zt)
newmax <- 0.9
newmin <- -0.9
Y_norm <- (((Zt - minZ) / (maxZ - minZ)) * (newmax - newmin)) + newmin
Z_in<-Y_norm[1:91]
Z_out<-Y_norm[2:92]
length(Z_in)
## [1] 91
length(Z_out)
## [1] 91
pacf(Zt)
grid()
Berdasarkan PACF di atas menunjukkan bahwa terdapat 1 lag dengan nilai PACF yang signifikan, yaitu pada lag ke-1. Sehingga variabel masukan yang digunakan adalah \(\varepsilon_{t-1}\) sebagai \(x_1\). Selanjutnya keluaran yang digunakan merupakan data Turbidity yang telah di standarisasi sebagai \(Y\), selanjutnya data masukan dan keluaran dimulai dari \(t=2\)
Z_in_in <- Z_in[1:81]
Z_out_in <- Z_out[1:81]
Z_in_out <- Z_in[82:90]
Z_out_out <- Z_out[82:90]
Data_in <- data.frame(Z_out_in = Z_out_in, Z_in_in = Z_in_in)
set.seed(1000)
nn1 <- neuralnet(Z_out_in ~ Z_in_in,
data = Data_in,
hidden = 1,
act.fct = "tanh",
algorithm = "backprop",
learningrate = 0.01,
linear.output = TRUE,
stepmax = 10000,
threshold = 0.05)
plot(nn1, cex=1)
Predict_in_1 <- ts(nn1$net.result[[1]])
Predict_out_1 <- rep(NA, length(Z_in_out))
for (i in 1:length(Z_in_out)) {
Predict_out_1[i] <- compute(nn1, covariate = matrix(Z_in_out[i], ncol=1))$net.result
}
Predict_out_1 <- ts(Predict_out_1)
Pred_in_real_1 <- (((Predict_in_1 - newmin)/(newmax - newmin))*(maxZ - minZ)) + minZ
Pred_out_real_1 <- (((Predict_out_1 - newmin)/(newmax - newmin))*(maxZ - minZ)) + minZ
MAPE_in_1 <- mape(Zt[2:82], Pred_in_real_1) * 100
MAPE_out_1 <- mape(Zt[83:91], Pred_out_real_1) * 100
Metode Neural Network dengan 2 Neuron pada Hidden Layer
set.seed(1000)
nn2 <- neuralnet(Z_out_in ~ Z_in_in,
data = Data_in,
hidden = 2,
act.fct = "tanh",
algorithm = "backprop",
learningrate = 0.01,
linear.output = TRUE,
stepmax = 10000,
threshold = 0.05)
plot(nn2, cex=1)
Predict_in_2 <- ts(nn2$net.result[[1]])
Predict_out_2 <- rep(NA, length(Z_in_out))
for (i in 1:length(Z_in_out)) {
Predict_out_2[i] <- compute(nn2, covariate = matrix(Z_in_out[i], ncol=1))$net.result
}
Predict_out_2 <- ts(Predict_out_2)
Pred_in_real_2 <- (((Predict_in_2 - newmin)/(newmax - newmin))*(maxZ - minZ)) + minZ
Pred_out_real_2 <- (((Predict_out_2 - newmin)/(newmax - newmin))*(maxZ - minZ)) + minZ
MAPE_in_2 <- mape(Zt[2:82], Pred_in_real_2) * 100
MAPE_out_2 <- mape(Zt[83:91], Pred_out_real_2) * 100
Metode Neural Network dengan 3 Neuron pada Hidden Layer
set.seed(1000)
nn3 <- neuralnet(Z_out_in ~ Z_in_in,
data = Data_in,
hidden = 3,
act.fct = "tanh",
algorithm = "backprop",
learningrate = 0.01,
linear.output = TRUE,
stepmax = 10000,
threshold = 0.05)
plot(nn3, cex=1)
Predict_in_3 <- ts(nn3$net.result[[1]])
Predict_out_3 <- rep(NA, length(Z_in_out))
for (i in 1:length(Z_in_out)) {
Predict_out_3[i] <- compute(nn3, covariate = matrix(Z_in_out[i], ncol=1))$net.result
}
Predict_out_3 <- ts(Predict_out_3)
Pred_in_real_3 <- (((Predict_in_3 - newmin)/(newmax - newmin))*(maxZ - minZ)) + minZ
Pred_out_real_3 <- (((Predict_out_3 - newmin)/(newmax - newmin))*(maxZ - minZ)) + minZ
MAPE_in_3 <- mape(Zt[2:82], Pred_in_real_3) * 100
MAPE_out_3 <- mape(Zt[83:91], Pred_out_real_3) * 100
cat("=== MAPE IN-SAMPLE ===\n")
## === MAPE IN-SAMPLE ===
cat("NN 1 Neuron:", round(MAPE_in_1,2), "%\n")
## NN 1 Neuron: 42.13 %
cat("NN 2 Neuron:", round(MAPE_in_2,2), "%\n")
## NN 2 Neuron: 43.24 %
cat("NN 3 Neuron:", round(MAPE_in_3,2), "%\n\n")
## NN 3 Neuron: 43.03 %
cat("=== MAPE OUT-SAMPLE ===\n")
## === MAPE OUT-SAMPLE ===
cat("NN 1 Neuron:", round(MAPE_out_1,2), "%\n")
## NN 1 Neuron: 21.89 %
cat("NN 2 Neuron:", round(MAPE_out_2,2), "%\n")
## NN 2 Neuron: 21.9 %
cat("NN 3 Neuron:", round(MAPE_out_3,2), "%\n")
## NN 3 Neuron: 24.73 %
Berdasarkan nilai MAPE di atas dapat dilihat bahwa Neural Network dengan 1 neuron memiliki MAPE terkecil baik pada in sample maupun pada out sample. Sehingga diperoleh model terbaik yaitu Neural Network 1 neuron karena memiliki MAPE paling kecil dibandingkan 2 neuron dan 3 neuron. Mape out sample pada neuron 1 lebih kecil dibandingkan pada in sample yang menunjukkan bahwa model Neural Network dengan 1 neuron tidak hanya mampu mempelajari pola data historis dengan baik, tetapi juga memiliki kemampuan generalisasi yang sangat baik terhadap data baru.
Ytest=c(Y_norm,rep(0,11))
k=11
for (i in 93:103)
{
Xtest=t(matrix(c(Ytest[i-1]),byrow=FALSE))
Ytest[i]=compute(nn1,covariate=Xtest)$net.result
}
Ytest=ts(Ytest[93:103])
Ytest
## Time Series:
## Start = 1
## End = 11
## Frequency = 1
## [1] -0.7213354 -0.7335863 -0.7416488 -0.7469608 -0.7504627 -0.7527722
## [7] -0.7542957 -0.7553007 -0.7559637 -0.7564012 -0.7566899
Peramalan<-(((Ytest-newmin)/(newmax-newmin))*(maxZ-minZ))+minZ
Gabungan_1 <- ts(c(NA, Pred_in_real_1, Pred_out_real_1, Peramalan), start=1)
plot(Gabungan_1, type="l", col="orange", lwd=2, ylim=range(Zt),
main="Prediksi Neural Network (1 Neuron)", xlab="Periode", ylab="Harga")
lines(Zt, col="black", lwd=2)
abline(v=82, col="red", lty=2)
abline(v=93, col="green", lty=2)
legend("topleft",
legend=c("Aktual", "Prediksi NN 1", "Batas In Sample", "Batas Out Sample"),
col=c("black", "orange", "red", "green"),
lty=c(1,1,2), lwd=2, bty="n")
Berdasarkan grafik di atas dapat dilihat bahwa pola data hasil peramalan cenderung mengikuti pola data aktual. Sehingga dapat disimpulkan bahwa metode neural network cukup menangkap perubahan atau fluktuasi data di masa depan. Hasil peramalan perode 02 April 2020 hingga 12 April 2020 memperlihatkan Turbidity atau kekeruhan air pada sungai Johnstone cenderung mengalami penurunan di setiap periodenya.
Y_in <- data$Zt[1:83]
Y_out <- data$Zt[84:92]
y_in_na<-data$Zt[2:83]
Y_in_nn<-Zt[2:82]
Y_out_nn<-Zt[83:91]
arima_in <- predinar
naive_in <- fitted(naive_model)[2:83]
nn_in <- Pred_in_real_1
arima_out <- fcastar
naive_out <- fcinn$`Point Forecast`
nn_out <- Pred_out_real_1
# Menghitung RMSE dan MAPE untuk ARIMA, Naive, dan Neural Network (NN)
rmse_in_arima <- rmse(Y_in, arima_in)
rmse_in_naive <- rmse(y_in_na, naive_in)
rmse_in_nn <- rmse(Y_in_nn, nn_in)
mape_in_arima <- mape(Y_in, arima_in)
mape_in_naive <- mape(y_in_na, naive_in)
mape_in_nn <- mape(Y_in_nn, nn_in)
mse_in_arima <- mse(Y_in, arima_in)
mse_in_naive <- mse(y_in_na, naive_in)
mse_in_nn <- mse(Y_in_nn, nn_in)
rmse_out_arima <- rmse(Y_out, arima_out)
## Warning in `-.default`(actual, predicted): longer object length is not a
## multiple of shorter object length
rmse_out_naive <- rmse(Y_out, naive_out)
rmse_out_nn <- rmse(Y_out_nn, nn_out)
mape_out_arima <- mape(Y_out, arima_out)
## Warning in `-.default`(actual, predicted): longer object length is not a
## multiple of shorter object length
## Warning in `/.default`(ae(actual, predicted), abs(actual)): longer object
## length is not a multiple of shorter object length
mape_out_naive <- mape(Y_out, naive_out)
mape_out_nn <- mape(Y_out_nn, nn_out)
mse_out_arima <- mse(Y_out, arima_out)
## Warning in `-.default`(actual, predicted): longer object length is not a
## multiple of shorter object length
mse_out_naive <- mse(Y_out, naive_out)
mse_out_nn <- mse(Y_out_nn, nn_out)
# Membuat tabel perbandingan model
comparison <- data.frame(
Model = c("ARIMA", "Naive", "Neural Network"),
RMSE_InSample = c(rmse_in_arima, rmse_in_naive, rmse_in_nn),
MAPE_InSample = c(mape_in_arima, mape_in_naive, mape_in_nn),
MSE_InSample = c(mse_in_arima, mse_in_naive, mse_in_nn),
RMSE_OutSample = c(rmse_out_arima, rmse_out_naive, rmse_out_nn),
MAPE_OutSample = c(mape_out_arima, mape_out_naive, mape_out_nn),
MSE_OutSample = c(mse_out_arima, mse_out_naive, mse_out_nn)
)
# Tampilkan perbandingan kinerja model
knitr::kable(comparison, digits = 3, caption = "Perbandingan Kinerja Model")
| Model | RMSE_InSample | MAPE_InSample | MSE_InSample | RMSE_OutSample | MAPE_OutSample | MSE_OutSample |
|---|---|---|---|---|---|---|
| ARIMA | 3.672 | 0.321 | 13.484 | 15.709 | 0.262 | 246.769 |
| Naive | 3.993 | 0.346 | 15.940 | 15.503 | 0.408 | 240.341 |
| Neural Network | 3.654 | 0.421 | 13.351 | 17.443 | 0.219 | 304.271 |
Berdasarkan tabel di atas dapat diketahui bahwa pada In Sample RMSE terkecil pada metode neural network, MAPE terkecil pada metode ARIMA, dan MSE terkecil pada metode neural network. Sedangkan pada Out Sample RMSE terkecil pada metode naive, MAPE terkecil pada metode neural network, dan MSE terkecil pada metode naive.
Pada data in sample, metode neural network menunjukkan performa terbaik dalam hal RMSE dan MSE, yang mengindikasikan kemampuannya dalam mempelajari pola historis dengan baik, sementara metode ARIMA memiliki nilai MAPE terkecil, yang berarti lebih akurat dalam hal kesalahan relatif.
Pada data out sample yang menunjukkan kemampuan model dalam memprediksi terhadap data baru, metode ARIMA memberikan performa terbaik untuk RMSE, menunjukkan bahwa metode naive memberikan nilai RMSE dan MSE terkecil, yang mengindikasikan bahwa meskipun metode ini sederhana, ia tetap mampu menghasilkan prediksi dengan kesalahan absolut dan kuadrat yang rendah. Namun, dalam hal kesalahan relatif, neural network menunjukkan performa terbaik dengan MAPE terkecil.
Hasil peramalan setelah out sample untuk 11 periode ke depan pada metode ARIMA dan neural network cenderung menunjukkan pola menurun pada setiap periodenya dan pada metode naive cenderung konstan.
Hal ini menunjukkan bahwa tidak ada satu metode yang unggul di semua metrik, dan pemilihan model terbaik sebaiknya disesuaikan dengan prioritas metrik evaluasi yang paling relevan dengan tujuan analisis, apakah fokus pada kesalahan absolut, kesalahan kuadrat, atau kesalahan relatif.
Ahmad, A. (2017). Mengenal Artificial Intelligence, Machine Learning, Neural Network, dan Deep Learning. Yayasan Cahaya Islam, Jurnal Teknologi Indonesia.
Fahril, M. A., Ida, R. N., & Nurhafiz, A. R. (2022). Pembuatan Alat Pendeteksi Tingkat Kekeruhan Air Menggunakan Fotodioda Berbasis Mikrokontroller Atmega 8535 Sebagai Sensor Turbidity, Hadron Jurnal Fisika dan Terapan, 4(1), 20-25.
Pebdika, A., Herdiana, R., & Solihudin , D. (2023). KLASIFIKASI MENGGUNAKAN METODE NAIVE BAYES UNTUK MENENTUKAN CALON PENERIMA PIP. Jurnal Mahasiswa Teknik Informatika, 7(1), 452-458.
United Nations Educational, Scientific and Cultural Organization (UNESCO). (2024). Laporan Perserikatan Bangsa-Bangsa tentang Perkembangan Sumber Daya Air 2024: Air untuk kesejahteraan dan perdamaian. Jakarta: Kementerian Pekerjaan Umum dan Perumahan Rakyat Republik Indonesia & UNESCO.
Yunita, T. (2019). Peramalan Jumlah Penggunaan Kuota Internet Menggunakan Metode Autoregressive Integrated Moving Average (ARIMA). Journal of Mathematics: Theory and Applications, 1(2), 16-22.