Membuat Model Time Series ARIMA Menggunakan Python

Membuat Model ARIMA dengan Python StatsModel

ARIMA

ARIMA atau Auto Regressive Integrated Moving Average adalah model yang banyak dipakai dalam peramalan data time series univariat. Sesuai namanya, model ARIMA terdiri 3 komponen yaitu Auto Regressive (AR), Integrated (I) dan Moving Average (MA) dan dinotasikan sebagai ARIMA(p, d, q).

Komponen p menunjukkan jumlah orde AR pada model. Model AR dapat dikatakan sebagai model regresi dengan peubah penjelasnya adalah data periode sebelumnya. Contoh, nilai p=2 menunjukkan untuk memprediksi data pada waktu ke-t, model menggunakan peubah penjelas yaitu data pada waktu ke-(t-1) dan (t-2).

Komponen d menunjukkan jumlah proses diferensiasi (d). Proses ini perlu dilakukan untuk menangani kondisi non-stasioner (misalnya trend) hingga mencapai stasioner. Nilai d=0 menunjukkan kondisi daata yang sudah stasioner tanpa perlu melakukan proses diferensiasi atau disebut juga model ARMA(p, q).

Komponen terakhir q menunjukkan orde atau lag dari error pada model MA. Nilai q menunjukkan jumlah periode yang digunakan untuk memprediksi error saat ini berdasarkan error periode sebelumnya.

Pemilihan kombinasi yang tepat untuk p, d dan q merupakan bagian penting untuk memperoleh model ARIMA yang optimal. Nilai p dan q umumnya dapat ditentukan dengan melihat plot Autocorrelation function (ACF) dan Partial Autocorrelation Function (PACF). Sementara itu untuk d terdapat uji yang dapat digunakan yaitu uji Augmented Dickey–Fuller (ADF).

Pendekatan lain yang banyak digunakan saat ini khususnya dalam konteks machine learning adalah grid search. Grid search atau dalam penerapan pada beberapa software menggunakan terminologi auto ARIMA adalah proses pencarian model secara iteratif dari berbagai kombinasi nilai p, d dan q. Nilai p, d dan q terbaik ditentukan berdasarkan metrik tertentu seperti AIC atau BIC.

Pada tutorial ini kita akan membuat model ARIMA menggunakan bahasa pemrograman python dengan library statsmodel dan memfokuskan pada penggunaan grid search dalam menentukan orde p, d dan q yang optimal.

Memuat Data Time Series

Contoh yang akan digunakan adalah data ekspor Indonesia periode bulanan selama tahun 2016-2019 (48 bulan). download

Data terdiri dari dua kolom yaitu periode dan nilai_jt_usd. Kita perlu merubah kolom periode sebagai indeks bagi dataframe. Langkah ini dilakukan dengan mengisi nilai parameter parse_dates. Selain itu, kita juga perlu menentukan frekuensi data yang digunakan yaitu bulanan.

Untuk eksplorasi data, kita dapat memvisualisasikan secara langsung menggunakan metode plot pada objek dataframe ekspor seperti kode berikut:

Python

import pandas as pd

# Memuat dataset ekspor-idn.csv
ekspor = pd.read_csv("ekspor-idn.csv", index_col="periode", parse_dates=True)

# mengatur frekuensi data bulanan
ekspor.index.freq = 'MS'

# print data
print(ekspor)

# membuat plot data
ekspor.plot(figsize=(12, 6))

Output

# Output

            nilai_jt_usd
periode                 
2016-01-01       39479.3
2016-02-01       38596.9
2016-03-01       42908.5
...
2019-10-01       61413.0
2019-11-01       56022.2
2019-12-01       55720.1

Membuat Model ARIMA

Pembuatan model ARIMA dilakukan dengan fungsi ARIMA dari library statsmodel. Pada bagian ini, kita akan membuat model ARIMA dengan nilai p,d,q yang sudah ditentukan yaitu p=1, d=1 dan q=1. Selanjutnya, dari model tersebut kita dapat melakukan forecasting atau prediksi nilai ekspor Indonesia untuk periode-periode berikutnya. Misalkan seperti contoh berikut ini, kita melakukan forecasting untuk 3 bulan yaitu Januari-Maret 2020.

Python

# Memuat fungsi ARIMA
from statsmodels.tsa.arima.model import ARIMA

# Membagun model ARIMA dengan p=1, d=1 dan q=1
model = ARIMA(data, order=(1, 1, 1))
model_fit = model.fit()

# Melakukan forecasting
# 3 bulan (Jan-Mar 2020)
print(model_fit.forecast(3))

