K-Means: müşterilerini kümele
2026 · 10 dakika okuma
Elinde 10.000 müşteri var. Hepsine aynı e-postayı mı göndereceksin? Ya da hepsine aynı indirimi mi sunacaksın? Hayır. Çünkü bazıları sık alışveriş yapıyor, bazıları sadece indirimde geliyor, bazıları yıllardır sessiz.
K-Means bu müşterileri benzer davranışlarına göre otomatik olarak gruplar. Etiket yok, kural yok — sadece veri ve mesafe.
Önce dene
Aşağıdaki demoda elmas şekiller centroid'leri (küme merkezlerini) temsil ediyor. Noktalar her adımda en yakın centroid'e atanıyor, centroid'ler de kümelerinin ortalamasına taşınıyor.
Nasıl çalışır:Her adımda iki şey olur: (1) Her nokta en yakın centroid'e atanır. (2) Her centroid kümesinin ortalamasına taşınır. Centroid'ler hareket etmeyi bırakınca yakınsadı demektir.
Algoritma adım adım
K-Means'in tüm sırrı iki basit adımın tekrarında:
import numpy as np
def kmeans(X, k, max_iter=100):
# 1. Rastgele k merkez seç
idx = np.random.choice(len(X), k, replace=False)
centroids = X[idx].copy()
for _ in range(max_iter):
# 2. Her noktayı en yakın merkeze ata
distances = np.array([[np.linalg.norm(x - c) for c in centroids] for x in X])
assignments = np.argmin(distances, axis=1)
# 3. Merkezleri güncelle
new_centroids = np.array([X[assignments == k].mean(axis=0) for k in range(len(centroids))])
# 4. Değişim yoksa dur
if np.allclose(centroids, new_centroids):
break
centroids = new_centroids
return assignments, centroidsk sayısını nasıl seçerim?
K-Means'in en zor sorusu bu. Elbow (dirsek) yöntemi en yaygın yaklaşım: farklı k değerleri için inertia'yı (noktaların kendi centroid'lerine olan uzaklık karelerinin toplamı) hesapla, grafikte "dirsek" nerede kırılıyorsa o k iyi bir seçim.
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
inertias = []
K_range = range(2, 11)
for k in K_range:
model = KMeans(n_clusters=k, random_state=42, n_init=10)
model.fit(X)
inertias.append(model.inertia_)
plt.plot(K_range, inertias, 'o-')
plt.xlabel('k (küme sayısı)')
plt.ylabel('Inertia')
plt.title('Elbow Method')
plt.show()K-Means küresel kümeler varsayar. Verinin şekli çok farklıysa (yay, halka, iç içe) DBSCAN veya Gaussian Mixture daha iyi sonuç verir.
Gerçek kullanım: müşteri segmentasyonu
E-ticarette RFM (Recency, Frequency, Monetary) analizi K-Means ile harika çalışır:
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
# RFM feature'ları oluştur
rfm = df.groupby('customer_id').agg({
'order_date': lambda x: (today - x.max()).days, # Recency
'order_id': 'count', # Frequency
'revenue': 'sum' # Monetary
}).rename(columns={'order_date':'R','order_id':'F','revenue':'M'})
# Ölçekle (K-Means mesafeye duyarlı!)
scaler = StandardScaler()
rfm_scaled = scaler.fit_transform(rfm)
# K-Means uygula
model = KMeans(n_clusters=4, random_state=42, n_init=10)
rfm['segment'] = model.fit_predict(rfm_scaled)
print(rfm.groupby('segment')[['R','F','M']].mean())K-Means'in sınırları
- Küre şeklinde olmayan kümelerle zayıf performans gösterir
- Aykırı değerlere (outlier) duyarlıdır — centroid kayar
- k'yı önceden belirlemek gerekir, her zaman bilinmez
- Başlangıç centroid'lerine bağlı — farklı çalıştırmalarda farklı sonuç
- Ölçekleme şart: büyük aralıklı değişkenler domine eder
Sıradaki yazıda Confusion Matrix: sınıflandırma modellerini nasıl değerlendirirsin, eşiği kaydırınca ne olur?