Algoritma Apriori & Frequent Itemsets
Market basket analysis, itemset, support, confidence, prinsip Apriori (anti-monoton), pembentukan kandidat join & prune, serta closed dan maximal itemset.
Notebook lab (pratinjau)
Unduh lalu jalankan di Jupyter, VS Code, atau Google Colab.
Lab Minggu 4 — Apriori & Frequent Itemsets
Tujuan lab:
- Menghitung support & confidence secara manual dengan Python.
- Menelusuri algoritma Apriori langkah demi langkah pada contoh Han & Kamber.
- Menjalankan Apriori dengan
mlxtendpada data transaksi ritel. - Melihat efek nilai min_support terhadap jumlah itemset dan waktu komputasi.
[1]
import sys
sys.path.insert(0, "..")
from itertools import combinations
import time
import pandas as pd
import matplotlib.pyplot as plt
from common.datasets import transaksi_contoh, transaksi_ritel
1. Support & confidence manual
[2]
trx = [["roti", "susu"], ["roti", "mentega", "telur"], ["susu", "mentega", "kopi"],
["roti", "susu", "mentega"], ["roti", "susu", "kopi"]]
def support(transaksi, itemset):
s = set(itemset)
return sum(s <= set(t) for t in transaksi) / len(transaksi)
print("s(roti) =", support(trx, {"roti"}))
print("s(roti, susu) =", support(trx, {"roti", "susu"}))
print("conf(roti=>susu) =", support(trx, {"roti", "susu"}) / support(trx, {"roti"}))
2. Apriori langkah demi langkah (Han & Kamber, min_sup count = 2)
[3]
T = [set(t) for t in transaksi_contoh()]
for i, t in enumerate(T, 1):
print(f"T{i}00: {sorted(t)}")
MIN = 2
def hitung(kandidat):
return {c: sum(c <= t for t in T) for c in kandidat}
[4]
# Iterasi 1
C1 = {frozenset([i]) for t in T for i in t}
cnt = hitung(C1)
L1 = {c for c, v in cnt.items() if v >= MIN}
pd.Series({",".join(sorted(c)): v for c, v in cnt.items()}).sort_index()
[5]
# Iterasi 2: semua pasangan dari L1
items = sorted(i for c in L1 for i in c)
C2 = {frozenset(p) for p in combinations(items, 2)}
cnt = hitung(C2)
L2 = {c for c, v in cnt.items() if v >= MIN}
tabel = pd.DataFrame([(",".join(sorted(c)), v, v >= MIN) for c, v in cnt.items()],
columns=["itemset", "count", "frequent"]).sort_values("itemset")
tabel
[6]
# Iterasi 3: JOIN lalu PRUNE
def join(L_prev, k):
srt = sorted(sorted(x) for x in L_prev)
hasil = set()
for i in range(len(srt)):
for j in range(i + 1, len(srt)):
if srt[i][:k - 2] == srt[j][:k - 2]:
hasil.add(frozenset(srt[i]) | frozenset(srt[j]))
return hasil
C3_join = join(L2, 3)
print("Hasil JOIN :", [sorted(c) for c in C3_join])
C3 = {c for c in C3_join if all(frozenset(s) in L2 for s in combinations(c, 2))}
print("Hasil PRUNE:", [sorted(c) for c in C3])
cnt = hitung(C3)
L3 = {c for c, v in cnt.items() if v >= MIN}
print("L3:", {",".join(sorted(c)): v for c, v in cnt.items() if v >= MIN})
[7]
# Iterasi 4
C4 = {c for c in join(L3, 4) if all(frozenset(s) in L3 for s in combinations(c, 3))}
print("C4:", C4, "-> kosong, algoritma berhenti")
print("Total frequent itemset:", len(L1) + len(L2) + len(L3))
3. Data ritel dengan mlxtend
[8]
from mlxtend.preprocessing import TransactionEncoder
from mlxtend.frequent_patterns import apriori
ritel = transaksi_ritel()
print(len(ritel), "transaksi; contoh:", ritel[:3])
te = TransactionEncoder()
onehot = pd.DataFrame(te.fit(ritel).transform(ritel), columns=te.columns_)
onehot.head()
[9]
onehot.mean().sort_values(ascending=False).plot(kind="bar", figsize=(10, 3), title="Support 1-itemset")
plt.show()
[10]
fi = apriori(onehot, min_support=0.05, use_colnames=True)
fi["panjang"] = fi["itemsets"].apply(len)
fi.sort_values("support", ascending=False).query("panjang >= 2").head(15)
Pola yang "ditanam" di generator data (roti–mentega, kopi–gula, sereal–susu, mie_instan–telur) muncul di atas.
4. Efek min_support
[11]
hasil = []
for ms in [0.2, 0.15, 0.1, 0.07, 0.05, 0.03, 0.02, 0.01]:
t0 = time.perf_counter()
f = apriori(onehot, min_support=ms, use_colnames=True)
hasil.append({"min_support": ms, "jumlah_itemset": len(f),
"waktu_ms": (time.perf_counter() - t0) * 1000})
efek = pd.DataFrame(hasil)
efek
[12]
efek.plot(x="min_support", y="jumlah_itemset", marker="o", logy=True,
title="Semakin kecil min_support, itemset meledak")
plt.gca().invert_xaxis()
plt.show()
5. Maximal itemsets
[13]
fs = set(apriori(onehot, min_support=0.05, use_colnames=True)["itemsets"])
maximal = [x for x in fs if not any(x < y for y in fs)]
print(len(fs), "frequent ->", len(maximal), "maximal")
sorted(sorted(x) for x in maximal if len(x) > 1)
✍️ Coba sendiri
- Hitung confidence
{sereal} => {susu}dan{susu} => {sereal}pada data ritel. Mengapa berbeda? - Tampilkan semua 3-itemset dengan min_support 0.02. Adakah pola
{roti, susu, telur}? - Implementasikan fungsi
apriori_saya(transaksi, min_support)sendiri (lihatexercise.py) lalu bandingkan hasilnya dengan mlxtend. - Rekomendasi bisnis: berdasarkan pasangan produk teratas, usulkan 2 strategi penempatan/promo.
[14]
# 1.
[15]
# 2.
[16]
# 3.
Rekomendasi no. 4:
- ...
Selanjutnya
Kerjakan kuis dan exercise.py, lalu jalankan python check.py 4 dari folder utama.