Tugas Mata Kuliah Penambangan Data – Reproduksi Analisis Explainability Skforecast#

Nama: Zakaria Mujur Prasetyo
NIM: 240411100144
Mata Kuliah: Penambangan Data Kelas A
Sumber reproduksi: https://skforecast.org/0.15.1/user_guides/explainability.html

Pada tugas ini, saya mereproduksi studi kasus dari dokumentasi resmi Skforecast tentang model explainability pada data time series.
Kasus yang saya angkat adalah prediksi permintaan listrik harian di Victoria, Australia menggunakan ForecasterRecursive dan LGBMRegressor.
Saya memilih kasus ini karena relevan dengan topik penambangan data, khususnya pada aspek bagaimana model machine learning bisa dijelaskan hasilnya, bukan sekadar menghasilkan angka prediksi.

Pertanyaan tugas yang saya jawab dalam notebook ini:

  1. Analisa prediksi tentang apa?

  2. Bagaimana bentuk data trainingnya, apa input dan outputnya?

  3. Apa itu lag?

  4. Jelaskan proses analysis yang dilakukan dari kasus tersebut.


Daftar Isi#

Bagian A – Reproduksi Kode

  1. Instalasi Library

  2. Import Library

  3. Mengambil Dataset

  4. Agregasi Data ke Harian

  5. Visualisasi Data Harian

  6. Split Data Training dan Testing

  7. Membuat dan Melatih Model Forecasting

  8. Membentuk Data Training Model

  9. Model-specific Feature Importance

  10. SHAP Values

  11. Explain Individual Observation

  12. SHAP Dependence Plot

  13. Prediksi 10 Hari ke Depan

  14. Membuat Matriks Input untuk Prediksi

  15. Menjelaskan Nilai Prediksi dengan SHAP

  16. Permutation Feature Importance

  17. Partial Dependence Plot

Bagian B – Jawaban Pertanyaan Tugas

Bagian C – Ringkasan Akhir


1. Instalasi Library#

Pertama-tama, saya perlu menginstal beberapa library yang dibutuhkan.
Saya menjalankan notebook ini di Google Colab, jadi saya menginstal library di sini.
Kalau teman-teman menjalankan di localhost dan library-nya sudah terpasang, bagian ini bisa dilewati saja.

!pip install -q skforecast==0.15.1 lightgbm shap scikit-learn pandas numpy matplotlib
[notice] A new release of pip is available: 25.3 -> 26.1.2
[notice] To update, run: C:\Python314\python.exe -m pip install --upgrade pip

2. Import Library#

Setelah instalasi selesai, saya meng-import semua library yang saya butuhkan.
Library yang saya pakai mengikuti dokumentasi Skforecast, yaitu pandas untuk manipulasi data, matplotlib untuk visualisasi, shap untuk explainability, sklearn untuk evaluasi model, lightgbm sebagai algoritma machine learning, dan skforecast sebagai framework forecasting.

import warnings
warnings.filterwarnings("ignore")

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import shap

from lightgbm import LGBMRegressor
from sklearn.inspection import permutation_importance
from sklearn.inspection import PartialDependenceDisplay
from sklearn.metrics import mean_absolute_error, mean_squared_error, mean_absolute_percentage_error

from skforecast.datasets import fetch_dataset
from skforecast.recursive import ForecasterRecursive

pd.set_option("display.max_columns", None)
pd.set_option("display.width", 120)

3. Mengambil Dataset#

Di sini saya mengambil dataset vic_electricity yang sudah disediakan oleh Skforecast.
Dataset ini berisi data permintaan listrik di Victoria, Australia. Saya menggunakan kolom-kolom berikut:

Kolom

Keterangan

Demand

jumlah permintaan listrik

Temperature

suhu rata-rata di Melbourne

Date

tanggal pencatatan

Holiday

penanda apakah hari tersebut hari libur

Saya memilih dataset ini karena datanya cukup lengkap dan cocok untuk menunjukkan bagaimana time series forecasting bekerja dalam konteks penambangan data.

data = fetch_dataset(name="vic_electricity")

