Bab 3 Optimisasi Parameter Pemulusan dengan Validasi Silang

library(smoothCV)

3.1 Metode

3.1.1 Validasi Silang Deret Waktu

Validasi silang deret waktu merupakan modifikasi yang lebih canggih dari pembagian training dan testing. Salah satu variasi dari prosedur ini menghasilkan beberapa data uji yang tersusun atas satu observasi. Data latih merupakan semua observasi sebelum data uji tersebut. Beberapa observasi awal menjadi data latin (Hyndman dan Athanasopoulos 2021). Akurasi dihitung dengan merata-ratakan dari beberapa iterasi.

Cerqueira et al. (2020) mengevaluasi modifikasi dari algoritma di atas. Data dibagi menjadi beberapa blok - blok pertama menjadi data latih dan blok kedua menjadi data uji. Di iterasi selanjutnya, blok pertama dan kedua menjadi data latih dan blok ketiga menjadi data uji, dan seterusnya. Algoritma tersebut dibandingkan dengan sliding window, di mana blok-blok sebelumnya dilupakan (di iterasi kedua, blok kedua menjadi data latih dan blok ketiga menjadi data uji), dan algoritma lain yang memberikan gap. Algoritma tersebut dibandingkan dengan holdout (latih-uji tradisional) dan repeated holdout - algoritma di mana sebagian data telah dibagi menjadi training dan testing, tetapi titik pemisahan eksaknya dicari secara acak (misal, titik pemisahannya berada di antara \(70\%-90\%\) - akan dicari angka acak antara angka tersebut).

Metode validasi silang berperforma baik di data sintetis \(AR(3)\) dan \(SAR\), tetapi berperforma di bawah rata-rata untuk \(MA(1)\). Validasi silang berperforma baik di 31 deret waktu stasioner, tetapi kurang baik di 31 deret waktu non-stasioner. Repeated holdout nampaknya berperforma paling baik.

Schnaubelt (2019) melakukan simulasi metode tersebut di suatu deret waktu yang mengalami perubahan mean dan ragam setelah periode waktu tertentu. Secara umum, untuk metode validasi silang dengan blok yang membesar berperforma paling baik saat gangguan tidak sangat besar (koefisien berubah kurang dari \(15\%\)). Selebihnya metode holdout lebih baik.

Dalam implementasinya ke harga minyak, akan digunakan algoritma validasi silang:

  1. Pilih n data awal sebagai training.
  2. Bagi sisanya jadi beberapa fold buat testing. Fold ke-1 menjadi testing di iterasi 1, fold ke-2 jadi testing di iterasi 2
  3. Untuk tiap iterasi:
    1. Hitung error
    2. Gabungkan data testing ke data training. Gunakan fold selanjutnya sebagai testing.

Ini analog dengan validasi silang dengan blok yang membesar. COVID dan perang Ukraina-Rusia dapat dianggap sebagai gangguan pada harga minyak, tetapi perubahan koefisien secara khusus tidak diketahui. Dapat dianggap gangguan tersebut tidak besar karena tren harga minyak sebelum perang masih naik. Semisal gangguan tersebut besar, ambil saja data dengan iterasi terakhir.

3.1.2 Metrik

Ada tiga metrik yang akan dipakai. Diskusi metrik tersebut terkandung di Hyndman dan Athanasopoulos (2021):

\[ MSE=\frac{1}{n}\sum_{i=1}^n (y_t-\hat{y}_t)^2 \]

MSE secara umum memboboti outlier secara lebih besar. Suatu contoh numerik sederhana: anggap ada gugus data dengan error (1,1,1), dan gugus data lain dengan error (0,0,3). Maka:

\[ MSE_1=\frac{1}{3}(1^2+1^2+1^2)=1\\ MSE_2=\frac{1}{3}(0^2+0^2+3^2)=3 \]

Secara absolut, error sama tetapi di gugus kedua ada outlier: \[ MAPE=\frac{1}{n}\sum_{i=1}^n \left|\frac{y_t-\hat{y}_t}{y_t}\right| \]

Note, MAPE lebih memboboti observasi dengan nilai amatan kecil. Artinya, overestimasi diboboti lebih besar dari underestimasi. Contoh numerik lain, anggap dugaan adalah 2. Semisal nilai asli adalah 3, atau 1:

\[ \begin{aligned} MAPE_1&= \left|\frac{2-1}{1}\right|=1\\ MAPE_2&= \left|\frac{2-3}{1}\right|=\frac{1}{3} \end{aligned} \]

Dan MAE:

\[ MAE=\frac{1}{n}\sum_{i=1}^n \left|y_t-\hat{y}_t\right| \]

3.2 Single Moving Average

Single Moving Average adalah suatu teknik pemulusan yang bertujuan untuk melihat grafik secara eksploratif dengan cara menghitung rata-rata periode sekarang dengan periode sebelumnya. Hal ini berguna untuk melihat pola dari suatu data tanpa dipengaruhi data harian yang bergerak lebih ekstrem (Montgomery et al. 2008).

Rumus dari Single Moving Average adalah:

\[ \begin{aligned} M_{T} = \left[y_{T} + y_{(T-1)} + ... + y_{(T-n+1)}\right]/n = 1/N \\ \sum_{t=T-n+1}^{T} y_{t} \end{aligned} \]

3.3 Validasi silang untuk SMA

Lakukan validasi silang untuk SMA dengan jumlah data latih awal sebesar 36 untuk mendapat parameter optimal. Selebihnya, data dibagi menjadi 15 fold sehingga ada \((276-36)/15=16\) observasi di tiap fold. Nilai M yang diuji adalah dari 2 sampai 30.

SMACV<-fcCV(weeklyCrude[,3],initialn=36,folds=15,type="SMA",start=2,end=30,dist=1)

Hasil dari prosedur tersebut:

resultSMA<-SMACV[[3]]

Buat boxplot untuk melihat M yang meminimumkan error:

library(ggplot2)
ggplot(resultSMA,aes(x=M,y=MSE,group=M))+
  geom_boxplot(fill="#E69F00")+theme_minimal()+
  ggtitle("Boxplot MSE tiap M untuk SMA")+
  xlab("M")+ylab(" ")

Dapat dilihat bahwa median MSE cenderung sama di tiap nilai parameter M. Setelah melewati \(M=20\), median baru terlihat naik. Namun, keragaman dari boxplot cenderung terus meningkat jika nilai parameter bertambah. Hampir semua boxplot memiliki pencilan. Bagaimana dengan MAPE?

library(ggplot2)
ggplot(resultSMA,aes(x=M,y=MAPE,group=M))+
  geom_boxplot(fill="#E69F00")+theme_minimal()+
  ggtitle("Boxplot MAPE tiap M untuk SMA")+
  xlab("M")+ylab(" ")

