Tahap ini memuat pustaka (library) R yang diperlukan untuk pengolahan data deret waktu, eksplorasi statistik, visualisasi, hingga pemodelan ARDL.
# REVISI: library yang tidak dipakai dibuang (nardl, ggcorrplot, corrplot, urca,
# openxlsx, MLmetrics, ARDL, MASS). e1071 juga dibuang karena menimpa
# skewness() dan kurtosis() milik moments sehingga hasilnya membingungkan.
library(readxl)
library(dplyr)
library(ggplot2)
library(moments)
library(forecast)
library(tseries)
library(dynlm)
library(dLagM)
library(lmtest)
library(car)
library(tidyr)
library(patchwork)
library(writexl)
library(dynamac)
library(ivreg)
library(sandwich)
Pustaka-pustaka di atas diaktifkan untuk mendukung seluruh tahapan analisis dari eksplorasi hingga evaluasi model.
Tahap ini mengimpor dataset harian dari file Excel lokal ke dalam lingkungan R dan membatasi variabel menjadi peubah terikat tunggal yaitu Tinggi Muka Air (\(\text{TMA}\)) sebagai \(Y\) dan peubah bebas tunggal yaitu Curah Hujan (\(\text{PC}\)) sebagai \(X\).
dataset <- read_excel("D:/IPB UNIVERSITY/KULIAH/SEMESTER 5/MPDW/Metode Peramalan Deret Waktu/Pertemuan 2/Data_Harian_2022_2024.xlsx")
data_sub <- dataset %>%
dplyr::select(Date, TMA, PC) %>%
rename(Yt = TMA, Xt = PC)
str(data_sub)
## tibble [1,096 × 3] (S3: tbl_df/tbl/data.frame)
## $ Date: POSIXct[1:1096], format: "2022-01-01" "2022-01-02" ...
## $ Yt : num [1:1096] 595 588 580 576 574 ...
## $ Xt : num [1:1096] 0.85 1.79 0.4 0.22 5.7 ...
Data harian periode 1 Januari 2022 - 31 Desember 2024 (\(1096\) hari) dengan fokus pada pemodelan bivariat antara Tinggi Muka Air (\(\text{TMA}\)) dan Curah Hujan (\(\text{PC}\)). Data Januari - Maret 2025 dipakai terpisah sebagai data evaluasi tambahan. Sumber Data: Data yang digunakan pada analisis ini diperoleh dari link berikut: https://github.com/fajryanti/ARDL-skripsi/tree/main.
Bagian ini mengeksplorasi karakteristik data melalui ringkasan statistik deskriptif, ukuran penyebaran, kemencengan, kurtosis, visualisasi deret waktu, serta korelasi antara \(\text{TMA}\) dan \(\text{PC}\).
Tahap ini melihat ukuran pemusatan dan penyebaran dasar dari peubah \(\text{TMA}\) dan \(\text{PC}\).
summary(data_sub[, c("Yt", "Xt")])
## Yt Xt
## Min. :555.4 Min. : 0.0000
## 1st Qu.:597.7 1st Qu.: 0.7375
## Median :620.0 Median : 4.0000
## Mean :625.3 Mean : 6.5700
## 3rd Qu.:650.1 3rd Qu.: 9.1325
## Max. :781.2 Max. :145.0300
Tahap ini menghitung simpangan baku untuk mengetahui tingkat keragaman data harian pada peubah \(\text{TMA}\) dan \(\text{PC}\).
sd_tma <- sd(data_sub$Yt, na.rm = TRUE)
sd_pc <- sd(data_sub$Xt, na.rm = TRUE)
cat("Standard Deviation TMA:", sd_tma, "\n")
## Standard Deviation TMA: 39.44962
cat("Standard Deviation PC:", sd_pc, "\n")
## Standard Deviation PC: 8.838259
Tinggi Muka Air (\(\text{TMA}\)) memiliki simpangan baku sebesar \(39.45\), menunjukkan sebaran data respon yang cukup bervariasi.
Curah Hujan (\(\text{PC}\)) memiliki simpangan baku sebesar \(8.84\), menunjukkan karakteristik fluktuasi harian curah hujan.
Tahap ini menghitung koefisien kemencengan (skewness) untuk mengevaluasi tingkat kesimetrisan distribusi data peubah \(\text{TMA}\) dan \(\text{PC}\).
skew_tma <- skewness(data_sub$Yt, na.rm = TRUE)
skew_pc <- skewness(data_sub$Xt, na.rm = TRUE)
cat("Skewness TMA:", skew_tma, "\n")
## Skewness TMA: 0.5304754
cat("Skewness PC:", skew_pc, "\n")
## Skewness PC: 5.070871
Jika skewness \(\approx 0\), berarti distribusi simetris.
\(\text{TMA}\) memiliki skewness \(0.53\), yaitu miring ke kanan secara ringan.
Curah Hujan (\(\text{PC}\)) memiliki skewness \(5.07\), yang tinggi dan positif, menandakan distribusi data sangat miring ke kanan (right-skewed) akibat adanya hari-hari dengan curah hujan ekstrem.
Tahap ini menghitung nilai kurtosis guna mengetahui tingkat keruncingan distribusi peubah \(\text{TMA}\) dan \(\text{PC}\).
# REVISI: moments::kurtosis() menghasilkan kurtosis biasa (normal = 3),
# jadi dikurangi 3 untuk mendapat excess kurtosis (normal = 0)
kurt_tma <- moments::kurtosis(data_sub$Yt, na.rm = TRUE) - 3
kurt_pc <- moments::kurtosis(data_sub$Xt, na.rm = TRUE) - 3
cat("Excess Kurtosis TMA:", kurt_tma, "\n")
## Excess Kurtosis TMA: -0.01559565
cat("Excess Kurtosis PC:", kurt_pc, "\n")
## Excess Kurtosis PC: 59.19679
Nilai yang ditampilkan adalah excess kurtosis (acuan distribusi normal = 0). Excess kurtosis \(\text{TMA}\) sebesar \(-0.016\) menunjukkan distribusi \(\text{TMA}\) sangat dekat dengan distribusi normal (mesokurtik), sedangkan \(\text{PC}\) sebesar \(59.2\) menunjukkan ekor yang sangat berat (leptokurtik) akibat kejadian hujan ekstrem.
Tahap ini menyajikan grafik garis deret waktu untuk melihat pola pergerakan harian dari peubah \(\text{TMA}\) dan \(\text{PC}\) secara visual.
data_long <- data_sub %>%
pivot_longer(cols = c(Yt, Xt),
names_to = "Variabel",
values_to = "Nilai") %>%
mutate(Variabel = ifelse(Variabel == "Yt", "TMA (Respon)", "PC (Curah Hujan)"))
ggplot(data_long, aes(x = Date, y = Nilai)) +
geom_line(color = "steelblue") +
facet_wrap(~ Variabel, scales = "free_y", ncol = 1) +
labs(title = "Time Series Plot TMA dan PC",
x = "Date",
y = "Value") +
theme_minimal()
Berdasarkan plot time series di atas, peubah Curah Hujan (\(\text{PC}\)) menunjukkan fluktuasi yang konstan di sekitar nilai rendah dengan beberapa lonjakan ekstrem yang tajam secara berkala.
Peubah Tinggi Muka Air (\(\text{TMA}\)) memperlihatkan pola naik turun tanpa tren linier yang kaku, mengindikasikan adanya dinamika merespon kondisi musim atau curah hujan.
Pada periode sekitar akhir 2023 hingga awal 2024, \(\text{TMA}\) tampak datar di nilai terendahnya. Pola ini perlu dicek apakah benar kondisi lapangan atau nilai yang terbatas/terisi otomatis oleh alat ukur, karena dapat memengaruhi uji kestasioneran dan kualitas model.
Pemeriksaan korelasi linear sederhana dilakukan untuk melihat sejauh mana hubungan awal antara peubah bebas dan peubah terikat.
cor_val <- cor(data_sub$Yt, data_sub$Xt, use = "complete.obs")
cat("Koefisien Korelasi antara TMA dan PC:", cor_val, "\n")
## Koefisien Korelasi antara TMA dan PC: 0.3945932
Berdasarkan perhitungan di atas, diperoleh koefisien korelasi antara Tinggi Muka Air (\(\text{TMA}\)) dan Curah Hujan (\(\text{PC}\)) sebesar \(0.3946\).
Nilai korelasi positif menunjukkan hubungan searah yang lemah hingga sedang antara curah hujan harian dan tinggi muka air.
Bagian ini membagi keseluruhan dataset menjadi data pelatihan (train) dan data pengujian (test) untuk keperluan evaluasi model peramalan.
total_rows <- nrow(data_sub)
test_size <- 153
train_index <- 1:(total_rows - test_size)
test_index <- (total_rows - test_size + 1):total_rows
train <- data_sub[train_index, ]
test <- data_sub[test_index, ]
cat("Jumlah data train:", nrow(train), "\n")
## Jumlah data train: 943
cat("Jumlah data test:", nrow(test), "\n")
## Jumlah data test: 153
Time Series Data Split Plot Plot Time Series Gabungan (TMA dan PC) Train vs Test Tahap ini memvisualisasikan pembagian data latih dan data uji pada peubah \(\text{TMA}\) dan \(\text{PC}\).
combined_data <- bind_rows(
train %>% mutate(DataType = "Train"),
test %>% mutate(DataType = "Test")
)
data_long_split <- combined_data %>%
dplyr::select(Date, Yt, Xt, DataType) %>%
pivot_longer(
cols = c(Yt, Xt),
names_to = "Variabel",
values_to = "Nilai"
) %>%
mutate(Variabel = ifelse(Variabel == "Yt", "TMA (Respon)", "PC (Curah Hujan)"))
ggplot(data_long_split, aes(x = Date, y = Nilai, color = DataType)) +
geom_line() +
facet_wrap(~ Variabel, scales = "free_y", ncol = 1) +
scale_color_manual(
values = c("Train" = "#00BFC4", "Test" = "#F8766D")
) +
labs(
title = "Time Series Plot (Train vs. Test)",
x = "Date",
y = "Value",
color = "Data Type"
) +
theme_minimal()
Bagian ini menganalisis kestasioneran data melalui plot ACF, PACF, uji formal Augmented Dickey-Fuller (ADF) dan KPSS, serta hubungan lag melalui Cross-Correlation Function (CCF).
Tahap ini menampilkan plot Autocorrelation Function (ACF) untuk peubah \(\text{TMA}\) dan \(\text{PC}\) pada data latih.
acf_TMA <- ggAcf(train$Yt) + labs(title = "ACF TMA")
acf_PC <- ggAcf(train$Xt) + labs(title = "ACF PC")
combined_acf <- acf_TMA / acf_PC
combined_acf
Plot ACF \(\text{TMA}\) meluruh lambat, artinya data sangat persisten (nilai hari ini sangat dipengaruhi nilai hari sebelumnya). ACF \(\text{PC}\) meluruh lebih cepat. Pola peluruhan lambat ini belum otomatis berarti data tidak stasioner, sehingga kestasioneran diputuskan lewat uji formal (ADF dan KPSS) di bawah.
Tahap ini menampilkan plot Partial Autocorrelation Function (PACF) untuk peubah \(\text{TMA}\) dan \(\text{PC}\).
pacf_TMA <- ggPacf(train$Yt) + labs(title = "PACF TMA")
pacf_PC <- ggPacf(train$Xt) + labs(title = "PACF PC")
combined_pacf <- pacf_TMA / pacf_PC
combined_pacf
Plot PACF \(\text{TMA}\) menunjukkan lag pertama yang sangat dominan disusul beberapa lag awal yang kecil tetapi signifikan. Pola ACF meluruh dan PACF terpotong di lag-lag awal ini adalah karakteristik proses autoregresif (AR) yang stasioner dan persisten, bukan tanda ketidakstasioneran.
Tahap ini melakukan pengujian formal untuk menguji kestasioneran data. ADF menguji \(H_0\): ada akar unit (tidak stasioner), sedangkan KPSS menguji \(H_0\): data stasioner. Keduanya dipakai bersama karena ADF kurang kuat pada data yang sangat persisten.
adf.test(train$Yt)
## Warning in adf.test(train$Yt): p-value smaller than printed p-value
##
## Augmented Dickey-Fuller Test
##
## data: train$Yt
## Dickey-Fuller = -4.0051, Lag order = 9, p-value = 0.01
## alternative hypothesis: stationary
kpss.test(train$Yt, null = "Level")
##
## KPSS Test for Level Stationarity
##
## data: train$Yt
## KPSS Level = 0.68864, Truncation lag parameter = 7, p-value = 0.01458
adf.test(train$Xt)
## Warning in adf.test(train$Xt): p-value smaller than printed p-value
##
## Augmented Dickey-Fuller Test
##
## data: train$Xt
## Dickey-Fuller = -7.5359, Lag order = 9, p-value = 0.01
## alternative hypothesis: stationary
kpss.test(train$Xt, null = "Level")
## Warning in kpss.test(train$Xt, null = "Level"): p-value greater than printed
## p-value
##
## KPSS Test for Level Stationarity
##
## data: train$Xt
## KPSS Level = 0.24939, Truncation lag parameter = 7, p-value = 0.1
ADF pada \(\text{TMA}\) dan \(\text{PC}\) menghasilkan \(p\text{-value} < 0.01\) (R memberi peringatan bahwa nilai sebenarnya lebih kecil dari yang dicetak), sehingga tolak \(H_0\): kedua peubah stasioner pada level \(I(0)\).
KPSS pada \(\text{PC}\) tidak menolak \(H_0\) (\(p > 0.10\)), sehingga ADF dan KPSS sepakat bahwa \(\text{PC}\) stasioner. Untuk \(\text{TMA}\), KPSS menolak \(H_0\) (\(p = 0.0146 < 0.05\)) sementara ADF menolak akar unit, sehingga buktinya bertentangan. Hal ini wajar pada deret yang sangat persisten (ACF meluruh lambat): \(\text{TMA}\) paling tepat dipandang sebagai deret stasioner dengan persistensi tinggi, dan keterbatasan ini perlu disebutkan.
Model ARDL utama tetap dibangun pada level, bukan pada data hasil differencing. Alasannya: ADF menolak akar unit pada kedua peubah, tidak ada peubah yang \(I(2)\), dan kerangka ARDL dengan uji batas (bounds test) tetap valid baik untuk peubah \(I(0)\) maupun \(I(1)\), sehingga ketidakpastian pada \(\text{TMA}\) tidak membatalkan pemodelan pada level.
Tahap ini melihat korelasi silang antara peubah \(\text{TMA}\) dan \(\text{PC}\) pada berbagai lag waktu.
ccf_result <- ccf(train$Yt, train$Xt, lag.max = 10, plot = TRUE, main = "CCF antara TMA dan PC")
Pada ccf(y, x), lag positif berarti \(X\) mendahului \(Y\). Korelasi tertinggi ada di lag \(+1\), sehingga curah hujan hari sebelumnya
berkaitan paling kuat dengan \(\text{TMA}\) hari ini. Perlu diingat bahwa
CCF pada data level dipengaruhi autokorelasi masing-masing deret,
sehingga hampir semua lag tampak signifikan. Penentuan lag optimum tetap
sebaiknya dikonfirmasi dengan kriteria informasi (AIC/BIC).
Karena ADF menunjukkan data sudah stasioner pada level, differencing tidak wajib. Bagian ini tetap dipertahankan untuk model DLM dan Koyck sebagai pembanding pada skala perubahan harian, sedangkan ARDL utama memakai data level.
DTMA <- diff(train$Yt, differences = 1)
DPC <- diff(train$Xt, differences = 1)
df <- data.frame(DTMA, DPC)
df.ts <- ts(df)
head(df)
## DTMA DPC
## 1 -7.708333 0.94
## 2 -7.500000 -1.39
## 3 -4.375000 -0.18
## 4 -1.458333 5.48
## 5 9.583333 3.75
## 6 -10.208333 6.72
Tahap ini menampilkan plot ACF untuk peubah \(\text{DTMA}\) hasil differencing pertama.
# REVISI: chunk duplikat (versi tanpa dan dengan ukuran font) digabung jadi satu
acf_DTMA <- ggAcf(DTMA) +
labs(title = "ACF DTMA") +
theme(
axis.text.x = element_text(size = 14),
axis.text.y = element_text(size = 14)
)
acf_DTMA
Plot ACF \(\text{DTMA}\) tidak meluruh perlahan sehingga stasioner dalam rata-rata. Namun autokorelasi lag-1 bernilai negatif cukup besar (sekitar \(-0.34\)), yang merupakan ciri khas over-differencing pada data yang sebenarnya sudah stasioner.
Tahap ini menampilkan plot ACF untuk peubah \(\text{DPC}\) hasil differencing pertama.
acf_DPC <- ggAcf(DPC) +
labs(title = "ACF DPC") +
theme(
axis.text.x = element_text(size = 14),
axis.text.y = element_text(size = 14)
)
acf_DPC
Plot ACF \(\text{DPC}\) tidak meluruh perlahan sehingga stasioner dalam rata-rata, dengan autokorelasi lag-1 negatif besar (sekitar \(-0.39\)) yang juga mengindikasikan over-differencing.
Tahap ini menampilkan plot PACF untuk peubah \(\text{DTMA}\) hasil differencing pertama.
pacf_DTMA <- ggPacf(DTMA) +
labs(title = "PACF DTMA") +
theme(
axis.text.x = element_text(size = 14),
axis.text.y = element_text(size = 14)
)
pacf_DTMA
PACF \(\text{DTMA}\) bernilai negatif dan signifikan berturut-turut sampai sekitar lag 8, lalu mengecil bertahap (tails off), bukan terpotong tegas. Karena itu lag maksimum tidak ditentukan dari “cut-off” saja, tetapi dari AIC/BIC pada bagian pemilihan orde ARDL.
Tahap ini menampilkan plot PACF untuk peubah \(\text{DPC}\) hasil differencing pertama.
pacf_DPC <- ggPacf(DPC) +
labs(title = "PACF DPC") +
theme(
axis.text.x = element_text(size = 14),
axis.text.y = element_text(size = 14)
)
pacf_DPC
PACF \(\text{DPC}\) juga bernilai negatif dan signifikan pada banyak lag awal, mengecil bertahap, konsisten dengan pola over-differencing.
adf.test(DTMA)
## Warning in adf.test(DTMA): p-value smaller than printed p-value
##
## Augmented Dickey-Fuller Test
##
## data: DTMA
## Dickey-Fuller = -12.566, Lag order = 9, p-value = 0.01
## alternative hypothesis: stationary
Nilai \(p\text{-value} < 0.01\) (lebih kecil dari \(\alpha = 0.05\)), sehingga tolak \(H_0\). \(\text{DTMA}\) stasioner secara uji formal.
adf.test(DPC)
## Warning in adf.test(DPC): p-value smaller than printed p-value
##
## Augmented Dickey-Fuller Test
##
## data: DPC
## Dickey-Fuller = -15.041, Lag order = 9, p-value = 0.01
## alternative hypothesis: stationary
Nilai \(p\text{-value} < 0.01\) (lebih kecil dari \(\alpha = 0.05\)), sehingga tolak \(H_0\). \(\text{DPC}\) stasioner secara uji formal.
Tahap ini menampilkan plot Cross-Correlation Function (CCF) antara peubah \(\text{DTMA}\) dan \(\text{DPC}\) untuk menentukan lag optimum dari peubah penjelas pada model DLM.
ccf_result1 <- ggCcf(DTMA, DPC, lag.max = 9) +
ggtitle("CCF antara DTMA dan DPC") +
theme(
axis.text.x = element_text(size = 14),
axis.text.y = element_text(size = 14)
)
ccf_result1
Nilai Korelasi
# REVISI: plot = FALSE lalu dicetak, supaya nilai korelasinya benar-benar tampil
ccf_nilai <- ccf(DTMA, DPC, lag.max = 9, plot = FALSE)
ccf_nilai
##
## Autocorrelations of series 'X', by lag
##
## -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1
## 0.053 -0.055 -0.008 0.027 -0.026 0.010 -0.099 0.106 -0.207 0.109 0.258
## 2 3 4 5 6 7 8 9
## -0.131 -0.012 0.038 0.010 -0.078 0.049 -0.019 0.008
Korelasi silang terbesar ada di lag \(+1\) (\(\approx 0.26\)), yaitu \(\text{DPC}\) hari sebelumnya berkaitan dengan \(\text{DTMA}\) hari ini, sehingga dipilih lag optimum \(q_1 = 1\). Lag lain (0, 2, dan beberapa lag negatif) juga melewati batas signifikansi, tetapi lag \(+1\) paling dominan dan tetap masuk akal secara hidrologi (air hujan butuh waktu mengalir ke titik pengukuran).
Tahap ini memodelkan hubungan keterlambatan waktu menggunakan Distributed Lag Model (DLM). Peubah respon (perubahan Tinggi Muka Air / \(\text{DTMA}\)) dipengaruhi oleh peubah penjelas (perubahan Curah Hujan / \(\text{DPC}\)) pada periode saat ini (\(t\)) serta periode sebelumnya (\(t-q\)) dengan \(q = 1\).
model_dlm <- dlm(x = as.vector(DPC), y = as.vector(DTMA), q = 1)
summary(model_dlm$model)
##
## Call:
## lm(formula = model.formula, data = design)
##
## Residuals:
## Min 1Q Median 3Q Max
## -108.387 -9.656 -0.435 7.632 138.664
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.01530 0.80867 0.019 0.985
## x.t 0.71077 0.09552 7.441 2.25e-13 ***
## x.1 1.01849 0.09552 10.663 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 24.81 on 938 degrees of freedom
## Multiple R-squared: 0.1186, Adjusted R-squared: 0.1168
## F-statistic: 63.14 on 2 and 938 DF, p-value: < 2.2e-16
\[\widehat{\text{DTMA}}_t = 0.01530 + 0.71077\,\text{DPC}_t + 1.01849\,\text{DPC}_{t-1}\]
Pengujian Koefisien Individu (Uji t): Semua koefisien peubah penjelas signifikan pada \(\alpha = 5\%\), sedangkan intersep tidak signifikan (\(p = 0.985\)).
Uji Simultan (Uji F): \(F = 63.14\) dengan \(p\text{-value} < 2.2 \times 10^{-16}\), sehingga tolak \(H_0\): \(\text{DPC}_t\) dan \(\text{DPC}_{t-1}\) bersama-sama berpengaruh signifikan terhadap \(\text{DTMA}_t\).
Koefisien Determinasi (\(R^2\)): Multiple R-squared \(0.1186\) (Adjusted \(0.1168\)), artinya sekitar \(11.86\%\) keragaman perubahan \(\text{TMA}\) dijelaskan oleh curah hujan saat ini dan \(1\) hari sebelumnya. Sisanya dipengaruhi faktor lain di luar model.
Tahap ini mengevaluasi kriteria kebaikan model (Goodness of Fit) DLM melalui AIC, BIC, serta metrik kesalahan in-sample pada data latih.
cat("AIC DLM:", AIC(model_dlm$model), "\n")
## AIC DLM: 8718.745
cat("BIC DLM:", BIC(model_dlm$model), "\n")
## BIC DLM: 8738.133
GoF(model_dlm)
## n MAE MPE MAPE sMAPE MASE MSE MRAE GMRAE
## model_dlm 941 15.77835 NaN Inf 1.535554 0.5764154 613.4048 951195863 5.180658
Kriteria Informasi: AIC \(= 8718.745\) dan BIC \(= 8738.133\).
Tingkat Kesalahan (Goodness of Fit): \(n = 941\), MAE \(= 15.78\), MSE \(= 613.40\), MASE \(= 0.576\).
Inf/NaN karena \(\text{DTMA}\) banyak bernilai nol atau
mendekati nol, sehingga tidak dilaporkan.Tahap ini memodelkan hubungan dinamik menggunakan Model
Koyck. Berbeda dengan DLM, model ini memasukkan lag peubah
respon (\(\text{DTMA}_{t-1}\)) sebagai
penjelas di samping \(\text{DPC}_t\),
dengan asumsi pengaruh peubah bebas meluruh secara eksponensial. Model
diestimasi dengan Instrumental Variable (IV) melalui
koyckDlm().
model_koyck <- koyckDlm(x = as.vector(DPC), y = as.vector(DTMA))
summary(model_koyck$model)
##
## Call:
## "Y ~ (Intercept) + Y.1 + X.t"
##
## Residuals:
## Min 1Q Median 3Q Max
## -232.759 -16.173 -1.249 10.972 310.149
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.01127 1.07451 0.010 0.992
## Y.1 -0.50644 0.04662 -10.864 < 2e-16 ***
## X.t -2.29141 0.31430 -7.291 6.55e-13 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 32.96 on 938 degrees of freedom
## Multiple R-Squared: -0.5561, Adjusted R-squared: -0.5594
## Wald test: 61.65 on 2 and 938 DF, p-value: < 2.2e-16
\[\widehat{\text{DTMA}}_t = 0.01127 - 0.50644\,\text{DTMA}_{t-1} - 2.29141\,\text{DPC}_t\]
Pengujian Koefisien Individu (Uji t):
Uji Simultan (Wald): \(61.65\) dengan \(p\text{-value} < 2.2 \times 10^{-16}\), sehingga tolak \(H_0\).
Kelayakan Model: Nilai \(\lambda\) negatif melanggar syarat \(0 < \lambda < 1\) sehingga asumsi peluruhan eksponensial Koyck tidak sesuai untuk data ini. \(R^2\) negatif (\(-0.5561\)) juga muncul, tetapi hal itu memang lazim pada estimasi IV sehingga bukan alasan utama; alasan utamanya adalah \(\lambda\) di luar rentang dan tanda koefisien yang tidak masuk akal.
GoF(model_koyck)
## n MAE MPE MAPE sMAPE MASE MSE MRAE
## model_koyck 941 21.38385 NaN Inf 1.538932 0.7811958 1082.998 2323802165
## GMRAE
## model_koyck 7.99342
Pada bagian ini ARDL dibangun pada data level karena \(\text{TMA}\) dan \(\text{PC}\) sudah stasioner. Bentuk umumnya:
\[Y_t = c + \sum_{i=1}^{p}\phi_i Y_{t-i} + \sum_{j=0}^{q}\beta_j X_{t-j} + \varepsilon_t\]
modelbound <- ardlBound(data = train, formula = Yt ~ Xt, case = 2, max.p = 1, max.q = 9)
##
## Orders being calculated with max.p = 1 and max.q = 9 ...
##
## Autoregressive order: 10 and p-orders: 2
## ------------------------------------------------------
##
## Breusch-Godfrey Test for the autocorrelation in residuals:
##
## Breusch-Godfrey test for serial correlation of order up to 1
##
## data: modelFull$model
## LM test = 0.22164, df1 = 1, df2 = 918, p-value = 0.6379
##
## ------------------------------------------------------
##
## Ljung-Box Test for the autocorrelation in residuals:
##
## Box-Ljung test
##
## data: res
## X-squared = 0.0029075, df = 1, p-value = 0.957
##
## ------------------------------------------------------
##
## Breusch-Pagan Test for the homoskedasticity of residuals:
##
## studentized Breusch-Pagan test
##
## data: modelFull$model
## BP = 203.43, df = 13, p-value < 2.2e-16
##
## The p-value of Breusch-Pagan test for the homoskedasticity of residuals: 2.700262e-36 < 0.05!
## ------------------------------------------------------
##
## Shapiro-Wilk test of normality of residuals:
##
## Shapiro-Wilk normality test
##
## data: modelFull$model$residual
## W = 0.88265, p-value < 2.2e-16
##
## The p-value of Shapiro-Wilk test normality of residuals: 5.754731e-26 < 0.05!
## ------------------------------------------------------
##
## PESARAN, SHIN AND SMITH (2001) COINTEGRATION TEST
##
## Observations: 942
## Number of Regressors (k): 1
## Case: 2
##
## ------------------------------------------------------
## - F-test -
## ------------------------------------------------------
## <------- I(0) ------------ I(1) ----->
## 10% critical value 3.02 3.51
## 5% critical value 3.62 4.16
## 1% critical value 4.94 5.58
##
##
## F-statistic = 41.6397821191344
##
## ------------------------------------------------------
## F-statistic note: Asymptotic critical values used.
##
## ------------------------------------------------------
##
## Ramsey's RESET Test for model specification:
##
## RESET test
##
## data: modelECM$model
## RESET = 18.937, df1 = 1, df2 = 920, p-value = 1.502e-05
##
## the p-value of RESET test: 1.502293e-05 < 0.05!
## ------------------------------------------------------
## ------------------------------------------------------
## Error Correction Model Output:
##
## Time series regression with "ts" data:
## Start = 10, End = 942
##
## Call:
## dynlm(formula = as.formula(model.text), data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -131.649 -10.959 -2.548 6.419 135.043
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## ec.1 -0.15640 0.01398 -11.189 < 2e-16 ***
## dXt.t 0.75245 0.08956 8.402 < 2e-16 ***
## dXt.1 0.33910 0.10011 3.387 0.000736 ***
## dYt.1 -0.43833 0.03002 -14.604 < 2e-16 ***
## dYt.2 -0.28542 0.03332 -8.565 < 2e-16 ***
## dYt.3 -0.21422 0.03400 -6.301 4.57e-10 ***
## dYt.4 -0.13794 0.03446 -4.003 6.77e-05 ***
## dYt.5 -0.15754 0.03397 -4.638 4.02e-06 ***
## dYt.6 -0.12855 0.03395 -3.787 0.000163 ***
## dYt.7 -0.10040 0.03357 -2.991 0.002856 **
## dYt.8 -0.04558 0.03250 -1.403 0.161080
## dYt.9 0.02097 0.02934 0.715 0.474982
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 21.23 on 921 degrees of freedom
## Multiple R-squared: 0.3654, Adjusted R-squared: 0.3571
## F-statistic: 44.19 on 12 and 921 DF, p-value: < 2.2e-16
##
## ------------------------------------------------------
## Long-run coefficients:
## Yt.1 Xt.1
## -0.1564025 1.2918485
##
Hasil Uji Kointegrasi Pesaran, Shin and Smith (2001) dengan \(942\) pengamatan, \(k = 1\), dan kasus \(2\): F-statistik \(= 41.64\). Nilai kritis batas atas \(I(1)\) adalah \(3.51\) (10%), \(4.16\) (5%), dan \(5.58\) (1%). Karena \(41.64\) jauh melampaui batas atas, tolak \(H_0\) dan disimpulkan ada hubungan jangka panjang antara \(\text{TMA}\) dan \(\text{PC}\).
Catatan penting:
Orde \(p\) (lag \(Y\)) dan \(q\) (lag \(X\)) dipilih dengan AIC pada semua kombinasi. Semua kombinasi dihitung pada sampel yang sama (baris awal yang kosong akibat lag dibuang) agar AIC dapat dibandingkan.
# fungsi untuk membuat kolom lag Y dan X
buat_lag <- function(dat, p, q) {
out <- dat
for (i in 1:p) out[[paste0("Y_lag", i)]] <- dplyr::lag(dat$Yt, i)
if (q > 0) {
for (j in 1:q) out[[paste0("X_lag", j)]] <- dplyr::lag(dat$Xt, j)
}
out
}
# fungsi untuk membuat formula ARDL(p, q)
buat_formula <- function(p, q) {
rhs <- c(paste0("Y_lag", 1:p), "Xt")
if (q > 0) rhs <- c(rhs, paste0("X_lag", 1:q))
as.formula(paste("Yt ~", paste(rhs, collapse = " + ")))
}
p_max <- 10
q_max <- 3
train_lag_max <- buat_lag(train, p_max, q_max)[-(1:p_max), ]
kandidat <- expand.grid(p = 1:p_max, q = 1:q_max)
kandidat$AIC <- NA
kandidat$BIC <- NA
for (i in 1:nrow(kandidat)) {
m <- lm(buat_formula(kandidat$p[i], kandidat$q[i]), data = train_lag_max)
kandidat$AIC[i] <- AIC(m)
kandidat$BIC[i] <- BIC(m)
}
head(kandidat[order(kandidat$AIC), ], 5)
## p q AIC BIC
## 19 9 2 8365.736 8433.474
## 20 10 2 8367.228 8439.804
## 18 8 2 8367.347 8430.246
## 29 9 3 8367.593 8440.169
## 30 10 3 8369.046 8446.461
p_opt <- kandidat$p[which.min(kandidat$AIC)]
q_opt <- kandidat$q[which.min(kandidat$AIC)]
cat("Orde terpilih (AIC): p =", p_opt, ", q =", q_opt, "\n")
## Orde terpilih (AIC): p = 9 , q = 2
Berdasarkan AIC terkecil, dipilih ARDL(\(9\), \(2\)). Tiga model teratas berselisih AIC kurang dari 2 (8365.7; 8367.2; 8367.3), sehingga ARDL(9, 2) tidak jauh lebih baik daripada ARDL(8, 2). Pada model terpilih, koefisien \(Y_{t-5}\) sampai \(Y_{t-8}\) juga tidak signifikan. Sebagai pembanding, berikut tiga model teratas menurut BIC yang lebih menghukum banyaknya parameter:
kandidat[order(kandidat$BIC), ][1:3, ]
## p q AIC BIC
## 14 4 2 8383.436 8426.982
## 18 8 2 8367.347 8430.246
## 16 6 2 8377.310 8430.532
BIC memilih ARDL(4, 2) (BIC \(8426.98\), AIC \(8383.44\)), yaitu model yang jauh lebih
hemat parameter daripada ARDL(9, 2) (BIC \(8433.47\)). Selisih BIC-nya kecil, tetapi
AIC-nya lebih besar sekitar \(17.7\),
sehingga kedua model layak. ARDL(9, 2) dipertahankan sebagai model utama
karena AIC-nya terkecil, dan ARDL(4, 2) dapat dijadikan analisis
sensitivitas: ubah p_opt <- 4 lalu knit ulang untuk
melihat apakah kesimpulan berubah.
Model koreksi galat (Error Correction Model, ECM) ekuivalen dengan
ARDL(\(9\), \(2\)) pada level. Data yang dimasukkan
adalah data level (\(\text{Yt}\) dan \(\text{Xt}\)), dan dynardl
sendiri yang membentuk selisihnya.
train_df <- as.data.frame(train[, c("Yt", "Xt")])
lagdiffs_list <- list()
if (p_opt > 1) lagdiffs_list[["Yt"]] <- 1:(p_opt - 1)
if (q_opt > 1) lagdiffs_list[["Xt"]] <- 1:(q_opt - 1)
if (length(lagdiffs_list) == 0) lagdiffs_list <- NULL
modelardl <- dynardl(
Yt ~ Xt,
data = train_df,
lags = list("Yt" = 1, "Xt" = 1),
diffs = c("Xt"),
lagdiffs = lagdiffs_list,
ec = TRUE,
simulate = FALSE
)
## [1] "Error correction (EC) specified; dependent variable to be run in differences."
summary(modelardl$model)
##
## Call:
## lm(formula = as.formula(paste(paste(dvnamelist), "~", paste(colnames(IVs),
## collapse = "+"), collapse = " ")))
##
## Residuals:
## Min 1Q Median 3Q Max
## -131.177 -11.452 -2.489 6.528 135.374
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 88.08571 13.24058 6.653 4.93e-11 ***
## l.1.Yt -0.15416 0.02154 -7.158 1.67e-12 ***
## ld.1.Yt -0.44144 0.03412 -12.937 < 2e-16 ***
## ld.2.Yt -0.29015 0.03658 -7.932 6.24e-15 ***
## ld.3.Yt -0.21879 0.03628 -6.030 2.37e-09 ***
## ld.4.Yt -0.14362 0.03597 -3.993 7.04e-05 ***
## ld.5.Yt -0.16226 0.03503 -4.633 4.13e-06 ***
## ld.6.Yt -0.13388 0.03438 -3.894 0.000106 ***
## ld.7.Yt -0.10745 0.03290 -3.266 0.001133 **
## ld.8.Yt -0.05568 0.02963 -1.879 0.060530 .
## d.1.Xt 0.75176 0.09109 8.253 5.31e-16 ***
## l.1.Xt 1.29517 0.12258 10.566 < 2e-16 ***
## ld.1.Xt 0.33221 0.10064 3.301 0.001000 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 21.25 on 921 degrees of freedom
## (9 observations deleted due to missingness)
## Multiple R-squared: 0.3645, Adjusted R-squared: 0.3562
## F-statistic: 44.03 on 12 and 921 DF, p-value: < 2.2e-16
Cara membaca hasil:
l.1.Yt adalah kecepatan
penyesuaian (speed of adjustment) sebesar \(-0.154\). Nilainya negatif dan berada di
antara \(-1\) dan \(0\), sehingga sistem stabil dan kembali ke
keseimbangan. Sekitar \(15\%\)
ketidakseimbangan terkoreksi setiap hari (waktu paruh sekitar \(4\) hari), dan nilai ini konsisten dengan
ECM dari ardlBound (\(-0.156\)).d.1.Xt sebesar \(0.752\) adalah dampak jangka pendek:
kenaikan curah hujan \(1\) satuan pada
hari yang sama langsung menaikkan \(\text{TMA}\) sekitar \(0.75\) satuan. Efek totalnya berkembang
bertahap menuju pengganda jangka panjang di bawah.Pengganda jangka panjang dihitung dari koefisien ARDL level (bukan hanya koefisien \(X_t\)):
\[\text{LRM} = \frac{\sum_j \beta_j}{1-\sum_i \phi_i}\]
# model ARDL level (dipakai juga untuk diagnostik dan peramalan)
n_buang <- max(p_opt, q_opt)
train_lag <- buat_lag(train, p_opt, q_opt)[-(1:n_buang), ]
model_ardl <- lm(buat_formula(p_opt, q_opt), data = train_lag)
summary(model_ardl)
##
## Call:
## lm(formula = buat_formula(p_opt, q_opt), data = train_lag)
##
## Residuals:
## Min 1Q Median 3Q Max
## -131.177 -11.452 -2.489 6.528 135.374
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 88.08571 13.24058 6.653 4.93e-11 ***
## Y_lag1 0.40440 0.03273 12.357 < 2e-16 ***
## Y_lag2 0.15128 0.03413 4.433 1.04e-05 ***
## Y_lag3 0.07136 0.03381 2.111 0.0351 *
## Y_lag4 0.07517 0.03362 2.236 0.0256 *
## Y_lag5 -0.01864 0.03360 -0.555 0.5793
## Y_lag6 0.02838 0.03344 0.849 0.3962
## Y_lag7 0.02642 0.03334 0.792 0.4283
## Y_lag8 0.05177 0.03308 1.565 0.1179
## Y_lag9 0.05568 0.02963 1.879 0.0605 .
## Xt 0.75176 0.09109 8.253 5.31e-16 ***
## X_lag1 0.87562 0.09995 8.761 < 2e-16 ***
## X_lag2 -0.33221 0.10064 -3.301 0.0010 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 21.25 on 921 degrees of freedom
## Multiple R-squared: 0.7343, Adjusted R-squared: 0.7309
## F-statistic: 212.1 on 12 and 921 DF, p-value: < 2.2e-16
koef <- coef(model_ardl)
phi_total <- sum(koef[grep("^Y_lag", names(koef))])
beta_total <- sum(koef[c("Xt", grep("^X_lag", names(koef), value = TRUE))])
lrm <- beta_total / (1 - phi_total)
kec_penyesuaian <- -(1 - phi_total)
cat("Jumlah koefisien lag Y :", phi_total, "\n")
## Jumlah koefisien lag Y : 0.8458407
cat("Jumlah koefisien X :", beta_total, "\n")
## Jumlah koefisien X : 1.295166
cat("Pengganda jangka panjang (LRM):", lrm, "\n")
## Pengganda jangka panjang (LRM): 8.401475
cat("Kecepatan penyesuaian (EC) :", kec_penyesuaian, "\n")
## Kecepatan penyesuaian (EC) : -0.1541593
cat("AIC ARDL level:", AIC(model_ardl), "\n")
## AIC ARDL level: 8374.42
l.1.Yt pada ECM (\(-0.154\)), sehingga kedua bentuk konsisten
(ECM dan ARDL level adalah penulisan ulang dari model yang sama).Uji asumsi dilakukan pada residual model ARDL level.
res_ardl <- residuals(model_ardl)
Karena ada lag peubah respon di ruas kanan, uji Breusch-Godfrey lebih tepat dipakai daripada uji Durbin-Watson. Ljung-Box tetap ditampilkan sebagai pelengkap.
bgtest(model_ardl, order = 10)
##
## Breusch-Godfrey test for serial correlation of order up to 10
##
## data: model_ardl
## LM test = 2.5411, df = 10, p-value = 0.9903
Box.test(res_ardl, lag = 20, type = "Ljung-Box", fitdf = p_opt)
##
## Box-Ljung test
##
## data: res_ardl
## X-squared = 9.0678, df = 11, p-value = 0.6156
Hipotesis: \(H_0\) tidak ada autokorelasi residual, \(H_1\) ada autokorelasi. Uji Breusch-Godfrey menghasilkan \(p = 0.990\) dan Ljung-Box \(p = 0.616\), keduanya lebih besar dari \(0.05\), sehingga gagal tolak \(H_0\): tidak ada bukti autokorelasi residual, dan jumlah lag pada model sudah memadai.
jarque.bera.test(res_ardl)
##
## Jarque Bera Test
##
## data: res_ardl
## X-squared = 1706.8, df = 2, p-value < 2.2e-16
\(H_0\): residual berdistribusi normal. Statistik Jarque-Bera \(= 1706.8\) dengan \(p < 2.2 \times 10^{-16}\), sehingga tolak \(H_0\): residual tidak normal (ekor berat akibat hari hujan ekstrem). Uji t dan selang kepercayaan hanya berlaku secara aproksimasi.
# REVISI: bptest langsung pada model, bukan pada regresi res ~ fitted
bptest(model_ardl)
##
## studentized Breusch-Pagan test
##
## data: model_ardl
## BP = 200.54, df = 12, p-value < 2.2e-16
\(H_0\): ragam residual konstan.
Hasil \(BP = 200.54\) dengan \(p < 2.2 \times 10^{-16}\), sehingga
tolak \(H_0\): ragam residual tidak
konstan (heteroskedastis), sesuai dengan temuan pada
ardlBound. Karena itu inferensi koefisien memakai galat
baku yang tahan heteroskedastisitas (HC3):
coeftest(model_ardl, vcov. = vcovHC(model_ardl, type = "HC3"))
##
## t test of coefficients:
##
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 88.085707 15.912786 5.5355 4.046e-08 ***
## Y_lag1 0.404404 0.050797 7.9612 4.995e-15 ***
## Y_lag2 0.151285 0.044197 3.4229 0.0006468 ***
## Y_lag3 0.071362 0.043955 1.6235 0.1048196
## Y_lag4 0.075169 0.036203 2.0763 0.0381401 *
## Y_lag5 -0.018639 0.033868 -0.5503 0.5822224
## Y_lag6 0.028383 0.036833 0.7706 0.4411510
## Y_lag7 0.026423 0.035895 0.7361 0.4618383
## Y_lag8 0.051769 0.039092 1.3243 0.1857337
## Y_lag9 0.055683 0.034950 1.5932 0.1114477
## Xt 0.751756 0.244716 3.0720 0.0021891 **
## X_lag1 0.875623 0.532310 1.6449 0.1003218
## X_lag2 -0.332213 0.150298 -2.2104 0.0273248 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Dengan galat baku HC3, koefisien \(X_t\) (\(p = 0.002\)) dan \(X_{t-2}\) (\(p = 0.027\)) tetap signifikan, tetapi \(X_{t-1}\) (\(p = 0.100\)) dan \(Y_{t-3}\) (\(p = 0.105\)) tidak lagi signifikan pada \(5\%\). Jadi klaim bahwa curah hujan hari sebelumnya berpengaruh signifikan menjadi lebih lemah setelah heteroskedastisitas diperhitungkan, walaupun jumlah koefisien curah hujan (\(1.295\)) tetap positif.
resettest(model_ardl, power = 2:3, type = "fitted")
##
## RESET test
##
## data: model_ardl
## RESET = 25.464, df1 = 2, df2 = 919, p-value = 1.724e-11
\(H_0\): bentuk fungsional linear sudah memadai. Hasil \(RESET = 25.46\) dengan \(p = 1.7 \times 10^{-11}\), sehingga tolak \(H_0\): spesifikasi linear belum memadai. Hubungan curah hujan dan \(\text{TMA}\) kemungkinan tidak linear (mis. efek hujan ekstrem berbeda), sehingga transformasi seperti \(\log(1+X_t)\) layak dicoba pada pengembangan berikutnya.
vif(model_ardl)
## Y_lag1 Y_lag2 Y_lag3 Y_lag4 Y_lag5 Y_lag6 Y_lag7 Y_lag8
## 3.718772 4.046942 3.976778 3.933900 3.935929 3.901369 3.882894 3.824497
## Y_lag9 Xt X_lag1 X_lag2
## 3.068784 1.300768 1.565318 1.586148
Nilai VIF berkisar antara \(1.30\) sampai \(4.05\), jauh di bawah batas kritis \(10\) (bahkan di bawah \(5\)), sehingga tidak ada masalah multikolinearitas serius antar lag.
Peramalan yang dipakai adalah peramalan satu hari ke depan (one-step-ahead): \(\hat{Y}_t\) dihitung dari \(Y_{t-1},\dots,Y_{t-p}\) aktual dan \(X_t, X_{t-1},\dots\) aktual. Model pembanding sederhana (naif) \(\hat{Y}_t = Y_{t-1}\) ditambahkan agar akurasi dapat dinilai secara wajar, karena \(\text{TMA}\) sangat persisten sehingga MAPE kecil saja tidak cukup membuktikan model bagus.
# fungsi ukuran akurasi
ukur_akurasi <- function(aktual, prediksi) {
data.frame(
MAE = mean(abs(aktual - prediksi)),
RMSE = sqrt(mean((aktual - prediksi)^2)),
MAPE = mean(abs((aktual - prediksi) / aktual)) * 100
)
}
pred_train <- fitted(model_ardl)
aktual_train <- train_lag$Yt
naif_train <- train_lag$Y_lag1
plot(train_lag$Date, aktual_train, type = "l", col = "black",
main = "Train: Actual vs Predicted TMA", xlab = "Tanggal", ylab = "TMA")
lines(train_lag$Date, pred_train, col = "blue")
legend("topleft", legend = c("Actual", "Predicted"), col = c("black", "blue"), lty = 1)
tabel_train <- rbind(
ARDL = ukur_akurasi(aktual_train, pred_train),
Naif = ukur_akurasi(aktual_train, naif_train)
)
round(tabel_train, 3)
## MAE RMSE MAPE
## ARDL 14.206 21.098 2.204
## Naif 16.647 26.466 2.571
Pada data training, ARDL memiliki MAPE \(2.2\%\) dan RMSE \(21.1\), sedangkan model naif RMSE-nya \(26.47\). RMSE ARDL lebih kecil dibandingkan model naif. RMSE training (\(21.1\)) hampir sama dengan simpangan baku residual model (\(21.25\)), yang menandakan prediksi sudah dihitung konsisten dengan model yang diestimasi. Pada grafik, prediksi tampak melonjak tajam mendekati \(780\) di sekitar hari hujan ekstrem (\(145\) mm), yang menunjukkan model sensitif terhadap pencilan curah hujan.
Data pengujian memiliki \(153\) observasi (1 Agustus - 31 Desember 2024). Lag untuk beberapa hari pertama diambil dari data training yang sebenarnya teramati.
# lag dibuat dari seluruh data agar hari-hari awal data test memakai nilai aktual sebelumnya
full_lag <- buat_lag(data_sub, p_opt, q_opt)
test_lag <- full_lag[test_index, ]
aktual_test <- test_lag$Yt
pred_ardl_test <- predict(model_ardl, newdata = test_lag)
naif_test <- test_lag$Y_lag1
# DLM dan Koyck (model pada skala selisih), dikembalikan ke level TMA
dX <- c(NA, diff(data_sub$Xt))
dY <- c(NA, diff(data_sub$Yt))
Y_prev <- data_sub$Yt[test_index - 1]
b_dlm <- unname(coef(model_dlm$model)) # urutan: intersep, x.t, x.1
pred_dlm_test <- Y_prev + b_dlm[1] + b_dlm[2] * dX[test_index] + b_dlm[3] * dX[test_index - 1]
b_koyck <- unname(coef(model_koyck$model)) # urutan: intersep, Y.1, X.t
pred_koyck_test <- Y_prev + b_koyck[1] + b_koyck[2] * dY[test_index - 1] + b_koyck[3] * dX[test_index]
plot(test_lag$Date, aktual_test, type = "l", col = "black",
main = "Test: Actual vs Predicted TMA", xlab = "Tanggal", ylab = "TMA")
lines(test_lag$Date, pred_ardl_test, col = "blue")
legend("topleft", legend = c("Actual", "ARDL"), col = c("black", "blue"), lty = 1)
tabel_test <- rbind(
ARDL = ukur_akurasi(aktual_test, pred_ardl_test),
DLM = ukur_akurasi(aktual_test, pred_dlm_test),
Koyck = ukur_akurasi(aktual_test, pred_koyck_test),
Naif = ukur_akurasi(aktual_test, naif_test)
)
round(tabel_test, 3)
## MAE RMSE MAPE
## ARDL 9.820 16.555 1.545
## DLM 10.655 19.696 1.667
## Koyck 18.705 33.842 2.937
## Naif 10.052 19.192 1.562
Untuk menguji apakah selisih ARDL dan model naif nyata secara statistik, dipakai uji Diebold-Mariano pada galat kuadrat, dengan \(H_1\): ARDL lebih akurat daripada model naif.
dm.test(aktual_test - pred_ardl_test, aktual_test - naif_test,
alternative = "less", h = 1, power = 2)
##
## Diebold-Mariano Test
##
## data: aktual_test - pred_ardl_testaktual_test - naif_test
## DM = -1.5974, Forecast horizon = 1, Loss function power = 2, p-value =
## 0.05612
## alternative hypothesis: less
Hasilnya \(DM = -1.60\) dengan \(p = 0.056\). Nilai ini sedikit di atas \(0.05\), sehingga keunggulan ARDL atas model naif belum signifikan pada taraf 5% (hanya mendekati signifikan pada taraf 10%). Perbaikan RMSE sebesar sekitar \(14\%\) pada data testing belum dapat dipastikan bukan kebetulan.
Model yang sudah dilatih dipakai untuk peramalan satu hari ke depan pada data Januari - Maret 2025 (\(90\) hari). Sebanyak \(9\) hari terakhir 2024 dipakai hanya untuk membentuk lag pada hari-hari pertama.
data_2025 <- read_excel("D:/IPB UNIVERSITY/KULIAH/SEMESTER 5/MPDW/Metode Peramalan Deret Waktu/Pertemuan 2/Data_Jan25_Mar25.xlsx")
data_2025 <- data_2025 %>%
transmute(Date = as.Date(Date), Yt = TMA, Xt = PC)
cat("Jumlah data 2025:", nrow(data_2025), "\n")
## Jumlah data 2025: 90
# REVISI: tail(..., 120) dihapus karena datanya hanya 90 baris
n_lag <- max(p_opt, q_opt)
gabung <- bind_rows(
data_sub %>% mutate(Date = as.Date(Date)) %>% tail(n_lag),
data_2025
)
gabung_lag <- buat_lag(gabung, p_opt, q_opt)[-(1:n_lag), ]
pred_2025 <- predict(model_ardl, newdata = gabung_lag)
hasil_prediksi <- data.frame(
date = gabung_lag$Date,
TMA_actual = gabung_lag$Yt,
TMA_pred = pred_2025,
TMA_naif = gabung_lag$Y_lag1
)
write_xlsx(hasil_prediksi, path = "hasil_peramalan.xlsx")
plot(hasil_prediksi$date, hasil_prediksi$TMA_actual, type = "l", col = "black",
ylab = "TMA", xlab = "Tanggal", main = "TMA Aktual vs Prediksi (Jan - Mar 2025)")
lines(hasil_prediksi$date, hasil_prediksi$TMA_pred, col = "blue")
legend("topleft", legend = c("Aktual", "Prediksi ARDL"), col = c("black", "blue"), lty = 1)
tabel_2025 <- rbind(
ARDL = ukur_akurasi(hasil_prediksi$TMA_actual, hasil_prediksi$TMA_pred),
Naif = ukur_akurasi(hasil_prediksi$TMA_actual, hasil_prediksi$TMA_naif)
)
round(tabel_2025, 3)
## MAE RMSE MAPE
## ARDL 11.093 16.64 1.659
## Naif 11.354 22.64 1.660
Pada periode Januari - Maret 2025, ARDL memiliki RMSE \(16.64\) dan MAPE \(1.66\%\), sedangkan model naif memiliki RMSE \(22.64\) dan MAPE \(1.66\%\). Seperti pada data testing, MAE dan MAPE ARDL hampir identik dengan model naif (MAE \(11.09\) vs \(11.35\)). Keunggulan RMSE datang dari lonjakan awal Maret, yang tetap diprediksi jauh lebih rendah dari nilai aktualnya (sekitar \(725\) vs \(795\)).
Catatan: ini adalah evaluasi peramalan satu hari ke depan dengan curah hujan aktual sebagai masukan. Untuk peramalan jauh ke depan yang sesungguhnya, nilai curah hujan masa depan juga harus diramalkan atau diberikan sebagai skenario.
Analisis deret waktu bivariat antara Tinggi Muka Air (TMA) dan Curah Hujan (PC) memberikan kesimpulan berikut:
Kestasioneran: Uji ADF menunjukkan \(\text{TMA}\) dan \(\text{PC}\) stasioner pada level. KPSS sepakat untuk \(\text{PC}\), tetapi menolak kestasioneran \(\text{TMA}\) (\(p = 0.0146\)), sehingga \(\text{TMA}\) dipandang sebagai deret sangat persisten dengan bukti yang tidak sepenuhnya seragam. Differencing menimbulkan ciri over-differencing (ACF lag-1 negatif besar), sehingga ARDL utama dibangun pada level, yang tetap valid dalam kerangka uji batas.
Model Distributed Lag (DLM): DLM dengan \(q = 1\) pada data selisih menunjukkan bahwa perubahan \(\text{TMA}\) dipengaruhi perubahan curah hujan hari yang sama (\(0.71077\)) dan hari sebelumnya (\(1.01849\)), dengan \(R^2\) hanya \(11.86\%\), MAE \(= 15.78\), dan MSE \(= 613.40\) pada data latih.
Model Koyck: Estimasi Koyck tidak layak dipakai karena parameter peluruhan \(\lambda = -0.506\) berada di luar rentang \(0 < \lambda < 1\) dan koefisien curah hujan bertanda negatif (tidak masuk akal secara hidrologi). MAE \(= 21.38\) dan MSE \(= 1082.00\) juga lebih buruk dari DLM.
Model ARDL: ARDL level terpilih adalah ARDL(\(9\), \(2\)) dengan kecepatan penyesuaian \(-0.154\) per hari dan pengganda jangka panjang \(8.401\). Uji batas Pesaran-Shin-Smith menunjukkan adanya hubungan jangka panjang, walaupun uji ini kurang informatif bila peubah sudah stasioner.
Kinerja peramalan: Pada data testing, RMSE ARDL sebesar \(16.56\) dibandingkan \(19.19\) untuk model naif, sedangkan DLM dan Koyck lebih buruk. Namun MAE dan MAPE ARDL hanya sedikit lebih baik daripada model naif, dan uji Diebold-Mariano menghasilkan \(p = 0.056\), sehingga keunggulan ARDL atas model naif belum signifikan pada taraf 5%. Perbaikannya bersifat moderat dan terutama muncul saat lonjakan \(\text{TMA}\). Pola yang sama terlihat pada data Januari - Maret 2025. Lonjakan tertinggi masih cenderung diprediksi lebih rendah dari nilai aktualnya.
Keterbatasan: Residual tidak normal (Jarque-Bera
dan Shapiro-Wilk), ragam residual tidak konstan (Breusch-Pagan pada
ardlBound), dan uji RESET menunjukkan kemungkinan hubungan
tidak linear. Karena itu inferensi (uji t, selang kepercayaan) perlu
ditafsirkan hati-hati, dan galat baku yang tahan heteroskedastisitas
sebaiknya dipakai. Dengan galat baku HC3, pengaruh curah hujan hari
sebelumnya (\(X_{t-1}\)) tidak lagi
signifikan pada \(5\%\).