print("Ukuran data awal:", data.shape)
display(data.head())
display(data.tail())
vic_electricity
---------------
Half-hourly electricity demand for Victoria, Australia
O'Hara-Wild M, Hyndman R, Wang E, Godahewa R (2022).tsibbledata: Diverse
Datasets for 'tsibble'. https://tsibbledata.tidyverts.org/,
https://github.com/tidyverts/tsibbledata/.
https://tsibbledata.tidyverts.org/reference/vic_elec.html
Shape of the dataset: (52608, 4)
Ukuran data awal: (52608, 4)
Demand Temperature Date Holiday
Time
2011-12-31 13:00:00 4382.825174 21.40 2012-01-01 True
2011-12-31 13:30:00 4263.365526 21.05 2012-01-01 True
2011-12-31 14:00:00 4048.966046 20.70 2012-01-01 True
2011-12-31 14:30:00 3877.563330 20.55 2012-01-01 True
2011-12-31 15:00:00 4036.229746 20.40 2012-01-01 True
Demand Temperature Date Holiday
Time
2014-12-31 10:30:00 3873.448714 19.0 2014-12-31 False
2014-12-31 11:00:00 3791.637322 18.5 2014-12-31 False
2014-12-31 11:30:00 3724.835666 17.7 2014-12-31 False
2014-12-31 12:00:00 3761.886854 17.3 2014-12-31 False
2014-12-31 12:30:00 3809.414586 17.1 2014-12-31 False

4. Agregasi Data ke Harian#

Data aslinya memiliki interval pencatatan setiap setengah jam, jadi terlalu detail kalau langsung dipakai.
Maka dari itu, saya mengubah data ini menjadi data harian dengan cara:

  • Demand saya jumlahkan per hari (karena kita ingin tahu total permintaan listrik satu hari penuh).

  • Temperature saya hitung rata-ratanya per hari (karena kita ingin tahu suhu rata-rata harian).

Ini adalah salah satu tahap preprocessing yang penting dalam penambangan data sebelum data dimasukkan ke model.

data_daily = data.resample("D").agg({
    "Demand": "sum",
    "Temperature": "mean"
})

print("Ukuran data setelah agregasi harian:", data_daily.shape)
display(data_daily.head())
display(data_daily.tail())
Ukuran data setelah agregasi harian: (1097, 2)
Demand Temperature
Time
2011-12-31 82531.745918 21.047727
2012-01-01 227778.257304 26.578125
2012-01-02 275490.988882 31.751042
2012-01-03 258955.329422 24.567708
2012-01-04 213792.376946 18.191667
Demand Temperature
Time
2014-12-27 173292.325672 18.189583
2014-12-28 196116.228892 24.539583
2014-12-29 188570.258296 17.677083
2014-12-30 187212.226846 17.391667
2014-12-31 104963.021342 21.034615

5. Visualisasi Data Harian#

Selanjutnya saya membuat grafik untuk melihat pola permintaan listrik dan suhu dari waktu ke waktu.
Dari visualisasi ini, saya bisa mengamati apakah ada pola musiman atau tren tertentu yang bisa dimanfaatkan oleh model.

fig, ax = plt.subplots(figsize=(12, 5))
data_daily["Demand"].plot(ax=ax)
ax.set_title("Permintaan Listrik Harian")
ax.set_xlabel("Tanggal")
ax.set_ylabel("Demand")
plt.show()

fig, ax = plt.subplots(figsize=(12, 5))
data_daily["Temperature"].plot(ax=ax)
ax.set_title("Suhu Harian")
ax.set_xlabel("Tanggal")
ax.set_ylabel("Temperature")
plt.show()
_images/a13bd3b9762b15eb52023878b0b5887800ff6d3db5c25231bda4b0700fe22010.png _images/7091c7fdc26a6e01da23ade2498f162f6af0e9ae3a605c19b00ce9fbfe01c6bd.png

6. Split Data Training dan Testing#

Di tahap ini saya membagi data menjadi dua bagian:

Bagian

Rentang

Data training

sampai 2014-12-21

Data testing

mulai 2014-12-22

Data training saya gunakan untuk melatih model, sedangkan data testing saya pakai untuk menguji seberapa akurat prediksi model.
Pembagian ini penting dalam penambangan data agar kita bisa mengevaluasi performa model secara objektif, yaitu dengan data yang belum pernah dilihat oleh model sebelumnya.

data_train = data_daily.loc[: "2014-12-21"]
data_test  = data_daily.loc["2014-12-22":]

print("Jumlah data training:", data_train.shape)
print("Jumlah data testing :", data_test.shape)

display(data_train.tail())
display(data_test.head())
Jumlah data training: (1087, 2)
Jumlah data testing : (10, 2)
Demand Temperature
Time
2014-12-17 215507.677076 17.675000
2014-12-18 214934.022460 16.520833
2014-12-19 197129.766534 16.543750
2014-12-20 186486.896670 18.506250
2014-12-21 216483.631690 24.031250
Demand Temperature
Time
2014-12-22 231957.371966 22.950000
2014-12-23 210444.465956 18.829167
2014-12-24 184197.155182 18.312500
2014-12-25 165398.200578 16.933333
2014-12-26 168797.125272 16.429167
fig, ax = plt.subplots(figsize=(12, 5))
data_train["Demand"].plot(ax=ax, label="Training")
data_test["Demand"].plot(ax=ax, label="Testing")
ax.set_title("Pembagian Data Training dan Testing")
ax.set_xlabel("Tanggal")
ax.set_ylabel("Demand")
ax.legend()
plt.show()
_images/f0135f7caad9e563c237b8dcdbe78e0be8a1d526044aadeeb02315cd28ad925c.png

