1 Pengantar

Dalam dunia analisis data, peramalan (forecasting) menjadi salah satu topik yang penting, terutama ketika kita berhadapan dengan data deret waktu (time series). Banyak sektor mulai dari ekonomi, pertanian, energi, hingga teknologi, bergantung pada kemampuan untuk memprediksi nilai masa depan berdasarkan pola historis.

Di ekosistem R, kita mengenal berbagai pendekatan klasik seperti ARIMA, ETS, dan TBATS yang tersedia dalam paket seperti forecast. Namun, seiring berkembangnya kebutuhan dan kemunculan model machine learning serta deep learning, muncul kebutuhan akan framework yang lebih fleksibel, terintegrasi, dan mudah diatur untuk berbagai jenis model time series.

Pada tulisan ini, kita akan membahas bagaimana cara kerja modeltime, komponen utamanya, serta bagaimana paket ini dapat mempercepat proses pengembangan model forecasting yang reproducible dan scalable.

2 Workflow

Alur kerja modeltime, seperti dikutip dari situs web CRAN-R, terdiri dari langkah-langkah berikut:

  1. Mengumpulkan data dan membaginya menjadi data pelatihan (training set) dan data pengujian (test set).

  2. Membuat dan menyesuaikan (fit) beberapa model.

  3. Menambahkan model yang telah disesuaikan ke dalam Model Table.

  4. Melakukan kalibrasi model terhadap data pengujian.

  5. Melakukan peramalan (forecast) pada data pengujian dan evaluasi akurasi.

  6. Melatih ulang (refit) model menggunakan seluruh dataset dan melakukan peramalan ke depan.

2.1 Mengumpulkan data dan membaginya menjadi data pelatihan (training set) dan data pengujian (test set)

Kita panggil data yang akan digunakan dalam tulisan ini. Data bisa didownload di website BPS Lampung.

# load library
library(tidymodels)
library(modeltime)
library(tidyverse)
library(xgboost)
library(prophet)
library(timetk)

# load data
data <- readxl::read_excel('prod_lpg_.xlsx') 
head(data)
## # A tibble: 6 × 2
##   bulan               lampung
##   <dttm>                <dbl>
## 1 2018-01-01 00:00:00 114130.
## 2 2018-02-01 00:00:00 148112.
## 3 2018-03-01 00:00:00 323383.
## 4 2018-04-01 00:00:00 554272.
## 5 2018-05-01 00:00:00 260567.
## 6 2018-06-01 00:00:00 127379.

Data terdiri dari 2 variabel, yaitu bulan dan lampung. Data ini merupakan data produksi padi bulanan yang dihasilkan dari kegiatan survei Kerangka Sampel Area (KSA) Padi di seluruh kabupaten/kota se-Lampung. Jadi data ini merupakan data agregasi di level provinsi.

2.1.1 Visualisasi data

data %>%
  plot_time_series(bulan, lampung)

Plot deret waktu produksi padi bulanan menunjukkan pola yang fluktuatif dengan kecenderungan musiman yang kuat. Setiap tahun tampak adanya periode puncak produksi yang tinggi, diikuti oleh penurunan tajam pada bulan-bulan berikutnya, yang mengindikasikan adanya siklus panen dan masa tanam yang berulang secara teratur.

Meskipun terjadi variasi yang cukup besar dari bulan ke bulan, garis tren berwarna biru memperlihatkan bahwa secara keseluruhan terdapat kecenderungan peningkatan produksi dari tahun 2021 hingga 2025, setelah sempat mengalami penurunan ringan pada periode awal 2018–2020. Pola ini menggambarkan bahwa produktivitas padi secara umum mengalami perbaikan dalam jangka panjang, meskipun masih dipengaruhi oleh faktor musiman dan variabilitas tahunan yang tinggi.

2.1.2 Split data menjadi train dan test sets.

Bagi data menjadi train dan test set dengan proporsi 0.9.

splits <- initial_time_split(data, prop = 0.9)



2.2 Membuat dan Menyesuaikan (Fit) Model