Hasil cukup mirip dengan MSE, tetapi ada sedikit perbedaan. Nilai pencilan pada boxplot MAPE cenderung meningkat seiring dengan bertambahnya nilai parameter M sampai \(M=10\), lalu stagnan. Bagaimana dengan MAE:

ggplot(resultSMA,aes(x=M,y=MAE,group=M))+
  geom_boxplot(fill="#E69F00")+theme_minimal()+
  ggtitle("Boxplot MAE tiap M untuk SMA")+
  xlab("M")+ylab(" ")

Garis median terlihat sedikit menaik saat nilai parameter M makin membesar. Nilai outlier di nilai \(M\leq 6\) terlihat menggerombol, sedangkan makin banyak M salah satu outlier bergabung ke boxplot dan satu lagi menjauh dari boxplot. Boxplot membesar sehingga kesalahan lebih beragam saat makin besar M. Lanjutkan dengan buat agregasi:

aggregateSMA<-resultSMA[,`.`(meanMSE=mean(MSE),
                 varMSE=var(MSE),
                 meanMAPE=mean(MAPE),
                 varMAPE=var(MAPE),
                 meanMAE=mean(MAE),
                 varMAE=var(MAE)), by=list(M)]

Jika dilihat nilai M yang meminimumkan mean dari MSE, MAPE, dan MAE:

knitr::kables(list(
  knitr::kable(head(setorder(aggregateSMA, meanMSE)[,c(1,2)],n=7),
               col.names = c("M","MSE")),
  knitr::kable(head(setorder(aggregateSMA, meanMAPE)[,c(1,4)],n=7),
               col.names = c("M","MAPE")),
  knitr::kable(head(setorder(aggregateSMA, meanMAE)[,c(1,6)],n=7),
               col.names = c("M","MAE"))
  ),
  caption="Rata-rata dari metrik akurasi untuk tiap nilai M (SMA)."
)
Table 3.1: Rata-rata dari metrik akurasi untuk tiap nilai M (SMA).
M MSE
2 108.0670
3 114.7901
4 118.5380
5 125.9310
6 132.4537
7 135.9281
8 139.0788
M MAPE
2 14.60480
3 14.92289
4 15.17458
5 15.56182
6 16.18383
7 16.87461
8 17.63472
M MAE
2 7.290667
3 7.468417
4 7.634146
5 7.846216
6 8.134944
7 8.387143
8 8.673552

Nilai MSE dan MAPE berurutan dari 2, 3, …, 8 dari yang terkecil hingga terbesar. Kemudian, hitung nilai M yang meminimumkan ragam MSE dan MAPE:

knitr::kables(list(
  knitr::kable(head(setorder(aggregateSMA, varMSE)[,c(1,3)],n=7),
               col.names = c("M","MSE")),
  knitr::kable(head(setorder(aggregateSMA, varMAPE)[,c(1,5)],n=7),
               col.names = c("M","MSE")),
  knitr::kable(head(setorder(aggregateSMA, varMAE)[,c(1,7)],n=7),
               col.names = c("M","MSE"))
  ),
    caption="Ragam dari metrik akurasi per iterasi untuk tiap nilai M (SMA)."
)
Table 3.2: Ragam dari metrik akurasi per iterasi untuk tiap nilai M (SMA).
M MSE
2 33470.24
3 39948.60
4 41435.88
5 47620.23
11 48140.85
8 48188.65
10 48264.50
M MSE
2 397.2491
4 434.3998
3 435.2714
5 446.5725
6 467.8972
7 507.1456
8 540.2385
M MSE
2 37.56372
3 41.68619
4 42.28482
12 44.68658
11 44.71050
10 45.01530
13 45.01998

Urutan nilai M yang meminimumkan ragam metrik-metrik tersebut sedikit berbeda. Walaupun \(M=2\) memiliki performa terbaik dalam meminimumkan rata-rata metrik, \(M=3\) sepertinya lebih baik dalam meminimumkan ragam dari metrik-metrik tersebut. Ini secara umum berarti kesalahan-kesalahan dari \(M=3\) akan lebih sering mendekati suatu nilai tertentu, walaupun rataannya lebih besar dari \(M=2\). Dapat dipilih dua nilai tersebut sebagai parameter optimal.

Setelah itu, cari iterasi-iterasi yang memiliki akurasi rendah:

library(ggplot2)
ggplot(resultSMA,aes(x=iter,y=MSE,group=iter))+
 geom_boxplot(fill="#E69F00")+theme_minimal()+
 ggtitle("Boxplot MSE tiap Iterasi")+
 xlab("Iterasi")+ylab(" ")

Boxplot untuk iterasi ke-9 (saat pandemi) dan ke-15 (pasca pandemi dan perang Rusia-Ukraina) memiliki rataan dan keragaman yang cukup besar dibandingkan iterasi lainnya pada data testing karena adanya fluktuasi yang ekstrem pada rentang waktu tersebut. Fluktuasi tersebut tidak cocok untuk SMA karena kurang dapat menangani data dengan tren.

library(ggplot2)
ggplot(resultSMA,aes(x=iter,y=MAPE,group=iter))+
  geom_boxplot(fill="#E69F00")+theme_minimal()+
  ggtitle("Boxplot MAPE tiap Iterasi")+
  xlab("Iterasi")+ylab(" ")

Boxplot untuk iterasi ke-15 ternyata tidak memiliki MAPE besar. Ini terjadi karena MAPE lebih memboboti observasi dengan nilai amatan kecil (COVID saat harga minyak turun) daripada saat nilai amatan besar (Ukraina-Rusia saat terjadi inflasi harga minyak).

library(ggplot2)
ggplot(resultSMA,aes(x=iter,y=MAE,group=iter))+
  geom_boxplot(fill="#E69F00")+theme_minimal()+
  ggtitle("Boxplot MAE tiap Iterasi")+
  xlab("Iterasi")+ylab(" ")

Boxplot MAE per iterasi mengikuti boxplot MSE - terjadi performa buruk di iterasi ke-9 dan 15.

3.3.1 Kesimpulan

Berdasarkan nilai rataan dan ragam MSE dan MAPE, parameter m untuk metode SMA yang dipakai adalah saat M = 2 dan 3.

3.4 DMA

Lakukan validasi silang untuk DMA dengan jumlah data latih awal sebesar 36 untuk mencari nilai parameter optimum. Selebihnya, data dibagi menjadi 15 fold sehingga ada \((276-36)/15=16\) observasi di tiap fold. Nilai M yang diuji adalah dari 2 sampai 16.