7. Membuat dan Melatih Model Forecasting#

Di sini saya membuat model peramalan menggunakan:

  • ForecasterRecursive sebagai metode peramalan multi-step secara rekursif.

  • LGBMRegressor sebagai algoritma machine learning berbasis pohon keputusan.

  • lags = 7, artinya saya menggunakan 7 nilai permintaan listrik sebelumnya sebagai fitur.

  • Temperature saya tambahkan sebagai variabel eksogen (variabel tambahan dari luar target).

Target yang saya prediksi adalah Demand, yaitu permintaan listrik harian.
Saya memilih LightGBM karena algoritma ini dikenal cepat dan cocok untuk data tabular seperti kasus ini.

forecaster = ForecasterRecursive(
    regressor = LGBMRegressor(random_state=123, verbose=-1),
    lags      = 7
)

forecaster.fit(
    y    = data_train["Demand"],
    exog = data_train["Temperature"]
)

forecaster

ForecasterRecursive

General Information
  • Regressor: LGBMRegressor
  • Lags: [1 2 3 4 5 6 7]
  • Window features: None
  • Window size: 7
  • Exogenous included: True
  • Weight function included: False
  • Differentiation order: None
  • Creation date: 2026-06-11 16:27:42
  • Last fit date: 2026-06-11 16:27:59
  • Skforecast version: 0.15.1
  • Python version: 3.14.3
  • Forecaster id: None
Exogenous Variables
    Temperature
Data Transformations
  • Transformer for y: None
  • Transformer for exog: None
Training Information
  • Training range: [Timestamp('2011-12-31 00:00:00'), Timestamp('2014-12-21 00:00:00')]
  • Training index type: DatetimeIndex
  • Training index frequency: D
Regressor Parameters
    {'boosting_type': 'gbdt', 'class_weight': None, 'colsample_bytree': 1.0, 'importance_type': 'split', 'learning_rate': 0.1, 'max_depth': -1, 'min_child_samples': 20, 'min_child_weight': 0.001, 'min_split_gain': 0.0, 'n_estimators': 100, 'n_jobs': None, 'num_leaves': 31, 'objective': None, 'random_state': 123, 'reg_alpha': 0.0, 'reg_lambda': 0.0, 'subsample': 1.0, 'subsample_for_bin': 200000, 'subsample_freq': 0, 'verbose': -1}
Fit Kwargs
    {}

🛈 API Reference    🗎 User Guide

8. Membentuk Data Training Model#

Pada bagian ini, saya ingin menunjukkan bagaimana Skforecast mengubah data time series menjadi bentuk tabel supervised learning.
Ini adalah konsep penting dalam penambangan data, yaitu transformasi data agar bisa diolah oleh algoritma machine learning.

Input model yang terbentuk terdiri dari:

  • lag_1 sampai lag_7 (nilai Demand hari-hari sebelumnya)

  • Temperature (suhu pada hari yang diprediksi)

Sedangkan output atau target modelnya adalah:

  • y, yaitu nilai Demand yang ingin saya prediksi.

X_train, y_train = forecaster.create_train_X_y(
    y    = data_train["Demand"],
    exog = data_train["Temperature"]
)

print("Bentuk X_train:", X_train.shape)
print("Bentuk y_train:", y_train.shape)

display(X_train.head())
display(y_train.head())
Bentuk X_train: (1080, 8)
Bentuk y_train: (1080,)
lag_1 lag_2 lag_3 lag_4 lag_5 lag_6 lag_7 Temperature
Time
2012-01-07 205338.714620 211066.426550 213792.376946 258955.329422 275490.988882 227778.257304 82531.745918 24.098958
2012-01-08 200693.270298 205338.714620 211066.426550 213792.376946 258955.329422 275490.988882 227778.257304 20.223958
2012-01-09 200061.614738 200693.270298 205338.714620 211066.426550 213792.376946 258955.329422 275490.988882 19.161458
2012-01-10 216201.836844 200061.614738 200693.270298 205338.714620 211066.426550 213792.376946 258955.329422 16.042708
2012-01-11 217176.907910 216201.836844 200061.614738 200693.270298 205338.714620 211066.426550 213792.376946 14.815625
Time
2012-01-07    200693.270298
2012-01-08    200061.614738
2012-01-09    216201.836844
2012-01-10    217176.907910
2012-01-11    217517.475010
Freq: D, Name: y, dtype: float64

Penjelasan Bentuk Data Training#

Untuk lebih jelasnya, berikut arti dari setiap kolom yang saya dapatkan:

Kolom

Arti

lag_1

Demand 1 hari sebelumnya

