Ana içeriğe geç

Orta13 dk

DBSCAN

Önkoşul:Hiyerarşik kümeleme

Kanca

27-29. derste K-Means ve hiyerarşik kümeleme, HER noktayı bir kümeye zorla atadı. Ama ya bazı noktalar gerçekten hiçbir kümeye ait değilse — sadece dağınık gürültüyse? Ve ya kümelerin şekli daire değil, eğri veya iç içe geçmişse?

Sezgi

DBSCAN, kümeleri “yoğunluk” fikriyle tanımlar — bir bölge, içinde yeterince fazla nokta varsa bir kümedir; az sayıda, izole nokta ise GÜRÜLTÜdür. Her nokta üç kategoriden birine girer:

  • Çekirdek (core): kendi çevresinde (yarıçap eps içinde) en az minPts komşusu olan nokta.
  • Sınır (border): kendi başına çekirdek olmasa da, bir çekirdek noktanın komşuluğunda olan nokta.
  • Gürültü (noise): ne çekirdek ne de bir çekirdeğin komşusu — hiçbir kümeye ait değil.
-2-10123-1012x1x2

çekirdek nokta    sınır noktası    gürültü

2 küme bulundu, 5 nokta gürültü olarak işaretlendi.

eps ve minPts’i değiştir: iki “ay” şeklindeki küme + birkaç dağınık nokta üzerinde, DBSCAN’in eğri yapıları nasıl doğru ayırdığını ve dağınık noktaları nasıl “gürültü” (içi boş daireler) olarak işaretlediğini izle.

Mekanizma

Önce K-Means’in bu tür bir veride neden zorlandığını görelim:

İki ay şekli + dağınık gürültü

# İki "ay" şekli -- dışbükey (convex) OLMAYAN bir yapı, K-Means'in zayıf olduğu klasik örnek.
X_aylar, gercek_etiketler = make_moons(n_samples=160, noise=0.08, random_state=23)
gurultu_noktalari = rng.uniform([-1.5, -1], [2.5, 2], size=(15, 2))
X = np.vstack([X_aylar, gurultu_noktalari])
print(f"{len(X)} nokta: {len(X_aylar)} 'ay' şeklinde + {len(gurultu_noktalari)} dağınık gürültü")
175 nokta: 160 'ay' şeklinde + 15 dağınık gürültü

K-Means başarısız

model_kmeans = KMeans(n_clusters=2, n_init=10, random_state=1)
etiket_kmeans = model_kmeans.fit_predict(X_aylar)
ari_kmeans = adjusted_rand_score(gercek_etiketler, etiket_kmeans)
print(f"K-Means (n_clusters=2), sadece 'ay' verisinde ARI: {ari_kmeans:.3f}")
print("K-Means, kümeleri DAİRESEL/DIŞBÜKEY varsayar -- ay şeklindeki eğri yapıyı yakalayamıyor.")
K-Means (n_clusters=2), sadece 'ay' verisinde ARI: 0.245
K-Means, kümeleri DAİRESEL/DIŞBÜKEY varsayar -- ay şeklindeki eğri yapıyı yakalayamıyor.

ARI sadece 0.245 — neredeyse rastgele! K-Means, kümeleri “merkeze yakın, dairesel” varsayar; ay şeklindeki eğri yapıyı hiç yakalayamıyor. Şimdi DBSCAN’i deneyelim:

DBSCAN başarılı

model_dbscan = DBSCAN(eps=0.2, min_samples=5)
etiket_dbscan = model_dbscan.fit_predict(X)
kume_sayisi = len(set(etiket_dbscan)) - (1 if -1 in etiket_dbscan else 0)
gurultu_sayisi = np.sum(etiket_dbscan == -1)
print(f"\nDBSCAN: {kume_sayisi} küme bulundu, {gurultu_sayisi} nokta gürültü olarak işaretlendi")
print(f"Eklediğimiz gürültü nokta sayısı: {len(gurultu_noktalari)}  (DBSCAN'in bulduğu: {gurultu_sayisi})")