# alternatif prediksi
# model_fit.predict(start=len(data), end=len(data)+2, typ="levels")

# menampilkan summary model
print(model_fit.summary())

Output

# forecast

2020-01-01    55472.142703
2020-02-01    55586.231825
2020-03-01    55533.737594
Freq: MS, Name: predicted_mean, dtype: float64


# summary

SARIMAX Results                                
==============================================================================
Dep. Variable:           nilai_jt_usd   No. Observations:                   48
Model:                 ARIMA(1, 1, 1)   Log Likelihood                -461.005
Date:                Sat, 21 Jan 2023   AIC                            928.009
Time:                        14:38:14   BIC                            933.560
Sample:                    01-01-2016   HQIC                           930.098
                         - 12-01-2019                                         
Covariance Type:                  opg                                         
==============================================================================
                 coef    std err          z      P>|z|      [0.025      0.975]
------------------------------------------------------------------------------
ar.L1         -0.4601      0.245     -1.878      0.060      -0.940       0.020
ma.L1          0.1835      0.272      0.675      0.500      -0.350       0.717
sigma2      1.218e+07   7.16e-09    1.7e+15      0.000    1.22e+07    1.22e+07
==============================================================================
Ljung-Box (L1) (Q):              9.50   Jarque-Bera (JB):                 0.38
Prob(Q):                         0.00   Prob(JB):                         0.83
Heteroskedasticity (H):          1.27   Skew:                             0.14
Prob(H) (two-sided):             0.63   Kurtosis:                         2.65
==============================================================================

Warnings:
[1] Covariance matrix calculated using the outer product of gradients (complex-step).
[2] Covariance matrix is singular or near-singular, with condition number 3.29e+31. 
    Standard errors may be unstable.

Seperti yang telah disampaikan, model ARIMA memerlukan penentuan nilai p,d dan q. Salah satu teknik yang dapat digunakan adalah grid search. Langkah pertama yang perlu dilakukan adalah menyiapkan nilai-nilai p, d dan q yang akan dicobakan. Untuk memudahkan pekerjaan ini, kita dapat menggunakan fungsi product pada library itertools. Contoh yang akan kita gunakan yaitu nilai p (0-4), d (0-2) dan q (0-4). Secara total, pengaturan ini akan membandingkan 5x3x5 atau 75 model dengan kombinasi nilai p, d dan q yang berbeda.

Python

from itertools import product

# Membuat list untuk p, d, dan q
# ingat : indeks pada python dimulai dari 0
p = range(0, 5)  # 0-4
d = range(0, 3)  # 0-2
q = range(0, 5)  # 0-4

# Menggunakan fungsi product dari itertools 
# untuk membuat kombinasi p, d, dan q
pdq = list(product(p, d, q))

print(pdq)

Output

Output:

[(0, 0, 0),
 (0, 0, 1),
 (0, 0, 2),
 ...
 (4, 2, 2),
 (4, 2, 3),
 (4, 2, 4)]

Berikutnya, kita lakukan iterasi untuk setiap kombinasi nilai pada variabel pdq. Pada setiap iterasi kita membuat model ARIMA dengan nilai p, d dan q tersebut. Dari setiap model yang dibuat, kita juga menyimpan metrik aic yang nantinya digunakan dalam penentuan model terbaik

Python

from statsmodels.tsa.arima.model import ARIMA

# Membuat list untuk menyimpan Skor AIC
aic_scores = []

# Melakukan grid search manual untuk menemukan p, d, q yang optimal
for param in pdq:
    # Melakukan fitting ARIMA model
    model = ARIMA(data, order=param)
    model_fit = model.fit()
    # Menambahkan aic score ke list
    aic_scores.append({'par': param, 'aic': model_fit.aic})
    
# Memilih aic score terkecil
best_aic = min(aic_scores, key=lambda x: x['aic'])

print(best_aic)

Output

Output:

{'par': (2, 1, 2), 'aic': 911.7672265060809}

Dari proses grid search diperoleh nilai p, d dan q yang optimal adalah p=2, d=1 dan q=2 dengan skor AIC terkecil yaitu 911,767.

Langkah berikutnya, buat model ARIMA menggunakan nilai p, d dan q tersebut. Model kemudian dapat digunakan untuk forecasting sama seperti sebelumnya

Python

# Membuat model dengan p, d, dan q hasil grid search
model = ARIMA(data, order=best_aic['par']) # order=(2, 1, 2)
model_fit = model.fit()

# forecasting 3 periode waktu ke depan
model_fit.forecast(3)