lag_2

Demand 2 hari sebelumnya

lag_3

Demand 3 hari sebelumnya

lag_4

Demand 4 hari sebelumnya

lag_5

Demand 5 hari sebelumnya

lag_6

Demand 6 hari sebelumnya

lag_7

Demand 7 hari sebelumnya

Temperature

suhu pada hari yang diprediksi

y

Demand aktual yang menjadi target prediksi

Jadi bisa saya simpulkan bahwa model ini belajar dari pola 7 hari terakhir ditambah informasi suhu untuk memprediksi permintaan listrik hari berikutnya.

9. Model-specific Feature Importance#

Di sini saya melihat fitur mana yang dianggap paling penting oleh model LGBMRegressor.
Feature importance ini merupakan salah satu teknik explainability dalam penambangan data yang membantu saya memahami alasan di balik prediksi model.

feature_importance = forecaster.get_feature_importances()
display(feature_importance)
feature importance
7 Temperature 570
0 lag_1 470
2 lag_3 387
1 lag_2 362
6 lag_7 325
5 lag_6 313
4 lag_5 298
3 lag_4 275
fig, ax = plt.subplots(figsize=(9, 5))
feature_importance.sort_values("importance").plot(
    x="feature",
    y="importance",
    kind="barh",
    ax=ax,
    legend=False
)
ax.set_title("Feature Importance dari LGBMRegressor")
ax.set_xlabel("Importance")
ax.set_ylabel("Feature")
plt.show()
_images/82d2c944169646146976008f998d22d26536cf090014b7e23a956fb8015b7a43.png

10. SHAP Values#

Selanjutnya saya menggunakan SHAP (SHapley Additive exPlanations) untuk menjelaskan kontribusi setiap fitur terhadap hasil prediksi model.
SHAP ini berbasis teori permainan dan bisa menunjukkan seberapa besar pengaruh masing-masing fitur, baik positif maupun negatif.
Karena model saya berbasis pohon keputusan (LightGBM), saya menggunakan TreeExplainer yang lebih cepat.

shap.initjs()

explainer = shap.TreeExplainer(forecaster.regressor)
shap_values_train = explainer.shap_values(X_train)

# Untuk menjaga kompatibilitas jika output SHAP berbentuk list
if isinstance(shap_values_train, list):
    shap_values_train = shap_values_train[0]

print("Bentuk SHAP values:", shap_values_train.shape)
Bentuk SHAP values: (1080, 8)

SHAP Summary Plot dalam Bentuk Bar#

Plot bar ini menunjukkan rata-rata pengaruh setiap fitur terhadap prediksi.
Dari sini saya bisa melihat fitur mana yang secara umum paling berpengaruh terhadap model.

shap.summary_plot(shap_values_train, X_train, plot_type="bar")
_images/ec63675565116302cfd736f0dbcaf0f27edd24d63746f442bb5a02f8c6188a42.png

SHAP Summary Plot Detail#

Berbeda dengan plot bar sebelumnya, plot ini menunjukkan arah pengaruh fitur.
Saya bisa melihat apakah nilai fitur yang tinggi mendorong prediksi naik atau turun.
Warna merah menunjukkan nilai fitur tinggi, sedangkan biru menunjukkan nilai rendah.

shap.summary_plot(shap_values_train, X_train)
_images/7586d3f6ce115f143e1cd943afe5d3f698ae53d30cd2f1a3e53a8e2ae29b7e4e.png

11. Explain Individual Observation#

Di bagian ini saya mencoba menjelaskan satu data training secara individual.
Tujuannya agar saya bisa melihat fitur mana yang menaikkan atau menurunkan hasil prediksi pada satu baris data tertentu.
Ini yang disebut sebagai local explanation dalam konteks explainability.

shap.force_plot(
    explainer.expected_value,
    shap_values_train[0, :],
    X_train.iloc[0, :]
)
Visualization omitted, Javascript library not loaded!
Have you run `initjs()` in this notebook? If this notebook was from another user you must also trust this notebook (File -> Trust notebook). If you are viewing this notebook on github the Javascript has been stripped for security. If you are using JupyterLab this error is because a JupyterLab extension has not yet been written.

12. SHAP Dependence Plot#

Dependence plot ini saya gunakan untuk melihat hubungan antara satu fitur dengan nilai SHAP-nya.
Pada contoh ini saya memilih fitur Temperature karena saya ingin tahu bagaimana suhu memengaruhi prediksi permintaan listrik.
Hasilnya cukup menarik karena bisa terlihat pola non-linear.

fig, ax = plt.subplots(figsize=(8, 5))
shap.dependence_plot("Temperature", shap_values_train, X_train, ax=ax)
plt.show()
_images/e5dd47fbd8863bd344b60a7cf7f45bd29e5726f86de94f1fa21f3fddf28d718e.png

