Laporan ini menganalisis pendapatan bulanan Rumah Makan Seafood “Laut Anyer” pada periode Januari 2023 sampai Desember 2024. Data terdiri atas 24 observasi dalam satuan juta Rupiah per bulan. Analisis disusun untuk menjawab empat soal Latihan Pendalaman Materi (Tugas Mandiri) pada materi Pertemuan 7 mata kuliah Analisis Deret Waktu (STA623303), yang ditempatkan pada folder Tugas 6. Tujuannya meliputi: (1) memvisualisasikan pendapatan dan memeriksa pembesaran lonjakan April serta Desember; (2) melakukan dekomposisi multiplicative dan menginterpretasikan 12 faktor musiman; (3) membandingkan simpangan baku residu model multiplicative dengan additive; dan (4) memilih model yang lebih sesuai berdasarkan pola data serta keterbatasan hasil dekomposisi.
Model multiplicative menyatakan nilai pengamatan sebagai hasil kali komponen tren, musiman, dan residu:
\[ Z_t=T_t\times S_t\times e_t. \]
Faktor musiman \(S_t=1\) menunjukkan tidak adanya perubahan terhadap tren, \(S_t>1\) menunjukkan pendapatan di atas tren, sedangkan \(S_t<1\) menunjukkan pendapatan di bawah tren. Efek musiman dalam persen dihitung sebagai \((S_t-1)\times100\%\). Residu model ini berupa rasio yang berpusat di sekitar satu, sedangkan residu additive memiliki satuan juta Rupiah dan berpusat di sekitar nol.
Data dimasukkan secara kronologis dan dibentuk menjadi objek runtun waktu bulanan dengan titik awal Januari 2023 serta frekuensi 12. Nilai seluruh observasi positif, sehingga dapat digunakan dalam dekomposisi multiplicative tanpa pembagian oleh data nol.
# Pendapatan bulanan Rumah Makan Seafood Laut Anyer (juta Rupiah)
pendapatan <- c(
85, 80, 88, 145, 92, 78, 75, 80, 90, 88, 95, 150,
98, 92, 101, 175, 106, 90, 87, 92, 104, 101, 109, 182
)
stopifnot(
length(pendapatan) == 24L,
all(is.finite(pendapatan)), all(pendapatan > 0)
)
pendapatan_ts <- ts(pendapatan, start = c(2023, 1), frequency = 12)
nama_bulan <- c(
"Januari", "Februari", "Maret", "April", "Mei", "Juni",
"Juli", "Agustus", "September", "Oktober", "November", "Desember"
)
label_periode <- paste(rep(nama_bulan, 2), rep(2023:2024, each = 12))
pendapatan_2023 <- pendapatan[1:12]
pendapatan_2024 <- pendapatan[13:24]
print(pendapatan_ts)## Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
## 2023 85 80 88 145 92 78 75 80 90 88 95 150
## 2024 98 92 101 175 106 90 87 92 104 101 109 182
plot(
pendapatan_ts, type = "o", pch = 16, col = "black",
xlab = "Waktu", ylab = "Pendapatan (juta Rupiah/bulan)",
main = "Pendapatan Rumah Makan Seafood Laut Anyer, 2023-2024",
ylim = c(65, 195)
)
idx_puncak <- c(4, 12, 16, 24)
points(time(pendapatan_ts)[idx_puncak], pendapatan[idx_puncak], pch = 17, col = "steelblue", cex = 1.3)
text(
time(pendapatan_ts)[idx_puncak], pendapatan[idx_puncak],
labels = fmt(pendapatan[idx_puncak], 0), pos = 3, cex = 0.9
)Grafik di atas memperlihatkan dua puncak berulang, yaitu April dan Desember. Nilai pendapatan berkisar dari 75 juta Rupiah pada Juli 2023 sampai 182 juta Rupiah pada Desember 2024. Perbandingan kedua tahun pada bulan kalender yang sama ditampilkan berikut agar perubahan besarnya lonjakan dapat dilihat secara langsung.
plot(
1:12, pendapatan_2023, type = "o", pch = 16, col = "black",
xaxt = "n", ylim = c(65, 195), xlab = "Bulan",
ylab = "Pendapatan (juta Rupiah/bulan)",
main = "Perbandingan Pola Pendapatan Tahun 2023 dan 2024"
)
axis(1, at = 1:12, labels = substr(nama_bulan, 1, 3))
lines(1:12, pendapatan_2024, type = "o", pch = 17, lty = 2, col = "steelblue", lwd = 2)
legend(
"topleft", legend = c("Tahun 2023", "Tahun 2024"),
col = c("black", "steelblue"), pch = c(16, 17), lty = c(1, 2), bty = "n"
)bulan_puncak <- c(4, 12)
kenaikan_puncak <- pendapatan_2024[bulan_puncak] - pendapatan_2023[bulan_puncak]
pertumbuhan_puncak <- kenaikan_puncak / pendapatan_2023[bulan_puncak] * 100
# Pembanding lokal: kenaikan April dari Maret dan Desember dari November
lonjakan_2023 <- pendapatan_2023[bulan_puncak] - pendapatan_2023[bulan_puncak - 1]
lonjakan_2024 <- pendapatan_2024[bulan_puncak] - pendapatan_2024[bulan_puncak - 1]
tabel_puncak <- data.frame(
Bulan = nama_bulan[bulan_puncak],
Pendapatan_2023 = fmt(pendapatan_2023[bulan_puncak], 0),
Pendapatan_2024 = fmt(pendapatan_2024[bulan_puncak], 0),
Kenaikan = fmt(kenaikan_puncak, 0),
Pertumbuhan = paste0(fmt(pertumbuhan_puncak, 2), "%"),
Lonjakan_2023 = fmt(lonjakan_2023, 0),
Lonjakan_2024 = fmt(lonjakan_2024, 0)
)
knitr::kable(
tabel_puncak, align = "c",
col.names = c("Bulan", "2023", "2024", "Kenaikan Antartahun", "Kenaikan (%)", "Lonjakan 2023", "Lonjakan 2024")
)| Bulan | 2023 | 2024 | Kenaikan Antartahun | Kenaikan (%) | Lonjakan 2023 | Lonjakan 2024 |
|---|---|---|---|---|---|---|
| April | 145 | 175 | 30 | 20,69% | 57 | 74 |
| Desember | 150 | 182 | 32 | 21,33% | 55 | 73 |
Seluruh kolom nominal pada tabel memiliki satuan juta Rupiah. Kolom lonjakan mengukur selisih dari bulan sebelumnya, yaitu April dikurangi Maret dan Desember dikurangi November. Selisih ini merupakan pembanding deskriptif dan belum memisahkan pengaruh tren.
rerata_tahunan <- c(mean(pendapatan_2023), mean(pendapatan_2024))
rentang_tahunan <- c(diff(range(pendapatan_2023)), diff(range(pendapatan_2024)))
tabel_tahunan <- data.frame(
Tahun = 2023:2024,
Rata_rata = fmt(rerata_tahunan, 3),
Minimum = fmt(c(min(pendapatan_2023), min(pendapatan_2024)), 0),
Maksimum = fmt(c(max(pendapatan_2023), max(pendapatan_2024)), 0),
Rentang = fmt(rentang_tahunan, 0)
)
knitr::kable(
tabel_tahunan, align = "c",
col.names = c("Tahun", "Rata-Rata", "Minimum", "Maksimum", "Rentang Maksimum-Minimum")
)| Tahun | Rata-Rata | Minimum | Maksimum | Rentang Maksimum-Minimum |
|---|---|---|---|---|
| 2023 | 95,500 | 75 | 150 | 75 |
| 2024 | 111,417 | 87 | 182 | 95 |
Berdasarkan kedua grafik dan tabel tersebut, lonjakan April dan Desember membesar dari 2023 ke 2024:
Tren model multiplicative tetap diestimasi menggunakan CMA \(2\times12\). Setelah tren diperoleh, dihitung rasio \(R_t=Z_t/\widehat{T}_t\). Rasio dirata-ratakan pada masing-masing bulan kalender dan dinormalisasi agar rata-rata 12 faktor musiman sama dengan satu:
\[ \widehat{S}_m=\frac{\overline{R}_m} {\frac{1}{12}\sum_{j=1}^{12}\overline{R}_j}, \qquad \frac{1}{12}\sum_{m=1}^{12}\widehat{S}_m=1. \]
dekomp_mul <- decompose(pendapatan_ts, type = "multiplicative")
tren <- dekomp_mul$trend
faktor_musiman <- as.numeric(dekomp_mul$figure)
residu_mul <- dekomp_mul$random
idx_valid <- which(!is.na(tren))
stopifnot(
length(idx_valid) == 12L,
all(tren[idx_valid] > 0),
abs(mean(faktor_musiman) - 1) < 1e-8,
max(abs(pendapatan_ts[idx_valid] -
tren[idx_valid] * dekomp_mul$seasonal[idx_valid] * residu_mul[idx_valid])) < 1e-8
)
print(tren)## Jan Feb Mar Apr May Jun Jul
## 2023 NA NA NA NA NA NA 96.04167
## 2024 103.83333 104.83333 105.91667 107.04167 108.16667 110.08333 NA
## Aug Sep Oct Nov Dec
## 2023 97.08333 98.12500 99.91667 101.75000 102.83333
## 2024 NA NA NA NA NA
Karena hanya tersedia 24 observasi, tren dan residu dapat dihitung
pada Juli 2023 sampai Juni 2024. Enam bulan pertama dan enam bulan
terakhir bernilai NA. Grafik dekomposisi berikut
menggunakan rentang sumbu residu yang tetap di sekitar satu agar
perbedaan pembulatan komputer tidak tampak sebagai fluktuasi
substantif.
par(mfrow = c(4, 1), mar = c(2.5, 4.5, 2, 1))
plot(pendapatan_ts, ylab = "Data Asli", xlab = "", main = "Dekomposisi Multiplicative Pendapatan Laut Anyer")
plot(tren, ylab = "Tren", xlab = "")
plot(dekomp_mul$seasonal, ylab = "Musiman", xlab = "")
abline(h = 1, lty = 2, col = "gray50")
plot(residu_mul, type = "o", pch = 16, ylab = "Residu Rasio", xlab = "Waktu", ylim = c(0.995, 1.005))
abline(h = 1, lty = 2, col = "gray50")Panel tren memperlihatkan kenaikan level pendapatan pada bagian tengah deret yang memiliki CMA. Panel musiman menunjukkan dua puncak di sekitar April dan Desember. Dua belas faktor musiman beserta pengaruh persentasenya disajikan pada tabel berikut.
idx_maks <- which.max(faktor_musiman)
idx_min <- which.min(faktor_musiman)
efek_persen <- (faktor_musiman - 1) * 100
tabel_musiman <- data.frame(
Bulan = nama_bulan,
Faktor = fmt(faktor_musiman, 6),
Efek = paste0(fmt(efek_persen, 3), "%"),
Interpretasi = ifelse(faktor_musiman > 1, "Di atas tren", "Di bawah tren")
)
knitr::kable(
tabel_musiman, align = "c",
col.names = c("Bulan", "Faktor Musiman", "Pengaruh terhadap Tren (%)", "Interpretasi")
)| Bulan | Faktor Musiman | Pengaruh terhadap Tren (%) | Interpretasi |
|---|---|---|---|
| Januari | 0,943616 | -5,638% | Di bawah tren |
| Februari | 0,877393 | -12,261% | Di bawah tren |
| Maret | 0,953373 | -4,663% | Di bawah tren |
| April | 1,634523 | 63,452% | Di atas tren |
| Mei | 0,979757 | -2,024% | Di bawah tren |
| Juni | 0,817385 | -18,261% | Di bawah tren |
| Juli | 0,780742 | -21,926% | Di bawah tren |
| Agustus | 0,823856 | -17,614% | Di bawah tren |
| September | 0,916999 | -8,300% | Di bawah tren |
| Oktober | 0,880543 | -11,946% | Di bawah tren |
| November | 0,933459 | -6,654% | Di bawah tren |
| Desember | 1,458355 | 45,835% | Di atas tren |
## Rata-rata 12 faktor musiman: 1,000000
plot(
1:12, faktor_musiman, type = "o", pch = 16, col = "steelblue",
xaxt = "n", ylim = c(0.7, 1.75), xlab = "Bulan", ylab = "Faktor Musiman (rasio)",
main = "Dua Belas Faktor Musiman Multiplicative Laut Anyer"
)
axis(1, at = 1:12, labels = substr(nama_bulan, 1, 3))
abline(h = 1, lty = 2, col = "gray30")
text(1:12, faktor_musiman, labels = fmt(faktor_musiman, 3), pos = 3, cex = 0.8)Interpretasi faktor musiman adalah sebagai berikut:
Untuk memenuhi soal perbandingan, data yang sama juga didekomposisi menggunakan model additive. Residu kedua model dihitung sebagai:
\[ \widehat{e}^{\mathrm{mul}}_t =\frac{Z_t}{\widehat{T}_t\widehat{S}^{\mathrm{mul}}_t}, \qquad \widehat{e}^{\mathrm{add}}_t =Z_t-\widehat{T}_t-\widehat{S}^{\mathrm{add}}_t. \]
Simpangan baku multiplicative memiliki skala rasio, sedangkan simpangan baku additive memiliki satuan juta Rupiah. Karena satuannya berbeda, besarnya angka SD mentah tidak dapat langsung dijadikan ukuran keunggulan suatu model.
dekomp_add <- decompose(pendapatan_ts, type = "additive")
residu_add <- dekomp_add$random
valid_bersama <- which(!is.na(residu_mul) & !is.na(residu_add))
sd_mul <- sd(residu_mul, na.rm = TRUE)
sd_add <- sd(residu_add, na.rm = TRUE)
rerata_mul <- mean(residu_mul, na.rm = TRUE)
rerata_add <- mean(residu_add, na.rm = TRUE)
# Notasi ilmiah menunjukkan bahwa SD hanya sebesar galat pembulatan
sd_mul## [1] 6.694897e-17
## [1] 5.531601e-15
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 1 1 1 1 1 1 12
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.3646 0.3646 0.3646 0.3646 0.3646 0.3646 12
tabel_sd <- data.frame(
Model = c("Multiplicative", "Additive"),
Residu_tersedia = c(length(valid_bersama), length(valid_bersama)),
Rata_rata = c(fmt(rerata_mul, 9), fmt(rerata_add, 9)),
SD = sprintf("%.6e", c(sd_mul, sd_add)),
Satuan = c("Rasio (tanpa satuan)", "Juta Rupiah")
)
knitr::kable(
tabel_sd, align = "c",
col.names = c("Model", "Jumlah Residu", "Rata-Rata Residu", "Simpangan Baku", "Skala Residu")
)| Model | Jumlah Residu | Rata-Rata Residu | Simpangan Baku | Skala Residu |
|---|---|---|---|---|
| Multiplicative | 12 | 1,000216774 | 6.694897e-17 | Rasio (tanpa satuan) |
| Additive | 12 | 0,364583333 | 5.531601e-15 | Juta Rupiah |
Tabel rinci berikut menunjukkan nilai residu pada seluruh periode yang dapat dihitung oleh kedua model.
tabel_residu <- data.frame(
Periode = label_periode[valid_bersama],
Tren = fmt(tren[valid_bersama], 6),
Additive = fmt(residu_add[valid_bersama], 9),
Multiplicative = fmt(residu_mul[valid_bersama], 9)
)
knitr::kable(
tabel_residu, align = "c",
col.names = c("Periode", "Tren (juta Rupiah)", "Residu Additive (juta Rupiah)", "Residu Multiplicative (rasio)")
)| Periode | Tren (juta Rupiah) | Residu Additive (juta Rupiah) | Residu Multiplicative (rasio) |
|---|---|---|---|
| Juli 2023 | 96,041667 | 0,364583333 | 1,000216774 |
| Agustus 2023 | 97,083333 | 0,364583333 | 1,000216774 |
| September 2023 | 98,125000 | 0,364583333 | 1,000216774 |
| Oktober 2023 | 99,916667 | 0,364583333 | 1,000216774 |
| November 2023 | 101,750000 | 0,364583333 | 1,000216774 |
| Desember 2023 | 102,833333 | 0,364583333 | 1,000216774 |
| Januari 2024 | 103,833333 | 0,364583333 | 1,000216774 |
| Februari 2024 | 104,833333 | 0,364583333 | 1,000216774 |
| Maret 2024 | 105,916667 | 0,364583333 | 1,000216774 |
| April 2024 | 107,041667 | 0,364583333 | 1,000216774 |
| Mei 2024 | 108,166667 | 0,364583333 | 1,000216774 |
| Juni 2024 | 110,083333 | 0,364583333 | 1,000216774 |
par(mfrow = c(2, 1), mar = c(4, 4.5, 3, 1))
plot(
residu_add, type = "o", pch = 16, col = "black", ylim = c(-0.1, 0.8),
xlab = "Waktu", ylab = "Residu (juta Rupiah)", main = "Residu Model Additive"
)
abline(h = 0, lty = 2, col = "gray30")
plot(
residu_mul, type = "o", pch = 17, col = "steelblue", ylim = c(0.995, 1.005),
xlab = "Waktu", ylab = "Residu (rasio)", main = "Residu Model Multiplicative"
)
abline(h = 1, lty = 2, col = "gray30")Hasil perhitungan menunjukkan bahwa SD kedua residu praktis sama dengan nol: SD multiplicative sebesar 6.694897e-17 dan SD additive sebesar 5.531601e-15. Nilai yang sangat kecil tersebut merupakan perbedaan pada ketelitian bilangan komputer. Residu additive hampir konstan pada 0,364583333 juta Rupiah, sedangkan residu multiplicative hampir konstan pada 1,000216774. Karena itu, grafik residu tidak menunjukkan fluktuasi acak yang dapat dipakai untuk menilai model secara kuat.
Hasil ini merupakan konsekuensi jumlah data dan prosedur dekomposisi, bukan bukti bahwa model menjelaskan seluruh pendapatan tanpa galat. Pada deret bulanan sepanjang 24 bulan, CMA menghilangkan enam bulan di awal dan enam bulan di akhir. Tersisa 12 periode dengan tren terestimasi, tepat satu periode untuk setiap bulan kalender.
Pada model additive, misalkan \(D_m\) merupakan satu-satunya selisih terhadap tren untuk bulan \(m\), dan \(\overline{D}\) adalah rata-rata 12 selisih tersebut. Normalisasi menghasilkan:
\[ \widehat{S}^{\mathrm{add}}_m=D_m-\overline{D} \quad\Longrightarrow\quad \widehat{e}^{\mathrm{add}}_m =D_m-\widehat{S}^{\mathrm{add}}_m=\overline{D}. \]
Pada model multiplicative, jika \(R_m\) merupakan satu-satunya rasio bulan \(m\) dan \(\overline{R}\) adalah rata-rata 12 rasio, diperoleh:
\[ \widehat{S}^{\mathrm{mul}}_m=\frac{R_m}{\overline{R}} \quad\Longrightarrow\quad \widehat{e}^{\mathrm{mul}}_m =\frac{R_m}{\widehat{S}^{\mathrm{mul}}_m}=\overline{R}. \]
Dengan demikian, seluruh residu masing-masing model menjadi konstanta yang sama pada periode validnya. SD hanya mengukur variasi terhadap rata-rata, sehingga dapat bernilai nol walaupun konstanta residu tidak tepat nol pada model additive atau tidak tepat satu pada model multiplicative. ACF atau uji keacakan tidak digunakan untuk deret residu yang praktis konstan ini karena hasilnya tidak informatif.
Sebagai pelengkap, dihitung galat rekonstruksi komponen tren dan musiman pada satuan asli. Galat ini bukan galat ramalan data uji, karena komponen musiman diestimasi dari data yang sama:
\[ u^{\mathrm{add}}_t=Z_t-(\widehat{T}_t+\widehat{S}^{\mathrm{add}}_t), \qquad u^{\mathrm{mul}}_t=Z_t-\widehat{T}_t\widehat{S}^{\mathrm{mul}}_t. \]
fitted_add <- dekomp_add$trend + dekomp_add$seasonal
fitted_mul <- dekomp_mul$trend * dekomp_mul$seasonal
galat_add <- as.numeric(pendapatan_ts[valid_bersama] - fitted_add[valid_bersama])
galat_mul <- as.numeric(pendapatan_ts[valid_bersama] - fitted_mul[valid_bersama])
rmse_add <- sqrt(mean(galat_add^2))
rmse_mul <- sqrt(mean(galat_mul^2))
tabel_galat <- data.frame(
Model = c("Additive", "Multiplicative"),
MAE = fmt(c(mean(abs(galat_add)), mean(abs(galat_mul))), 6),
RMSE = fmt(c(rmse_add, rmse_mul), 6),
MAPE = paste0(fmt(c(
mean(abs(galat_add) / pendapatan[valid_bersama]) * 100,
mean(abs(galat_mul) / pendapatan[valid_bersama]) * 100
), 6), "%")
)
knitr::kable(
tabel_galat, align = "c",
col.names = c("Model", "MAE (juta Rupiah)", "RMSE (juta Rupiah)", "MAPE Rekonstruksi (%)")
)| Model | MAE (juta Rupiah) | RMSE (juta Rupiah) | MAPE Rekonstruksi (%) |
|---|---|---|---|
| Additive | 0,364583 | 0,364583 | 0,372893% |
| Multiplicative | 0,022395 | 0,023210 | 0,021673% |
Galat rekonstruksi model multiplicative memiliki RMSE 0,023210 juta Rupiah, sedangkan model additive memiliki RMSE 0,364583 juta Rupiah. Perbandingan ini menggunakan satuan dan periode yang sama, tetapi nilainya tetap dipengaruhi oleh konstanta hasil normalisasi di atas. Oleh karena itu, perbedaan tersebut hanya menjadi informasi tambahan tentang rekonstruksi historis dan tidak membuktikan bahwa model tertentu akan lebih akurat dalam meramalkan pendapatan baru.
Berdasarkan pola data yang tersedia, model multiplicative lebih sesuai sebagai pilihan awal untuk mendeskripsikan pendapatan Laut Anyer. Alasan dan batas penilaian tersebut adalah sebagai berikut:
Analisis pendapatan bulanan Rumah Makan Seafood Laut Anyer periode Januari 2023 sampai Desember 2024 menghasilkan kesimpulan berikut:
stats::decompose().