DMACV<-fcCV(weeklyCrude[,3],initialn=36,folds=15,type="DMA",start=2,end=16,dist=1)

Ambil hasil dari prosedur tersebut:

resultDMA<-DMACV[[3]]

Buat boxplot untuk melihat M yang meminimumkan error:

library(ggplot2)
ggplot(resultDMA,aes(x=M,y=MSE,group=M))+
  geom_boxplot(fill="#E69F00")+theme_minimal()+
  ggtitle("Boxplot MSE tiap M")+
  xlab("M")+ylab(" ")

Dapat dilihat bahwa error dari tiap parameter cukup bervariasi di tiap iterasi. Hampir semua boxplot memiliki pencilan yang sangat jauh dari kebanyakan observasi. Namun, terlihat bahwa di \(9\leq M\leq 12\) keragamanboxplot lebih kecil, outlier lebih dekat, dan garis median lebih rendah dari boxplot lainnya. Ini berarti MSE di DMA dengan parameter tersebut biasanya rendah dan tidak beragam. Bagaimana dengan MAPE?

library(ggplot2)
ggplot(resultDMA,aes(x=M,y=MAPE,group=M))+
  geom_boxplot(fill="#E69F00")+theme_minimal()+
  ggtitle("Boxplot MAPE tiap M")+
  xlab("M")+ylab(" ")

Hasil cukup mirip dengan MSE, tetapi ada sedikit perbedaan. Terlihat bahwa di \(4\leq M \leq 7\), boxplot tidak memiliki pencilan sama sekali. Justru, daerah yang sebelumnya dianggap baik, \(9 \leq M \leq 12\) memiliki beberapa pencilan walaupun boxplot di daerah tersebut menunjukkan keragaman lebih kecil di antara kuantil pertama sampai ketiga.

library(ggplot2)
ggplot(resultDMA,aes(x=M,y=MAE,group=M))+
  geom_boxplot(fill="#E69F00")+theme_minimal()+
  ggtitle("Boxplot MAE tiap M")+
  xlab("M")+ylab(" ")

Boxplot MAE memiliki pola yang mengikuti MSE. Untuk memastikan, buat agregasi data error dari tiap nilai M:

aggregateDMA<-resultDMA[,`.`(meanMSE=mean(MSE),
                 varMSE=var(MSE),
                 meanMAPE=mean(MAPE),
                 varMAPE=var(MAPE),
                 meanMAE=mean(MAE),
                 varMAE=var(MAE)), by=list(M)]

Jika dilihat nilai M yang meminimumkan mean dari MSE:

knitr::kables(list(
  knitr::kable(head(setorder(aggregateDMA, meanMSE)[,c(1,2)],n=7),
               col.names = c("M","MSE")),
  knitr::kable(head(setorder(aggregateDMA, meanMAPE)[,c(1,4)],n=7),
                col.names = c("M","MAPE")),
  knitr::kable(head(setorder(aggregateDMA, meanMAE)[,c(1,6)],n=7),
                col.names = c("M","MAE"))
  ), caption="Rata-rata metrik akurasi di semua iterasi untuk tiap nilai M"
)
Table 3.3: Rata-rata metrik akurasi di semua iterasi untuk tiap nilai M
M MSE
11 118.3255
12 118.6915
10 133.1766
13 139.3820
9 165.7192
14 169.9829
15 197.5252
M MAPE
10 15.02806
9 15.67344
11 15.67879
12 16.39718
8 17.76458
13 17.99311
7 19.33181
M MAE
12 7.523578
11 7.578989
10 7.805900
13 8.056381
9 8.568045
14 9.024821
15 9.891670

Tampak bahwa nilai M=10 cukup konsisten baik (ranking 2) di MSE, MAPE, dan MAE. Nilai M=11 juga meminimumkan nilai harapan MAE dan MSE, tetapi tidak meminimumkan nilai harapan MAPE. Bagaimana dengan ragam dari MSE, MAPE, dan MAE?

knitr::kables(list(
  knitr::kable(head(setorder(aggregateDMA, varMSE)[,c(1,3)],n=7),
                col.names = c("M","MSE")),
  knitr::kable(head(setorder(aggregateDMA, varMAPE)[,c(1,5)],n=7),
                col.names = c("M","MAPE")),
    knitr::kable(head(setorder(aggregateDMA, varMAE)[,c(1,7)],n=7),
                  col.names = c("M","MAE"))
  ), caption="Ragam metrik akurasi di semua iterasi untuk tiap M"
)
Table 3.4: Ragam metrik akurasi di semua iterasi untuk tiap M
M MSE
12 34548.72
11 38944.08
13 48830.32
10 65084.47
14 78964.40
2 106858.62
15 109681.57
M MAPE
8 221.3336
9 230.1605
2 239.9527
10 303.3681
3 303.9728
7 309.7535
4 355.4908
M MAE
11 39.34564
12 44.04738
10 46.03796
3 53.34972
2 55.22787
13 56.67645
9 61.33235

M=10 dan 11 konsisten baik di berbagai metrik kecuali ragam dari MAPE.

Dapat juga dilihat iterasi mana yang memiliki kesalahan tinggi:

library(ggplot2)
ggplot(resultDMA,aes(x=iter,y=MSE,group=iter))+
  geom_boxplot(fill="#E69F00")+theme_minimal()+
  ggtitle("Boxplot MSE tiap Iterasi")+
  xlab("Iterasi")+ylab(" ")

Error terbesar ada di iterasi 5, 9, 10, dan 15. Iterasi 15 merupakan perang Rusia-Ukraina. Ada apa di iterasi 9 dan 10 tersebut?

knitr::kables(list(
  knitr::kable(c(DMACV[[1]][5],DMACV[[2]][5]),col.names = 
               "Range data iterasi 5"),
  knitr::kable(c(DMACV[[1]][9],DMACV[[1]][10],DMACV[[2]][10]),col.names = 
               "Range data iterasi 9-10")
)
)
Range data iterasi 5
101.5333
116.6667
Range data iterasi 9-10
166.0667
182.2000
197.3333

Cari tanggal tanggal tersebut:

knitr::kable(weeklyCrude[,2][c(101,116,165,181,196)])
Date
2018-12-07
2019-03-22
2020-02-28
2020-06-19
2020-10-02

Dari 2018-2019, harga turun. Tentu, 2020 adalah COVID. Namun, dari MSE terlihat bahwa performa DMA beragam. Di SMA, di iterasi tersebut boxplot hampir homogen memiliki nilai error tinggi. Ini berarti, ada nilai-nilai M tertentu yang dapat meminimukan error di data tren tersebut.