13. Prediksi 10 Hari ke Depan#

Sekarang saya menggunakan model yang sudah dilatih untuk memprediksi 10 hari pertama pada data testing.
Saya ingin melihat seberapa akurat model dalam memprediksi permintaan listrik di hari-hari yang belum pernah dilihat sebelumnya.

predictions = forecaster.predict(
    steps = 10,
    exog  = data_test["Temperature"]
)

display(predictions)
2014-12-22    241514.532543
2014-12-23    226165.936559
2014-12-24    220506.468700
2014-12-25    209260.948991
2014-12-26    184885.145832
2014-12-27    195623.591810
2014-12-28    222766.340659
2014-12-29    223112.716406
2014-12-30    219103.891733
2014-12-31    217948.965404
Freq: D, Name: pred, dtype: float64
hasil_prediksi = pd.DataFrame({
    "Actual_Demand": data_test["Demand"].iloc[:10],
    "Predicted_Demand": predictions
})

hasil_prediksi["Error"] = hasil_prediksi["Actual_Demand"] - hasil_prediksi["Predicted_Demand"]

display(hasil_prediksi)
Actual_Demand Predicted_Demand Error
2014-12-22 231957.371966 241514.532543 -9557.160577
2014-12-23 210444.465956 226165.936559 -15721.470603
2014-12-24 184197.155182 220506.468700 -36309.313518
2014-12-25 165398.200578 209260.948991 -43862.748413
2014-12-26 168797.125272 184885.145832 -16088.020560
2014-12-27 173292.325672 195623.591810 -22331.266138
2014-12-28 196116.228892 222766.340659 -26650.111767
2014-12-29 188570.258296 223112.716406 -34542.458110
2014-12-30 187212.226846 219103.891733 -31891.664887
2014-12-31 104963.021342 217948.965404 -112985.944062
mae = mean_absolute_error(hasil_prediksi["Actual_Demand"], hasil_prediksi["Predicted_Demand"])
rmse = np.sqrt(mean_squared_error(hasil_prediksi["Actual_Demand"], hasil_prediksi["Predicted_Demand"]))
mape = mean_absolute_percentage_error(hasil_prediksi["Actual_Demand"], hasil_prediksi["Predicted_Demand"]) * 100

print("Evaluasi prediksi 10 hari pertama data testing")
print(f"MAE  : {mae:,.2f}")
print(f"RMSE : {rmse:,.2f}")
print(f"MAPE : {mape:.2f}%")
Evaluasi prediksi 10 hari pertama data testing
MAE  : 34,994.02
RMSE : 44,748.89
MAPE : 23.68%
fig, ax = plt.subplots(figsize=(10, 5))
hasil_prediksi[["Actual_Demand", "Predicted_Demand"]].plot(ax=ax)
ax.set_title("Perbandingan Demand Aktual dan Prediksi")
ax.set_xlabel("Tanggal")
ax.set_ylabel("Demand")
plt.show()
_images/135214a333eefa0a6c3978169c052f9d9b6281bc80351d03f8029ba47ef77133.png

14. Membuat Matriks Input untuk Prediksi#

Di sini saya membuat matriks X_predict yang berisi fitur-fitur yang dipakai model ketika melakukan prediksi.
Kolomnya sama seperti data training, yaitu lag_1 sampai lag_7 dan Temperature.
Ini berguna untuk saya analisis lebih lanjut menggunakan SHAP di langkah berikutnya.

X_predict = forecaster.create_predict_X(
    steps = 10,
    exog  = data_test["Temperature"]
)

display(X_predict)
lag_1 lag_2 lag_3 lag_4 lag_5 lag_6 lag_7 Temperature
2014-12-22 216483.631690 186486.896670 197129.766534 214934.022460 215507.677076 226093.767670 231923.044018 22.950000
2014-12-23 241514.532543 216483.631690 186486.896670 197129.766534 214934.022460 215507.677076 226093.767670 18.829167
2014-12-24 226165.936559 241514.532543 216483.631690 186486.896670 197129.766534 214934.022460 215507.677076 18.312500
2014-12-25 220506.468700 226165.936559 241514.532543 216483.631690 186486.896670 197129.766534 214934.022460 16.933333
2014-12-26 209260.948991 220506.468700 226165.936559 241514.532543 216483.631690 186486.896670 197129.766534 16.429167
2014-12-27 184885.145832 209260.948991 220506.468700 226165.936559 241514.532543 216483.631690 186486.896670 18.189583
2014-12-28 195623.591810 184885.145832 209260.948991 220506.468700 226165.936559 241514.532543 216483.631690 24.539583
2014-12-29 222766.340659 195623.591810 184885.145832 209260.948991 220506.468700 226165.936559 241514.532543 17.677083
2014-12-30 223112.716406 222766.340659 195623.591810 184885.145832 209260.948991 220506.468700 226165.936559 17.391667
2014-12-31 219103.891733 223112.716406 222766.340659 195623.591810 184885.145832 209260.948991 220506.468700 21.034615

