(Athaya Azzahra Rahman, Diego Christian, Filzah Syakirah, Widya Ayu Andini)
May 12th, 2025
Pengembangan perkebunan merupakan bagian penting dalam sektor pertanian yang perlu ditingkatkan karena mampu mengoptimalkan lahan kosong, meningkatkan pendapatan masyarakat, dan menyumbang devisa negara. Berbagai komoditas seperti cengkeh, teh, kelapa sawit, kakao, dan kopi berperan dalam menyediakan bahan baku industri. Kopi sendiri memiliki potensi dalam menciptakan lapangan kerja, mendorong pertumbuhan wilayah, dan mengembangkan sektor agroindustri (Setiadi, 2023). Kopi merupakan salah satu komoditas yang memiliki peran strategis dalam mendukung perekonomian Indonesia. Komoditas ini berkontribusi dalam mendorong pertumbuhan ekonomi serta meningkatkan kesejahteraan para petani (Pratiwi, Fitriani, dan Berliana, 2023). Menurut Kementrian Pertanian Republik Indonesia produksi kopi di Indonesia sangat signifikan, dengan Indonesia menjadi produsen kopi terbesar keempat di dunia setelah Brazil, Vietnam, dan Kolombia. Pada Tahun 2022-2025, total produksi kopi diperkirakan mencapai 789.000 ton per tahun dengan beberapa daerah sebagai penghasil kopi terbesar di Indonesia termasuk Sumatera Selatan, Lampung, dan Sumatera Utara.
Ketahanan pangan adalah kondisi terpenuhinya kebutuhan pangan secara cukup, aman, bergizi, merata, dan terjangkau, yang selaras dengan nilai agama dan budaya, untuk mendukung hidup sehat dan produktif secara berkelanjutan (Badan Pangan Nasional, 2023). Produksi kopi dipengaruhi oleh berbagai faktor, antara lain tanaman kopi yang telah memasuki usia tidak produktif, penerapan teknik budidaya yang kurang optimal, serta pengaruh perubahan iklim yang cenderung ekstrim pada periode tertentu, sehingga menyebabkan terjadinya fluktuasi (Angka dan Dewi, 2021). Jika dilihat dari fluktuasi data produksi perkebunan kopi tahun 2017 hingga 2024 yang diperoleh dari Badan Pusat Statistik (BPS) yaitu mengalami pola musiman setiap 12 periode. Pola musiman yang dimiliki oleh data produksi perkebunan kopi menandakan bahwa data tersebut lebih cocok menggunakan metode yang cocok dengan pola musiman seperti Autoregressive Integrated Moving Average (ARIMA) Musiman. Selain itu, terdapat metode analisis runtun waktu non linear yang dimana tidak memiliki asumsi khusus pada metodenya. Metode non linear dapat menangkap pola musiman pada data produksi perkebunan kopi. Metode non linear yang banyak digunakan salah satunya adalah Neural Network (NN).
##### Packages and Function Libraries
library(MASS)
library(car)
## Loading required package: carData
library(forecast)
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
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(urca)
## Warning: package 'urca' was built under R version 4.4.3
##
## Attaching package: 'urca'
## The following objects are masked from 'package:fUnitRoots':
##
## punitroot, qunitroot, unitrootTable
library(nortest)
library(neuralnet)
## Warning: package 'neuralnet' was built under R version 4.4.3
library(MLmetrics)
## Warning: package 'MLmetrics' was built under R version 4.4.3
##
## Attaching package: 'MLmetrics'
## The following object is masked from 'package:base':
##
## Recall
library(magick)
## Warning: package 'magick' was built under R version 4.4.3
## Linking to ImageMagick 6.9.12.98
## Enabled features: cairo, freetype, fftw, ghostscript, heic, lcms, pango, raw, rsvg, webp
## Disabled features: fontconfig, x11
#Function
akurasi_model <- function(aktual, prediksi) {
aktual <- as.vector(aktual)
prediksi <- as.vector(prediksi)
residual <- aktual-prediksi
rmse <- sqrt(mean(residual^2, na.rm = TRUE))
mape <-mean(abs(residual / aktual), na.rm = TRUE) * 100
smape <- mean(2 *abs(residual) /(abs(aktual) + abs(prediksi)), na.rm = TRUE) * 100
ukuran_akurasi <- data.frame( MAPE = round(mape, 4), RMSE = round(rmse,4), SMAPE = round(smape, 4) )
return(ukuran_akurasi)
}
data<-read.csv(file.choose(),header=TRUE)
head(data)
## Warning in attr(x, "align"): 'xfun::attr()' is deprecated.
## Use 'xfun::attr2()' instead.
## See help("Deprecated")
| data |
|---|
| 0.03 |
| 0.05 |
| 0.05 |
| 1.14 |
| 2.24 |
| 3.89 |
#data Keseluruhan
ts.plot(data$data,type="o",xlab="Periode",ylab="Jumlah Produksi",main="Produksi Perkebunan Kopi Periode Januari 2017 - Desember 2024")
grid()
Terlihat bahwasanya grafik tersebut menunjukkan pola musiman yang konsisten dengan puncak produksi yang terjadi secara berkala, namun disertai dengan tren menurun dari waktu ke waktu. Pada awal periode, produksi kopi mencapai angka tertinggi, namun secara bertahap mengalami penurunan signifikan hingga akhir periode. Pola ini mengindikasikan adanya siklus panen tahunan yang kuat.
insample <- data[1:86,]
outsample <- data[87:96,]
Zt <- insample
outsample <- data.frame(zt = outsample)
ts.plot(Zt,type="o",xlab="Periode",ylab="Jumlah Produksi",main="Produksi Perkebunan Kopi (Insample)")
grid()
Berdasarkan pada grafik di atas, yang mencerminkan data in-sample sebesar 90% dari keseluruhan data. Terlihat bahwa pola produksi menunjukkan siklus musiman tahunan yang kuat dengan fluktuasi yang konsisten. Pada grafik tersebut juga terlihat bahwasanya data insample cenderung belum stasioner baik dalam variansi maupun rata-rata. Sehingga langkah selanjutnya akan dilakukan pengecekan stasioneritas data insample baik dalam variansi maupun dalam rata-rata.
boxcox(Zt~1)
p<-powerTransform(Zt)
p
## Estimated transformation parameter
## Zt
## -0.006150835
Berdasarkan grafik boxcox data insample diperoleh bahwasanya nilai lambda belum mendekati angka 1, dan untuk memvalidasi hal tersebut dilakukan pengecekan nilai lambda. Diperoleh nilai lambda sebesar -0,006150835, angka tersebut belum mendekati angka 1. Sehingga akan dilakukan transformasi pada data insample agar data tersebut stasioner dalam variansi dengan memangkatkan data insample dengan lambda sebesar 0,006150835.
y<-(Zt^p$lambda)
p1<-powerTransform(y)
p1
## Estimated transformation parameter
## y
## 0.9999994
boxcox(y~1)
Berdasarkan grafik boxcox data hasil transformasi, diperoleh bahwasanya nilai lambda sudah mendekati angka 1 dengan nilailambda sebesar 0,9999994. Hal ini menunjukkan bahwasanya data sudah stasioner dalam variansi.
ts.plot(y,type="o",xlab="Time",ylab="data", main="TS Plot setelah
transformasi")
grid()
Berdasarkan grafik diatas, terlihat bahwasanya data setelah transformasi telah stasioner dalam variansi. Namun grafik tersebut terlihat belum stasioner dalam rata-rata. Sehingga untuk memvalidasi hal tersebut, akan dilakukan pengecekan stasioneritas dalam rata-rata.
acf(y)
Berdasarkan hasil plot ACF di atas terlihat bahwasanya, plot tersebut cenderung dies down. Hal ini menandakan bahwasanya data hasil transformasi belum stasioner dalam rata-rata. Untuk memvalidasi hal tersebut dilakukan pengecekan dengan menggunakan uji ADF (Augmented Dickey-Fuller).
adfTest(y)
##
## Title:
## Augmented Dickey-Fuller Test
##
## Test Results:
## PARAMETER:
## Lag Order: 1
## STATISTIC:
## Dickey-Fuller: 0.0016
## P VALUE:
## 0.613
##
## Description:
## Mon May 12 14:17:12 2025 by user: filza
Diperoleh nilai p-value sebesar 0,613. Nilai p-value yang lebih besar dari taraf signifikansi sebesar 0,05 menunjukkan bahwasanya data tersebut belum stasioner dalam rata-rata. Sehingga selanjutnya akan dilakukan differencing dengan orde 1 agar data tersebut stasioner dalam rata-rata.
datadiff=diff(y,differences=1)
ts.plot(datadiff,type="o",xlab="Time",ylab="data", main="TS Plot data In
Sample Setelah Transformasi dan Differencing")
Berdasarkan grafik tersebut, secara visual terlihat bahwasanya data setelah differencing orde 1 telah stasioner baik dalam variansi maupun dalam rata-rata. Untuk memvalidasi hal tersebut dilakukan pengecekan dengan uji ADF.
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: -4.7719
## P VALUE:
## 0.01
##
## Description:
## Mon May 12 14:17:12 2025 by user: filza
Diperoleh nilai p-value sebesar 0,01. Nilai p-value yang lebih kecil dari taraf signifikansi sebesar 0,05 menunjukkan bahwasanya data tersebut telah stasioner dalam rata-rata. Sehingga selanjutnya akan dilakukan estimasi model ARIMA non musiman dari data yang telah di differencing.
###PACF
Pacf(datadiff, length(datadiff))
Berdasarkan plot PACF di atas, diketahui bahwa grafik PACF mengalami cut off setelah lag 1. Sehingga diperoleh model ARIMA sementara yang terbentuk memiliki orde AR yang mungkin adalah 0, dan 1.
acf(datadiff,length(datadiff)) #cutoff 1 grid()
Berdasarkan plot ACF di atas, diketahui bahwa grafik ACF mengalami cut off setelah lag 1. Sehingga diperoleh model ARIMA sementara yang terbentuk memiliki orde MA yang mungkin adalah 0, dan 1.Terlihat pada plot tersebut, dimana terdapat pola osilasi setiap 12 kali. Sehingga diasumsikan terjadi pola musiman pada data dengan orde 12. Selanjutnya akan dilakukan pembentukan model ARIMA musiman dengan melakukan differencing orde 12 pada data hasil differencing orde 1.
datadiff2=diff(datadiff,differences=12)
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: -28.6246
## P VALUE:
## 0.01
##
## Description:
## Mon May 12 14:17:13 2025 by user: filza
Diperoleh nilai p-value sebesar 0,01. Nilai p-value yang lebih kecil dari taraf signifikansi sebesar 0,05 menunjukkan bahwasanya data differencing orde 12 telah stasioner dalam rata-rata. Sehingga selanjutnya akan dilakukan estimasi model ARIMA musiman dari data yang telah di differencing dengan orde 12.
Pacf(datadiff2, length(datadiff2)) #cutoff 5 grid()
Berdasarkan plot PACF, diketahui bahwa grafik pACF mengalami cut off setelah lag 5. Sehingga diperoleh model SARIMA musiman sementara yang terbentuk memiliki orde AR yang mungkin adalah 0, 1, 2, 3, 4, dan 5.
Acf(datadiff2, length(datadiff2)) #cutoff 4 grid()
Berdasarkan plot ACF, diketahui bahwa grafik pACF mengalami cut off setelah lag 4. Sehingga diperoleh model SARIMA musiman sementara yang terbentuk memiliki orde MA yang mungkin adalah 0, 1, 2, 3, dan 4.
Selanjutnya dilakukan uji signifikansi terhadap 87 model yang terbentuk berdasarkan model ARIMA (1,1,1)(5,1,4)^12. Diperoleh 9 model yang seluruh parameternya signifikan sebagai berikut.
#Model SARIMA (1,1,1)(5,1,4)^12
fit1=arima(x=y,order=c(0,1,1),seasonal=list(order=c(0,1,1),period=12))
fit1
##
## Call:
## arima(x = y, order = c(0, 1, 1), seasonal = list(order = c(0, 1, 1), period = 12))
##
## Coefficients:
## ma1 sma1
## -0.8797 -0.3913
## s.e. 0.0886 0.1510
##
## sigma^2 estimated as 3.879e-05: log likelihood = 265.33, aic = -524.66
coeftest(fit1)
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## ma1 -0.879685 0.088581 -9.9309 < 2.2e-16 ***
## sma1 -0.391318 0.151045 -2.5907 0.009577 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
fit5=arima(x=y,order=c(0,1,1),seasonal=list(order=c(1,1,0),period=12))
fit5
##
## Call:
## arima(x = y, order = c(0, 1, 1), seasonal = list(order = c(1, 1, 0), period = 12))
##
## Coefficients:
## ma1 sar1
## -0.8977 -0.2165
## s.e. 0.0889 0.1091
##
## sigma^2 estimated as 4.104e-05: log likelihood = 263.93, aic = -521.87
coeftest(fit5)
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## ma1 -0.89768 0.08888 -10.1000 <2e-16 ***
## sar1 -0.21651 0.10910 -1.9845 0.0472 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
fit10=arima(x=y,order=c(0,1,1),seasonal=list(order=c(2,1,0),period=12))
fit10
##
## Call:
## arima(x = y, order = c(0, 1, 1), seasonal = list(order = c(2, 1, 0), period = 12))
##
## Coefficients:
## ma1 sar1 sar2
## -0.8852 -0.2963 -0.3361
## s.e. 0.0820 0.1113 0.1274
##
## sigma^2 estimated as 3.634e-05: log likelihood = 266.95, aic = -525.91
coeftest(fit10)
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## ma1 -0.885165 0.082005 -10.7940 < 2.2e-16 ***
## sar1 -0.296332 0.111297 -2.6625 0.007756 **
## sar2 -0.336089 0.127419 -2.6377 0.008348 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
fit31=arima(x=y,order=c(1,1,1),seasonal=list(order=c(0,1,1),period=12))
fit31
##
## Call:
## arima(x = y, order = c(1, 1, 1), seasonal = list(order = c(0, 1, 1), period = 12))
##
## Coefficients:
## ar1 ma1 sma1
## 0.3928 -0.9559 -0.4869
## s.e. 0.1262 0.0599 0.1646
##
## sigma^2 estimated as 3.319e-05: log likelihood = 270.07, aic = -532.14
coeftest(fit31)
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## ar1 0.392797 0.126205 3.1124 0.001856 **
## ma1 -0.955904 0.059921 -15.9527 < 2.2e-16 ***
## sma1 -0.486907 0.164635 -2.9575 0.003102 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
fit35=arima(x=y,order=c(1,1,1),seasonal=list(order=c(1,1,0),period=12))
fit35
##
## Call:
## arima(x = y, order = c(1, 1, 1), seasonal = list(order = c(1, 1, 0), period = 12))
##
## Coefficients:
## ar1 ma1 sar1
## 0.3637 -0.9692 -0.2585
## s.e. 0.1221 0.0584 0.1118
##
## sigma^2 estimated as 3.607e-05: log likelihood = 268.2, aic = -528.4
coeftest(fit35)
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## ar1 0.363672 0.122141 2.9775 0.002906 **
## ma1 -0.969201 0.058364 -16.6062 < 2.2e-16 ***
## sar1 -0.258540 0.111786 -2.3128 0.020732 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
fit61=arima(x=y,order=c(1,1,0),seasonal=list(order=c(0,1,1),period=12))
fit61
##
## Call:
## arima(x = y, order = c(1, 1, 0), seasonal = list(order = c(0, 1, 1), period = 12))
##
## Coefficients:
## ar1 sma1
## -0.2369 -0.6057
## s.e. 0.1164 0.1666
##
## sigma^2 estimated as 4.096e-05: log likelihood = 262.41, aic = -518.81
coeftest(fit61)
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## ar1 -0.23688 0.11637 -2.0356 0.0417875 *
## sma1 -0.60574 0.16658 -3.6363 0.0002766 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
fit65=arima(x=y,order=c(1,1,0),seasonal=list(order=c(1,1,0),period=12))
fit65
##
## Call:
## arima(x = y, order = c(1, 1, 0), seasonal = list(order = c(1, 1, 0), period = 12))
##
## Coefficients:
## ar1 sar1
## -0.2724 -0.3091
## s.e. 0.1138 0.1120
##
## sigma^2 estimated as 4.7e-05: log likelihood = 259.51, aic = -513.02
coeftest(fit65)
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## ar1 -0.27237 0.11382 -2.3930 0.016713 *
## sar1 -0.30913 0.11200 -2.7601 0.005778 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
fit70=arima(x=y,order=c(1,1,0),seasonal=list(order=c(2,1,0),period=12))
fit70
##
## Call:
## arima(x = y, order = c(1, 1, 0), seasonal = list(order = c(2, 1, 0), period = 12))
##
## Coefficients:
## ar1 sar1 sar2
## -0.2571 -0.4321 -0.3353
## s.e. 0.1147 0.1211 0.1329
##
## sigma^2 estimated as 4.182e-05: log likelihood = 262.29, aic = -516.57
coeftest(fit70)
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## ar1 -0.25710 0.11473 -2.2409 0.0250332 *
## sar1 -0.43212 0.12107 -3.5690 0.0003583 ***
## sar2 -0.33530 0.13285 -2.5239 0.0116059 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
fit75=arima(x=y,order=c(1,1,0),seasonal=list(order=c(3,1,0),period=12))
fit75
##
## Call:
## arima(x = y, order = c(1, 1, 0), seasonal = list(order = c(3, 1, 0), period = 12))
##
## Coefficients:
## ar1 sar1 sar2 sar3
## -0.2841 -0.5565 -0.4934 -0.3367
## s.e. 0.1147 0.1268 0.1426 0.1528
##
## sigma^2 estimated as 3.721e-05: log likelihood = 264.27, aic = -518.54
coeftest(fit75)
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## ar1 -0.28414 0.11473 -2.4765 0.0132671 *
## sar1 -0.55652 0.12675 -4.3906 1.13e-05 ***
## sar2 -0.49338 0.14260 -3.4599 0.0005404 ***
## sar3 -0.33672 0.15279 -2.2038 0.0275367 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Berdasarkan sembilan model di atas, selanjutnya akan dilakukan pengujian diagnostik.
Uji Diagnostik yang pertama dilakukan adalah uji normalitas residual dengan menggunakan Uji Kolmogorov Smirnov.
#Uji Normalitas Residual
res1=resid(fit1)
res5=resid(fit5)
res10=resid(fit10)
res31=resid(fit31)
res35=resid(fit35)
res61=resid(fit61)
res65=resid(fit65)
res70=resid(fit70)
res75=resid(fit75)
ks.test(res1,"pnorm",mean(res1),sd(res1)) #Normal
##
## Exact one-sample Kolmogorov-Smirnov test
##
## data: res1
## D = 0.12622, p-value = 0.1183
## alternative hypothesis: two-sided
ks.test(res5,"pnorm",mean(res5),sd(res5))
##
## Exact one-sample Kolmogorov-Smirnov test
##
## data: res5
## D = 0.15456, p-value = 0.02928
## alternative hypothesis: two-sided
ks.test(res10,"pnorm",mean(res10),sd(res10)) #Normal
##
## Exact one-sample Kolmogorov-Smirnov test
##
## data: res10
## D = 0.12443, p-value = 0.128
## alternative hypothesis: two-sided
ks.test(res31,"pnorm",mean(res31),sd(res31)) #Normal
##
## Exact one-sample Kolmogorov-Smirnov test
##
## data: res31
## D = 0.14204, p-value = 0.0562
## alternative hypothesis: two-sided
ks.test(res35,"pnorm",mean(res35),sd(res35)) #Normal
##
## Exact one-sample Kolmogorov-Smirnov test
##
## data: res35
## D = 0.14384, p-value = 0.05135
## alternative hypothesis: two-sided
ks.test(res61,"pnorm",mean(res61),sd(res61)) #Normal
##
## Exact one-sample Kolmogorov-Smirnov test
##
## data: res61
## D = 0.12982, p-value = 0.1007
## alternative hypothesis: two-sided
ks.test(res65,"pnorm",mean(res65),sd(res65)) #Normal
##
## Exact one-sample Kolmogorov-Smirnov test
##
## data: res65
## D = 0.13432, p-value = 0.08173
## alternative hypothesis: two-sided
ks.test(res70,"pnorm",mean(res70),sd(res70)) #Normal
##
## Exact one-sample Kolmogorov-Smirnov test
##
## data: res70
## D = 0.11492, p-value = 0.1907
## alternative hypothesis: two-sided
ks.test(res75,"pnorm",mean(res75),sd(res75))
##
## Exact one-sample Kolmogorov-Smirnov test
##
## data: res75
## D = 0.14576, p-value = 0.04656
## alternative hypothesis: two-sided
Berdasarkan hasil pengujian normalitas residual, diperoleh 7 model dengan nilai p-value lebih dari taraf signifikansi sebesar 0,05. Sehingga disimpulkan bahwa terdapat 7 model dengan residual yang mengikuti distribusi normal. Sehingga dari 7 model tersebut akan dilakukan pengujian diagnostik selanjutnya yaitu pengujian asumsi white noise.
#Uji White Noise
tsdiag(fit1, length(y))
tsdiag(fit10, length(y))
tsdiag(fit31,length(y))
tsdiag(fit35, length(y))
tsdiag(fit61, length(y))
tsdiag(fit65, length(y))
tsdiag(fit70, length(y))
Berdasarkan hasil grafik Ljung Box ketujuh model, diperoleh bahwasanya hanya fit31 yang memenuhi syarat white noise karena nilai p-value setiap lag lebih besar dari 0,05 (secara visual berada di atas garis batas signifikansi 0,05).
Sehingga disimpulkan bahwa fit31 yaitu model ARIMA(1,1,1)(0,1,1)^12 merupakan model terbaik, karena model tersebut memenuhi seluruh asumsi. Maka model tersebut yang akan terpilih menjadi model untuk peramalan. Sebelum peramalan akan dilakukan pengecekan nilai evaluasi pada model terbaik.
model1=arima(y,order=c(1,1,1),seasonal=list(order=c(0,1,1),period=12))
summary(model1)
##
## Call:
## arima(x = y, order = c(1, 1, 1), seasonal = list(order = c(0, 1, 1), period = 12))
##
## Coefficients:
## ar1 ma1 sma1
## 0.3928 -0.9559 -0.4869
## s.e. 0.1262 0.0599 0.1646
##
## sigma^2 estimated as 3.319e-05: log likelihood = 270.07, aic = -532.14
##
## Training set error measures:
## ME RMSE MAE MPE MAPE
## Training set -0.0002203287 0.005321582 0.003322583 -0.02267762 0.3272724
## MASE ACF1
## Training set 0.608996 0.02170787
Berdasarkan hasil evaluasi di atas diperoleh nilai MAPE sebesar 32%, hal ini menunjukkan bahwasanya model memiliki akurasi yang baik dalam memprediksi data. Dengan model tersebut, selanjutnya akan dilakukan peramalan.
#Prediksi
prediksi_sarima <- fitted(model1)^(1/p$lambda)
#Peramalan
peramalan_sarima <- predict(model1, n.ahead = nrow(outsample))$pred^(1/-0.006150835)
#Akurasi Peramalan
akurasi_sarima <- akurasi_model(outsample$zt,peramalan_sarima)
akurasi_sarima
## Warning in attr(x, "align"): 'xfun::attr()' is deprecated.
## Use 'xfun::attr2()' instead.
## See help("Deprecated")
| MAPE | RMSE | SMAPE |
|---|---|---|
| 31.047 | 0.2049 | 37.1082 |
#Perbandingan Akurasi
#Perbandingan Akurasi
data.frame( Model = c( "SARIMA"), MAPE = c( akurasi_sarima$MAPE),
RMSE = c( akurasi_sarima$RMSE), SMAPE = c( akurasi_sarima$SMAPE) )
## Warning in attr(x, "align"): 'xfun::attr()' is deprecated.
## Use 'xfun::attr2()' instead.
## See help("Deprecated")
| Model | MAPE | RMSE | SMAPE |
|---|---|---|---|
| SARIMA | 31.047 | 0.2049 | 37.1082 |
#Grafik Perbandingan
ts.plot(data$data,type = "o",col="grey22",main="Produksi Kopi 2017 sampai 2024",xlab="Periode",ylab="Jumlah Pencarian",xlim=c(0,nrow(data)),ylim=c(0,10),lwd=1.5)
lines(c(prediksi_sarima, peramalan_sarima), type = "o",col="green", lwd=1.5)
abline(v=length(Zt)+0.5, col="orange", lwd=1.5,lty=2)
legend('topleft',legend=c("Aktual","Prediksi"),col=c("grey22", "green"),lty=1, cex = 1, lwd = 2)
Berdasarkan grafik tersebut terlihat bahwa garis hitam merepresentasikan data aktual, sementara garis hijau menunjukkan hasil prediksi model. Secara umum, model mampu menangkap pola musiman tahunan dengan cukup baik, ditunjukkan oleh kemiripan bentuk dan letak puncak antara data aktual dan prediksi. Puncak pencarian yang terjadi secara berkala berhasil direplikasi oleh model, meskipun dengan intensitas yang sedikit lebih rendah pada beberapa titik. Hal ini mengindikasikan bahwa model dapat mengidentifikasi karakteristik musiman dalam data. Setelah titik vertikal oranye (batas data insample), hasil peramalan tetap mempertahankan pola musiman yang serupa, hal ini menunjukkan kemampuan model dalam memproyeksikan tren jangka pendek dengan baik.
Zt<-ts(data$data)
Zt
## Time Series:
## Start = 1
## End = 96
## Frequency = 1
## [1] 0.03 0.05 0.05 1.14 2.24 3.89 4.75 5.14 4.89 4.48 2.79 0.85 0.02 0.07 0.03
## [16] 0.71 2.33 4.40 7.05 5.94 3.59 2.17 1.25 0.57 0.57 0.01 0.01 0.02 0.19 0.86
## [31] 2.96 2.74 1.78 1.13 0.22 0.13 0.05 0.04 0.05 0.03 0.04 0.33 1.11 1.28 1.47
## [46] 0.54 0.09 0.06 0.01 0.01 0.02 0.07 0.22 0.87 1.60 1.71 0.53 0.12 0.12 0.05
## [61] 0.01 0.01 0.03 0.03 0.32 0.91 1.07 1.04 0.37 0.14 0.06 0.02 0.05 0.05 0.01
## [76] 0.04 0.40 0.85 0.89 0.70 0.22 0.05 0.04 0.02 0.03 0.03 0.01 0.03 0.37 0.90
## [91] 0.99 0.88 0.29 0.09 0.05 0.02
jumlah_train = round(NROW(Zt)*0.90,0)
jumlah_test = NROW(Zt)-jumlah_train
data_train = Zt[1:jumlah_train]
data_test = Zt[(jumlah_train+1):(jumlah_test+jumlah_train)]
max<-max(data_train)
min<-min(data_train)
newmax<-(1)
newmin<-(-1)
Yt<-(((data_train-min)/(max-min))*(newmax-newmin))+newmin
Yt
## [1] -0.99431818 -0.98863636 -0.98863636 -0.67897727 -0.36647727 0.10227273
## [7] 0.34659091 0.45738636 0.38636364 0.26988636 -0.21022727 -0.76136364
## [13] -0.99715909 -0.98295455 -0.99431818 -0.80113636 -0.34090909 0.24715909
## [19] 1.00000000 0.68465909 0.01704545 -0.38636364 -0.64772727 -0.84090909
## [25] -0.84090909 -1.00000000 -1.00000000 -0.99715909 -0.94886364 -0.75852273
## [31] -0.16193182 -0.22443182 -0.49715909 -0.68181818 -0.94034091 -0.96590909
## [37] -0.98863636 -0.99147727 -0.98863636 -0.99431818 -0.99147727 -0.90909091
## [43] -0.68750000 -0.63920455 -0.58522727 -0.84943182 -0.97727273 -0.98579545
## [49] -1.00000000 -1.00000000 -0.99715909 -0.98295455 -0.94034091 -0.75568182
## [55] -0.54829545 -0.51704545 -0.85227273 -0.96875000 -0.96875000 -0.98863636
## [61] -1.00000000 -1.00000000 -0.99431818 -0.99431818 -0.91193182 -0.74431818
## [67] -0.69886364 -0.70738636 -0.89772727 -0.96306818 -0.98579545 -0.99715909
## [73] -0.98863636 -0.98863636 -1.00000000 -0.99147727 -0.88920455 -0.76136364
## [79] -0.75000000 -0.80397727 -0.94034091 -0.98863636 -0.99147727 -0.99715909
## [85] -0.99431818 -0.99431818
pacf(data_train)
Berdasarkan grafik dapat dilihat bahwa terdapat 2 lag dengan nilai PACF yang signifikan, yaitu lag ke-1 dan lag ke-2. Berdasarkan hal tersebut, variabel masukan yang digunakan pada metode NN adalah error t???1 dan error t???2 sebagai x1 dan x2. Selanjutnya, keluaran yang digunakan merupakan data produksi perkebunan kopi di Indonesia yang telah distandarisasi dan dilambangkan dengan Y, selanjutnya data masukan dan keluaran dimulai dari t = 3.
X<-Yt[1:84]
Y<-Yt[3:86]
length(X)
## [1] 84
length(Y)
## [1] 84
Kemudian, dilakukan proses pelatihan backpropagation dengan 1 neuron, 2 neuron, dan 3 neuron pada lapisan tersembunyi. Kondisi pemberhentian yang digunakan adalah maksimum iterasi sebesar 10.000 dan target error sebesar 0,05. Berdasarkan proses pelatihan yang dilakukan, diperoleh arsitektur NN sebagai berikut:
Prediksi1<-(((Predict1-newmin)/(newmax-newmin))*(max-min))+min
Prediksi2<-(((Predict2-newmin)/(newmax-newmin))*(max-min))+min
Prediksi3<-(((Predict3-newmin)/(newmax-newmin))*(max-min))+min
MAPE_1<-MAPE(Prediksi1[1:84],Yt[3:86])*100
MAPE_2<-MAPE(Prediksi2[1:84],Yt[3:86])*100
MAPE_3<-MAPE(Prediksi3[1:84],Yt[3:86])*100
MAPE_1
## [1] 527.8965
MAPE_2 #TERBAIK
## [1] 520.1451
MAPE_3
## [1] 541.4504
Berdasarkan hasil output, dapat dilihat bahwa NN dengan 1 neuron, 2 neuron, dan 3 neuron mempunyai kemampuan peramalan yang buruk untuk meramalkan produksi kopi di Indonesia. Namun NN dengan 2 neuron lebih baik dibandingkan model lainnya, sehingga dipilih model terbaiknya yaitu NN 2 neuron.
ts.plot(data_train[1:84],col="black",type="o",main="Peramalan Produksi Kopi di Indonesia",xlab="Waktu",ylab="Produksi",
lwd=1, xlim = c(0, length(data_train)))
lines(Prediksi2,col="blue",type="o",lwd=1)
legend('topright',legend=c("Aktual","Prediksi"),col=c("black","blue"),lty=1, cex = 1.05)
Ytest=c(Y,rep(0,11))
k=11
for (i in 87:97)
{
Xtest=t(matrix(c(Ytest[i-1]),byrow=FALSE))
Ytest[i]=compute(nn2,covariate=Xtest)$net.result
}
Ytest=ts(Ytest[87:97])
Ytest
## Time Series:
## Start = 1
## End = 11
## Frequency = 1
## [1] -0.1774272 -0.2938434 -0.3867841 -0.4667031 -0.5364119 -0.5958455
## [7] -0.6442900 -0.6816864 -0.7090536 -0.7281858 -0.7410938
Peramalan<-(((Ytest-newmin)/(newmax-newmin))*(max-min))+min
Aktual<-Zt
Hasil_NN<-ts(c(NA,Prediksi2,Peramalan))
plot(Hasil_NN,ylim=c(0,10),main="",sub="Januari 2017 - Desember 2024",xlim=c(0,120),
ylab="Produksi Kopi (Ribu Ton)", xlab="Periode",col="white",lty=1,lwd=2)
points(Hasil_NN[1:96],cex=1,col="orange",pch=19)
lines(Hasil_NN[1:96],col="orange",lwd=3,cex=1.5)
points(Aktual[1:86],cex=1,col="black",pch=10)
lines(Aktual[1:86],col="black",lwd=1.5,cex=1)
lines(87:96, Aktual[87:96], col="blue", cex=1, lwd=1.5)
points(87:96, Aktual[87:96], pch=10, col="blue")
legend("topleft",c("Data Train"),bty="n",cex=1,lty=1, col="black",lwd=3,bg="white")
legend("top",c("Data test"),bty="n",cex=1,lty=1, col="blue",lwd=3,bg="white")
legend("topright",c("NN 2 Neuron"),bty="n",cex=1,lty=1, col="orange",lwd=3,bg="white")
grid()
Berdasarkan gambar diatas dapat dilihat bahwa model NN mampu mengikuti pola musiman tahunan dengan cukup baik, terutama pada bagian data latih. Namun, terlihat bahwa pada beberapa puncak produksi (khususnya sekitar periode ke-20 dan ke-80), model cenderung meremehkan nilai aktual (underfitting). Pada data uji, meskipun model masih dapat mengikuti arah tren secara umum, terdapat deviasi antara nilai aktual dan hasil prediksi, yang menunjukkan bahwa model memiliki keterbatasan dalam menangkap fluktuasi mendadak. Secara keseluruhan, model NN dengan 3 neuron cukup mampu menangkap pola musiman, namun peningkatan jumlah neuron atau teknik lain mungkin diperlukan untuk meningkatkan akurasi prediksi.