Modeltime mengakomodir berbagai model yang dapat digunakan.

Model 1: Auto ARIMA

Kita buat model dasar Auto ARIMA:

# Model 1: auto_arima ----
model_fit_arima_no_boost <- arima_reg() %>%
    set_engine(engine = "auto_arima") %>%
    fit(lampung ~ bulan, data = training(splits))

Model 2: Boosted Auto ARIMA

Model arima_boost() menggabungkan dua pendekatan, yaitu ARIMA dan XGBoost, untuk meningkatkan akurasi peramalan deret waktu. ARIMA digunakan untuk menangkap pola linear berdasarkan urutan waktu, sedangkan XGBoost mempelajari residual (kesalahan) dari ARIMA untuk menangani pola non-linear yang tidak bisa dijelaskan oleh ARIMA. Dalam model ini, fitur tanggal (bulan) digunakan oleh ARIMA sebagai penanda waktu, sementara turunan dari bulan, kuartal, atau hari dalam minggu digunakan oleh XGBoost sebagai variabel tambahan (regressor).

Agar fitur waktu tersebut dapat dibuat secara efisien, gunakan fungsi step_timeseries_signature() dari paket timetk. Fungsi ini secara otomatis mengekstrak berbagai komponen waktu dari variabel tanggal, seperti tahun, bulan, kuartal, dan sebagainya, sehingga memudahkan proses pemodelan tanpa harus menulis formula yang kompleks. Dengan cara ini, arima_boost() dapat memanfaatkan kekuatan ARIMA dalam menangkap tren linear sekaligus kekuatan XGBoost dalam mengenali pola non-linear pada data time series.

# Model 2: arima_boost ----
model_fit_arima_boosted <- arima_boost(
    min_n = 2,
    learn_rate = 0.015
) %>%
    set_engine(engine = "auto_arima_xgboost") %>%
    fit(lampung ~ bulan + as.numeric(bulan) + factor(month(bulan, label = TRUE), ordered = F),
        data = training(splits))

Model 3: Exponential Smoothing

Kita buat model Error-Trend Seasonal menggunakan model Exponential Smoothing State Space.

# Model 3: ets ----
model_fit_ets <- exp_smoothing() %>%
    set_engine(engine = "ets") %>%
    fit(lampung ~ bulan, data = training(splits))

Model 4: Prophet

# Model 4: prophet ----
model_fit_prophet <- prophet_reg() %>%
    set_engine(engine = "prophet") %>%
    fit(lampung ~ bulan, data = training(splits))

Model 5: Linear Regression

Model ini menjelaskan nilai deret waktu sebagai kombinasi dari tren waktu (linear) dan musiman (periodik). Linear regression menggunakan 2 jenis informasi dari variabel bulan, yaitu:

  1. Trend dimodelkan sebagai as.numeric(bulan), artinya bulan diubah menjadi angka. Halini memungkinkan model menangkap arah trend jangka panjang apakah nilai datanya cenderung naik atau cenderung turun seiring berjalannya waktu.

  2. Seasonal dimodelkan dengan month(bulan), yaitu bulan diambil dari variabel tersebut untuk merepresentasikan pola musiman, misalnya produksi padi meningkat pada bulan-bulan tertentu setiap tahun.

# Model 5: lm ----
model_fit_lm <- linear_reg() %>%
    set_engine("lm") %>%
    fit(lampung ~ as.numeric(bulan) + factor(month(bulan, label = TRUE), ordered = FALSE),
        data = training(splits))



2.3 Menambahkan Fit Model ke Model Table

Setelah model selesai dibuat dan di-fit pada data, langkah berikutnya adalah menggabungkan semua model tersebut ke dalam satu wadah menggunakan fungsi modeltime_table(). Fungsi ini akan memeriksa apakah setiap model sudah dilatih dengan benar, lalu menyusunnya dalam struktur terorganisir yang disebut “Modeltime Table”.