15. Menjelaskan Nilai Prediksi dengan SHAP#

Pada bagian ini saya menjelaskan prediksi pada tanggal tertentu, yaitu 2014-12-22, menggunakan SHAP.
Dengan cara ini saya bisa memahami mengapa model memberikan prediksi tertentu pada tanggal tersebut — fitur mana yang mendorong nilai naik dan mana yang menariknya turun.

predicted_date = "2014-12-22"
iloc_predicted_date = X_predict.index.get_loc(predicted_date)

shap_values_predict = explainer.shap_values(X_predict)
if isinstance(shap_values_predict, list):
    shap_values_predict = shap_values_predict[0]

shap.force_plot(
    explainer.expected_value,
    shap_values_predict[iloc_predicted_date, :],
    X_predict.iloc[iloc_predicted_date, :]
)
Visualization omitted, Javascript library not loaded!
Have you run `initjs()` in this notebook? If this notebook was from another user you must also trust this notebook (File -> Trust notebook). If you are viewing this notebook on github the Javascript has been stripped for security. If you are using JupyterLab this error is because a JupyterLab extension has not yet been written.

16. Permutation Feature Importance#

Selain SHAP, saya juga menggunakan metode permutation importance.
Cara kerjanya adalah dengan mengacak nilai satu fitur, lalu melihat seberapa besar performa model menurun.
Kalau performa model turun banyak setelah fitur diacak, berarti fitur itu memang penting buat model.
Metode ini saya anggap lebih “jujur” karena model-agnostic, artinya bisa dipakai untuk model apa saja.

r = permutation_importance(
    estimator    = forecaster.regressor,
    X            = X_train,
    y            = y_train,
    n_repeats    = 3,
    max_samples  = 0.5,
    random_state = 123
)

permutation_importances = pd.DataFrame({
    "feature": X_train.columns,
    "mean_importance": r.importances_mean,
    "std_importance": r.importances_std
}).sort_values("mean_importance", ascending=False)

display(permutation_importances)
feature mean_importance std_importance
0 lag_1 0.617276 0.014583
7 Temperature 0.411240 0.014405
6 lag_7 0.196190 0.001865
1 lag_2 0.122398 0.007803
5 lag_6 0.083912 0.003637
2 lag_3 0.041294 0.002019
4 lag_5 0.030787 0.001079
3 lag_4 0.024816 0.001021
fig, ax = plt.subplots(figsize=(9, 5))
permutation_importances.sort_values("mean_importance").plot(
    x="feature",
    y="mean_importance",
    kind="barh",
    ax=ax,
    legend=False
)
ax.set_title("Permutation Feature Importance")
ax.set_xlabel("Mean Importance")
ax.set_ylabel("Feature")
plt.show()
_images/35a7d38f6de217ef1aa44a2c4e25d55184f458d55c1e30984fd0008c222eb2a1.png

17. Partial Dependence Plot#

Terakhir, saya membuat Partial Dependence Plot (PDP) untuk melihat hubungan antara fitur tertentu dengan hasil prediksi model.
Saya memilih fitur Temperature dan lag_1 karena dari analisis sebelumnya kedua fitur ini termasuk yang paling berpengaruh.
PDP ini membantu saya memahami bagaimana perubahan nilai suatu fitur memengaruhi prediksi secara rata-rata.

fig, ax = plt.subplots(figsize=(10, 5))

PartialDependenceDisplay.from_estimator(
    estimator = forecaster.regressor,
    X         = X_train,
    features  = ["Temperature", "lag_1"],
    kind      = "both",
    ax        = ax
)

ax.set_title("Partial Dependence Plot")
fig.tight_layout()
plt.show()
_images/9256b3a3b49e032b03f44ff4d027ed14fc1d6eb037eb529b2f877d5a1be44f25.png

Jawaban Pertanyaan Tugas#

Berikut adalah jawaban saya terhadap pertanyaan-pertanyaan yang diberikan dalam tugas mata kuliah Penambangan Data Kelas A.

Pertanyaan 1: Analisa prediksi tentang apa?#

Menurut pemahaman saya, analisis prediksi pada kasus ini membahas tentang prediksi permintaan (demand) listrik harian di wilayah Victoria, Australia.

Secara lebih rinci:

  • Variabel yang diprediksi (target): Demand, yaitu total kebutuhan atau permintaan listrik dalam satu hari.

  • Tujuan prediksi: Memperkirakan berapa besar permintaan listrik di hari-hari mendatang berdasarkan pola permintaan di masa lalu dan kondisi suhu.

  • Metode yang digunakan: Model ForecasterRecursive dari library Skforecast dengan algoritma LGBMRegressor (LightGBM).

  • Jenis analisis: Selain prediksi, kasus ini juga fokus pada explainability (kemampuan menjelaskan model), yaitu memahami mengapa model memberikan prediksi tertentu.