library(ggplot2)
ggplot(resultDMA,aes(x=iter,y=MAE,group=iter))+
  geom_boxplot(fill="#E69F00")+theme_minimal()+
  ggtitle("Boxplot MAE tiap Iterasi")+
  xlab("Iterasi")+ylab(" ")

Profil boxplot MAE untuk iterasi relatif sama dengan boxplot MSE.

library(ggplot2)
ggplot(resultDMA,aes(x=iter,y=MAPE,group=iter))+
  geom_boxplot(fill="#E69F00")+theme_minimal()+
  ggtitle("Boxplot MAPE tiap Iterasi")+
  xlab("Iterasi")+ylab(" ")

MAPE tidak memboboti error saat perang Ukraina dan Rusia, sama seperti saat SMA. Parameter terbaika dalah \(M=10\) dan \(M=11\).

3.5 SES

SESCV<-fcCV(weeklyCrude[,3],initialn=36,folds=15,type="SES",alphrange=seq(0.01,1,0.01))

Masukkan hasilnya:

resultSES<-SESCV[[3]]

Karena ada 100 nilai alpha yang berbeda, tidak praktis untuk membuat boxplot untuk semua nilai tersebut. Bulatkan nilai alpha sebesar satu desimal \((0.1, 0.2, \ldots)\) lalu buat boxplot. Gunakan latex2exp (Meschiari 2022) untuk menghasilkan teks judul dan sumbu x dengan simbol \(\alpha\):

library(latex2exp)
ggplot(resultSES,aes(x=alpha,y=MSE,group=round(alpha,1)))+
  geom_boxplot(fill="#E69F00")+theme_minimal()+
  ggtitle("Boxplot MSE di tiap alpha")+
  xlab(TeX(r'($\alpha$)'))+ylab(" ")

Sepertinya, makin besar nilai alpha hasil pemulusan semakin baik. Ini berarti bobot observasi sekarang lebih besar dari observasi sebelumnya. :

ggplot(resultSES,aes(x=alpha,y=MAE,group=round(alpha,1)))+
  geom_boxplot(fill="#E69F00")+theme_minimal()+
  ggtitle("Boxplot MAE di tiap alpha")+
  xlab(TeX(r'($\alpha$)'))+ylab(" ")

MAE nampaknya juga mengikuti pola tersebut.

ggplot(resultSES,aes(x=alpha,y=MAPE,group=round(alpha,1)))+
  geom_boxplot(fill="#E69F00")+theme_minimal()+
  ggtitle("Boxplot MAPE di tiap alpha")+
  xlab(TeX(r'($\alpha$)'))+ylab(" ")

MAPE juga mengikuti pola umum tersebut, tetapi nampaknya di \(\alpha=0.5\) nilai pencilan minimum. Lakukan agregasi:

aggregateSES<-resultSES[,`.`(meanMSE=mean(MSE),
                 varMSE=var(MSE),
                 meanMAPE=mean(MAPE),
                 varMAPE=var(MAPE),
                 meanMAE=mean(MAE),
                 varMAE=var(MAE)), by=list(alpha)]

Jika dilihat nilai \(\alpha\) yang meminimumkan mean dari MSE, MAPE, MAE:

knitr::kables(list(
  knitr::kable(head(setorder(aggregateSES, meanMSE)[,c(1,2)],n=20),
               col.names = c("$\\alpha$",'MSE')),
  knitr::kable(head(setorder(aggregateSES, meanMAPE)[,c(1,4)],n=20),
               col.names = c("$\\alpha$",'MAPE')),
  knitr::kable(head(setorder(aggregateSES, meanMAE)[,c(1,6)],n=20),
               col.names = c("$\\alpha$",'MAE'))
  ), caption="Rata-rata metrik akurasi untuk semua iterasi di tiap nilai $\\alpha$"
)
Table 3.5: Rata-rata metrik akurasi untuk semua iterasi di tiap nilai \(\alpha\)
\(\alpha\) MSE
1.00 94.34572
0.99 94.58195
0.98 94.82050
0.97 95.06133
0.96 95.30443
0.95 95.54979
0.94 95.79740
0.93 96.04725
0.92 96.29936
0.91 96.55372
0.90 96.81035
0.89 97.06929
0.88 97.33055
0.87 97.59417
0.86 97.86020
0.85 98.12867
0.84 98.39964
0.83 98.67317
0.82 98.94932
0.81 99.22817
\(\alpha\) MAPE
1.00 13.23114
0.99 13.25724
0.98 13.28320
0.97 13.30903
0.96 13.33471
0.95 13.36027
0.94 13.38568
0.93 13.41095
0.92 13.43609
0.91 13.46108
0.90 13.48594
0.89 13.51065
0.88 13.53523
0.87 13.55967
0.86 13.58408
0.85 13.60837
0.84 13.63287
0.83 13.65772
0.82 13.68243
0.81 13.70701
\(\alpha\) MAE
1.00 6.853250
0.99 6.861433
0.98 6.869597
0.97 6.877744
0.96 6.885874
0.95 6.893986
0.94 6.902082
0.93 6.910161
0.92 6.918225
0.91 6.926272
0.90 6.934305
0.89 6.942323
0.88 6.950327
0.87 6.958318
0.86 6.966374
0.85 6.974426
0.84 6.982615
0.83 6.991064
0.82 6.999505
0.81 7.007941

Nilai-nilai dari tabel ini cukup kontradiktif. Untuk meminimumkan MSE, sebaiknya mengambil \(\alpha\) sekitar 0.9. MAPE minimum di \(\alpha\) 0.6 sampai 0.7, sedangkan MAE minimum di \(\alpha\) 0.8. Bagaimana dengan ragam dari MSE, MAPE, dan MAE?

knitr::kables(list(
  knitr::kable(head(setorder(aggregateSES, varMSE)[,c(1,3)],n=7),
               col.names = c("$\\alpha$",'MSE')),
  knitr::kable(head(setorder(aggregateSES, varMAPE)[,c(1,5)],n=7),
               col.names = c("$\\alpha$",'MAPE')),
    knitr::kable(head(setorder(aggregateSES, varMAE)[,c(1,7)],n=7),
                 col.names = c("$\\alpha$",'MAE'))
  ), caption="Ragam metrik akurasi untuk semua iterasi di tiap nilai $\\alpha$"
)
Table 3.6: Ragam metrik akurasi untuk semua iterasi di tiap nilai \(\alpha\)
\(\alpha\) MSE
1.00 24798.11
0.99 24929.36
0.98 25063.65
0.97 25200.97
0.96 25341.31
0.95 25484.67
0.94 25631.05
\(\alpha\) MAPE
1.00 255.0456
0.99 257.5344
0.98 260.0311
0.97 262.5353
0.96 265.0464
0.95 267.5641
0.94 270.0878
\(\alpha\) MAE
1.00 30.09061
0.99 30.21161
0.98 30.33493
0.97 30.46053
0.96 30.58839
0.95 30.71849
0.94 30.85080