Struktur ini berguna karena memudahkan kita untuk melakukan proses lanjutan seperti evaluasi performa, kalibrasi, atau membuat peramalan terhadap banyak model sekaligus secara efisien dan terukur. Jadi, modeltime_table() berfungsi sebagai tempat penyimpanan dan pengelolaan model-model time series dalam satu workflow yang rapi dan scalable.

models_tbl <- modeltime_table(
    model_fit_arima_no_boost,
    model_fit_arima_boosted,
    model_fit_ets,
    model_fit_prophet,
    model_fit_lm
)



2.4 Kalibrasi Model terhadap Data Pengujian

Ketika kita melakukan kalibrasi model, fungsi modeltime_calibrate() akan menambahkan kolom baru bernama .calibration_data ke dalam Modeltime Table. Kolom ini berisi prediksi model pada data uji (test set) dan residualnya (selisih antara nilai aktual dan prediksi). Data inilah yang disebut calibration data, yaitu hasil prediksi di luar sampel pelatihan (out-of-sample), yang digunakan untuk mengukur seberapa baik model memprediksi data baru.

Melalui proses ini, modeltime dapat menghitung akurasi (seperti MAPE, RMSE, MAE) dan interval kepercayaan (confidence intervals) untuk peramalan. Setelah dikalibrasi, data kalibrasi tersebut akan terus “mengikuti” model dalam seluruh proses berikutnya (seperti forecasting atau refitting), sehingga hasil ramalan yang dihasilkan lebih terukur dan dapat dipercaya.

calibration_tbl <- models_tbl %>%
    modeltime_calibrate(new_data = testing(splits))

calibration_tbl
## # Modeltime Table
## # A tibble: 5 × 5
##   .model_id .model   .model_desc                         .type .calibration_data
##       <int> <list>   <chr>                               <chr> <list>           
## 1         1 <fit[+]> ARIMA(2,0,0)(0,1,1)[12] WITH DRIFT  Test  <tibble [10 × 4]>
## 2         2 <fit[+]> ARIMA(2,0,0)(0,1,1)[12] WITH DRIFT… Test  <tibble [10 × 4]>
## 3         3 <fit[+]> ETS(M,N,A)                          Test  <tibble [10 × 4]>
## 4         4 <fit[+]> PROPHET                             Test  <tibble [10 × 4]>
## 5         5 <fit[+]> LM                                  Test  <tibble [10 × 4]>



2.5 Peramalan (Forecast) pada Data Test dan Evaluasi Akurasi

Ketika kita ingin menilai seberapa baik model bekerja, ada dua hal yang harus dilakukan:

  1. Visualisasi hasil peramalan terhadap data uji (test set), yaitu dengan memplot prediksi model dibandingkan nilai aktual dari data uji, sehingga kita bisa melihat secara visual apakah ramalan model mengikuti pola data sebenarnya atau tidak.

  2. Evaluasi akurasi pada data uji (out-of-sample accuracy), yaitu menghitung metrik seperti MAPE, RMSE, atau MAE untuk mengukur seberapa besar kesalahan model dalam memprediksi data yang belum pernah dilihat.

Visualisasi hasil peramalan:

calibration_tbl %>%
    modeltime_forecast(
        new_data    = testing(splits),
        actual_data = data
    ) %>%
    plot_modeltime_forecast(
      .legend_max_width = 30,
      .interactive      = TRUE
    )

Evaluasi akurasi:

calibration_tbl %>%
    modeltime_accuracy() %>%
    table_modeltime_accuracy(
        .interactive = TRUE
    )

Interpretasi:

Tabel hasil evaluasi menunjukkan kinerja beberapa model peramalan deret waktu yang diujikan pada data testing set menggunakan berbagai metrik kesalahan, yaitu MAE, MAPE, MASE, SMAPE, dan RMSE. Metrik-metrik ini menggambarkan seberapa besar perbedaan antara nilai aktual dan nilai hasil prediksi, di mana semakin kecil nilainya menandakan performa model yang semakin baik.