DBSCAN: 2 küme bulundu, 11 nokta gürültü olarak işaretlendi
Eklediğimiz gürültü nokta sayısı: 15  (DBSCAN'in bulduğu: 11)

DBSCAN, 2 kümeyi doğru buluyor VE eklediğimiz 15 gürültü noktasından 11’ini doğru tespit ediyor. Çoğu kişi “kümeleme algoritmaları her noktayı MUTLAKA bir kümeye atar” sanır. DBSCAN için yanlış, çünkü algoritma, yoğunluğu düşük bölgelerdeki noktaları BİLİNÇLİ olarak “hiçbir kümeye ait değil” diye işaretleyebiliyor — bu, K-Means ve hiyerarşik kümelemenin YAPAMADIĞI bir şey.

Matematik

Çekirdek, sınır, gürültü tanımları
C¸ekirdek(p)    {q:d(p,q)eps}minPts\text{Çekirdek}(p) \iff |\{q : d(p,q) \le \text{eps}\}| \ge \text{minPts}
KategoriTanımı
Çekirdekeps yarıçapında en az minPts komşusu olan nokta (kendisi dahil)
SınırÇekirdek değil, ama bir çekirdek noktanın eps komşuluğunda
GürültüNe çekirdek ne de herhangi bir çekirdeğin komşusu

Kümeler, birbirine “yoğunluk-ulaşılabilir” (density-reachable) çekirdek noktalarının zincirlenmesiyle oluşur — bu sayede kümeler DAİRESEL olmak zorunda değil, ay şekli gibi eğri yapılar da doğal olarak ortaya çıkabilir.

Kod

Çekirdek/sınır/gürültü sayılarına ve parametre hassasiyetine bakalım:

Nokta türlerinin sayısı

cekirdek_maskesi = np.zeros(len(X), dtype=bool)
cekirdek_maskesi[model_dbscan.core_sample_indices_] = True
sinir_maskesi = (etiket_dbscan != -1) & ~cekirdek_maskesi
print(f"\nÇekirdek nokta sayısı: {cekirdek_maskesi.sum()}")
print(f"Sınır nokta sayısı: {sinir_maskesi.sum()}")
print(f"Gürültü nokta sayısı: {gurultu_sayisi}")
print("DBSCAN, K-Means'in HİÇ yapmadığı bir şeyi yapıyor: bazı noktaları hiçbir kümeye ait olmayan 'gürültü' olarak işaretliyor.")

Çekirdek nokta sayısı: 153
Sınır nokta sayısı: 11
Gürültü nokta sayısı: 11
DBSCAN, K-Means'in HİÇ yapmadığı bir şeyi yapıyor: bazı noktaları hiçbir kümeye ait olmayan 'gürültü' olarak işaretliyor.

eps parametresinin hassasiyeti

for eps_deneme in [0.1, 0.15, 0.2, 0.3, 0.5]:
    m = DBSCAN(eps=eps_deneme, min_samples=5)
    e = m.fit_predict(X)
    k = len(set(e)) - (1 if -1 in e else 0)
    g = np.sum(e == -1)
    print(f"eps={eps_deneme:<5} küme sayısı={k}  gürültü={g}")
print("Çok küçük eps: neredeyse her şey gürültü. Çok büyük eps: kümeler birbirine karışıp TEK kümeye dönüşebilir.")
eps=0.1   küme sayısı=13  gürültü=94
eps=0.15  küme sayısı=11  gürültü=25
eps=0.2   küme sayısı=2  gürültü=11
eps=0.3   küme sayısı=1  gürültü=10
eps=0.5   küme sayısı=1  gürültü=2
Çok küçük eps: neredeyse her şey gürültü. Çok büyük eps: kümeler birbirine karışıp TEK kümeye dönüşebilir.

eps=0.1’de neredeyse her şey (94 nokta) gürültü; eps=0.2’de tam istediğimiz sonuç (2 küme, 11 gürültü); eps=0.3’ten itibaren iki ay TEK bir kümeye birleşiyor. Doğru eps aralığı, bu veri setinde şaşırtıcı derecede DAR.

Solda K-Means'in iki ay şeklini yanlış, dikey bir çizgiyle böldüğünü gösteren grafik; sağda DBSCAN'in iki ay şeklini doğru ayırdığını ve dağınık gürültü noktalarını X işaretiyle gösterdiği grafik.
Sol: K-Means, ay şekillerini dairesel varsayarak yanlış bölüyor. Sağ: DBSCAN, eğri yapıyı doğru yakalıyor ve gürültü noktalarını (X) ayrı tutuyor.

Nerede işe yarar

DBSCAN, K-Means’in varsayımlarının (dairesel kümeler, her nokta bir kümeye ait) geçerli olmadığı durumlarda güçlü bir alternatiftir:

  • Anomali/aykırı değer tespiti. Gürültü olarak işaretlenen noktalar, doğrudan potansiyel anormallikler olarak yorumlanabilir (31. derste Isolation Forest ile bu fikri daha da geliştireceğiz).
  • Coğrafi veri kümeleme. Şehir, yol ağı gibi doğal olarak dairesel olmayan yoğunluk bölgelerini bulmak.
  • Küme sayısını ÖNCEDEN bilmediğinde. K-Means’in aksine, k parametresi YOK — DBSCAN küme sayısını veriden kendisi çıkarır.

Bu 3 hatayı yaparsın:

  1. eps’i rastgele seçmek — bu derste gördüğümüz gibi, doğru aralık şaşırtıcı derecede dar olabilir; k-mesafe grafiği (en yakın k komşuya olan mesafelerin sıralı grafiği) daha sistematik bir başlangıç noktası sağlar.
  2. Farklı yoğunluklu kümeleri olan bir veri setinde tek bir eps kullanmak — DBSCAN, TÜM veri setinde sabit bir yoğunluk eşiği varsayar; çok farklı yoğunluklu kümeler varsa zorlanabilir.
  3. Gürültü noktalarını otomatik olarak “hatalı veri” saymak — bazen gerçekten anlamlı, nadir olaylardır (dolandırıcılık, anomali); atmadan önce incelemek gerekir.

Kendini test et

1. DBSCAN'in K-Means'ten en temel farkı nedir?
  1. DBSCAN sadece 2 boyutlu verilerde çalışır
  2. DBSCAN, kümeleri yoğunluğa göre tanımlar ve bazı noktaları hiçbir kümeye atamadan "gürültü" olarak işaretleyebilir; K-Means her noktayı zorla bir kümeye atar (doğru cevap)
  3. DBSCAN'de k parametresi vardır, K-Means'te yoktur
  4. Aralarında hiçbir fark yoktur

Neden: DBSCAN, yoğunluğu düşük noktaları "gürültü" olarak işaretleyip hiçbir kümeye atamayabilir; K-Means ise (Hiyerarşik kümeleme gibi) her noktayı mutlaka bir kümeye atar.

2. Notebook'ta K-Means'in ay şeklindeki verilerde ARI'si (0.245) neden bu kadar düşük çıktı?
  1. Kod hatalıydı
  2. K-Means kümeleri dairesel/dışbükey varsayar; ay şeklindeki eğri yapıyı bu varsayımla yakalayamıyor (doğru cevap)
  3. Veri seti çok büyüktü
  4. K-Means sadece sınıflandırma için kullanılır

Neden: K-Means, her noktayı en yakın merkeze atayarak dairesel/dışbükey kümeler oluşturur; ay şeklindeki eğri, iç içe geçmiş yapı bu varsayımı ihlal ettiği için K-Means başarısız oluyor.

3. eps parametresi çok büyük seçildiğinde (notebook'ta eps=0.3+ gibi) ne oldu?
  1. Hiçbir şey değişmedi
  2. İki ayrı küme birbirine karışıp TEK bir kümeye dönüştü (doğru cevap)
  3. Tüm noktalar gürültü oldu
  4. Model hata verdi

Neden: Çok büyük eps, komşuluk yarıçapını gereğinden geniş yaptığı için, aslında ayrı olması gereken iki küme birbirine "bağlanıp" tek bir kümeye dönüşebilir.

Özet

Özet

  • DBSCAN, kümeleri yoğunluğa göre tanımlar: çekirdek, sınır ve gürültü noktaları olarak sınıflandırır.
  • K-Means/hiyerarşik kümelemenin aksine, bazı noktaları hiçbir kümeye atamadan "gürültü" olarak bırakabilir.
  • Dairesel olmayan (ay şekli gibi) kümeleri, K-Means'in başaramadığı şekilde doğru bulabilir.
  • eps ve minPts parametreleri sonucu çok hassas etkiler -- çok küçük eps her şeyi gürültü yapar, çok büyük eps kümeleri birleştirir.
  • Küme sayısını (k) önceden belirtmek gerekmez -- DBSCAN bunu veriden kendisi çıkarır.
Sonraki adım: Isolation Forest →