Penerapan Data Mining Regresi untuk Prediksi Lama Pembayaran Invoice
pada PT Kreasi Pandawa Sakti dengan Algoritma Random Forest
Aris Kurniawan2311510438
Chaisar Wildan2311510669
Rilo Pamuji2311510461
Dosen Pembimbing Basuki Hari Prasetyo, S.Kom., M.Kom.
Program Studi Teknik Informatika — Peminatan Programming Expert
Fakultas Teknologi Informasi, Universitas Budi Luhur · Semester Genap 2025/2026
[ALUR] peta-presentasi
Yang Akan Kami Sampaikan
Segmen 1 · ±10 menit
Aris Kurniawan— BAB I–II
Profil instansi & latar belakang
Rumusan masalah, tujuan, manfaat
Batasan masalah
Penelitian terdahulu
Metodologi CRISP-DM
Segmen 2 · ±10 menit
Chaisar Wildan— BAB III
Sumber data & funnel penyaringan
Target penelitian & 12 fitur
Rekayasa fitur & pipeline
Cara kerja Random Forest
Setup eksperimen
Segmen 3 · ±10 menit
Rilo Pamuji— BAB IV–V
Hasil evaluasi model
Validasi silang & feature importance
Integrasi ke sistem keuangan
Demo prediksi runtime
Keterbatasan, kesimpulan, saran
Sesi tanya jawab
Kami menyiapkan 17 slide cadangan di bagian akhir — termasuk penurunan matematis
kriteria pemecahan node, mekanisme bagging, dan definisi feature importance.
01
Pendahuluan & Metodologi
Aris Kurniawan · 2311510438
BAB I Pendahuluan · BAB II Landasan Teori
Profil instansi → latar belakang → rumusan masalah → tujuan & manfaat →
batasan → penelitian terdahulu → CRISP-DM
[BAB II] profil-instansi
PT Kreasi Pandawa Sakti
Perusahaan aktivasi merek (brand activation) berlokasi di Jakarta,
menangani banyak klien dengan pola pembayaran yang sangat beragam.
Klien utama
PT Sayap Mas Utama (Wings Group)
PT Energizer Indonesia
PT Bital Asia
PT Ichi Tan Indonesia
PT Amarta Indah Otsuka
Dua entitas legal
Operasional melibatkan PT Kreasi Pandawa Sakti (KPS) dan PT Sinergi Unggul Barakarsa
(SUB) dalam satu grup usaha — karenanya rekap invoice tersebar di beberapa berkas.
Skala data
Klien24entitasberbeda
Invoice857barisrekap mentah
Periode7tahun2019–2026
Posisi penulis
Kerja praktik dilaksanakan di bagian Keuangan, yang bertanggung jawab atas
pengelolaan piutang usaha dan pemantauan pembayaran invoice.
[BAB I] latar-belakang
Piutang Usaha yang Dipantau Manual
Rp1,70 miliar
Outstanding piutang belum tertagih
dari total nilai invoice sekitar Rp64,9 miliar
sepanjang 2019–2026
Kondisi saat ini
857 baris invoice tersebar di 5 berkas rekap yang formatnya tidak seragam
Pemantauan keterlambatan masih manual memakai lembar kerja
Tidak ada estimasi kapan sebuah invoice akan dilunasi
Prioritas penagihan disusun berdasarkan perkiraan, bukan data
Dampak
Keterlambatan pembayaran berpengaruh langsung terhadap arus kas perusahaan:
proyeksi kas sulit disusun dan risiko piutang tak tertagih meningkat.
[BAB I] gagasan-solusi
Dari Masalah ke Gagasan Solusi
Pemantauan manual→prioritas penagihan tidak terukur, arus kas sulit diproyeksikan
Data historis 2019–2026→tersimpan lengkap, tetapi belum pernah dianalisis untuk memprediksi apa pun
Teknik regresi→menggali pola dari data historis untuk memprediksi nilai numerik (Han dkk., 2011)
Random Forest→menangani hubungan non-linear, tahan overfitting lewat bagging (Breiman, 2001)
Hipotesis kerja: apabila lama pembayaran sebuah invoice dapat diperkirakan
sejak invoice diterbitkan, bagian Keuangan dapat menyusun prioritas penagihan
secara lebih tepat dan terukur.
Batas kelayakan
Prediksi hanya boleh memakai atribut yang sudah diketahui saat invoice terbit —
inilah yang membedakannya dari sekadar melaporkan keterlambatan setelah terjadi.
[BAB I] rumusan-masalah
Tiga Pertanyaan Penelitian
01
Membangun model. Bagaimana membangun model regresi menggunakan algoritma
Random Forest untuk memprediksi lama pembayaran invoice berdasarkan atribut yang
tersedia saat invoice diterbitkan?
Dijawab pada Segmen 2 — slide data, fitur, dan pemodelan
02
Mengukur kinerja. Seberapa baik kinerja algoritma Random Forest dalam
memprediksi lama pembayaran invoice yang diukur menggunakan metrik
R², RMSE, dan MAE?
Dijawab pada Segmen 3 — slide hasil evaluasi dan validasi silang
03
Mengidentifikasi faktor. Atribut apa yang paling berpengaruh terhadap lama
pembayaran invoice berdasarkan analisis feature importance?
Dijawab pada Segmen 3 — slide feature importance
[BAB I] tujuan-manfaat
Tujuan dan Manfaat Penelitian
Tujuan
Menghasilkan model regresi Random Forest untuk memprediksi lama pembayaran invoice
Mengukur akurasi model berdasarkan metrik R², RMSE, dan MAE
Mengidentifikasi atribut paling berpengaruh terhadap lama pembayaran
Manfaat praktis
Membantu penyusunan prioritas penagihan
Mengoptimalkan arus kas perusahaan
Mengurangi risiko piutang tak tertagih
Manfaat akademis
Menambah penerapan Random Forest pada kasus regresi data piutang usaha
perusahaan jasa aktivasi merek — bidang yang masih jarang diteliti, karena penelitian
sejenis umumnya merumuskannya sebagai klasifikasi.
[BAB I] batasan-masalah
Batasan Masalah
No
Batasan
Konsekuensi
01
Rekap invoice PT Kreasi Pandawa Sakti 2019–2026 dari lima berkas CSV
Tidak mencakup data di luar periode tersebut
02
Target bersifat kontinu — lama pembayaran dalam hari, bukan klasifikasi
Metrik yang dipakai regresi, bukan akurasi
03
Random Forest Regression: 300 pohon, kedalaman maksimum 12, max_features="sqrt"
Algoritma lain tidak dibandingkan secara empiris
04
Terbatas pada invoice berstatus PAID dengan tanggal pembayaran lengkap
Model hanya belajar dari invoice yang sudah lunas
05
Outlier di-cap pada 90 hari berdasarkan aturan IQR
15 baris dibuang — lihat A7
Catatan atas batasan 04
Ini konsekuensi metodologis, bukan pilihan: model regresi mustahil belajar dari baris yang
belum memiliki nilai target.
Proporsi keragaman data yang berhasil dijelaskan model.
Bernilai 1 bila prediksi sempurna, 0 bila model tidak lebih baik daripada
sekadar menebak rata-rata.
\(y_i\) — lama pembayaran aktual invoice ke-\(i\) (hari)
\(\hat{y}_i\) — lama pembayaran prediksi model (hari)
\(\bar{y}\) — rata-rata lama pembayaran pada data uji
\(n\) — banyaknya data uji, dalam penelitian ini \(n=90\)
Mengapa RMSE dan MAE keduanya dilaporkan
RMSE mengkuadratkan galat sehingga menghukum kesalahan besar lebih berat;
MAE memperlakukan semua galat setara. Selisih keduanya menunjukkan ada tidaknya
segelintir prediksi yang meleset jauh.
Kategori penelitian
Data mining → prediksi → teknik regresi (supervised learning,
target numerik kontinu) → algoritma Random Forest.
[BAB II] studi-literatur
Penelitian Terdahulu & Kebaruan
Peneliti
Fokus
Metode
Hasil
Appel dkk. (2019)
Prediksi hasil pembayaran invoice pada perusahaan multinasional
Machine learning — klasifikasi
Akurasi hingga 77%
Appel dkk. (2020)
Prediksi waktu pembayaran piutang usaha pada sebuah bank
Model berbasis pohon — klasifikasi
Akurasi 81%
Nursyahbani dkk. (2026)
Keterlambatan pinjaman online di Indonesia
Random Forest vs XGBoost
RF unggul sensitivitas, XGBoost unggul presisi
Perhatian saat membandingkan
Angka 77% dan 81% di atas adalah akurasi klasifikasi, bukan R²
regresi. Keduanya tidak sebanding langsung — memprediksi berapa hari
jauh lebih sulit daripada memprediksi label telat / tidak telat.
Kebaruan penelitian ini: (1) dirumuskan sebagai regresi — memprediksi lama
pembayaran dalam hari, bukan klasifikasi status; (2) data piutang perusahaan jasa
aktivasi merek; (3) model diintegrasikan langsung ke sistem keuangan yang
dipakai sehari-hari, bukan berhenti sebagai notebook.
[BAB I] metodologi
Kerangka Kerja CRISP-DM
flowchart TD
subgraph "CRISP-DM (Cross-Industry Standard Process for Data Mining)"
direction LR
B[Business Understanding<br/>Pemahaman Bisnis] --> D[Data Understanding<br/>Pemahaman Data]
D --> P[Data Preparation<br/>Persiapan Data]
P --> M[Modeling<br/>Pemodelan]
M --> E[Evaluation<br/>Evaluasi]
E --> Dep[Deployment<br/>Penerapan]
Dep -.->|umpan balik| B
M -.->|iteratif| P
E -.->|iteratif| B
D -.->|iteratif| B
end
B1[Wawancara Finance,<br/>Ops, BOD] --> B
D1[857 baris dari<br/>5 CSV] --> D
P1[Pra-pemrosesan<br/>→ 446 baris<br/>12 fitur] --> P
M1[Random Forest<br/>300 pohon<br/>Pipeline sklearn] --> M
E1[CV 5-lipat<br/>R²=0,5563<br/>MAE=7,35 hr] --> E
Dep1[ML Sidecar<br/>FastAPI + Go<br/>Joblib model] --> Dep
[BAB I] tahapan-crisp-dm
Apa yang Dikerjakan di Setiap Tahap
Fase
Tahap
Kegiatan konkret dalam penelitian ini
01
Business Understanding
Wawancara bagian Finance, Operations, dan BOD untuk mengidentifikasi masalah pemantauan piutang
02
Data Understanding
Eksplorasi struktur 5 berkas CSV, pemeriksaan kelengkapan tanggal dan distribusi target
Pelatihan Random Forest Regression 300 pohon dengan pipeline scikit-learn
05
Evaluation
Validasi silang 5-lipat pada data latih, lalu pengujian pada data uji yang tidak pernah dilihat model
06
Deployment
Integrasi model ke sistem keuangan lewat microservice — bukan berhenti sebagai notebook
Perkakas
Seluruh analisis dan pemodelan dikerjakan dengan Python dan pustaka
scikit-learn; penerapan memakai FastAPI (sidecar) dan Go (backend).
02
Data, Fitur & Model
Chaisar Wildan · 2311510669
BAB III Analisis Masalah dan Perancangan Solusi
Sumber data → funnel penyaringan → target & 12 fitur → rekayasa fitur →
cara kerja Random Forest → setup eksperimen
[BAB III] sumber-data
Lima Berkas Rekap Invoice
Berkas CSV
Periode
Invoice
Punya tgl. bayar
Rasio
rekap_invoice_older.csv
2019–2022
152
142
93%
rekap_invoice_2023.csv
2023
95
93
98%
rekap_invoice_2024.csv
2024
220
217
99%
rekap_invoice_2025.csv
2025
316
26
8%
rekap_invoice_2026.csv
2026
71
19
27%
Total setelah deduplikasi
2019–2026
854
478
56%
Perhatikan kolom rasio
Invoice 2025 dan 2026 sebagian besar belum memiliki tanggal pembayaran — dari 316
invoice 2025, hanya 26 yang lunas tercatat. Inilah penyebab utama data menyusut, dan
menjadi keterbatasan yang kami akui di BAB V.
apps/ml/scripts/fase1_load.py — dihitung ulang saat penyusunan presentasi
[BAB III] funnel-penyaringan
Funnel Penyaringan: 857 → 446 Baris
Penyusutan terbesar: −314 baris
Terjadi karena invoice yang belum dibayar tidak memiliki nilai target — bukan
karena data rusak. Rincian tiap tahap ada di slide cadangan A10.
[BAB III] split-data
Pembagian Data Latih dan Data Uji
Bersih446baris100%
Latih356baris80%
Uji90baris20%
Cara pembagian
Pembagian acak dengan train_test_split,
test_size=0.2, shuffle=True, dan random_state=42
supaya hasilnya dapat direproduksi oleh siapa pun yang menjalankan ulang skrip.
Mengapa data uji dikunci sejak awal
90 baris data uji tidak dilibatkan sama sekali dalam
pelatihan maupun validasi silang. Ini menjamin metrik akhir mencerminkan kinerja pada
data yang benar-benar baru bagi model.
Format tanggal beragam — diseragamkan parse_date, termasuk nama
bulan Bahasa Indonesia
Koreksi lintas tahun — bila \(y_i < -180\), tahun pembayaran ditambah satu;
kesalahan penulisan tahun lazim terjadi di pergantian tahun
Nilai uang — string berformat Rupiah diubah ke bilangan riil oleh
parse_money
Mengapa bukan kolom Inv. Aging yang sudah ada?
Kolom Inv. Aging di spreadsheet tidak reliabel: kosong pada berkas
2025–2026 dan terpolusi pada berkas lama. Target karena itu dihitung ulang langsung
dari selisih tanggal.
Konsekuensi
Target dihitung dari sumber primer (tanggal), bukan dari kolom turunan yang sudah
ada — sehingga tidak mewarisi kesalahan pencatatan sebelumnya.
[BAB III] variabel-prediktor
Dua Belas Fitur Prediktor
Numerik — 6 fitur
TOTAL
Total nilai invoice
Budget
Anggaran proyek
Agency Fee
Biaya agensi
VAT
Pajak Pertambahan Nilai
WHT 23
PPh Pasal 23
top_days
Termin pembayaran
Kategorikal — 4 fitur
klien
8 tersering + Lainnya
bulan
Bulan terbit (1–12)
kuartal
Kuartal terbit (1–4)
source_year
Tahun berkas sumber
Biner — 2 fitur
ada_po
Punya nomor PO
ada_ce
Punya nomor C.E.
Prinsip pemilihan: cegah kebocoran data
Hanya atribut yang sudah diketahui saat invoice diterbitkan yang dipakai.
Kolom Payment, Balance, Status,
AR, dan Inv. Agingsengaja dibuang — semuanya baru
terisi setelah pembayaran terjadi. Bila dipakai, model akan terlihat sangat
akurat padahal sebenarnya sedang membaca jawaban.
Setelah one-hot encoding
12 fitur asli berkembang menjadi 38 kolom masukan model
— lihat A15.
[BAB III] rekayasa-fitur
Lima Tahap Rekayasa Fitur
01Konversi uangString Rupiah menjadi bilangan riil lewat parse_money
02Bentuk top_daysDue Date − Inv. Date = lama termin dalam hari
03Ekstrak waktuDari tanggal invoice diambil bulan dan kuartal
04Fitur binerada_po & ada_ce dari kolom terisi / kosong
05Kelompokkan klien8 tersering, sisanya jadi kategori "Lainnya"
Mengapa klien dikelompokkan?
Ada 24 klien berbeda, sebagian hanya muncul satu-dua kali.
Tanpa pengelompokan, one-hot encoding menghasilkan kolom yang sangat jarang
terisi dan membuat model menghafal, bukan belajar.
Mengapa PO & C.E. dibuat biner?
Nomor PO dan C.E. adalah identitas unik — tidak ada pola yang
bisa dipelajari darinya. Yang bermakna secara bisnis adalah ada atau tidaknya
dokumen tersebut, karena menandakan kelengkapan administrasi.
[BAB III] pipeline-praproses
Pipeline Transformasi Kolom
ColumnTransformer([
# 6 fitur numerik: isi kosong dengan median, lalu standardisasi
("num", Pipeline([
("imp", SimpleImputer(strategy="median")),
("sc", StandardScaler())
]), NUM),
# 4 fitur kategorikal: one-hot encoding
("cat", OneHotEncoder(handle_unknown="ignore"), CATE),
# 2 fitur biner: diteruskan apa adanya
("bin", "passthrough", BIN),
])
apps/ml/scripts/fase2_4_model.py:55–59
Mengapa dibungkus Pipeline?
Ini bukan sekadar kerapian kode, melainkan soal kebenaran metodologi.
Saat validasi silang, imputer dan scaler hanya belajar
dari lipatan latih — bukan dari lipatan validasi. Tanpa pipeline,
informasi dari data validasi bocor ke tahap praproses dan membuat metrik terlihat
lebih baik daripada kenyataan.
handle_unknown="ignore"
Membuat model tetap dapat memprediksi ketika bertemu klien baru yang belum pernah ada
saat pelatihan.
\[ \hat{y}(x) \;=\; \frac{1}{T}\sum_{t=1}^{T} h_t(x), \qquad T = 300 \]
dengan \(h_t\) pohon regresi ke-\(t\) dan \(x\) satu baris invoice.
Agar perata-rataan bermanfaat, tiap \(h_t\) harus berbeda — dua mekanisme berikut
yang menjaminnya.
01 · Bootstrap sampling
Setiap pohon dilatih pada sampel acak dengan pengembalian dari
356 data latih. Peluang satu baris tidak terpilih sama sekali:
kolom acak dari \(p=38\) kolom yang tersedia. Tanpa aturan
ini semua pohon akan memilih pemecah terbaik yang sama dan menjadi nyaris kembar,
sehingga perata-rataan tidak mengurangi galat apa pun.
Verifikasi pada model terlatih
Kedalaman pohon rata-rata 12,0 (menyentuh batas max_depth), dengan
rata-rata 62 daun per pohon. Penurunan variansinya dijelaskan di
A5.
[BAB IV] lingkungan-percobaan
Konfigurasi Model dan Lingkungan
Hyperparameter Random Forest
Parameter
Nilai
Keterangan
n_estimators
300
Jumlah pohon
max_depth
12
Kedalaman maksimum
max_features
sqrt
≈ 6 kolom per split
min_samples_split
5
Minimum untuk memecah node
min_samples_leaf
2
Minimum sampel per daun
bootstrap
True
Sampling dengan pengembalian
random_state
42
Reprodusibilitas
apps/ml/scripts/fase2_4_model.py:64–66
Lingkungan
Bahasa
Python
Pustaka
scikit-learn, pandas, NumPy
Backend
Go
Sidecar ML
FastAPI
Basis data
PostgreSQL
Protokol evaluasi
Validasi silang 5-lipat pada 356 data latih
(tiap lipatan: 284 latih / 72 validasi)
Pengujian akhir pada 90 data uji
Analisis feature importance
Pengendali overfitting tambahanmin_samples_leaf=2 dan min_samples_split=5 mencegah pohon
tumbuh terlalu spesifik pada dataset yang relatif kecil.
03
Hasil, Integrasi & Penutup
Rilo Pamuji · 2311510461
BAB IV Implementasi dan Uji Coba · BAB V Penutup
Hasil evaluasi → validasi silang → feature importance → integrasi sistem →
demo prediksi → keterbatasan → kesimpulan & saran
[BAB IV] hasil-evaluasi
Kinerja Model pada 90 Data Uji
R²0,556355,6%
RMSE11,13hariakar rata-rata kuadrat galat — menghukum kesalahan besar
MAE7,35harirata-rata galat absolut — meleset ± satu minggu
Cara membacanya secara praktis
prediksi 30 hari→kenyataan rata-rata 23–37 hari
RMSE > MAE→sebagian kecil invoice meleset jauh
R² = 0,5563→model menjelaskan 55,6% keragaman
Kesimpulan praktis
Untuk keperluan menyusun urutan prioritas penagihan — bukan menjanjikan tanggal
pasti kepada klien — ketelitian ini sudah memadai.
Selisih RMSE dan MAE (11,13 vs 7,35) menunjukkan mayoritas
prediksi cukup dekat, namun ada segelintir invoice dari klien berpola tidak teratur
yang meleset jauh. Justifikasi lengkap di A2.
Cara membaca
Garis putus-putus adalah prediksi sempurna \((\hat{y}=y)\). Semakin dekat titik
ke garis, semakin akurat prediksinya.
Yang terlihat
Titik mengumpul di sekitar garis pada rentang 0–40 hari, tempat mayoritas
invoice berada
Model terlalu berhati-hati pada nilai ekstrem — pembayaran sangat cepat
diprediksi agak lambat, dan sebaliknya
Sifat ini wajar pada model rata-rata ensemble: merata-ratakan 300
pohon menarik prediksi ke arah tengah distribusi
[BAB IV] validasi-silang
Validasi Silang 5-Lipat
Hasil agregat
Rata-rata R²
0,4523
Simpangan baku
0,0520
Rentang
0,4012–0,5365
RMSE rata-rata
10,91 hr
MAE rata-rata
7,33 hr
Mengapa ini bukti tidak overfit
Kinerja stabil di kelima lipatan — simpangan baku hanya 0,05. Model yang
overfit berkinerja sangat baik pada satu lipatan lalu anjlok pada lipatan lain.
Perhatikan arah selisihnya
R² data uji (0,5563) justru lebih tinggi daripada rata-rata validasi silang
(0,4523) — pola yang berlawanan dengan overfitting. Penjelasan lengkap di
A11.
[BAB IV] feature-importance
Fitur Paling Berpengaruh
Menjawab rumusan masalah 03
Dua fitur teratas — top_days (23,48%) dan klien (17,40%) — menyumbang lebih
dari 40% seluruh kekuatan prediksi. Nilai importance kolom hasil
one-hot telah dijumlahkan kembali ke fitur asalnya; definisi formalnya di
A6.
[BAB IV] interpretasi-bisnis
Mengapa Temuan Ini Masuk Akal
23,48% top_days — termin pembayaran
TOP adalah kesepakatan kontraktual yang secara langsung
membentuk ekspektasi kapan klien membayar. Invoice bertermin 60 hari secara alamiah
dibayar lebih lambat daripada yang bertermin 14 hari. Wajar bila ini menjadi penentu
terkuat.
17,40% klien — identitas klien
Setiap klien memiliki kebiasaan pembayaran berbeda: ada yang
taat termin, ada yang konsisten terlambat karena proses internalnya panjang. Pola ini
sulit ditangkap regresi linear, tetapi mudah dipelajari pohon keputusan.
Temuan yang berlawanan dengan praktik saat ini
Fitur bernilai uang (TOTAL 6,74%, Budget 6,71%) justru
berkontribusi kecil. Artinya besar-kecilnya nilai invoice bukan penentu utama
cepat-lambatnya pembayaran — padahal selama ini penagihan diurutkan berdasarkan nilai
invoice terbesar.
Implikasi praktis: prioritas penagihan sebaiknya disusun berdasarkan
kombinasi termin dan karakteristik klien, bukan nilai invoice.
Aturan kategorisasi
\(\hat{y} > \texttt{top\_days}\) → berisiko telat; selain itu → tepat waktu.
Pada 90 data uji: 61 berisiko telat, 29 tepat waktu.
[BAB IV] tampilan-sistem
Hasil Prediksi di Layar Pengguna
Dashboard BOD — panel Risiko Penagihan
Menampilkan jumlah invoice yang diprediksi telat dan
total outstanding yang berisiko.
AR Aging Finance — kolom Estimasi Lunas
Setiap baris invoice memperoleh estimasi hari dan
penanda risiko: Berisiko telat atau Sesuai termin.
Model tidak berhenti sebagai notebook — hasilnya sudah tampil di dua halaman
yang dipakai sehari-hari oleh manajemen dan bagian Keuangan.
[BAB IV] keterbatasan
Keterbatasan Penelitian
No
Keterbatasan
Uraian
01
Dominasi data lama
Dataset didominasi invoice 2019–2024 karena sebagian besar invoice 2025–2026
belum memiliki tanggal pembayaran lengkap. Pola pembayaran terkini belum
sepenuhnya terwakili.
02
Fitur terbatas
Fitur hanya berasal dari data yang tersedia di spreadsheet. Faktor eksternal
seperti kondisi ekonomi makro, siklus anggaran klien, atau riwayat komunikasi
penagihan belum tercakup.
03
Ukuran data
Hanya 446 baris yang layak dilatih. Untuk metode ensemble, jumlah
ini tergolong kecil sehingga membatasi kompleksitas pola yang dapat dipelajari.
04
Tanpa pembanding empiris
Algoritma lain (XGBoost, SVR, regresi linear) tidak dijalankan sebagai
pembanding; pemilihan Random Forest berdasar pertimbangan teoretis.
Sikap kami
Keempat keterbatasan ini kami sampaikan terbuka, dan semuanya menjadi dasar langsung bagi
saran pengembangan pada BAB V.
[BAB V] kesimpulan-saran
Kesimpulan dan Saran
Kesimpulan — menjawab 3 rumusan masalah
01
Model regresi Random Forest berhasil dibangun dari 446 data invoice
dengan 12 fitur prediktor, mengikuti kerangka CRISP-DM
02
Kinerja memadai: R² 0,5563, RMSE 11,13 hari,
MAE 7,35 hari; validasi silang konsisten (rata-rata R² 0,4523)
menunjukkan model tidak overfit
03
Fitur paling berpengaruh: top_days (23,48%) dan klien (17,40%)
Saran pengembangan
Menambah data tahun berikutnya, khususnya invoice 2025–2026 yang sudah lunas
Membandingkan secara empiris dengan XGBoost atau LightGBM
Optimasi hyperparameter dengan grid search atau
random search
Pembaruan estimasi secara real-time seiring masuknya data pembayaran
baru
Sidang Kuliah Kerja Praktek
Terima Kasih
Kami siap menerima pertanyaan
dan masukan dari Bapak/Ibu penguji.
Aris Kurniawan2311510438
Chaisar Wildan2311510669
Rilo Pamuji2311510461
Dosen Pembimbing Basuki Hari Prasetyo, S.Kom., M.Kom. 17 slide cadangan tersedia — tekan panah bawah (↓) pada slide
berikutnya, atau Ctrl + Shift + F untuk mencari
A
Slide Cadangan
Tidak dibawakan dalam paparan — disiapkan untuk sesi tanya jawab.
Tekan panah bawah (↓) untuk menelusuri, atau Ctrl + Shift + F untuk
mencari kata kunci seperti "outlier", "XGBoost", atau "bagging".
[LAMPIRAN] daftar-isi
Daftar Slide Cadangan
A1 Mengapa Random Forest, bukan XGBoost / linear / SVR?
A2 Mengapa R² 0,5563 dianggap memadai?
A3 Penurunan metrik evaluasi
A4 Kriteria pemecahan node (matematis)
A5 Bagging & penurunan variansi (matematis)
A6 Definisi feature importance (MDI)
A7 Aturan IQR dan cap 90 hari
A8 Mengapa 300 pohon dan max_depth 12?
A9 Detail lengkap 12 fitur
A10 Rincian penyusutan 857 → 446
A11 Selisih R² validasi silang vs data uji
A12 Potongan kode inti
A13 Bila ML sidecar mati — graceful fallback
A14 Distribusi target & statistik data
A15 Mengapa 12 fitur menjadi 38 kolom?
A16 Tepat waktu vs berisiko telat
A17 Reprodusibilitas — menjalankan ulang
A1pemilihan-algoritma
Mengapa Random Forest, Bukan Algoritma Lain?
Kriteria kasus ini
Regresi Linear
SVR
XGBoost
Random Forest
Hubungan non-linear antar variabel
Lemah
Baik
Baik
Baik
Kategorikal kardinalitas tinggi (klien)
Lemah
Lemah
Baik
Baik
Tahan outlier, tanpa feature scaling
Lemah
Perlu scaling
Cukup
Baik
Stabil pada data kecil (446 baris)
Cukup
Cukup
Rawan overfit
Baik
Menyediakan feature importance
Koefisien
Tidak
Ya
Ya
Sensitivitas terhadap tuning
Rendah
Tinggi
Tinggi
Rendah
Jawaban jujur
Pada penelitian ini kami tidak menjalankan perbandingan empiris terhadap XGBoost,
SVR, maupun regresi linear. Pemilihan Random Forest didasarkan pada pertimbangan teoretis
di atas dan rujukan Breiman (2001). Perbandingan empiris sudah kami cantumkan sebagai
saran pengembangan BAB V.
Nursyahbani dkk. (2026) membandingkan RF dan XGBoost pada kasus
keterlambatan pinjaman online: RF unggul sensitivitas, XGBoost unggul presisi —
keduanya kompetitif, tidak ada yang mutlak lebih baik.
A2justifikasi-r2
Mengapa R² 0,5563 Dianggap Memadai?
01 · Sifat domain
Yang diprediksi adalah perilaku manusia dan proses administrasi
klien — kapan tim keuangan klien memproses pembayaran. Ini bukan proses fisik
deterministik. Pada domain perilaku, R² di atas 0,5 umumnya sudah dinilai bermanfaat.
Terhadap termin paling umum 30 hari, galat tipikal ±24%.
Untuk menyusun urutan prioritas — bukan menjanjikan tanggal pasti kepada
klien — ketelitian ini memadai.
03 · Tujuan penggunaan
Model dipakai untuk memberi peringkat risiko, bukan untuk
akuntansi presisi. Yang dibutuhkan Keuangan adalah: invoice mana yang perlu ditagih
lebih dulu. Kesalahan beberapa hari tidak mengubah urutan prioritas.
04 · Perbandingan literatur
Appel dkk. melaporkan akurasi 77% (2019) dan 81% (2020) — namun itu
metrik klasifikasi, bukan R² regresi. Keduanya tidak dapat dibandingkan
langsung: memprediksi angka hari jauh lebih sulit daripada memprediksi label
telat / tidak telat.
Yang tidak kami klaim
Kami tidak mengklaim model ini sangat akurat. Sisa 44,4% keragaman belum dapat
dijelaskan — sebagian besar berasal dari faktor yang tidak ada di data, seperti proses
internal klien dan komunikasi penagihan.
\(SS_{\text{res}}\) jumlah kuadrat galat model;
\(SS_{\text{tot}}\) jumlah kuadrat simpangan terhadap rata-rata. Bila model hanya
menebak \(\bar{y}\), maka \(SS_{\text{res}}=SS_{\text{tot}}\) dan \(R^2=0\).
\(R^2\) dapat bernilai negatif bila model lebih buruk daripada menebak rata-rata.
Mengapa MAPE tidak dipakai sebagai metrik utama
MAPE membagi dengan \(y_i\). Banyak invoice dibayar sangat cepat (\(y_i\) kecil,
bahkan 0), sehingga penyebutnya mendekati nol dan MAPE meledak — pada data uji
nilainya 70,8% meski galat absolutnya hanya 7,35 hari. Metrik ini
menyesatkan untuk kasus kami.
Kesamaan kiri tercapai hanya bila semua galat sama besar.
Karena \(11{,}13 > 7{,}35\), distribusi galat kami tidak seragam — ada
segelintir prediksi yang meleset jauh.
A4kriteria-split
Kriteria Pemecahan Node
Pada regresi, tiap node dipecah untuk meminimumkan jumlah kuadrat galat
di dalam anak-anaknya. Untuk node \(m\) dengan himpunan sampel \(Q_m\) dan \(N_m=|Q_m|\):
\(\hat{c}_m\) adalah nilai prediksi node (rata-rata target di
dalamnya) dan \(H(Q_m)\) adalah variansi di node tersebut — inilah ukuran
ketidakmurnian untuk kasus regresi.
Suatu kandidat pemecahan \(\theta=(j,t)\) — fitur ke-\(j\) pada
ambang \(t\) — membelah \(Q_m\) menjadi \(Q_m^{\text{kiri}}\) dan
\(Q_m^{\text{kanan}}\). Biayanya:
Di sinilah max_features bekerja
\(\Theta_m\) bukan seluruh kemungkinan pemecahan. Pada tiap node, hanya
\(m=\lfloor\sqrt{38}\rfloor=6\) kolom yang dipilih acak untuk dievaluasi. Inilah yang
membuat 300 pohon menempuh jalur yang berbeda-beda.
Kriteria berhenti pada model kami
Kedalaman mencapai max_depth = 12
Node berisi < min_samples_split = 5 sampel
Pemecahan akan menghasilkan daun < min_samples_leaf = 2 sampel
Suku kedua \(\dfrac{1-\rho}{T}\sigma^2\) mengecil saat \(T\) bertambah —
inilah manfaat menambah pohon
Suku pertama \(\rho\sigma^{2}\) tidak terpengaruh \(T\). Berapa pun pohon
ditambahkan, variansi tidak pernah turun di bawah batas ini
Karena itu menurunkan \(\rho\) sama pentingnya dengan memperbesar \(T\)
Konsekuensi rancanganBootstrap dan max_features="sqrt" keduanya bekerja untuk menurunkan
\(\rho\) — membuat pohon saling tidak berkorelasi. Tanpa keduanya, \(\rho \to 1\) dan
ensemble tidak lebih baik daripada satu pohon.
Menjawab: "kenapa tidak 1000 pohon saja?"
Karena suku kedua meluruh sebagai \(1/T\), manfaatnya jenuh. Dari 300 ke 1000
pohon, suku itu hanya turun ~0,23%\(\sigma^2\) — tidak sebanding dengan biaya
komputasi 3,3× lipat.
Catatan: menambah \(T\) tidak pernah menyebabkan
overfitting pada Random Forest — sifat khas bagging, berbeda dari
boosting yang justru dapat memburuk bila iterasi terlalu banyak.
A6definisi-mdi
Definisi Feature Importance (MDI)
scikit-learn memakai Mean Decrease in Impurity: kontribusi
fitur \(j\) pada satu pohon adalah jumlah penurunan ketidakmurnian berbobot pada semua
node yang memecah memakai fitur tersebut, lalu dirata-ratakan atas seluruh pohon dan
dinormalisasi agar berjumlah satu.
Agregasi kembali ke 12 fitur asli
Fitur kategorikal pecah menjadi banyak kolom one-hot. Kami
menjumlahkan importance seluruh kolom turunannya kembali ke fitur asal:
\(\mathrm{Imp}(\texttt{klien}) = \sum_{k \in \text{one-hot}(\texttt{klien})} \mathrm{Imp}(k)\).
Tanpa ini, kontribusi klien akan terdilusi ke 9 kolom dan tampak jauh
lebih kecil daripada seharusnya.
Keterbatasan MDI yang kami akui
MDI bias terhadap fitur berkardinalitas tinggi — fitur dengan banyak nilai unik
punya lebih banyak kesempatan memecah node. top_days dan
klien memang termasuk kategori itu.
Permutation importance tidak bias demikian, namun tidak kami jalankan pada
penelitian ini.
Karena itu kami menafsirkan peringkatnya bersama
logika bisnis (slide Interpretasi Bisnis), bukan mengandalkan angka semata.
apps/ml/scripts/fase2_4_model.py:86–99
A7aturan-iqr
Dasar Aturan IQR dan Cap 90 Hari
\[ \text{batas} = Q_3 + 3\,(Q_3 - Q_1) \]
Dihitung pada 461 baris
Q₁10harikuartil 1
Q₃30harikuartil 3
IQR20hariQ₃ − Q₁
Batas90hari30 + 3 × 20
Dibuang15baris3,3% dari 461
Mengapa pengali 3, bukan 1,5?
Aturan Tukey memiliki dua ambang: \(1{,}5\times\mathrm{IQR}\) menandai
outlier ringan, dan \(3\times\mathrm{IQR}\) menandai outlier ekstrem.
Kami sengaja memilih kriteria yang lebih longgar agar hanya membuang kasus yang
benar-benar ekstrem dan mempertahankan sebanyak mungkin data yang sah.
Dengan \(1{,}5\times\mathrm{IQR}\) batasnya menjadi
\(30 + 1{,}5 \times 20 = 60\) hari, dan data yang dibuang akan jauh lebih banyak —
padahal invoice bertermin 60 hari adalah hal yang lazim di perusahaan ini.
Apa yang dibuang, dan mengapa
Invoice dengan lama pembayaran hingga 380 hari — umumnya sengketa penagihan
atau kesalahan pencatatan tanggal
Kasus semacam ini bukan pola pembayaran normal yang ingin dipelajari model
Bila dipertahankan, kasus ekstrem akan menarik prediksi seluruh invoice ke
atas dan merusak ketelitian pada mayoritas data
apps/ml/scripts/fase2_4_model.py:46–48 — dihitung ulang
A8pemilihan-hyperparameter
Mengapa 300 Pohon dan max_depth 12?
n_estimators = 300
Variansi ensemble meluruh sebagai \(\tfrac{1-\rho}{T}\sigma^2\)
(lihat A5) — menurun cepat lalu jenuh
300 dipilih sebagai titik aman di atas ambang konvergensi namun tetap
ringan dijalankan (< 1 detik pada laptop)
Menambah pohon tidak menyebabkan overfitting pada Random Forest —
hanya menambah waktu komputasi
max_depth = 12
Dengan hanya 356 baris latih, pohon tanpa batas kedalaman akan tumbuh
sampai tiap daun berisi satu-dua sampel — praktis menghafal data
Kedalaman 12 memberi ruang cukup untuk pola bertingkat
(klien → termin → bulan) tanpa menghafal
Diperkuat min_samples_leaf=2 dan min_samples_split=5
Verifikasi pada model terlatih
Kedalaman pohon rata-rata 12,0 (menyentuh batas), rata-rata 62 daun per pohon
dari 356 sampel latih. Artinya batas kedalaman memang aktif membatasi, bukan angka
hiasan. Bandingkan: pohon tanpa batas pada 356 sampel dengan
min_samples_leaf=2 dapat mencapai ~178 daun.
Jujur soal proses penentuan
Parameter ini ditetapkan di awal berdasarkan pertimbangan di atas dan praktik umum,
bukan hasil grid search. Optimasi hyperparameter sistematis sudah kami
tulis sebagai saran nomor 4 BAB V.
Separuh fitur adalah hasil rekayasa
Enam fitur diambil langsung dari kolom CSV; enam sisanya kami bentuk sendiri. Dan
justru dua fitur rekayasa — top_days dan klien — yang menjadi
dua prediktor terkuat.
A10funnel-rinci
Rincian Penyusutan 857 → 446 Baris
No
Tahap penyaringan
Sisa
Dibuang
Alasan metodologis
00
Gabungan 5 berkas CSV
857
—
Data mentah awal
01
Deduplikasi
854
−3
Duplikat pada kunci (Client, C.E No., Inv. Date, TOTAL, tahun)
02
Saring status PAID
792
−62
Invoice belum lunas tidak punya nilai target
03
Target y dapat dihitung
478
−314
Tanggal pembayaran kosong — mayoritas invoice 2025–2026
04
Saring y ≥ 0
461
−17
Anomali tanggal (pembayaran tercatat mendahului invoice)
05
Cap outlier IQR
446
−15
y > 90 hari — kasus ekstrem / sengketa
Penyusutan terbesar ada di tahap 03
Ini bukan data rusak, melainkan invoice yang memang belum dibayar saat
data diambil. Model regresi mustahil belajar dari baris tanpa nilai target.
Apakah 446 cukup?
Untuk Random Forest dengan 12 fitur, 446 baris tergolong kecil namun memadai —
dibuktikan validasi silang yang stabil di kelima lipatan (simpangan baku R² hanya
0,052). Penambahan data tetap menjadi saran utama kami.
A11selisih-cv-uji
Mengapa R² Validasi Silang Berbeda dari Data Uji?
Validasi silang→rata-rata R² 0,4523 · tiap model dilatih dengan 284 baris
Data uji→R² 0,5563 · model final dilatih dengan 356 baris
01 · Jumlah data latih berbeda
Pada validasi silang, tiap model hanya dilatih dengan 284 baris
(4/5 dari 356). Model final dilatih dengan seluruh 356 baris. Lebih banyak
data latih → model sedikit lebih baik.
02 · Variasi acak pada data kecil
Data uji hanya 90 baris. Pada ukuran sekecil ini R² wajar
berfluktuasi. Rentang antar lipatan CV sendiri sudah lebar —
0,4012–0,5365 — dan 0,5563 hanya sedikit di atas lipatan terbaik.
Arah selisihnya justru menenangkan
Gejala overfitting adalah kinerja tinggi saat latih lalu anjlok
saat uji. Yang kami temukan sebaliknya: kinerja pada data uji sedikit
lebih tinggi daripada rata-rata validasi silang. Ini menunjukkan model
generalisasi dengan baik, bukan menghafal.
Kapan justru perlu khawatir
Bila R² uji jauh lebih rendah daripada CV (misalnya 0,45 → 0,20), barulah itu
indikasi kuat overfitting atau data uji yang tidak representatif.
Nilai mana yang lebih jujur dilaporkan?Keduanya. Validasi silang menggambarkan stabilitas; data uji menggambarkan
kinerja pada data yang belum pernah dilihat. Karena itu kami melaporkan keduanya
berdampingan, tidak memilih yang paling bagus saja.
A12kode-inti
Potongan Kode Inti
Definisi fitur & praproses
NUM = ["TOTAL","Budget","Agency Fee",
"VAT","WHT 23","top_days"]
CATE = ["klien","bulan","kuartal","source_year"]
BIN = ["ada_po","ada_ce"]
pre = ColumnTransformer([
("num", Pipeline([
("imp", SimpleImputer(strategy="median")),
("sc", StandardScaler())]), NUM),
("cat", OneHotEncoder(
handle_unknown="ignore"), CATE),
("bin", "passthrough", BIN),
])
Perhatikan dua baris terakhirpipe.fit hanya dipanggil pada Xtr — data latih. Data uji baru
muncul di baris berikutnya untuk prediksi. Tidak ada kebocoran data.
flowchart TD
A[Pengguna buka<br/>Dashboard BOD / AR Aging] --> B[Go backend ambil<br/>invoice dari PostgreSQL]
B --> C{Panggil ML sidecar<br/>timeout 3 detik}
C -->|Berhasil| D[Estimasi hari + penanda<br/>risiko ditampilkan]
C -->|Timeout / mati /<br/>model tidak ada| E[Available = false]
E --> F[Kolom estimasi disembunyikan<br/>Halaman tetap tampil normal]
D --> G[Halaman selesai dirender]
F --> G
style D fill:#EDF7F0,stroke:#16A34A
style E fill:#FFF6EC,stroke:#B45309
style F fill:#FFF6EC,stroke:#B45309
Prinsip perancanganDashboard tidak boleh gagal hanya karena komponen ML bermasalah. Prediksi
bersifat nice-to-have; data piutang inti tetap harus tampil.
Enam kondisi pemicu fallback
Alamat sidecar tidak dikonfigurasi · gagal menyusun permintaan JSON ·
timeout 3 detik terlampaui · status HTTP bukan 200 · respons gagal diuraikan ·
peta prediksi kosong
Keputusan sadar
Pada kondisi fallback, sistem tidak menampilkan angka tebakan. Kolom
estimasi dikosongkan (—) agar pengguna tidak salah menganggapnya hasil model.
Distribusi miring ke kanan
Mayoritas invoice dibayar dalam dua minggu pertama (median 14 hari), dengan ekor
panjang ke arah pembayaran lambat. Karena rerata (19,9) > median (14),
MAE lebih representatif daripada RMSE untuk menggambarkan galat tipikal.
Dihitung ulang dari 446 baris final — apps/ml/scripts/fase2_4_model.py
A15dimensi-encoding
Mengapa 12 Fitur Menjadi 38 Kolom?
Blok
Kolom
Numerik (scaled)
6
klien (8 + Lainnya)
9
bulan (1–12)
12
kuartal (1–4)
4
source_year
5
Biner (passthrough)
2
Total
38
One-hot encoding mengubah tiap kategori
menjadi satu kolom biner tersendiri, karena algoritma tidak boleh menganggap
"bulan 12 lebih besar dari bulan 1" sebagai hubungan numerik.
Catatan koreksi terhadap dokumen proposal
Dokumen proposal menyebut ±29 kolom — itu estimasi awal. Perhitungan ulang
langsung dari pipeline yang berjalan menghasilkan 38 kolom, dan angka
inilah yang kami pakai. Konsekuensinya max_features="sqrt" berarti
\(\lfloor\sqrt{38}\rfloor = 6\) kolom acak per percabangan, bukan \(\sqrt{29}\approx 5\).
Perlu ditegaskan
Ini adalah turunan dari keluaran regresi, bukan model klasifikasi tersendiri.
Model tetap memprediksi angka hari; kategorisasi hanya membandingkan angka itu dengan
termin yang disepakati.
Proporsi berisiko telat yang tinggi (67,8%) sejalan
dengan kondisi nyata — outstanding piutang Rp1,70 miliar memang menunjukkan
banyak invoice melewati termin.
A17reprodusibilitas
Reprodusibilitas — Menjalankan Ulang
# 1. Ekstraksi & penggabungan 5 berkas CSV
python3 apps/ml/scripts/fase1_load.py
# 2. Praproses, pemodelan, evaluasi
python3 apps/ml/scripts/fase2_4_model.py
# 3. Latih ulang pada seluruh data & simpan model
python3 apps/ml/scripts/fase5_train_save.py
# 4. Jalankan sidecar inferensi
uvicorn apps.ml.app.main:app --port 8000
Penjamin reprodusibilitas
random_state=42 pada pembagian data, Random Forest, dan KFold
Seluruh praproses terbungkus dalam satu Pipeline
Berkas CSV sumber tersimpan di repositori
Angka pada presentasi ini
Seluruhnya dihasilkan ulang dengan menjalankan skrip di samping — bukan disalin
manual dari dokumen. Karena itu dapat diverifikasi kapan saja.