Dalam konteks mata kuliah Penambangan Data, kasus ini relevan karena menunjukkan bagaimana teknik data mining dapat diaplikasikan pada data time series untuk menghasilkan prediksi yang bukan hanya akurat, tetapi juga bisa dijelaskan. Ini penting karena dalam dunia nyata, kita tidak cukup hanya mengetahui “angka prediksinya berapa”, tetapi juga perlu tahu “kenapa model memberikan angka itu”.

Pertanyaan 2: Bagaimana bentuk data trainingnya, apa input dan outputnya?#

Data awal yang saya gunakan berbentuk time series (data runtun waktu), yaitu data yang tersusun berdasarkan urutan waktu.
Setelah saya ubah dari interval setengah jam menjadi data harian, library Skforecast secara otomatis mengubah data ini menjadi format supervised learning — yaitu format tabel yang terdiri dari kolom input (fitur) dan kolom output (target).

Input Model (Fitur)#

Fitur

Keterangan

Tipe

lag_1

Demand 1 hari sebelumnya

Lag feature

lag_2

Demand 2 hari sebelumnya

Lag feature

lag_3

Demand 3 hari sebelumnya

Lag feature

lag_4

Demand 4 hari sebelumnya

Lag feature

lag_5

Demand 5 hari sebelumnya

Lag feature

lag_6

Demand 6 hari sebelumnya

Lag feature

lag_7

Demand 7 hari sebelumnya

Lag feature

Temperature

Suhu rata-rata harian di Melbourne

Variabel eksogen

Output Model (Target)#

Output

Keterangan

y

Nilai Demand aktual yang ingin diprediksi

Ilustrasi#

Misalnya, untuk memprediksi permintaan listrik pada tanggal 8 Januari 2012, model akan menggunakan:

  • Permintaan listrik tanggal 7 Januari (lag_1), 6 Januari (lag_2), …, hingga 1 Januari (lag_7)

  • Suhu rata-rata pada tanggal 8 Januari (Temperature)

Jadi, bentuk data training saya adalah tabel dengan 8 kolom input (lag_1 s.d. lag_7 + Temperature) dan 1 kolom output (y).
Proses transformasi dari time series ke tabel ini merupakan contoh nyata dari feature engineering dalam penambangan data.

Pertanyaan 3: Apa itu lag?#

Dari yang saya pelajari, lag (atau lagged variable) adalah nilai data pada periode sebelumnya yang digunakan sebagai input untuk memprediksi nilai saat ini atau masa depan.

Penjelasan Sederhana#

Bayangkan kita ingin memprediksi permintaan listrik hari ini. Salah satu informasi yang berguna adalah mengetahui permintaan listrik kemarin, 2 hari lalu, 3 hari lalu, dan seterusnya. Nah, nilai-nilai di masa lalu inilah yang disebut “lag”.

Dalam Kasus Ini#

Lag

Arti

lag_1

Demand 1 hari sebelumnya

lag_2

Demand 2 hari sebelumnya

lag_3

Demand 3 hari sebelumnya

lag_4

Demand 4 hari sebelumnya

lag_5

Demand 5 hari sebelumnya

lag_6

Demand 6 hari sebelumnya

lag_7

Demand 7 hari sebelumnya

Karena saya memakai lags = 7, artinya model saya menggunakan data permintaan listrik selama 7 hari terakhir sebagai “jendela” (window) untuk memprediksi permintaan listrik hari berikutnya.

Mengapa Lag Penting?#

  • Menangkap pola temporal: Lag membantu model mengenali pola berulang, misalnya permintaan listrik yang selalu tinggi di hari kerja dan rendah di akhir pekan.

  • Mengubah time series jadi tabel: Dengan lag, data time series bisa diubah menjadi format supervised learning yang bisa diolah oleh algoritma machine learning biasa.

  • Konsep fundamental: Dalam penambangan data dan forecasting, lag adalah salah satu teknik paling dasar dan paling sering digunakan untuk menangkap ketergantungan antar waktu (temporal dependency).

Pertanyaan 4: Jelaskan proses analysis yang dilakukan#

Berikut adalah proses analisis yang saya lakukan secara bertahap:

Tahap 1: Pengambilan Data#

Saya mengambil dataset vic_electricity dari library Skforecast. Dataset ini berisi data permintaan listrik, suhu, tanggal, dan informasi hari libur di Victoria, Australia. Data awalnya berjumlah sangat banyak karena dicatat setiap setengah jam.