Model ARIMA(2,0,0)(0,1,1)[12] WITH DRIFT + XGBOOST ERRORS menunjukkan kinerja terbaik di antara semua model yang diuji. Model ini memiliki nilai MAE sebesar 58.512, MAPE 34,62%, MASE 0,29, SMAPE 29,21, dan RMSE 78.806, yang berarti prediksi model cukup akurat dan stabil. Penambahan komponen XGBoost errors pada model ARIMA terbukti membantu memperbaiki hasil model linear dasar dengan menangkap pola non-linear pada data.

Model ARIMA(2,0,0)(0,1,1)[12] WITH DRIFT dan ETS(M,N,A) juga memberikan hasil yang baik, dengan nilai kesalahan yang hanya sedikit lebih besar dibandingkan model terbaik. Kedua model ini masih tergolong akurat dan dapat digunakan sebagai model pembanding atau alternatif.

Sebaliknya, model PROPHET menunjukkan kinerja terendah dengan nilai MAPE mencapai 56,66% dan RMSE sebesar 91.779, yang mengindikasikan tingkat kesalahan prediksi cukup besar. Hal ini kemungkinan disebabkan karena model Prophet kurang optimal dalam menangkap pola musiman dan tren yang terdapat pada data. Model Linear Regression (LM) juga menunjukkan hasil yang moderat, lebih baik dari Prophet tetapi masih kalah dibandingkan ARIMA dan ETS.

Secara umum, nilai MAPE berkisar antara 29–35% pada model-model terbaik, yang berarti rata-rata hasil prediksi meleset sekitar 30% dari nilai aktual. Selain itu, nilai MASE yang berada di bawah 1 menunjukkan bahwa model ARIMA dan ETS lebih baik daripada model naïf yang hanya menggunakan peramalan sederhana tanpa mempertimbangkan pola historis.

Dari hasil tersebut dapat disimpulkan bahwa model ARIMA dengan kombinasi XGBoost Errors merupakan pilihan yang optimal untuk memprediksi data ini. Model ini mampu menangkap baik pola linear maupun non-linear sehingga menghasilkan prediksi yang lebih akurat. Untuk peningkatan akurasi di masa depan, model dapat dikembangkan lebih lanjut dengan menambahkan variabel eksternal (seperti curah hujan, suhu, atau luas tanam), melakukan tuning hyperparameter, atau membangun model ensemble untuk menggabungkan kekuatan beberapa pendekatan sekaligus.

2.6 Melatih ulang (refit) Model dan Forecast

Pada tahapan ini, model dilatih ulang menggunakan seluruh data dan melakukan peramalan 6 bulan ke depan.

refit_tbl <- calibration_tbl %>%
    modeltime_refit(data = data)

refit_tbl %>%
  modeltime_forecast(h = "6 months", actual_data = data) %>%
  plot_modeltime_forecast(
    .legend_max_width = 25,
    .interactive      = TRUE
  ) |>
  plotly::layout(
    legend = list(
      orientation = "h",   
      y = -0.2,            
      x = 0.5,             
      xanchor = "center"   
    )
  )

Plot di atas menampilkan hasil peramalan data time series menggunakan beberapa model berbeda, yaitu ARIMA, ARIMA + XGBoost, ETS, Prophet, dan Linear Model (LM). Jika diperhatikan, data aktual menunjukkan pola musiman tahunan yang cukup kuat, dengan puncak dan lembah yang berulang setiap tahun. Pola ini menggambakan adanya siklus yang konsisten, misalnya, dalam konteks produksi padi, bisa jadi mewakili periode tanam dan panen yang terjadi secara berulang setiap tahun.

Dari hasil peramalan yang tampak di sisi kanan grafik (periode tahun 2025 hingga awal 2026), semua model secara umum mampu mengikuti pola musiman yang sama, namun dengan tingkat ketepatan yang berbeda-beda. Model ARIMA + XGBoost Errors terlihat paling menempel dengan data aktual dan memiliki area ketidakpastian (shading abu-abu) yang lebih sempit, menandakan bahwa prediksinya lebih stabil dan konsisten. Kombinasi antara ARIMA dan XGBoost ini memungkinkan model untuk menangkap pola linear sekaligus memperbaiki kesalahan residu yang bersifat non-linear, sehingga hasilnya lebih halus dan realistis.

