Transformasi, Differencing, dan Evaluasi Ramalan Harga GKP Kabupaten Serang
1 Gambaran Umum
Analisis ini membahas harga Gabah Kering Panen (GKP) di tingkat petani Kabupaten Serang selama Januari 2023 sampai Desember 2024.
Data terdiri atas 24 observasi bulanan. Analisis diarahkan pada tiga pertanyaan utama:
- Bagaimana karakteristik pergerakan harga GKP sepanjang periode pengamatan?
- Apakah transformasi logaritma dan differencing dapat membantu menstabilkan runtun waktu?
- Seberapa besar kesalahan yang dihasilkan oleh naive forecast pada tiga bulan terakhir?
Workflow analisis:
Data GKP
↓
Time Series
↓
Eksplorasi Visual
↓
Transformasi Logaritma
↓
First Differencing
↓
Train–Test Split
↓
Naive Forecast
↓
ME • MAE • MSE • RMSE • MAPE
↓
Interpretasi
Fokus analisis
Transformasi log digunakan untuk mengevaluasi kestabilan variansi, sedangkan differencing digunakan untuk melihat apakah kecenderungan/tren pada mean dapat dikurangi. Setelah itu, evaluasi forecast dilakukan menggunakan data aktual pada tiga periode terakhir.
2 Data dan Pembentukan Runtun Waktu
2.1 Input Data
Data harga GKP diberikan dalam satuan Rp/kg.
gkp <- c(
5200, 5150, 5300, 5400, 5250, 5350,
5450, 5500, 5400, 5550, 5600, 5700,
5650, 5700, 5800, 5900, 5750, 5850,
5950, 6000, 5900, 6050, 6150, 6300
)
tanggal <- seq(
from = as.Date("2023-01-01"),
by = "month",
length.out = length(gkp)
)
gkp_df <- data.frame(
tanggal = tanggal,
tahun = format(tanggal, "%Y"),
bulan = format(tanggal, "%b"),
harga = gkp
)
gkp_ts <- ts(
gkp,
start = c(2023, 1),
frequency = 12
)2.2 Struktur Data
overview <- tibble(
Informasi = c(
"Periode",
"Jumlah observasi",
"Frekuensi",
"Harga minimum",
"Harga maksimum",
"Harga rata-rata"
),
Nilai = c(
"Januari 2023 – Desember 2024",
length(gkp_ts),
"Bulanan",
paste0("Rp ", comma(min(gkp_ts))),
paste0("Rp ", comma(max(gkp_ts))),
paste0("Rp ", comma(round(mean(gkp_ts), 2)))
)
)
kable(
overview,
align = c("l", "l"),
caption = "Ringkasan Data Harga GKP"
) |>
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE
)| Informasi | Nilai |
|---|---|
| Periode | Januari 2023 – Desember 2024 |
| Jumlah observasi | 24 |
| Frekuensi | Bulanan |
| Harga minimum | Rp 5,150 |
| Harga maksimum | Rp 6,300 |
| Harga rata-rata | Rp 5,660 |
2.3 Plot Runtun Waktu
Visualisasi pertama digunakan untuk melihat pola data sebelum dilakukan transformasi apa pun.
ggplot(gkp_df, aes(tanggal, harga)) +
geom_area(
aes(y = harga),
alpha = 0.12
) +
geom_line(
linewidth = 1
) +
geom_point(
size = 2.4
) +
geom_smooth(
method = "loess",
se = FALSE,
linewidth = 0.8,
linetype = "dashed"
) +
scale_y_continuous(
labels = label_number(big.mark = "."),
expand = expansion(mult = c(0.02, 0.06))
) +
scale_x_date(
date_breaks = "3 months",
date_labels = "%b\n%Y"
) +
labs(
title = "Harga GKP Menunjukkan Kecenderungan Meningkat",
subtitle = "Pergerakan bulanan dengan garis tren lokal sebagai panduan visual",
x = NULL,
y = "Harga (Rp/kg)",
caption = "Sumber: Data latihan Analisis Deret Waktu"
) +
theme_minimal(base_size = 12) +
theme(
axis.text.x = element_text(angle = 0),
plot.title = element_text(face = "bold", size = 15),
plot.subtitle = element_text(color = "grey40"),
panel.grid.minor = element_blank()
)Pergerakan harga GKP Kabupaten Serang, Januari 2023–Desember 2024.
2.3.1 Pembacaan Awal
Secara visual, harga GKP bergerak pada level yang lebih rendah di awal 2023 dan mencapai level yang lebih tinggi pada akhir 2024. Dengan demikian, terdapat kecenderungan naik secara keseluruhan, meskipun beberapa bulan mengalami penurunan sementara.
Pola tersebut menjadi alasan untuk melanjutkan analisis ke tahap transformasi dan differencing.
3 Transformasi Logaritma
3.1 Mengapa Logaritma?
Transformasi logaritma digunakan untuk melihat apakah perubahan pada skala data dapat dibuat lebih proporsional terhadap level pengamatan.
Secara matematis:
\[ W_t = \ln(Z_t) \]
Transformasi ini terutama relevan ketika fluktuasi absolut cenderung meningkat bersama level data.
3.2 Perbandingan Skala Asli dan Logaritmik
plot_data <- gkp_df |>
select(tanggal, harga, log_harga) |>
pivot_longer(
cols = c(harga, log_harga),
names_to = "series",
values_to = "nilai"
) |>
mutate(
series = recode(
series,
harga = "Harga asli",
log_harga = "Logaritma harga"
)
)
ggplot(plot_data, aes(tanggal, nilai)) +
geom_line(linewidth = 1) +
geom_point(size = 1.8) +
facet_wrap(
~series,
scales = "free_y",
ncol = 1
) +
scale_x_date(
date_breaks = "3 months",
date_labels = "%b\n%Y"
) +
labs(
title = "Perbandingan Sebelum dan Sesudah Transformasi Log",
subtitle = "Transformasi mengubah skala, bukan urutan waktu pengamatan",
x = NULL,
y = NULL
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 15),
strip.text = element_text(face = "bold"),
panel.grid.minor = element_blank()
)3.3 Perbandingan Penyebaran
variability <- tibble(
Series = c(
"Harga asli",
"Log harga"
),
Mean = c(
mean(gkp_ts),
mean(log_gkp)
),
SD = c(
sd(gkp_ts),
sd(log_gkp)
)
)
kable(
variability,
digits = 4,
caption = "Perbandingan ukuran penyebaran sebelum dan sesudah transformasi"
) |>
kable_styling(
bootstrap_options = c("striped", "hover"),
full_width = FALSE
)| Series | Mean | SD |
|---|---|---|
| Harga asli | 5660.42 | 314.1514 |
| Log harga | 8.64 | 0.0554 |
Catatan interpretasi
Perbandingan standar deviasi antar-skala perlu dibaca dengan hati-hati karena harga asli dan log harga memiliki satuan/skala yang berbeda. Oleh sebab itu, keberhasilan transformasi tidak ditentukan hanya dari angka SD yang lebih kecil, tetapi juga dari pola visual penyebaran data setelah transformasi.
4 First Differencing
4.1 Differencing pada Data Logaritmik
Setelah transformasi logaritma, dilakukan differencing tingkat pertama:
\[ \Delta W_t = W_t-W_{t-1} \]
atau:
\[ \Delta\ln(Z_t) = \ln(Z_t)-\ln(Z_{t-1}) \]
Dalam konteks ini, perubahan tersebut juga dapat dibaca sebagai ukuran perubahan relatif antarperiode.
4.2 Visualisasi Differencing
ggplot(diff_df, aes(tanggal, diff_log)) +
geom_hline(
yintercept = 0,
linetype = "dashed",
linewidth = 0.7
) +
geom_col(
alpha = 0.65,
width = 20
) +
geom_line(
linewidth = 0.8
) +
scale_x_date(
date_breaks = "3 months",
date_labels = "%b\n%Y"
) +
scale_y_continuous(
labels = percent_format(accuracy = 0.1)
) +
labs(
title = "First Difference dari Log Harga GKP",
subtitle = "Perubahan relatif antarbulan setelah transformasi logaritma",
x = NULL,
y = "Δ log(GKP)",
caption = "Nilai positif menunjukkan kenaikan relatif dari bulan sebelumnya."
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 15),
panel.grid.minor = element_blank()
)4.3 Ringkasan Hasil Differencing
diff_summary <- tibble(
Statistik = c(
"Rata-rata",
"Standar deviasi",
"Minimum",
"Maksimum"
),
Nilai = c(
mean(diff_log_gkp),
sd(diff_log_gkp),
min(diff_log_gkp),
max(diff_log_gkp)
)
)
kable(
diff_summary,
digits = 5,
caption = "Ringkasan first difference log harga"
) |>
kable_styling(
bootstrap_options = c("striped", "hover"),
full_width = FALSE
)| Statistik | Nilai |
|---|---|
| Rata-rata | 0.00834 |
| Standar deviasi | 0.01726 |
| Minimum | -0.02817 |
| Maksimum | 0.02871 |
4.3.1 Apakah Tren Sudah Hilang?
Setelah differencing, runtun waktu tidak lagi memperlihatkan kecenderungan naik yang sama seperti pada data level. Nilai hasil differencing berfluktuasi di sekitar nol dengan perubahan positif dan negatif.
Hal ini menunjukkan bahwa first differencing terhadap log harga berhasil mengurangi pola tren pada mean.
Namun, untuk tugas ini, kesimpulan tersebut didasarkan terutama pada pemeriksaan visual dan karakteristik hasil differencing, bukan pada pengujian formal stasioneritas.
5 Naive Forecast
5.1 Pembagian Data Latih dan Data Uji
Soal menetapkan:
- 21 observasi pertama sebagai training set
- 3 observasi terakhir sebagai testing set
Dengan demikian, periode training berakhir pada September 2024, sedangkan periode pengujian mencakup Oktober–Desember 2024.
5.2 Visualisasi Train–Test Split
ggplot(split_df, aes(tanggal, harga, group = 1)) +
geom_line(linewidth = 0.9) +
geom_point(
aes(shape = kelompok),
size = 3
) +
geom_vline(
xintercept = as.numeric(min(test_dates)),
linetype = "dashed",
linewidth = 0.8
) +
scale_shape_manual(
values = c(
"Training" = 16,
"Testing" = 17
)
) +
scale_y_continuous(
labels = label_number(big.mark = ".")
) +
scale_x_date(
date_breaks = "3 months",
date_labels = "%b\n%Y"
) +
labs(
title = "Pembagian Training dan Testing",
subtitle = "21 observasi digunakan untuk membentuk baseline forecast",
x = NULL,
y = "Harga GKP (Rp/kg)",
shape = "Data"
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 15),
panel.grid.minor = element_blank()
)5.3 Membentuk Naive Forecast
Naive forecast menggunakan nilai aktual terakhir dari data training sebagai ramalan untuk seluruh periode berikutnya.
Secara matematis:
\[ \hat{Y}_{t+h}=Y_t \]
last_train <- tail(train, 1)
naive_forecast <- rep(
last_train,
length(test)
)
forecast_df <- tibble(
tanggal = test_dates,
aktual = test,
ramalan_naif = naive_forecast
)
last_train## [1] 5900
Dengan demikian, forecast untuk ketiga bulan pengujian menggunakan nilai September 2024 sebesar Rp5.900/kg sebagai baseline.
5.4 Aktual vs Forecast
kable(
forecast_df |>
mutate(
tanggal = format(tanggal, "%B %Y")
),
col.names = c(
"Periode",
"Aktual (Rp/kg)",
"Naive Forecast (Rp/kg)"
),
format.args = list(big.mark = "."),
caption = "Perbandingan aktual dan naive forecast"
) |>
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE
)| Periode | Aktual (Rp/kg) | Naive Forecast (Rp/kg) |
|---|---|---|
| October 2024 | 6.050 | 5.900 |
| November 2024 | 6.150 | 5.900 |
| December 2024 | 6.300 | 5.900 |
5.5 Visualisasi Forecast
ggplot() +
geom_line(
data = gkp_df,
aes(tanggal, harga),
linewidth = 0.9
) +
geom_point(
data = gkp_df,
aes(tanggal, harga),
size = 1.8
) +
geom_line(
data = forecast_df,
aes(tanggal, ramalan_naif),
linewidth = 1.1,
linetype = "dashed"
) +
geom_point(
data = forecast_df,
aes(tanggal, aktual),
size = 3
) +
geom_point(
data = forecast_df,
aes(tanggal, ramalan_naif),
size = 2.5,
shape = 1
) +
geom_vline(
xintercept = as.numeric(min(test_dates)),
linetype = "dotted",
linewidth = 0.8
) +
annotate(
"text",
x = min(test_dates),
y = max(gkp) + 100,
label = "Awal periode testing",
hjust = 0,
size = 3.5
) +
scale_y_continuous(
labels = label_number(big.mark = "."),
limits = c(
min(gkp) - 100,
max(gkp) + 250
)
) +
scale_x_date(
date_breaks = "3 months",
date_labels = "%b\n%Y"
) +
labs(
title = "Naive Forecast vs Harga Aktual",
subtitle = "Forecast mempertahankan harga terakhir pada training set",
x = NULL,
y = "Harga GKP (Rp/kg)"
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 15),
panel.grid.minor = element_blank()
)6 Evaluasi Akurasi Ramalan
6.1 Forecast Error
Kesalahan ramalan didefinisikan sebagai:
\[ e_t=Y_t-\hat{Y}_t \]
error_df <- forecast_df |>
mutate(
error = aktual - ramalan_naif,
abs_error = abs(error),
squared_error = error^2,
percentage_error = abs(error / aktual) * 100
)
kable(
error_df |>
mutate(
tanggal = format(tanggal, "%B %Y")
),
digits = 2,
col.names = c(
"Periode",
"Aktual",
"Forecast",
"Error",
"|Error|",
"Error²",
"APE (%)"
),
caption = "Perhitungan error naive forecast"
) |>
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = TRUE
)| Periode | Aktual | Forecast | Error | |Error| | Error² | APE (%) |
|---|---|---|---|---|---|---|
| October 2024 | 6050 | 5900 | 150 | 150 | 22500 | 2.48 |
| November 2024 | 6150 | 5900 | 250 | 250 | 62500 | 4.07 |
| December 2024 | 6300 | 5900 | 400 | 400 | 160000 | 6.35 |
6.2 Lima Metrik Evaluasi
ME <- mean(error_df$error)
MAE <- mean(error_df$abs_error)
MSE <- mean(error_df$squared_error)
RMSE <- sqrt(MSE)
MAPE <- mean(error_df$percentage_error)
metrics <- tibble(
Metrik = c(
"ME",
"MAE",
"MSE",
"RMSE",
"MAPE"
),
Nilai = c(
ME,
MAE,
MSE,
RMSE,
MAPE
),
Interpretasi = c(
"Arah bias forecast",
"Rata-rata besar kesalahan absolut",
"Rata-rata kuadrat kesalahan",
"Akar rata-rata kuadrat kesalahan",
"Rata-rata kesalahan absolut dalam persen"
)
)
kable(
metrics,
digits = 2,
caption = "Hasil evaluasi naive forecast"
) |>
kable_styling(
bootstrap_options = c("striped", "hover"),
full_width = FALSE
)| Metrik | Nilai | Interpretasi |
|---|---|---|
| ME | 266.7 | Arah bias forecast |
| MAE | 266.7 | Rata-rata besar kesalahan absolut |
| MSE | 81666.7 | Rata-rata kuadrat kesalahan |
| RMSE | 285.8 | Akar rata-rata kuadrat kesalahan |
| MAPE | 4.3 | Rata-rata kesalahan absolut dalam persen |
7 Membaca Hasil Evaluasi
7.0.1 ME = 266,67
Nilai ME positif menunjukkan bahwa aktual secara rata-rata berada di atas hasil ramalan. Dengan kata lain, naive forecast cenderung under-forecast pada tiga bulan pengujian.
7.0.2 MAE = Rp266,67/kg
Secara absolut, kesalahan rata-rata naive forecast adalah sekitar Rp266,67/kg.
7.0.3 MSE = 81.666,67
MSE memberikan penalti lebih besar terhadap kesalahan yang besar karena error dikuadratkan.
7.0.4 RMSE = Rp285,77/kg
RMSE menunjukkan besarnya kesalahan forecast pada skala yang sama dengan harga GKP, yaitu sekitar Rp285,77/kg.
7.0.5 MAPE = 4,30%
Secara relatif, naive forecast menghasilkan rata-rata kesalahan absolut sekitar 4,30% terhadap harga aktual pada tiga observasi testing.
8 Ringkasan Analisis
final_summary <- tibble(
Tahap = c(
"Data asli",
"Transformasi",
"Differencing",
"Forecast",
"Evaluasi"
),
Temuan = c(
"Harga GKP menunjukkan kecenderungan meningkat sepanjang periode pengamatan.",
"Logaritma mengubah skala data dan digunakan untuk mengevaluasi kestabilan variansi.",
"First differencing pada log harga membuat perubahan berfluktuasi di sekitar nol dan mengurangi tren.",
"Naive forecast menggunakan Rp5.900/kg sebagai ramalan untuk Oktober–Desember 2024.",
"MAPE sebesar 4,30% dengan ME positif menunjukkan adanya kecenderungan under-forecast."
)
)
kable(
final_summary,
col.names = c("Tahap Analisis", "Temuan Utama"),
caption = "Ringkasan hasil analisis"
) |>
kable_styling(
bootstrap_options = c("striped", "hover"),
full_width = TRUE
)| Tahap Analisis | Temuan Utama |
|---|---|
| Data asli | Harga GKP menunjukkan kecenderungan meningkat sepanjang periode pengamatan. |
| Transformasi | Logaritma mengubah skala data dan digunakan untuk mengevaluasi kestabilan variansi. |
| Differencing | First differencing pada log harga membuat perubahan berfluktuasi di sekitar nol dan mengurangi tren. |
| Forecast | Naive forecast menggunakan Rp5.900/kg sebagai ramalan untuk Oktober–Desember 2024. |
| Evaluasi | MAPE sebesar 4,30% dengan ME positif menunjukkan adanya kecenderungan under-forecast. |
8.1 Kesimpulan
Berdasarkan analisis yang dilakukan, harga GKP Kabupaten Serang selama Januari 2023–Desember 2024 memperlihatkan kecenderungan meningkat dari waktu ke waktu. Kondisi tersebut menunjukkan adanya komponen tren pada data level.
Transformasi logaritma kemudian digunakan untuk mengubah skala data sehingga perubahan relatif dapat diamati dengan lebih baik. Selanjutnya, first differencing diterapkan pada data hasil transformasi. Hasil differencing berfluktuasi di sekitar nol dan tidak lagi memperlihatkan pola tren naik yang kuat seperti pada data awal.
Untuk evaluasi forecasting, sebanyak 21 observasi pertama digunakan sebagai training set dan tiga observasi terakhir sebagai testing set. Metode naive forecast mempertahankan nilai terakhir training, yaitu Rp5.900/kg, sebagai ramalan untuk ketiga bulan pengujian.
Hasil evaluasi menghasilkan ME sebesar Rp266,67/kg, MAE sebesar Rp266,67/kg, MSE sebesar 81.666,67, RMSE sebesar Rp285,77/kg, dan MAPE sebesar 4,30%. ME yang positif menunjukkan bahwa baseline naive cenderung menghasilkan ramalan yang lebih rendah daripada nilai aktual pada periode pengujian.
Key takeaway
Naive forecast memberikan baseline yang sederhana untuk mengukur kemampuan peramalan. Hasil ini belum dimaksudkan sebagai model terbaik, melainkan sebagai benchmark awal yang nantinya dapat dibandingkan dengan metode forecasting yang lebih kompleks.
9 Lampiran: Reproduksibilitas
Seluruh analisis dalam dokumen ini dapat direproduksi dengan menjalankan kembali seluruh chunk R secara berurutan.
## R version 4.5.0 (2025-04-11 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 11 x64 (build 26200)
##
## Matrix products: default
## LAPACK version 3.12.1
##
## locale:
## [1] LC_COLLATE=English_United States.utf8
## [2] LC_CTYPE=English_United States.utf8
## [3] LC_MONETARY=English_United States.utf8
## [4] LC_NUMERIC=C
## [5] LC_TIME=English_United States.utf8
##
## time zone: Asia/Jakarta
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] plotly_4.12.0 scales_1.4.0 kableExtra_1.4.1 knitr_1.51
## [5] tidyr_1.3.2 dplyr_1.2.0 ggplot2_4.0.2
##
## loaded via a namespace (and not attached):
## [1] sass_0.4.10 generics_0.1.4 xml2_1.4.0 lattice_0.22-6
## [5] stringi_1.8.7 digest_0.6.37 magrittr_2.0.3 evaluate_1.0.5
## [9] grid_4.5.0 RColorBrewer_1.1-3 bookdown_0.46 fastmap_1.2.0
## [13] Matrix_1.7-3 jsonlite_2.0.0 httr_1.4.7 mgcv_1.9-1
## [17] purrr_1.1.0 viridisLite_0.4.2 lazyeval_0.2.2 textshaping_1.0.3
## [21] jquerylib_0.1.4 cli_3.6.5 rlang_1.1.7 splines_4.5.0
## [25] withr_3.0.2 cachem_1.1.0 yaml_2.3.10 otel_0.2.0
## [29] tools_4.5.0 vctrs_0.7.1 R6_2.6.1 lifecycle_1.0.5
## [33] stringr_1.6.0 htmlwidgets_1.6.4 pkgconfig_2.0.3 pillar_1.11.0
## [37] bslib_0.9.0 gtable_0.3.6 glue_1.8.0 data.table_1.17.8
## [41] rmdformats_1.0.4 systemfonts_1.3.2 xfun_0.53 tibble_3.3.0
## [45] tidyselect_1.2.1 rstudioapi_0.17.1 farver_2.1.2 nlme_3.1-168
## [49] htmltools_0.5.8.1 labeling_0.4.3 rmarkdown_2.29 svglite_2.2.2
## [53] compiler_4.5.0 S7_0.2.1
Analisis Deret Waktu — STA623303
Transformasi, Differencing, dan Metrik Evaluasi Model Peramalan