Tahap 2: Preprocessing Data#

Saya melakukan preprocessing dengan mengagregasi data menjadi data harian:

  • Kolom Demand dijumlahkan per hari (untuk mendapat total permintaan satu hari penuh)

  • Kolom Temperature dihitung rata-ratanya per hari

Tahap ini penting karena data yang terlalu granular bisa menyulitkan model dan membuat proses training lebih lama.

Tahap 3: Eksplorasi & Visualisasi Data#

Saya membuat grafik time series untuk melihat pola dari data Demand dan Temperature. Dari visualisasi ini, saya bisa mengamati adanya pola musiman (seasonal pattern) di mana permintaan listrik naik di musim panas dan dingin.

Tahap 4: Split Data Training & Testing#

Data saya bagi menjadi:

  • Training: sampai 2014-12-21 (untuk melatih model)

  • Testing: mulai 2014-12-22 (untuk menguji prediksi model)

Pembagian ini sesuai dengan prinsip evaluasi objektif dalam penambangan data, di mana model diuji pada data yang belum pernah dilihat sebelumnya.

Tahap 5: Pembuatan & Training Model#

Saya membuat model ForecasterRecursive dengan algoritma LGBMRegressor, menggunakan 7 lag dan variabel eksogen Temperature. Model dilatih menggunakan data training.

Tahap 6: Transformasi Data ke Supervised Learning#

Skforecast secara otomatis mengubah time series menjadi tabel supervised learning dengan kolom lag_1 s.d. lag_7 + Temperature sebagai input dan Demand sebagai output.

Tahap 7: Analisis Explainability#

Ini adalah bagian inti dari kasus ini. Saya menggunakan beberapa metode untuk menjelaskan model:

Metode

Penjelasan

Feature Importance

Menunjukkan fitur mana yang paling sering dipakai oleh model LightGBM dalam proses splitting pohon keputusan

SHAP Values

Menunjukkan kontribusi setiap fitur secara detail. SHAP Summary Plot (bar) untuk gambaran umum, SHAP Summary Plot (dot) untuk arah pengaruh, dan Force Plot untuk penjelasan per observasi

SHAP Dependence Plot

Menunjukkan hubungan non-linear antara satu fitur (misalnya Temperature) dengan pengaruhnya terhadap prediksi

Permutation Importance

Mengukur pentingnya fitur dengan cara mengacak nilainya dan melihat seberapa besar performa model menurun. Metode ini model-agnostic

Partial Dependence Plot (PDP)

Menunjukkan bagaimana perubahan nilai satu fitur memengaruhi prediksi secara rata-rata, dengan mempertahankan fitur lain konstan

Tahap 8: Prediksi & Evaluasi#

Model saya gunakan untuk memprediksi 10 hari pertama pada data testing. Hasilnya saya bandingkan dengan data aktual dan evaluasi menggunakan metrik:

  • MAE (Mean Absolute Error): rata-rata kesalahan absolut

  • RMSE (Root Mean Squared Error): akar dari rata-rata kuadrat kesalahan

  • MAPE (Mean Absolute Percentage Error): rata-rata kesalahan dalam persentase

Kesimpulan Proses#

Keseluruhan proses ini menunjukkan bahwa model machine learning tidak hanya bisa dipakai untuk forecasting, tetapi juga bisa dijelaskan hasilnya menggunakan teknik explainability. Ini sejalan dengan apa yang saya pelajari di mata kuliah Penambangan Data, bahwa memahami model sama pentingnya dengan membangun model itu sendiri.


Ringkasan Akhir#

Dari reproduksi yang saya lakukan dalam tugas Penambangan Data ini, saya dapat menyimpulkan bahwa:

  1. Target prediksi dalam kasus ini adalah Demand (permintaan listrik harian di Victoria, Australia).

  2. Input model terdiri dari lag_1 sampai lag_7 (nilai permintaan listrik 7 hari terakhir) dan Temperature (suhu harian rata-rata). Total ada 8 fitur input.

  3. Output model adalah prediksi Demand untuk hari berikutnya.

  4. Lag adalah nilai masa lalu yang digunakan sebagai fitur input. Konsep ini sangat fundamental dalam analisis time series karena membantu model mengenali pola temporal.

  5. Analisis explainability yang saya lakukan (feature importance, SHAP, permutation importance, dan PDP) menunjukkan bahwa lag_1 dan Temperature adalah fitur yang paling berpengaruh terhadap prediksi model.

Tugas ini memberikan saya pemahaman yang lebih mendalam tentang bagaimana teknik penambangan data dapat diterapkan pada permasalahan nyata, khususnya dalam hal forecasting dan model interpretability.


Notebook ini dibuat oleh Zakaria Mujur Prasetyo (240411100144) untuk tugas mata kuliah Penambangan Data Kelas A.