Model ARIMA dengan Drift juga masih cukup akurat, namun prediksinya cenderung sedikit kaku dan tidak sefleksibel model hybrid ketika menghadapi perubahan musiman yang cepat. Model ETS (Error, Trend, Seasonality) pun masih mampu mengikuti pola, tetapi kadang tampak agak terlambat dalam merespons perubahan nilai aktual. Sementara itu, model Prophet dan Linear Model tidak begitu baik dalam menangkap pola musiman, prediksinya terlihat agak menyimpang dari data aktual, terutama pada bagian puncak dan lembah grafik.

Bagian abu-abu yang semakin melebar ke arah kanan menunjukkan selang kepercayaan (confidence interval) yang meningkat seiring waktu. Ini artinya, semakin jauh periode peramalan yang dilakukan, semakin besar pula ketidakpastian hasil prediksi, hal yang wajar dalam analisis deret waktu. Secara keseluruhan, ARIMA + XGBoost Errors menjadi model yang paling unggul karena mampu menghasilkan prediksi yang halus, stabil, dan paling mendekati pola aktual. Model ini juga menunjukkan bagaimana pendekatan hybrid antara metode statistik klasik dan pembelajaran mesin dapat meningkatkan akurasi forecasting, terutama pada data dengan pola musiman yang kuat.

Untuk menampilkan hasil forecast, gunakan kode sebagai berikut:

forecast_tbl <- refit_tbl %>%
    modeltime_forecast(h = "6 months", actual_data = data) %>%
    filter(.key == "prediction")

forecast_tbl
## # Forecast Results
## 
## # A tibble: 30 × 7
##    .model_id .model_desc      .key  .index              .value .conf_lo .conf_hi
##        <int> <chr>            <fct> <dttm>               <dbl>    <dbl>    <dbl>
##  1         1 UPDATE: ARIMA(2… pred… 2025-09-01 00:00:00 4.47e5  285854.  609042.
##  2         1 UPDATE: ARIMA(2… pred… 2025-10-01 00:00:00 2.70e5  108374.  431562.
##  3         1 UPDATE: ARIMA(2… pred… 2025-11-01 00:00:00 1.04e5  -58036.  265152.
##  4         1 UPDATE: ARIMA(2… pred… 2025-12-01 00:00:00 8.94e4  -72174.  251015.
##  5         1 UPDATE: ARIMA(2… pred… 2026-01-01 00:00:00 9.12e4  -70391.  252797.
##  6         1 UPDATE: ARIMA(2… pred… 2026-02-01 00:00:00 1.12e5  -49633.  273556.
##  7         2 UPDATE: ARIMA(2… pred… 2025-09-01 00:00:00 4.56e5  297559.  614497.
##  8         2 UPDATE: ARIMA(2… pred… 2025-10-01 00:00:00 2.79e5  120078.  437017.
##  9         2 UPDATE: ARIMA(2… pred… 2025-11-01 00:00:00 1.12e5  -46331.  270607.
## 10         2 UPDATE: ARIMA(2… pred… 2025-12-01 00:00:00 9.80e4  -60469.  256469.
## # ℹ 20 more rows



3 Kesimpulan

Secara umum, modeltime adalah package yang powerfull karena dalam satu workflow, kita bisa membuat berbagai model, membandingkan hasilnya, dan melakukan forecast berdasarkan model yang sudah dibuat, sangat efisien.

Tapi bicara hasilnya, kurang menggembirakan ya. Semua model yang digunakan punya error yang besar, bisa dilihat sendiri di tabel nilai MAPE-nya berapa, kemudian selang kepercayaanya juga ada yang melewati 0. Hal ini membuat hasil forecast menjadi tidak meyakinkan.

Nanti kita coba dengan model lain ya, di luar framework modeltime.

Seluruh ide dalam tulisan ini adalah adaptasi dari artikel berjudul “Getting Started with Modeltime”, bisa diakses di url https://cran.r-project.org/web/packages/modeltime/vignettes/getting-started-with-modeltime.html.