Ragam minimum MSE dan MAE minimum saat alpha mendekati 1, sedangkan ragam MAPE minimum saat alpha mendekati 0.5. Bagaimana dengan performa di tiap iterasi?

ggplot(resultSES,aes(x=iter,y=MSE,group=iter))+
  geom_boxplot(fill="#E69F00")+theme_minimal()+
  ggtitle("Boxplot MSE tiap Iterasi")+
  xlab("Iterasi")+ylab(" ")

Boxplot untuk iterasi ke-9 (saat pandemi) dan ke-15 (pasca pandemi dan perang Rusia-Ukraina) memiliki rataan dan keragaman yang cukup besar dibandingkan iterasi lainnya pada data testing karena adanya fluktuasi yang ekstrem pada rentang waktu tersebut. Fluktuasi tersebut tidak cocok untuk SES karena kurang dapat menangani data dengan tren.

ggplot(resultSES,aes(x=iter,y=MAPE,group=iter))+
  geom_boxplot(fill="#E69F00")+theme_minimal()+
  ggtitle("Boxplot MAPE tiap Iterasi")+
  xlab("Iterasi")+ylab(" ")

Boxplot untuk iterasi ke-15 ternyata tidak memiliki MAPE besar. Ini terjadi karena MAPE lebih memboboti observasi dengan nilai amatan kecil (COVID saat harga minyak turun) daripada saat nilai amatan besar (Ukraina-Rusia saat terjadi inflasi harga minyak).

ggplot(resultSES,aes(x=iter,y=MAE,group=iter))+
  geom_boxplot(fill="#E69F00")+theme_minimal()+
  ggtitle("Boxplot MAE tiap Iterasi")+
  xlab("Iterasi")+ylab(" ")

Boxplot MAE per iterasi secara umum lebih mengikuti MSE. Sama seperti SMA, nilai error homogen buruk di iterasi 9 dan 15.

3.6 DES

Load fungsi:

DESCV<-fcCV(weeklyCrude[,3],initialn=36,folds=15,type="DES",alphrange=seq(0.1,1,0.1),betarange=seq(0.1,1,0.1))

Masukkan hasilnya:

resultDES<-DESCV[[3]]

Karena parameter DES memiliki dua dimensi (alpha dan beta), cukup susah untuk menampilkan hasil optimalisasi parameter dalam suatu boxplot atau scatterplot. Oleh karena itu langsung buat agregasi:

aggregateDES<-resultDES[,`.`(meanMSE=mean(MSE),
                 varMSE=var(MSE),
                 meanMAPE=mean(MAPE),
                 varMAPE=var(MAPE),
                 meanMAE=mean(MAE),
                 varMAE=var(MAE)), by=list(alphrange,betarange)]

Buat heatmap untuk melihat titik mana memiliki rata-rata MSE yang rendah:

ggplot(aggregateDES, aes(alphrange, betarange)) +
  geom_tile(aes(fill = sqrt(meanMSE)), colour = "white") +
  scale_fill_gradient('Akar dari rata-rata MSE', low="#FFFFE0",high="#DB0000")+
  ggtitle("Heatmap rerata MSE untuk tiap nilai alpha dan beta")+
  theme_minimal()+theme(axis.title.y = element_text(angle = 0, vjust = 0.5))+
  xlab(TeX(r"($\alpha$)"))+ylab(TeX(r"($\beta$)"))

Terlihat bahwa di beta lebih dari \(0.1\) rata-rata dari MSE relatif lebih besar. Bagaimana dengan ragam dari MSE (menggunakan skala log agar mudah dilihat).

ggplot(aggregateDES, aes(alphrange, betarange)) +
  geom_tile(aes(fill = log(varMSE)), colour = "white") +
  scale_fill_gradient('Log dari ragam MSE', low="#FFFFE0",high="#DB0000")+
  ggtitle("Heatmap ragam MSE untuk tiap nilai alpha dan beta")+
  theme_minimal()+theme(axis.title.y = element_text(angle = 0, vjust = 0.5))+
  xlab(TeX(r"($\alpha$)"))+ylab(TeX(r"($\beta$)"))

Ragam dari MSE mengikuti rata-rata MSE. Di beta lebih dari 0.1, ragam MSE relatif besar. Tampak bahwa ragam MSE juga mengecil jika alpha mendekati 1. Bagaimana dengan MAPE?

ggplot(aggregateDES, aes(alphrange, betarange)) +
  geom_tile(aes(fill = meanMAPE), colour = "white") +
  scale_fill_gradient('Rata-rata MAPE', low="#FFFFE0",high="#DB0000")+
  ggtitle("Heatmap rerata MAPE untuk tiap nilai alpha dan beta")+
  theme_minimal()+theme(axis.title.y = element_text(angle = 0, vjust = 0.5))+
  xlab(TeX(r"($\alpha$)"))+ylab(TeX(r"($\beta$)"))

Pola cukup mengikuti MSE sebelumnya, tetapi tampaknya MAPE minimum di alpha mendekati 0.5. Bagaimana dengan ragamnya:

ggplot(aggregateDES, aes(alphrange, betarange)) +
  geom_tile(aes(fill = sqrt(varMAPE)), colour = "white") +
 scale_fill_gradient('Akar dari ragam MAPE', low="#FFFFE0",high="#DB0000")+
  ggtitle("Heatmap ragam MAPE untuk tiap nilai alpha dan beta")+
  theme_minimal()+theme(axis.title.y = element_text(angle = 0, vjust = 0.5))+
  xlab(TeX(r"($\alpha$)"))+ylab(TeX(r"($\beta$)"))

Ragam MAPE memiliki pola yang cukup beda. Ragam tersebut nampak minimum di diagonal antara Beta 0.5 dan alpha mendekati nol ke Beta 0.2 dan Alpha 0.25. Lakukan pemeringkatan:

ggplot(aggregateDES, aes(alphrange, betarange)) +
  geom_tile(aes(fill = meanMAE), colour = "white") +
  scale_fill_gradient('Rata-rata MAE', low="#FFFFE0",high="#DB0000")+
  ggtitle("Heatmap rerata MAE untuk tiap nilai alpha dan beta")+
  theme_minimal()+theme(axis.title.y = element_text(angle = 0, vjust = 0.5))+
  xlab(TeX(r"($\alpha$)"))+ylab(TeX(r"($\beta$)"))

Mean dari MAE memiliki pola sama seperti sebelumnya.

