Data yang dipakai adalah volume produksi air minum PDAM Kabupaten Serang dari Januari 2022 sampai Desember 2024, satuannya ribu m³ per bulan.
prod_air <- c(
410, 415, 405, 420, 430, 445, 455, 440, 425, 420, 418, 435,
440, 445, 438, 452, 462, 478, 488, 472, 458, 452, 450, 468,
470, 476, 468, 483, 494, 510, 521, 504, 489, 483, 480, 499
)
ts_air <- ts(prod_air, start = c(2022, 1), frequency = 12)
ts_air
## Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
## 2022 410 415 405 420 430 445 455 440 425 420 418 435
## 2023 440 445 438 452 462 478 488 472 458 452 450 468
## 2024 470 476 468 483 494 510 521 504 489 483 480 499
# bantuan untuk sumbu grafik dan tabel
nama_bln <- month.abb
waktu <- seq(as.Date("2022-01-01"), by = "month", length.out = length(ts_air))
Model additive:
\[Z_t = T_t + S_t + e_t\]
Artinya, nilai data = tren + musiman + residu (sisa).
Buat objek ts dari data di atas, lalu lakukan dekomposisi
additive menggunakan decompose().
library(ggplot2)
hasil_aditif <- decompose(ts_air, type = "additive")
plot(hasil_aditif)
Melihat masing-masing komponen:
hasil_aditif$trend
## Jan Feb Mar Apr May Jun Jul Aug
## 2022 NA NA NA NA NA NA 427.7500 430.2500
## 2023 443.7083 446.4167 449.1250 451.8333 454.5000 457.2083 459.8333 462.3750
## 2024 475.4583 478.1667 480.7917 483.3750 485.9167 488.4583 NA NA
## Sep Oct Nov Dec
## 2022 432.8750 435.5833 438.2500 440.9583
## 2023 464.9167 467.4583 470.0833 472.7500
## 2024 NA NA NA NA
hasil_aditif$seasonal
## Jan Feb Mar Apr May
## 2022 -4.53993056 -1.74826389 -11.91493056 -0.06076389 7.83506944
## 2023 -4.53993056 -1.74826389 -11.91493056 -0.06076389 7.83506944
## 2024 -4.53993056 -1.74826389 -11.91493056 -0.06076389 7.83506944
## Jun Jul Aug Sep Oct
## 2022 21.21006944 27.75173611 9.73090278 -7.35243056 -15.47743056
## 2023 21.21006944 27.75173611 9.73090278 -7.35243056 -15.47743056
## 2024 21.21006944 27.75173611 9.73090278 -7.35243056 -15.47743056
## Nov Dec
## 2022 -20.12326389 -5.31076389
## 2023 -20.12326389 -5.31076389
## 2024 -20.12326389 -5.31076389
hasil_aditif$random
## Jan Feb Mar Apr May Jun
## 2022 NA NA NA NA NA NA
## 2023 0.83159722 0.33159722 0.78993056 0.22743056 -0.33506944 -0.41840278
## 2024 -0.91840278 -0.41840278 -0.87673611 -0.31423611 0.24826389 0.33159722
## Jul Aug Sep Oct Nov Dec
## 2022 -0.50173611 0.01909722 -0.52256944 -0.10590278 -0.12673611 -0.64756944
## 2023 0.41493056 -0.10590278 0.43576389 0.01909722 0.03993056 0.56076389
## 2024 NA NA NA NA NA NA
Dekomposisi menghasilkan empat bagian: data asli (observed), tren,
musiman, dan residu (random). Pada komponen tren ada nilai
NA di 6 bulan pertama dan 6 bulan terakhir (total 12). Ini
normal, karena tren dihitung dengan rata-rata bergerak terpusat
(2×12-MA) yang butuh data di kiri dan kanan tiap bulan.
Datanya punya tren yang naik, pola musiman yang berulang tiap tahun, dan sisa (residu) yang kecil.
Tampilkan dan gambarkan komponen tren. Apakah produksi air minum menunjukkan tren naik?
df_tren_aditif <- data.frame(
waktu = waktu,
nilai_tren = as.numeric(hasil_aditif$trend)
)
ggplot(df_tren_aditif, aes(x = waktu, y = nilai_tren)) +
geom_line(color = "purple", linewidth = 1) +
geom_point(color = "purple", size = 2) +
labs(title = "Tren Produksi Air Minum (Model Additive)",
x = "Periode", y = "Tren (ribu m³)") +
scale_x_date(date_breaks = "3 months", date_labels = "%b\n%Y") +
theme_bw()
## Warning: Removed 12 rows containing missing values or values outside the scale range
## (`geom_line()`).
## Warning: Removed 12 rows containing missing values or values outside the scale range
## (`geom_point()`).
Tren pertama yang bisa dihitung (Juli 2022) sekitar 427,75 ribu m³, dan tren terakhir (Juni 2024) sekitar 488,46 ribu m³.
Garis tren terus naik dari waktu ke waktu, jadi produksi air minum PDAM Kabupaten Serang memang punya tren naik selama periode ini. Naiknya sekitar 60,7 ribu m³ dalam 23 bulan, atau rata-rata sekitar 2,6 ribu m³ per bulan.
Tampilkan 12 indeks musiman. Bulan apa yang cenderung tertinggi dan terendah? Berikan dugaan penjelasannya.
tabel_musim_aditif <- data.frame(
Nama_Bulan = nama_bln,
Nilai_Musiman = as.numeric(hasil_aditif$seasonal[1:12])
)
tabel_musim_aditif
sum(tabel_musim_aditif$Nilai_Musiman) # harus 0 (syarat model additive)
## [1] 0
ggplot(tabel_musim_aditif,
aes(x = factor(Nama_Bulan, levels = nama_bln), y = Nilai_Musiman)) +
geom_col(fill = "purple") +
geom_hline(yintercept = 0) +
labs(title = "Pola Musiman Produksi Air Minum (Model Additive)",
x = "Bulan", y = "Nilai Musiman (ribu m³)") +
theme_bw()
| Bulan | Indeks Musiman |
|---|---|
| Januari | -4,54 |
| Februari | -1,75 |
| Maret | -11,91 |
| April | -0,06 |
| Mei | 7,84 |
| Juni | 21,21 |
| Juli | 27,75 |
| Agustus | 9,73 |
| September | -7,35 |
| Oktober | -15,48 |
| November | -20,12 |
| Desember | -5,31 |
Jumlah ke-12 indeks sama dengan 0, sesuai syarat model additive.
Indeks positif disini artinya produksi bulan itu di atas tren, indeks negatif artinya di bawah tren.
Dugaan: Juni sampai Agustus biasanya musim kemarau, jadi pemakaian air naik dan produksi ikut naik. Sebaliknya, Oktober sampai November mulai masuk musim hujan, jadi kebutuhan air dari PDAM turun.
Periksa komponen residu (ringkasan statistik dan simpangan bakunya). Apakah residu tampak berfluktuasi acak di sekitar nol?
summary(hasil_aditif$random)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -0.9184 -0.4184 -0.0434 -0.0434 0.3316 0.8316 12
sd_sisa_aditif <- sd(hasil_aditif$random, na.rm = TRUE)
sd_sisa_aditif
## [1] 0.4862621
df_sisa_aditif <- data.frame(
waktu = waktu,
nilai_sisa = as.numeric(hasil_aditif$random)
)
ggplot(df_sisa_aditif, aes(x = waktu, y = nilai_sisa)) +
geom_hline(yintercept = 0, linetype = "dashed", color = "red") +
geom_line(color = "purple", linewidth = 1) +
geom_point(color = "purple", size = 2) +
labs(title = "Residu Model Additive",
x = "Periode", y = "Residu (ribu m³)") +
theme_bw()
## Warning: Removed 12 rows containing missing values or values outside the scale range
## (`geom_line()`).
## Warning: Removed 12 rows containing missing values or values outside the scale range
## (`geom_point()`).
Rata-rata residu sekitar -0,043 (hampir nol), nilainya berkisar dari -0,92 sampai +0,83, dan simpangan bakunya sekitar 0,4863 ribu m³.
Residunya kecil sekali dibanding level datanya yang sekitar 450 ribu m³, dan naik-turunnya di sekitar nol tanpa pola yang jelas. Jadi tren dan musiman sudah menjelaskan hampir semua pola di data.
Model multiplicative:
\[Z_t = T_t \times S_t \times e_t\]
Artinya, nilai data = tren × musiman × residu. Faktor musiman 1 berarti pas di tren, lebih dari 1 berarti di atas tren, dan kurang dari 1 berarti di bawah tren. Residu yang bagus berfluktuasi di sekitar 1 (bukan 0).
Lakukan dekomposisi multiplicative pada data produksi air minum PDAM.
hasil_multi <- decompose(ts_air, type = "multiplicative")
plot(hasil_multi)
Melihat masing-masing komponen:
hasil_multi$trend
## Jan Feb Mar Apr May Jun Jul Aug
## 2022 NA NA NA NA NA NA 427.7500 430.2500
## 2023 443.7083 446.4167 449.1250 451.8333 454.5000 457.2083 459.8333 462.3750
## 2024 475.4583 478.1667 480.7917 483.3750 485.9167 488.4583 NA NA
## Sep Oct Nov Dec
## 2022 432.8750 435.5833 438.2500 440.9583
## 2023 464.9167 467.4583 470.0833 472.7500
## 2024 NA NA NA NA
hasil_multi$seasonal
## Jan Feb Mar Apr May Jun Jul
## 2022 0.9901875 0.9962547 0.9744168 0.9999039 1.0166776 1.0449005 1.0625939
## 2023 0.9901875 0.9962547 0.9744168 0.9999039 1.0166776 1.0449005 1.0625939
## 2024 0.9901875 0.9962547 0.9744168 0.9999039 1.0166776 1.0449005 1.0625939
## Aug Sep Oct Nov Dec
## 2022 1.0218486 0.9835709 0.9656814 0.9556379 0.9883262
## 2023 1.0218486 0.9835709 0.9656814 0.9556379 0.9883262
## 2024 1.0218486 0.9835709 0.9656814 0.9556379 0.9883262
hasil_multi$random
## Jan Feb Mar Apr May Jun Jul
## 2022 NA NA NA NA NA NA 1.0010461
## 2023 1.0014693 1.0005740 1.0008342 1.0004650 0.9998269 1.0005500 0.9987391
## 2024 0.9983158 0.9992111 0.9989510 0.9993202 0.9999583 0.9992351 NA
## Aug Sep Oct Nov Dec
## 2022 1.0007953 0.9982074 0.9984910 0.9980699 0.9981398
## 2023 0.9989899 1.0015778 1.0012941 1.0017152 1.0016454
## 2024 NA NA NA NA NA
Dekomposisi multiplicative juga menghasilkan data asli, tren, musiman, dan residu. Bedanya, komponen musiman berbentuk faktor (angka di sekitar 1), bukan selisih.
Pengaruh musiman di model ini berbentuk persentase terhadap tren, bukan jumlah tetap.
Tampilkan dan gambarkan komponen tren dari dekomposisi multiplicative.
df_tren_multi <- data.frame(
waktu = waktu,
nilai_tren = as.numeric(hasil_multi$trend)
)
ggplot(df_tren_multi, aes(x = waktu, y = nilai_tren)) +
geom_line(color = "darkorange", linewidth = 1) +
geom_point(color = "darkorange", size = 2) +
labs(title = "Tren Produksi Air Minum (Model Multiplicative)",
x = "Periode", y = "Tren (ribu m³)") +
scale_x_date(date_breaks = "3 months", date_labels = "%b\n%Y") +
theme_bw()
## Warning: Removed 12 rows containing missing values or values outside the scale range
## (`geom_line()`).
## Warning: Removed 12 rows containing missing values or values outside the scale range
## (`geom_point()`).
Tren pertama yang bisa dihitung sekitar 427,75 ribu m³ dan tren terakhir sekitar 488,46 ribu m³. Angkanya sama persis dengan model additive, karena keduanya memakai CMA 2×12 yang sama untuk menghitung tren.
Tren di model multiplicative juga naik, jadi kesimpulannya sama: produksi air minum cenderung meningkat dari waktu ke waktu.
Tampilkan 12 faktor musiman dan identifikasi bulan dengan faktor musiman tertinggi dan terendah.
tabel_musim_multi <- data.frame(
Nama_Bulan = nama_bln,
Faktor_Bulanan = as.numeric(hasil_multi$seasonal[1:12])
)
tabel_musim_multi$Persen_thd_Tren <- round((tabel_musim_multi$Faktor_Bulanan - 1) * 100, 1)
tabel_musim_multi
mean(tabel_musim_multi$Faktor_Bulanan) # harus 1 (syarat model multiplicative)
## [1] 1
ggplot(tabel_musim_multi,
aes(x = factor(Nama_Bulan, levels = nama_bln), y = Faktor_Bulanan)) +
geom_col(fill = "darkorange") +
geom_hline(yintercept = 1, linetype = "dashed") +
labs(title = "Faktor Musiman Produksi Air Minum (Model Multiplicative)",
x = "Bulan", y = "Faktor Musiman") +
theme_bw()
| Bulan | Faktor Musiman | Terhadap Tren |
|---|---|---|
| Januari | 0,990 | -1,0% |
| Februari | 0,996 | -0,4% |
| Maret | 0,974 | -2,6% |
| April | 1,000 | 0,0% |
| Mei | 1,017 | +1,7% |
| Juni | 1,045 | +4,5% |
| Juli | 1,063 | +6,3% |
| Agustus | 1,022 | +2,2% |
| September | 0,984 | -1,6% |
| Oktober | 0,966 | -3,4% |
| November | 0,956 | -4,4% |
| Desember | 0,988 | -1,2% |
Bulan tertinggi dan terendahnya sama dengan model additive, hanya saja di sini dinyatakan dalam persen.
Periksa komponen residu multiplicative dan bandingkan dengan model additive.
Di model additive, residu ada di sekitar 0. Di model multiplicative, residu ada di sekitar 1.
summary(hasil_multi$random)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.9981 0.9989 0.9999 0.9999 1.0009 1.0017 12
sd_sisa_multi <- sd(hasil_multi$random, na.rm = TRUE)
sd_sisa_multi
## [1] 0.001249183
df_sisa_multi <- data.frame(
waktu = waktu,
nilai_sisa = as.numeric(hasil_multi$random)
)
ggplot(df_sisa_multi, aes(x = waktu, y = nilai_sisa)) +
geom_hline(yintercept = 1, linetype = "dashed", color = "red") +
geom_line(color = "darkorange", linewidth = 1) +
geom_point(color = "darkorange", size = 2) +
labs(title = "Residu Model Multiplicative",
x = "Periode", y = "Residu (rasio)") +
theme_bw()
## Warning: Removed 12 rows containing missing values or values outside the scale range
## (`geom_line()`).
## Warning: Removed 12 rows containing missing values or values outside the scale range
## (`geom_point()`).
Perbandingan langsung simpangan baku kedua model:
data.frame(
Model = c("Additive", "Multiplicative"),
SD_Residu = c(sd_sisa_aditif, sd_sisa_multi)
)
Rata-rata residu sekitar 0,9999 (hampir 1), nilainya berkisar dari 0,9981 sampai 1,0017, dan simpangan bakunya sekitar 0,00125. Sebagai perbandingan, simpangan baku residu additive sekitar 0,4863.
Residu multiplicative naik-turun di sekitar 1 dengan jarak yang sangat kecil, tanpa pola yang jelas. Jadi model multiplicative juga sudah menjelaskan data dengan baik.
Tapi angka 0,4863 dan 0,00125 belum bisa dibandingkan langsung, karena yang satu dalam ribu m³ dan yang satu dalam rasio. Karena itu perlu di samakan dulu skalanya.
Bagian ini untuk memutuskan model mana yang lebih cocok. Ada tiga hal yang dicek: pola grafik, besar residu di skala yang sama, dan pola residunya.
df_asli <- data.frame(waktu = waktu, volume = as.numeric(ts_air))
ggplot(df_asli, aes(x = waktu, y = volume)) +
geom_line(color = "purple", linewidth = 1) +
geom_point(size = 2) +
labs(title = "Data Asli Produksi Air Minum PDAM Kabupaten Serang",
x = "Periode", y = "Volume (ribu m³)") +
scale_x_date(date_breaks = "3 months", date_labels = "%b\n%Y") +
theme_bw()
Supaya tidak sekadar menebak dari grafik, kita bandingkan bulan puncak (Juli) dan bulan lembah (Maret) di tiap tahun.
tahun_cek <- 2022:2024
nilai_jul <- sapply(0:2, function(i) prod_air[i * 12 + 7])
nilai_mar <- sapply(0:2, function(i) prod_air[i * 12 + 3])
data.frame(Tahun = tahun_cek,
Juli = nilai_jul,
Maret = nilai_mar,
Selisih = nilai_jul - nilai_mar,
Rasio = round(nilai_jul / nilai_mar, 4))
| Tahun | Juli | Maret | Selisih | Rasio |
|---|---|---|---|---|
| 2022 | 455 | 405 | 50 | 1,1235 |
| 2023 | 488 | 438 | 50 | 1,1142 |
| 2024 | 521 | 468 | 53 | 1,1132 |
Levelnya naik tiap tahun, tapi jarak antara Juli dan Maret hampir sama, yaitu sekitar 50 sampai 53 ribu m³. Rasionya malah sedikit turun. Jadi naik-turun musimannya tidak ikut membesar saat level naik. Ini ciri model additive.
# Cara 1: ubah SD additive jadi skala rasio (dibagi rata-rata tren)
sd_aditif_rasio <- sd_sisa_aditif / mean(hasil_aditif$trend, na.rm = TRUE)
# Cara 2: ubah residu multiplicative ke skala asli (ribu m3)
sisa_multi_asli <- ts_air - hasil_multi$trend * hasil_multi$seasonal
sd_multi_asli <- sd(sisa_multi_asli, na.rm = TRUE)
data.frame(
Skala = c("Rasio (relatif terhadap level)", "Asli (ribu m3)"),
Additive = c(sd_aditif_rasio, sd_sisa_aditif),
Multiplicative = c(sd_sisa_multi, sd_multi_asli)
)
df_banding <- data.frame(
waktu = rep(waktu, 2),
nilai_sisa = c(as.numeric(hasil_aditif$random), as.numeric(sisa_multi_asli)),
Model = rep(c("Additive", "Multiplicative"), each = length(waktu))
)
ggplot(df_banding, aes(x = waktu, y = nilai_sisa, colour = Model)) +
geom_hline(yintercept = 0, linetype = "dashed") +
geom_line(linewidth = 0.9) +
labs(title = "Residu Kedua Model pada Skala Asli (ribu m³)",
x = "Periode", y = "Residu") +
theme_bw()
## Warning: Removed 24 rows containing missing values or values outside the scale range
## (`geom_line()`).
| Skala | Additive | Multiplicative |
|---|---|---|
| Rasio | 0,00106 | 0,00125 |
| Asli (ribu m³) | 0,486 | 0,561 |
Setelah skalanya disamakan, residu additive sedikit lebih kecil di kedua skala. Bedanya tipis, tapi konsisten mengarah ke additive.
Kedua model punya residu yang naik-turun acak di sekitar nilai idealnya (0 untuk additive, 1 untuk multiplicative). Tidak ada tanda residu yang berubah arah seiring naiknya level, jadi tidak ada bukti bahwa additive “dipaksakan” pada data ini.
Produksi air minum PDAM Kabupaten Serang dari Januari 2022 sampai Desember 2024 punya tren naik (tren yang bisa dihitung naik dari sekitar 427,75 ke 488,46 ribu m³) dan pola musiman yang jelas.
Dari pola grafik (ayunan musiman konstan) dan perbandingan residu di skala yang sama, model additive lebih sesuai untuk data ini. Perlu dicatat bahwa kedua model hasilnya mirip, karena naik turun musimannya kecil dibanding level datanya, jadi selisih kualitasnya tipis. Jadi alasan utama memilih additive adalah pola musimannya yang konstan.