Mengetahui produk apa yang sering dibeli bersama dapat membantu peritel merancang penempatan barang, rekomendasi, dan promosi. Namun, kedek...
Mengetahui produk apa yang sering dibeli bersama dapat membantu peritel merancang penempatan barang, rekomendasi, dan promosi. Namun, kedekatan dua produk dalam data tidak otomatis berarti salah satunya menyebabkan pembelian yang lain. Analisis keranjang pasar bekerja dengan pola kemunculan bersama pada sekumpulan transaksi, lalu mengubah pola tersebut menjadi hipotesis yang bisa diuji dalam konteks bisnis.
Pada artikel ini kita menyusun alur sederhana dari transaksi retail menjadi matriks basket, menambang itemset dengan FP-Growth, dan membentuk aturan asosiasi menggunakan mlxtend. Contoh memakai data kecil untuk laboratorium lokal: tujuannya menjelaskan proses, bukan membuktikan manfaat komersial. Kode ditulis untuk pandas 2.x dan mlxtend 0.25.x, tetapi belum diverifikasi melalui eksekusi di lingkungan penulisan ini karena dependensi tersebut tidak terpasang.
1. Dari transaksi ke pertanyaan bisnis
Bayangkan sebuah toko ingin mencari kombinasi produk yang layak dipertimbangkan untuk rekomendasi. Unit pengamatan yang dipakai adalah satu transaksi, bukan satu baris produk. Setiap transaksi berisi satu atau lebih item, dan pengulangan produk yang sama dalam transaksi hanya dihitung sebagai keberadaan item, bukan sebagai jumlah unit yang terjual.
Aturan seperti {roti} → {selai} dibaca: dalam transaksi yang mengandung roti, seberapa sering selai juga muncul? Bagian kiri disebut antecedent, sementara bagian kanan disebut consequent. Arah aturan memengaruhi pertanyaan dan confidence: aturan roti ke selai tidak harus memiliki confidence yang sama dengan aturan sebaliknya.
Tentukan batas keranjang sebelum menghitung
ID transaksi harus benar-benar mewakili satu pembelian. Jika data menggabungkan transaksi dari banyak cabang, periode, kanal, atau pelanggan, pertimbangkan apakah populasi itu cukup seragam untuk dianalisis bersama. Pisahkan pembatalan dan retur sesuai kebijakan yang jelas; jangan diam-diam mengubah denominator setelah hasil terlihat kurang menarik.
Dalam praktik, kode produk juga perlu distandardisasi. Dua ejaan untuk produk yang sama akan terhitung sebagai item berbeda, sementara penggabungan kategori yang terlalu luas dapat menutupi perbedaan perilaku. Simpan definisi produk dan rentang tanggal analisis agar hasil dapat ditinjau ulang.
2. Menyiapkan data dan encoding basket
Contoh berikut sengaja kecil dan tidak mewakili populasi pelanggan toko tertentu. Setiap daftar bersarang adalah satu transaksi; tidak ada nilai penjualan, kuantitas, atau identitas pelanggan. Dengan struktur ini kita bisa fokus pada keberadaan item dalam keranjang.
import pandas as pd
from mlxtend.preprocessing import TransactionEncoder
from mlxtend.frequent_patterns import fpgrowth, association_rules
transactions = [
["roti", "susu", "selai"],
["roti", "susu"],
["roti", "selai"],
["susu", "sereal"],
["roti", "susu", "sereal"],
["roti", "selai", "sereal"],
["susu", "selai"],
["roti", "susu", "selai", "sereal"],
]
encoder = TransactionEncoder()
basket_array = encoder.fit(transactions).transform(transactions)
basket = pd.DataFrame(basket_array, columns=encoder.columns_)
print(basket.head())
TransactionEncoder mempelajari daftar item dan menghasilkan kolom boolean: True berarti item hadir dalam transaksi. Jumlah baris harus sama dengan jumlah transaksi yang dianalisis. Dataset contoh menggunakan delapan transaksi hanya untuk memperlihatkan bentuk data; jumlah sekecil ini tidak cukup untuk menyimpulkan kebiasaan belanja pelanggan secara andal.
Jika sumber berupa baris transaksi
Pada data nyata, satu transaksi lazimnya tersebar dalam beberapa baris dengan kolom ID transaksi dan nama produk. Pastikan keduanya tidak kosong, lalu hilangkan pasangan duplikat agar jumlah unit tidak dianggap sebagai transaksi tambahan. Berikut pola konversi jika df sudah berisi kolom transaction_id dan item:
clean = df.dropna(subset=["transaction_id", "item"]).copy()
clean["item"] = clean["item"].astype(str).str.strip()
clean = clean[clean["item"] != ""]
clean = clean.drop_duplicates(["transaction_id", "item"])
transactions = (clean.groupby("transaction_id")["item"]
.agg(list).tolist())
Selanjutnya berikan transactions tersebut kepada encoder pada contoh sebelumnya. Periksa juga ID yang tidak unik lintas cabang dan transaksi kosong: bila keranjang kosong memang termasuk populasi studi, keputusan mengeluarkannya akan mengubah support dan harus dicatat. Pengelompokan sederhana di atas mengabaikan transaksi tanpa item valid.
3. Menambang frequent itemset dengan FP-Growth
Frequent itemset adalah himpunan produk yang muncul bersama pada proporsi transaksi setidaknya sebesar ambang min_support. Misalnya, support {roti, selai} adalah jumlah transaksi yang memuat keduanya dibagi jumlah seluruh transaksi dalam populasi yang dipilih. Ambang bukan ukuran kualitas bisnis yang universal: terlalu tinggi dapat membuang pola relevan, terlalu rendah dapat menghasilkan banyak kandidat yang sulit ditinjau.
itemsets = fpgrowth(
basket,
min_support=0.25,
use_colnames=True,
)
print(itemsets.sort_values("support", ascending=False))
Di laboratorium ini, 0,25 hanyalah ambang ilustratif untuk delapan keranjang. Hasilnya tidak boleh langsung diterapkan ke toko nyata. Parameter use_colnames=True membuat itemset ditampilkan dengan nama produk, bukan indeks kolom. Rincian parameter dan bentuk hasil tersedia pada dokumentasi resmi mlxtend untuk FP-Growth.
Mengapa FP-Growth, bukan Apriori?
Apriori membangun kandidat itemset secara bertahap dan memangkas kandidat berdasarkan frekuensi subset. FP-Growth memampatkan pola transaksi ke dalam FP-tree dan menambang pola melalui struktur tersebut, sehingga tidak perlu membangkitkan kandidat secara eksplisit seperti Apriori. Pendekatan ini sering menarik ketika jumlah kombinasi kandidat besar.
Pilihan itu bukan janji bahwa FP-Growth selalu lebih cepat atau lebih hemat memori. Bentuk data, ambang support, jumlah item, dan implementasi sangat memengaruhi hasil. Untuk keputusan operasional, bandingkan keduanya pada data dan lingkungan yang sama, dengan pemeriksaan kebenaran hasil serta pengukuran sumber daya. Tidak ada benchmark yang dijalankan dalam contoh ini.
4. Membentuk aturan dan membaca metrik
Frequent itemset belum menjadi rekomendasi. Fungsi association_rules membagi itemset menjadi sisi kiri dan kanan, kemudian menghitung metrik untuk aturan yang memenuhi ambang. Berikutnya kita gunakan confidence sebagai penyaring awal, bukan sebagai satu-satunya kriteria keputusan.
from inspect import signature
rule_options = {"metric": "confidence", "min_threshold": 0.5}
if "num_itemsets" in signature(association_rules).parameters:
rule_options["num_itemsets"] = len(basket)
rules = association_rules(itemsets, **rule_options)
columns = ["antecedents", "consequents", "support",
"confidence", "lift"]
print(rules[columns].sort_values("lift", ascending=False))
Dokumentasi resmi mlxtend 0.25.0 memakai num_itemsets=len(df.index) pada contoh association_rules; blok kode di atas memeriksa tanda tangan fungsi agar tetap berjalan pada versi lama yang belum memiliki argumen tersebut. Pastikan frequent itemset diperoleh dari populasi yang sama dengan jumlah transaksi tersebut. Lihat juga dokumentasi resmi association_rules untuk definisi metrik dan opsi versi yang dipakai.
Support, confidence, dan lift
Untuk aturan A → B, support adalah proporsi seluruh transaksi yang memuat A dan B. Confidence adalah proporsi transaksi yang memuat A dan juga memuat B. Lift membandingkan confidence itu dengan proporsi transaksi yang memuat B: secara matematis, lift = confidence(A → B) / support(B), selama support(B) tidak nol.
Lift di atas satu menunjukkan B muncul bersama A lebih sering daripada yang diharapkan dari frekuensi marginalnya berdasarkan perbandingan tersebut; lift satu menunjukkan kesesuaian dengan baseline independensi, sedangkan lift di bawah satu menunjukkan frekuensi bersama yang lebih rendah. Ini adalah deskripsi asosiasi dalam data, bukan bukti sebab akibat atau kepastian bahwa intervensi promosi akan berhasil.
5. Menyaring aturan yang benar-benar berguna
Daftar aturan sering panjang dan mengandung kombinasi yang secara statistik muncul bersama tetapi tidak berguna untuk tindakan. Tetapkan batas yang sesuai kebutuhan sebelum melihat hasil, lalu gunakan analisis sensitivitas untuk memahami bagaimana hasil berubah ketika ambang digeser. Contoh berikut hanya menunjukkan mekanisme penyaringan, bukan rekomendasi ambang untuk semua toko.
if rules.empty:
useful = rules.copy()
else:
useful = rules.loc[
(rules["support"] >= 0.25)
& (rules["confidence"] >= 0.5)
& (rules["lift"] > 1.0)
& (rules["consequents"].map(len) == 1)
].sort_values(["lift", "support"], ascending=False)
print(useful[columns])
Jika tidak ada aturan yang lolos, hasil kosong juga merupakan hasil yang perlu dilaporkan; jangan menurunkan ambang hanya untuk menghasilkan cerita. Satu consequent memudahkan penyajian sebagai rekomendasi satu produk, tetapi bukan syarat matematis aturan asosiasi. Tambahkan pemeriksaan jumlah transaksi pendukung, ketersediaan stok, margin, serta relevansi terhadap kanal sebelum aturan dipakai.
Prioritas bukan sekadar peringkat lift
Aturan dengan lift tertinggi mungkin hanya didukung segelintir pembelian. Sebaliknya, pola dengan lift moderat dan jangkauan lebih besar dapat lebih menarik untuk diuji. Pertimbangkan apakah rekomendasi dapat ditindaklanjuti, apakah produk sudah hampir selalu dibeli tanpa intervensi, dan apakah aturan itu hanya mengulangi pola yang sudah jelas bagi tim toko.
Hindari juga aturan yang tidak masuk akal secara operasional, misalnya mempromosikan produk yang tidak tersedia di cabang yang dituju. Catat aturan yang ditolak beserta alasannya agar proses kurasi tidak bergantung pada intuisi yang sulit diaudit.
Sebelum menyerahkan daftar kepada tim bisnis, buat tabel evaluasi yang memuat aturan, jumlah keranjang pendukung, periode pengamatan, dan alasan aturan dapat ditindaklanjuti. Tim dapat menambahkan status stok, kecocokan produk, dan batasan operasional sebagai kolom terpisah. Dengan demikian, aturan tidak disamakan dengan instruksi otomatis untuk mengubah harga atau tata letak.
Perhatikan pula arah penerapan. Jika produk antecedent sudah berada di keranjang pelanggan, consequent mungkin menjadi kandidat rekomendasi; tetapi bila data hanya tersedia setelah pembayaran, aturan tersebut lebih cocok untuk evaluasi atau perencanaan berikutnya. Pastikan informasi yang dibutuhkan benar-benar tersedia pada saat keputusan akan dibuat. Pisahkan aturan penemuan dari aturan yang sudah disetujui, dan catat kapan setiap aturan perlu ditinjau kembali.
6. Jebakan dataset kecil dan rencana validasi
Pada dataset kecil, satu transaksi tambahan dapat mengubah support dan confidence secara besar. Lift juga dapat tampak tinggi ketika produk konsekuen jarang dibeli, walaupun jumlah kemunculan bersama sangat sedikit. Menambang banyak aturan sekaligus meningkatkan peluang menemukan pola yang tampak menarik hanya karena variasi acak. Karena itu, nilai metrik tanpa hitungan dasar dan ukuran sampel dapat menyesatkan.
Confidence tinggi bukan probabilitas universal untuk setiap pelanggan, dan lift tinggi bukan ukuran besarnya kenaikan penjualan akibat rekomendasi. Keduanya bergantung pada populasi, periode, dan cara transaksi dibentuk. Musiman, promosi sebelumnya, stok kosong, dan perbedaan perilaku cabang bisa mengubah frekuensi produk maupun hubungan yang terlihat. Penjelasan formal tambahan tentang definisi aturan dapat dibaca di Association rule learning.
Uji ulang sebelum dijadikan keputusan
Gunakan periode pengembangan untuk menemukan aturan dan periode lain yang lebih baru untuk memeriksa apakah pola bertahan. Laporkan jumlah transaksi pendukung dan frekuensi produk, bukan hanya metrik yang dibulatkan. Jika data memungkinkan, periksa kestabilan menurut cabang atau kanal dan tetapkan batas minimum dukungan yang relevan dengan ukuran populasi.
Untuk mengukur dampak bisnis, rancang eksperimen terkontrol yang sesuai, dengan kelompok pembanding dan ukuran keberhasilan yang disepakati. Perhatikan privasi data pelanggan dan pastikan rekomendasi tidak melanggar kebijakan organisasi. Hasil eksperimen dapat berbeda dari asosiasi historis karena rekomendasi sendiri mengubah perilaku pembeli.
Alur ini memberikan titik awal yang transparan: bentuk transaksi secara konsisten, encode menjadi basket boolean, tambang frequent itemset dengan FP-Growth, hitung aturan, lalu saring dan validasi. Contoh lokal ini belum diuji eksekusinya, belum dibandingkan dengan Apriori, dan belum diuji pada data retail nyata maupun eksperimen bisnis. Verifikasi lingkungan serta evaluasi pada data yang representatif adalah langkah berikutnya sebelum hasilnya dipakai untuk keputusan.
COMMENTS