ggplot(aggregateDES, aes(alphrange, betarange)) +
  geom_tile(aes(fill = sqrt(varMAE)), colour = "white") +
  scale_fill_gradient('Akar dari ragam MAE', low="#FFFFE0",high="#DB0000")+
  ggtitle("Heatmap ragam MAE untuk tiap nilai alpha dan beta")+
  theme_minimal()+theme(axis.title.y = element_text(angle = 0, vjust = 0.5))+
  xlab(TeX(r"($\alpha$)"))+ylab(TeX(r"($\beta$)"))

Akar dari ragam MAE tampak minimum di diagonal dan di alpha 0.3 sampai 0.6.

knitr::kables(list(
  knitr::kable(head(setorder(aggregateDES, meanMSE)[,c(1,2,3)],n=5),
               col.names=c("$\\alpha$","$\\beta$","MSE")),
  knitr::kable(head(setorder(aggregateDES, meanMAPE)[,c(1,2,5)],n=5),
               col.names=c("$\\alpha$","$\\beta$","MAPE")),
  knitr::kable(head(setorder(aggregateDES, meanMAE)[,c(1,2,7)],n=5),
               col.names=c("$\\alpha$","$\\beta$","MAE"))
  ), caption="Rata-rata metrik akurasi di semua iterasi untuk tiap kombinasi nilai parameter."
)
Table 3.7: Rata-rata metrik akurasi di semua iterasi untuk tiap kombinasi nilai parameter.
\(\alpha\) \(\beta\) MSE
1.0 0.1 94.85663
0.9 0.1 97.46174
0.8 0.1 100.30364
0.7 0.1 103.28965
0.6 0.1 106.26093
\(\alpha\) \(\beta\) MAPE
1.0 0.1 13.01272
0.9 0.1 13.11358
0.8 0.1 13.22221
0.4 0.1 13.24879
0.5 0.1 13.28264
\(\alpha\) \(\beta\) MAE
0.4 0.1 6.918836
0.5 0.1 6.987916
0.3 0.1 6.996000
1.0 0.1 7.023870
0.9 0.1 7.031178

Nampak kombinasi alpha dan beta 0.4 dan 0.1 cukup baik dalam meminmumkan rataan error. Terlihat bahwa range alpha yang meminimumkan MSE dan MAPE kira kira 0.3 sampai 0.6. Pencarian lebih detail dapat dilakukan di daerah ini.

knitr::kables(list(
  knitr::kable(head(setorder(aggregateDES, varMSE)[,c(1,2,4)],n=7),
               col.names=c("$\\alpha$","$\\beta$","MSE")),
  knitr::kable(head(setorder(aggregateDES, varMAPE)[,c(1,2,6)],n=7),
               col.names=c("$\\alpha$","$\\beta$","MAPE")),
  knitr::kable(head(setorder(aggregateDES, varMAE)[,c(1,2,8)],n=7),
               col.names=c("$\\alpha$","$\\beta$","MAE"))
    ), caption="Ragam metrik akurasi di semua iterasi untuk tiap kombinasi nilai parameter."
)
Table 3.8: Ragam metrik akurasi di semua iterasi untuk tiap kombinasi nilai parameter.
\(\alpha\) \(\beta\) MSE
1.0 0.1 19373.94
0.9 0.1 21052.12
0.8 0.1 23133.75
0.7 0.1 25768.44
0.6 0.1 29198.67
1.0 0.2 30823.88
0.5 0.1 33528.18
\(\alpha\) \(\beta\) MAPE
1.0 0.1 123.1107
0.9 0.1 137.1151
1.0 0.2 144.8069
0.8 0.1 154.0144
0.9 0.2 158.0809
0.7 0.1 169.9230
0.8 0.2 173.8135
\(\alpha\) \(\beta\) MAE
1.0 0.1 23.37971
0.9 0.1 25.02203
0.8 0.1 27.01915
1.0 0.2 28.18582
0.7 0.1 29.23953
1.0 0.4 29.90639
1.0 0.3 30.10881

Terlihat bahwa kriteria peminimuman ragam MSE dan MAPE berbeda dari peminimuman rata-rata MSE dan MAPE.

Lakukan iterasi kedua untuk range \(\alpha\ 0.3-0.6\), \(\beta\ 0.01-0.2\):

DESCV2<-fcCV(weeklyCrude[,3],initialn=36,folds=15,type="DES",alphrange=seq(0.3,0.6,0.01),betarange=seq(0.01,0.2,0.01))

Masukkan hasilnya:

resultDES2<-DESCV2[[3]]

Langsung lakukan agregasi:

aggregateDES2<-resultDES2[,`.`(meanMSE=mean(MSE),
                 varMSE=var(MSE),
                 meanMAPE=mean(MAPE),
                 varMAPE=var(MAPE),
                 meanMAE=mean(MAE),
                 varMAE=var(MAE)), by=list(alphrange,betarange)]

Nilai nilai apa saja yang menimumkan MSE, MAPE, dan MAE:

knitr::kables(list(
  knitr::kable(head(setorder(aggregateDES2, meanMSE)[,c(1,2,3)],n=5),
                col.names=c("$\\alpha$","$\\beta$","MSE")),
  knitr::kable(head(setorder(aggregateDES2, meanMAPE)[,c(1,2,5)],n=5),
                col.names=c("$\\alpha$","$\\beta$","MAPE")),
  knitr::kable(head(setorder(aggregateDES2, meanMAE)[,c(1,2,7)],n=5),
                col.names=c("$\\alpha$","$\\beta$","MAE"))
  ), caption="Rata-rata metrik akurasi di semua iterasi untuk tiap kombinasi nilai parameter."
)
Table 3.9: Rata-rata metrik akurasi di semua iterasi untuk tiap kombinasi nilai parameter.
\(\alpha\) \(\beta\) MSE
0.60 0.05 95.80204
0.60 0.06 95.92052
0.59 0.05 96.11010
0.59 0.06 96.20836
0.58 0.05 96.42100
\(\alpha\) \(\beta\) MAPE
0.60 0.08 13.04247
0.59 0.08 13.05033
0.58 0.08 13.05788
0.57 0.08 13.06533
0.56 0.08 13.07340
\(\alpha\) \(\beta\) MAE
0.60 0.07 6.787763
0.59 0.07 6.791494
0.58 0.07 6.795033
0.57 0.07 6.799216
0.51 0.08 6.803002

Dan ragamnya.