# alternatif prediksi
# model_fit.predict(start=len(data), end=len(data)+2, typ="levels")

Output

2020-01-01    51357.694104
2020-02-01    54836.830177
2020-03-01    52991.158003
Freq: MS, Name: predicted_mean, dtype: float64

Validasi dan Evaluasi Model

Pada bagian sebelumnya, kita membangun model ARIMA menggunakan SELURUH DATA yang ada sehingga model tidak dapat dievaluasi dengan data baru. Cara tersebut terkadang dapat menghasilkan model yang overfitting. Praktik yang disarankan adalah membagi data menjadi setidaknya 2 bagian yaitu data training dan testing. Model akan dilatih dan dibentuk hanya berdasarkan data training saja, kemudian dilakukan evaluasi performa model menggunakan data testing (out-of-sample forecasting).

Tidak seperti validasi pada data cross section, pada data time series pembagian data tidak dapat dilakukan secara acak. Data harus dibagi 2, tepat pada suatu titik waktu tertentu. Setiap data yang berada pada periode sebelum titik tersebut digunakan sebagai data training, sementara data-data setelahnya menjadi menjadi data testing.

Dalam contoh ini, kita akan menggunakan data 5 bulan terakhir (Agustus-Desember 2019) sebagai data testing sehingga data sebelum periode tersebut menjadi data training.

Untuk menentukan nilai p,d dan q kita akan menggunakan cara yang sama seperti sebelumnya, namun data untuk fitting model adalah data training saja, bukan seluruh data.

Python

from statsmodels.tsa.arima.model import ARIMA

# Membagi data training dan testing
data_train = data[:-5]
data_test = data[-5:]

# Membuat list untuk menyimpan Skor AIC
aic_scores = []

# Melakukan grid search manual untuk menemukan p, d, q yang optimal
for param in pdq:
    # Melakukan fitting model ARIMA
    model = ARIMA(data_train, order=param)
    model_fit = model.fit()
    # Menambahkan aic score ke list
    aic_scores.append({'par': param, 'aic': model_fit.aic})
    
# Mencari skor aic terkecil
best_aic = min(aic_scores, key=lambda x: x['aic'])

print(best_aic)

# Membuat model ARIMA dengan p, d, dan q hasil grid search
model = ARIMA(data_train, order=best_aic['par'])
model_fit = model.fit()

# Melakukan prediksi 5 periode ke depan (data testing)
# (Agustus - Desember 2019)
preds = model_fit.forecast(5)

print(preds)

# alternatif prediksi periode data testing
# model_fit.predict(start=data_test.index[0], end=data_test.index[-1], typ="levels")

Output

Output:

{'par': (3, 1, 3), 'aic': 819.6467518173176}

2019-08-01    53694.007736
2019-09-01    54841.950539
2019-10-01    56074.166643
2019-11-01    53314.075703
2019-12-01    57545.297465
Freq: MS, Name: predicted_mean, dtype: float64

Hasil grid search menggunakan data training memberikan nilai yang sedikit berbeda dari sebelumnya. Nilai AIC terkecil diperoleh pada p=3, d=1 dan q=3.

Selanjutnya, untuk mengevaluasi model, kita melakukan prediksi pada periode data testing. Hasil prediksi model kemudian dibandingkan dengan nilai sebenarnya. Di sini kita akan menggunakan metrik RMSE. Untuk menghitung nilai RMSE dapat menggunakan fungsi rmse pada library statsmodels.

Dari hasil penghitungan, diperoleh nilai RMSE data testing dari model ARIMA(3, 1, 3) adalah sebesar 2861,661. Jika melihat kisaran nilai pada data testing yang berada pada rentang 50.000 – 60.000. Nilai rata-rata error sebesar 2861,661 dapat kita katakan relatif kecil sehingga model yang kita peroleh sepertinya sudah cukup bagus.

Python

from statsmodels.tools.eval_measures import  rmse

rmse = rmse(data_test["nilai_jt_usd"], preds)

print(f"RMSE : {rmse}")



data.plot(figsize=(12, 6), alpha=0.5, marker="s")
preds.plot(linewidth=2, marker="o", legend=True)

Output

RMSE : 2861.6614013795875

Dalam evalausi model time series, terdapat teknik lainnya yang dapat digunakan untuk validasi dan evaluasi yaitu walk forward validation. Teknik ini mirip seperti K-Fold CV atau LOOVC namun tentunya dengan mempertimbangkan adanya keterkaitan antar waktu pada data time series. Topik ini akan dibahas lebih lanjut pada kesempatan lainnya.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

Daftar Isi