Algoritma K-Means Clustering: Iterasi Manual plus Kode Python
TL;DR
Algoritma k-means clustering ngelompokkan data lewat dua langkah yang diulang: masukkan tiap titik ke centroid terdekat, lalu geser centroid ke rata-rata anggotanya. Prosesnya berhenti waktu nggak ada titik yang pindah kelompok lagi. Jumlah klaster harus kamu tentuin sendiri di awal, biasanya lewat metode elbow atau silhouette score. K-means butuh fitur yang udah diskalakan kalau satuannya beda jauh.
Algoritma k-means clustering ngelompokkan data lewat dua langkah yang diulang terus: masukkan tiap titik ke centroid terdekat, lalu geser centroid ke rata-rata anggotanya. Berhenti waktu nggak ada titik yang pindah lagi.
Kedengeran sederhana, dan memang sederhana. Yang bikin orang bingung biasanya bukan algoritmanya, tapi cara nentuin jumlah klaster dan kapan harus menskalakan data.
Di bawah ini aku hitung tiga iterasi penuh pakai tangan dengan data 7 pelanggan warung, baru setelah itu ulang pakai Python.
Apa itu algoritma k-means clustering?
K-means clustering adalah metode buat membagi data jadi sejumlah kelompok berdasarkan kemiripan nilainya. Huruf k mewakili jumlah kelompok yang kamu tentuin di awal. Tiap kelompok diwakili satu titik pusat bernama centroid, dan tiap baris data masuk ke centroid yang jaraknya paling dekat.
Metode ini masuk kelompok unsupervised, artinya datanya nggak punya label. Kelompok metode lain yang bisa jadi pembanding aku bahas di metode data mining.
Data latihan: 7 pelanggan warung
Dua kolom: frekuensi belanja per bulan dan rata-rata nilai belanja dalam ratus ribu rupiah. Satuannya sengaja disamain biar hitungan manualnya bersih.
| Pelanggan | Frekuensi (x) | Belanja rata-rata (y) |
|---|---|---|
| P1 | 1 | 2 |
| P2 | 2 | 2 |
| P3 | 2 | 3 |
| P4 | 8 | 8 |
| P5 | 9 | 9 |
| P6 | 9 | 8 |
| P7 | 5 | 5 |
Nilai y = 2 berarti rata-rata belanja Rp 200.000, y = 9 berarti Rp 900.000.
Jarak yang dipakai Euclidean:
d = akar( (x1 - x2)^2 + (y1 - y2)^2 )
Aku sengaja pilih centroid awal yang jelek, yaitu P1 dan P2 yang letaknya bersebelahan. Tujuannya biar kamu lihat centroid beneran bergerak, bukan langsung benar di iterasi pertama.
Iterasi 1: centroid awal P1 dan P2
C1 = (1, 2)
C2 = (2, 2)
| Titik | Jarak ke C1 | Jarak ke C2 | Masuk |
|---|---|---|---|
| P1 (1,2) | 0,00 | 1,00 | K1 |
| P2 (2,2) | 1,00 | 0,00 | K2 |
| P3 (2,3) | 1,41 | 1,00 | K2 |
| P4 (8,8) | 9,22 | 8,49 | K2 |
| P5 (9,9) | 10,63 | 9,90 | K2 |
| P6 (9,8) | 10,00 | 9,22 | K2 |
| P7 (5,5) | 5,00 | 4,24 | K2 |
Hasilnya timpang: K1 cuma isi 1 titik, K2 isi 6 titik. Sekarang geser centroid ke rata-rata anggota masing-masing.
C1 baru = (1, 2) -> anggotanya cuma P1, jadi nggak pindah
C2 baru = ((2+2+8+9+9+5)/6, (2+3+8+9+8+5)/6)
= (35/6, 35/6)
= (5,833 ; 5,833)
Iterasi 2: centroid geser, ada titik yang pindah
C1 = (1,000 ; 2,000)
C2 = (5,833 ; 5,833)
| Titik | Jarak ke C1 | Jarak ke C2 | Masuk | Status |
|---|---|---|---|---|
| P1 (1,2) | 0,00 | 6,17 | K1 | tetap |
| P2 (2,2) | 1,00 | 5,42 | K1 | pindah |
| P3 (2,3) | 1,41 | 4,77 | K1 | pindah |
| P4 (8,8) | 9,22 | 3,06 | K2 | tetap |
| P5 (9,9) | 10,63 | 4,48 | K2 | tetap |
| P6 (9,8) | 10,00 | 3,84 | K2 | tetap |
| P7 (5,5) | 5,00 | 1,18 | K2 | tetap |
Contoh hitungan buat P3 ke C2:
d = akar( (5,833 - 2)^2 + (5,833 - 3)^2 )
= akar( 3,833^2 + 2,833^2 )
= akar( 14,69 + 8,03 )
= akar( 22,72 ) = 4,77
Dua titik pindah kelompok. Centroid digeser lagi:
C1 baru = ((1+2+2)/3, (2+2+3)/3) = (1,667 ; 2,333)
C2 baru = ((8+9+9+5)/4, (8+9+8+5)/4) = (7,750 ; 7,500)
Iterasi 3: berhenti
| Titik | Jarak ke C1 | Jarak ke C2 | Masuk |
|---|---|---|---|
| P1 (1,2) | 0,75 | 8,71 | K1 |
| P2 (2,2) | 0,47 | 7,96 | K1 |
| P3 (2,3) | 0,75 | 7,30 | K1 |
| P4 (8,8) | 8,50 | 0,56 | K2 |
| P5 (9,9) | 9,91 | 1,95 | K2 |
| P6 (9,8) | 9,27 | 1,35 | K2 |
| P7 (5,5) | 4,27 | 3,72 | K2 |
Nggak ada titik yang pindah, jadi prosesnya berhenti. Hasil akhirnya dua kelompok:
- K1: P1, P2, P3. Pelanggan yang belanja 1 sampai 2 kali sebulan dengan nilai Rp 200.000 sampai Rp 300.000.
- K2: P4, P5, P6, P7. Pelanggan yang belanja 5 sampai 9 kali sebulan dengan nilai Rp 500.000 sampai Rp 900.000.
Perhatiin P7. Jaraknya ke dua centroid cuma beda 0,55, jadi dia titik paling rapuh. Kalau centroid awalnya beda sedikit, P7 bisa jatuh ke K1. Titik semacam ini yang perlu kamu cek ulang sebelum dipakai buat keputusan promo.
Cara nentuin jumlah klaster
Nilai k harus kamu tentuin sebelum algoritmanya jalan. Dua cara yang paling sering dipakai:
- Metode elbow. Jalankan k-means buat k = 1 sampai 10, catat total jarak kuadrat tiap titik ke centroidnya (inertia), lalu plot. Cari titik tempat garisnya mulai melandai.
- Silhouette score. Ngukur seberapa rapat anggota satu klaster dibanding jaraknya ke klaster tetangga. Nilainya dari -1 sampai 1, makin mendekati 1 makin bagus.
Pakai dua-duanya. Elbow sering ngasih siku yang samar, dan silhouette bantu mutusin di antara dua kandidat yang mirip.
Satu pertimbangan yang jarang disebut: jumlah klaster juga harus bisa ditindaklanjuti. Kalau tim marketing cuma sanggup bikin 3 jenis promo, k = 8 nggak ada gunanya walau skornya paling tinggi.
Kode Python untuk k-means
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score
data = pd.DataFrame({
"pelanggan": ["P1","P2","P3","P4","P5","P6","P7"],
"frekuensi": [1, 2, 2, 8, 9, 9, 5],
"belanja": [2, 2, 3, 8, 9, 8, 5],
})
X = data[["frekuensi", "belanja"]]
model = KMeans(n_clusters=2, random_state=42)
data["klaster"] = model.fit_predict(X)
print(data)
print("Centroid:", model.cluster_centers_)
print("Inertia:", round(model.inertia_, 3))
print("Silhouette:", round(silhouette_score(X, data["klaster"]), 3))
Centroid yang keluar bakal sama dengan hitungan tangan tadi, yaitu sekitar (1,667 ; 2,333) dan (7,750 ; 7,500).
Buat nyari nilai k lewat elbow:
inertia = []
for k in range(1, 7):
km = KMeans(n_clusters=k, random_state=42).fit(X)
inertia.append(km.inertia_)
print(inertia)
Kalau kolommu punya satuan yang beda jauh, misalnya frekuensi 1 sampai 30 dan total belanja jutaan rupiah, skalakan dulu:
X_scaled = StandardScaler().fit_transform(X)
model = KMeans(n_clusters=3, random_state=42).fit(X_scaled)
Tanpa penskalaan, kolom rupiah bakal nguasain perhitungan jarak dan kolom frekuensi jadi nggak ngaruh sama sekali. Rincian parameter dan perilaku k-means++ ada di dokumentasi scikit-learn.
Contoh kasus: segmentasi 612 pelanggan toko_berkah
Dataset latihan ngulikdata toko_berkah punya 612 pelanggan dengan riwayat 6 bulan. Fitur yang dipakai tiga: jarak hari sejak transaksi terakhir, jumlah transaksi, dan total belanja.
Setelah penskalaan dan uji k dari 2 sampai 8, silhouette tertinggi jatuh di k = 3.
| Klaster | Jumlah pelanggan | Ciri | Tindakan |
|---|---|---|---|
| Rutin nilai kecil | 341 | Belanja 8 kali, rata-rata Rp 21.000 | Paket bundling harian |
| Pemborong bulanan | 127 | Belanja 2 kali, rata-rata Rp 214.000 | Pengingat tanggal gajian |
| Sudah lama hilang | 144 | Terakhir belanja 71 hari lalu | Pesan WhatsApp berisi voucher |
Yang menarik, kelompok pemborong bulanan cuma 21% dari jumlah pelanggan tapi nyumbang 46% omzet. Angka itu yang akhirnya ngubah prioritas promo pemilik toko.
Kalau kamu mau ngerti istilahnya lebih dulu, cek glosarium segmentasi.
Kesalahan umum waktu pakai k-means
- Lupa menskalakan fitur. Kolom rupiah bakal nutup semua kolom lain.
- Nentuin k karena angkanya bagus. Tiga klaster memang enak dijelaskan, tapi cek dulu elbow dan silhouette.
- Nggak ngeluarin outlier. Satu transaksi Rp 40 juta bisa narik centroid jauh. Cek dulu outlier sebelum modelnya jalan.
- Masukin kolom kategori mentah. Rata-rata dari nama kota nggak ada artinya.
- Nggak ngasih nama klaster. Angka 0, 1, 2 nggak bisa dipakai tim marketing. Kasih nama dari ciri anggotanya.
- Nganggap hasilnya permanen. Perilaku pelanggan berubah, jadi ulang klasterisasinya tiap kuartal.
FAQ
Gimana cara nentuin jumlah klaster yang pas?
Pakai metode elbow dan silhouette score bareng. Elbow nyari titik tempat penurunan inertia mulai melandai, silhouette ngukur kerapatan klaster dibanding jarak ke tetangganya.
Kenapa hasil k-means berubah tiap dijalankan?
Karena centroid awal dipilih acak. Isi parameter random_state dengan angka tetap kalau kamu butuh hasil yang sama persis tiap kali.
Perlu nggak menskalakan data sebelum k-means?
Perlu, kalau satuan kolommu beda jauh. K-means ngukur jarak, jadi kolom rupiah yang nilainya jutaan bakal menenggelamkan kolom frekuensi yang cuma satu digit.
Apa bedanya k-means dan k-medoids?
K-means naruh pusat klaster di titik rata-rata, k-medoids naruh pusatnya di salah satu titik data asli. K-medoids lebih tahan sama nilai ekstrem.
K-means bisa dipakai buat data kategori?
Nggak langsung, soalnya rata-rata dari kategori nggak punya arti. Pakai k-prototypes, atau klaster pakai kolom angka saja lalu lihat sebaran kategorinya per klaster.
Penutup
Dua langkah yang diulang, itu seluruh isi k-means: tempel titik ke centroid terdekat, geser centroid ke rata-rata. Sisanya cuma soal nyiapin data dan milih k.
Coba ulang hitungan tiga iterasi di atas pakai centroid awal yang beda, misalnya P1 dan P7. Kamu bakal lihat sendiri kenapa pilihan awal berpengaruh.
Lanjut baca: Algoritma C4.5 dan Decision Tree kalau datamu udah punya label dan kamu butuh model yang bisa dijelasin per aturan.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Artikel terkait
Pandas groupby: Agregasi Data ala Pivot di Python (2026)
groupby ngelompokin baris berdasarkan kolom, lalu ngitung ringkasan per grup kayak total atau rata-rata. Ini pivot-nya pandas.
Pandas to_excel: Ekspor DataFrame ke Excel (2026)
to_excel nyimpen DataFrame pandas jadi file Excel .xlsx. Ini cara pakainya, dari satu sheet sampai banyak sheet, plus setelan yang bikin hasilnya rapi.
Pandas read_excel: Baca File Excel di Python
pandas read_excel baca file Excel jadi DataFrame, bisa pilih sheet tertentu dan lompatin baris judul yang berantakan. Ini cara pakai plus parameter penting dengan contoh data toko.