knitr::kables(list(
  knitr::kable(head(setorder(aggregateDES2, varMSE)[,c(1,2,4)],n=5),
                col.names=c("$\\alpha$","$\\beta$","MSE")),
  knitr::kable(head(setorder(aggregateDES2, varMAPE)[,c(1,2,6)],n=5),
                col.names=c("$\\alpha$","$\\beta$","MAPE")),
  knitr::kable(head(setorder(aggregateDES2, varMAE)[,c(1,2,8)],n=5),
                col.names=c("$\\alpha$","$\\beta$","MAE"))
  ), caption="Ragam metrik akurasi di semua iterasi untuk tiap kombinasi nilai parameter."
)
Table 3.10: Ragam metrik akurasi di semua iterasi untuk tiap kombinasi nilai parameter.
\(\alpha\) \(\beta\) MSE
0.60 0.04 20781.43
0.59 0.04 21002.53
0.60 0.03 21168.86
0.58 0.04 21226.63
0.60 0.05 21339.40
\(\alpha\) \(\beta\) MAPE
0.60 0.13 177.0180
0.60 0.12 177.8438
0.60 0.14 178.0261
0.59 0.13 178.2966
0.59 0.12 179.1988
\(\alpha\) \(\beta\) MAE
0.60 0.05 26.95027
0.60 0.04 26.96540
0.59 0.05 27.14474
0.59 0.04 27.15655
0.58 0.05 27.34111

Plot iterasi mana yang susah:

ggplot(resultDES,aes(x=iter,y=MAPE,group=iter))+
  geom_boxplot(fill="#E69F00")+theme_minimal()+
  ggtitle("Boxplot MAPE tiap Iterasi")+
  xlab("Iterasi")+ylab(" ")

Sama seperti sebelumnya, performa pemulusan buruk saat COVID.

3.7 Kesimpulan

Suatu hasil peramalan dikatakan baik apabila nilai dari metode peramalannya mendekati data aktual serta memiliki tingkat kesalahan yang paling kecil.

Untuk itu pemilihan metode terbaik dapat dipilih berdasarkan nilai MSE, MAPE, dan MAE.

knitr::kables(list(
  knitr::kable(head(setorder(aggregateSMA, meanMSE)[,c(1,2)],n=1),
               col.names=c("M","MSE")),
  knitr::kable(head(setorder(aggregateSMA, meanMAPE)[,c(1,4)],n=1),
               col.names=c("M","MAPE")),
  knitr::kable(head(setorder(aggregateSMA, meanMAE)[,c(1,6)],n=1),
               col.names=c("M","MAE"))
  ),caption="SMA"
)
Table 3.11: SMA
M MSE
2 108.067
M MAPE
2 14.6048
M MAE
2 7.290667
knitr::kables(list(
  knitr::kable(head(setorder(aggregateDMA, meanMSE)[,c(1,2)],n=1),
               col.names=c("M","MSE")),
  knitr::kable(head(setorder(aggregateDMA, meanMAPE)[,c(1,4)],n=1),
               col.names=c("M","MAPE")),
  knitr::kable(head(setorder(aggregateDMA, meanMAE)[,c(1,6)],n=1),
               col.names=c("M","MAE"))
  ),caption="DMA"
)
Table 3.11: DMA
M MSE
11 118.3255
M MAPE
10 15.02806
M MAE
12 7.523578
knitr::kables(list(
  knitr::kable(head(setorder(aggregateSES, meanMSE)[,c(1,2)],n=1),
               col.names=c("$\\alpha$","MSE")),
  knitr::kable(head(setorder(aggregateSES, meanMAPE)[,c(1,4)],n=1),
               col.names=c("$\\alpha$","MAPE")),
  knitr::kable(head(setorder(aggregateSES, meanMAE)[,c(1,6)],n=1),
               col.names=c("$\\alpha$","MAE"))
  ),caption="SES"
)
Table 3.11: SES
\(\alpha\) MSE
1 94.34572
\(\alpha\) MAPE
1 13.23114
\(\alpha\) MAE
1 6.85325
knitr::kables(list(
  knitr::kable(head(setorder(aggregateDES2, meanMSE)[,c(1,2,3)],n=1),
               col.names=c("$\\alpha$","$\\beta$","MSE")),
  knitr::kable(head(setorder(aggregateDES2, meanMAPE)[,c(1,2,5)],n=1),
               col.names=c("$\\alpha$","$\\beta$","MAPE")),
  knitr::kable(head(setorder(aggregateDES2, meanMAE)[,c(1,2,7)],n=1),
               col.names=c("$\\alpha$","$\\beta$","MAE"))
  ),caption="DES"
)
Table 3.11: DES
\(\alpha\) \(\beta\) MSE
0.6 0.05 95.80204
\(\alpha\) \(\beta\) MAPE
0.6 0.08 13.04247
\(\alpha\) \(\beta\) MAE
0.6 0.07 6.787763

Berdasarkan hasil di atas, dapat dilihat bahwa nilai ketepatan yang lebih kecil dibanding dengan metode lainnya adalah DES dengan nilai MSE = 116.593, MAPE = 14.82092.

3.8 Addendum: Last Block

Tadi digunakan validasi silang untuk mengukur akurasi di berbagai kemungkinan data testing. Bagaimana jika data dianggap terganggu secara signifikan, dan hanya blok terakhir yang relevan? Ambil saja iterasi terakhir dari hasil validasi silang:

lbSMA<-resultSMA[,`.`("MSE"=last(MSE),
                "MAE"=last(MAE),
                "MAPE"=last(MAPE)),by=list(M)]

lbDMA<-resultDMA[,`.`("MSE"=last(MSE),
                   "MAE"=last(MAE),
                   "MAPE"=last(MAPE)),by=list(M)]

lbSES<-resultSES[,`.`("MSE"=last(MSE),
                   "MAE"=last(MAE),
                   "MAPE"=last(MAPE)),by=list(alpha)]

lbDES<-resultDES[,`.`("MSE"=last(MSE),
                   "MAE"=last(MAE),
                   "MAPE"=last(MAPE)),by=list(alphrange,betarange)]

Lalu, cari saja nilai yang meminimumkan error:

knitr::kables(list(
  knitr::kable(head(setorder(lbSMA, MSE)[,c(1,2)],n=1),
               col.names=c("M","MSE")),
  knitr::kable(head(setorder(lbSMA, MAE)[,c(1,3)],n=1),
               col.names=c("M","MAE"))
  ),caption="SMA"
)
Table 3.12: SMA
M MSE
13 541.1841
M MAE
13 20.66764
knitr::kables(list(
  knitr::kable(head(setorder(lbDMA, MSE)[,c(1,2)],n=1),
               col.names=c("M","MSE")),
  knitr::kable(head(setorder(lbDMA, MAE)[,c(1,3)],n=1),
               col.names=c("M","MAE"))
  ),caption="DMA"
)
Table 3.12: DMA
M MSE
2 61.32953
M MAE
2 5.900313
knitr::kables(list(
  knitr::kable(head(setorder(lbSES, MSE)[,c(1,2)],n=1),
               col.names=c("$\\alpha$","MSE")),
  knitr::kable(head(setorder(lbSES, MAE)[,c(1,3)],n=1),
               col.names=c("$\\alpha$","MAE"))
  ),caption="SES"
)
Table 3.12: SES
\(\alpha\) MSE
1 591.3185
\(\alpha\) MAE
1 21.84688
knitr::kables(list(
  knitr::kable(head(setorder(lbDES, MSE)[,c(1,2,3)],n=1),
               col.names=c("$\\alpha$","$\\beta$","MSE")),
  knitr::kable(head(setorder(lbDES, MAE)[,c(1,2,5)],n=1),
               col.names=c("$\\alpha$","$\\beta$","MAE"))
  ),caption="DES"
)
Table 3.12: DES
\(\alpha\) \(\beta\) MSE
0.6 1 58.09093
\(\alpha\) \(\beta\) MAE
0.6 1 5.772313

DES dengan \(\alpha=1\) dan \(\beta=0.8-0.9\) baik untuk data ini. Lakukan pemulusan:

des1<-esWrapper(weeklyCrude[,3][1:260],
                HoltWinters(weeklyCrude[,3][1:260],alpha=1,beta=0.8,gamma=F),
                16)

smooth<- cbind(weeklyCrude,c(des1[[1]]$Smoothed,rep(NA,16)),c(rep(NA,260),des1[[2]]$forc))

Plot hasil pemulusan tersebut:

ggplot(aes(x=Date,y=Close),data=smooth)+geom_point( size=2, alpha=.3, color="grey")+
  geom_line(aes(y=V2,color="Pemulusan"), ,size=0.5)+
  geom_line(aes(y=V3, color="Prediksi"),size=0.5)+
  ylab("")+xlab("Waktu")+
  ggtitle(TeX(r'(Hasil pemulusan dan prediksi DES $\alpha=1$, $\beta=0.8$)'))+
  scale_color_manual(name='DES',
                     breaks=c('Pemulusan', 'Prediksi'),
                     values=c('Pemulusan'='black', 'Prediksi'='#DB0000'))+
  theme_minimal()

Atau,

des2<-esWrapper(weeklyCrude[,3][1:260],
                HoltWinters(weeklyCrude[,3][1:260],alpha=1,beta=0.9,gamma=F),
                16)

smooth<- cbind(weeklyCrude,c(des2[[1]]$Smoothed,rep(NA,16)),c(rep(NA,260),des2[[2]]$forc))

Plot hasil pemulusan tersebut:

ggplot(aes(x=Date,y=Close),data=smooth)+geom_point( size=2, alpha=.3, color="grey")+
  geom_line(aes(y=V2,color="Pemulusan"), ,size=0.5)+
  geom_line(aes(y=V3, color="Prediksi"),size=0.5)+
  ylab("")+xlab("Waktu")+
  ggtitle(TeX(r'(Hasil pemulusan dan prediksi DES $\alpha=1$, $\beta=0.9$)'))+
  scale_color_manual(name='DES',
                     breaks=c('Pemulusan', 'Prediksi'),
                     values=c('Pemulusan'='black', 'Prediksi'='#DB0000'))+
  theme_minimal()
## Warning: Removed 20 row(s) containing missing values (geom_path).
## Warning: Removed 262 row(s) containing missing values (geom_path).

Plot hasil DMA:

dma<-dma.dt(weeklyCrude[,3][1:260],3,16)

smooth<- cbind(weeklyCrude,c(dma[[1]]$forc,rep(NA,16)),c(rep(NA,260),dma[[2]]$forc))

Plot hasil pemulusan tersebut:

ggplot(aes(x=Date,y=Close),data=smooth)+geom_point( size=2, alpha=.3, color="grey")+
  geom_line(aes(y=V2,color="Training"), ,size=0.5)+
  geom_line(aes(y=V3, color="Testing"),size=0.5)+
  ylab("")+xlab("Waktu")+
  ggtitle(TeX(r'(Hasil prediksi DMA $m=3$)'))+
  scale_color_manual(name='Prediksi DMA',
                     breaks=c('Training', 'Testing'),
                     values=c('Training'='black', 'Testing'='#DB0000'))+
  theme_minimal()
## Warning: Removed 23 row(s) containing missing values (geom_path).
## Warning: Removed 262 row(s) containing missing values (geom_path).

SMA?

smar<-sma.dt(weeklyCrude[,3][1:260],12,16)

smooth<- cbind(weeklyCrude,c(smar[[1]]$forc,rep(NA,16)),c(rep(NA,260),smar[[2]]$forc))

Plot hasil pemulusan tersebut:

ggplot(aes(x=Date,y=Close),data=smooth)+geom_point( size=2, alpha=.3, color="grey")+
  geom_line(aes(y=V2,color="Training"), ,size=0.5)+
  geom_line(aes(y=V3, color="Testing"),size=0.5)+
  ylab("")+xlab("Waktu")+
  ggtitle(TeX(r'(Hasil prediksi SMA $m=12$)'))+
  scale_color_manual(name='Prediksi SMA',
                     breaks=c('Training', 'Testing'),
                     values=c('Training'='black', 'Testing'='#DB0000'))+
  theme_minimal()
## Warning: Removed 30 row(s) containing missing values (geom_path).
## Warning: Removed 262 row(s) containing missing values (geom_path).

Forecast dari plot deret waktu tampak buruk. Note: SES(1) sama saja dengan menggunakan data yang paling recent, sehingga plot SES akan tampak relatif sama dengan SMA.

References

Cerqueira V, Torgo L, Mozetič I. 2020. Evaluating time series forecasting models: an empirical study on performance estimation methods. Machine Learning. 109(11):1997–2028.doi:10.1007/s10994-020-05910-7. [diunduh 2022 Apr 14]. Tersedia pada: https://doi.org/10.1007/s10994-020-05910-7
Hyndman RJ, Athanasopoulos G. 2021. Forecasting: Principles and Practice. ed ke-3. Australia: OTexts.
Meschiari S. 2022. latex2exp: Use LaTeX Expressions in Plots. Ed ke-R package version 0.9.4.
Montgomery DC, Jennings CL, Kulachi M. 2008. Introduction to Time Series Analysis and Forecasting. ed ke-2. New Jersey, United States: John Wiley; Sons Inc.
Schnaubelt M. 2019. A comparison of machine learning model validation schemes for non-stationary time series data. FAU Discussion Papers in Economics. Report No.: 11/2019. [diunduh 2022 Apr 14]. Tersedia pada: https://www.econstor.eu/handle/10419/209136