Okullar için Robotik ve Mühendislik · anaokulundan liseye

Bölüm 3 · Klasik algoritmalar · Ders 19

DBSCAN: yoğunluğa göre kümeler

Kıvrık raf sıralarını LiDAR noktalarından bulmak, gürültüyü ayıklayarak

Veri. Depoda gezen bir otonom forklift zemin seviyesindeki LiDAR’ıyla 365 nokta topladı: iki kıvrık raf sırası ile yuvarlak bir raf (110’ar nokta), bir de tozdan ve yansımadan gelen 35 seyrek gürültü noktası. Kaç nesne olduğunu bilmiyoruz. k-means burada işe yaramaz: hilalleri ortadan böler ve gürültüyü de bir kümeye zorla katar.

LiDAR taraması: 365 nokta, etiket yok365 nokta · eps = 0,50 m · minPts = 5
1 / 63
dbscan.pypython
  1. import numpy as np
  2. rng = np.random.default_rng(3)
  3. def yay(cx, cy, r, a0, a1, n): # kıvrık raf sırası
  4. a = rng.uniform(a0, a1, n)
  5. p = np.c_[cx + r * np.cos(a), cy + r * np.sin(a)]
  6. return p + rng.normal(0, 0.1, (n, 2)) # 10 cm ölçüm gürültüsü
  7. X = np.vstack([yay(4, 2.8, 3, 0.3, 2.8, 110), # hilal 1
  8. yay(7, 5.2, 3, 3.4, 6.0, 110), # hilal 2
  9. yay(12.5, 4, 1.2, 0, 6.3, 110), # yuvarlak raf
  10. rng.uniform(0, [15, 8], (35, 2))]) # gürültü
  11. eps, min_pts = 0.5, 5 # metre, nokta
  12. D = np.linalg.norm(X[:, None] - X, axis=2) # bütün uzaklıklar
  13. N = D <= eps; cekirdek = N.sum(1) >= min_pts # çekirdek noktalar
  14. etiket = np.full(len(X), -1); k = 0 # −1: etiketsiz
  15. for i in np.flatnonzero(cekirdek):
  16. if etiket[i] != -1: continue # zaten bir kümede
  17. etiket[i] = k; kuyruk = [i] # yeni küme
  18. while kuyruk:
  19. j = kuyruk.pop(0) # sıradaki nokta
  20. if not cekirdek[j]: continue # sınır: genişlemez
  21. yeni = np.flatnonzero(N[j] & (etiket == -1)) # çemberdeki etiketsizler
  22. etiket[yeni] = k; kuyruk += list(yeni)
  23. k += 1
  24. print(k, 'küme ·', (etiket == -1).sum(), 'gürültü')
  25. def kume(eps): # aynı algoritma, fonksiyon olarak
  26. N, c = D <= eps, (D <= eps).sum(1) >= min_pts
  27. e, k = np.full(len(X), -1), 0
  28. for i in np.flatnonzero(c):
  29. if e[i] != -1: continue
  30. e[i] = k; q = [i]
  31. while q:
  32. j = q.pop(0)
  33. if not c[j]: continue
  34. y = np.flatnonzero(N[j] & (e == -1))
  35. e[y] = k; q += list(y)
  36. k += 1
  37. return e, k
  38. def siluet(e): # ortalama siluet, gürültü hariç
  39. m = e >= 0; L = np.unique(e[m])
  40. if len(L) < 2: return 0.0
  41. Dm, em = D[np.ix_(m, m)], e[m]
  42. own = em[:, None] == L; cnt = own.sum(0)
  43. S = np.stack([Dm[:, em == l].sum(1) for l in L], 1) # kümelere uzaklık toplamı
  44. n = own @ cnt # kendi kümesinin boyu
  45. a = (S * own).sum(1) / np.maximum(n - 1, 1) # kendi kümesine ort.
  46. b = np.where(own, np.inf, S / cnt).min(1) # en yakın diğer küme
  47. s = np.where(n > 1, (b - a) / np.maximum(a, b), 0)
  48. return float(s.mean())
  49. history = {'eps': [], 'clusters': [], # eps taraması
  50. 'noise_share': [], 'silhouette': []}
  51. for e_ in np.round(np.arange(0.1, 1.501, 0.05), 2):
  52. lab, kk = kume(e_)
  53. r = [e_, kk, (lab == -1).mean(), siluet(lab)]
  54. for c_, v in zip(history, r): history[c_] += [float(v)]
  55. fin = [('clusters', k), # son ölçümler
  56. ('noise_share', (etiket == -1).mean()),
  57. ('silhouette', siluet(etiket))]
  58. for c_, v in fin: print(f'{c_:<12}{v:>8.3f}')
  59. import csv
  60. with open('egitim_gecmisi.csv', 'w', newline='') as f: # satır başına bir eps
  61. csv.writer(f).writerows([list(history),
  62. *zip(*history.values())])
  63. try:
  64. import matplotlib.pyplot as plt # varsa grafik çiz
  65. for c_ in ('silhouette', 'noise_share'):
  66. plt.plot(history['eps'], history[c_], label=c_)
  67. plt.xlabel('eps (m)'); plt.legend(); plt.show()
  68. except ImportError:
  69. print('matplotlib yok: grafik atlandı')

Eğitim paneli

Eğitim çalıştırılıyor…

Sahnedeki her sayı, aynı algoritmanın tarayıcında yapılan gerçek çalıştırmasından gelir (sabit tohum, her seferinde aynı sonuç). Python kodunu kendi bilgisayarında çalıştırırsan rastgele başlangıçlar farklı olacağı için sayılar biraz değişebilir.

Bu dersin kodu verisini kendi içinde üretir; indirilecek dosya yok. Kodu yine de aşağıda tarayıcında çalıştırabilirsin.

Kodu tarayıcıda çalıştırPython · NumPy · matplotlib · Pyodide

Python ve NumPy bu sayfada, tarayıcında çalışır (Pyodide). Kodu değiştirip yeniden çalıştırabilirsin; dersin veri setleri çalışma klasöründe hazır. Kod matplotlib kullanırsa grafikler çıktının altında görünür, yazdığı dosyalar (ör. egitim_gecmisi.csv) indirilebilir.

dbscan.pypython

Çıktı

Çıktı burada görünecek.

Nasıl çalışır

  1. Her noktanın çevresine eps yarıçaplı bir çember çizilir; içinde (kendisi dahil) en az minPts nokta varsa o nokta çekirdektir.
  2. Etiketsiz bir çekirdekten yeni küme başlar. Kuyruktan çıkan her çekirdek, çemberindeki etiketsiz noktaları kümeye katar (genişlik öncelikli arama).
  3. Çekirdek olmayan ama bir çekirdeğin çemberine düşen nokta sınır noktasıdır: kümeye girer ama küme ondan genişlemez.
  4. Hiçbir kümeye ulaşılamayan noktalar gürültüdür. Küme sayısını kimse söylemez; yoğunluk belirler.
  5. Şunu dene: eps’i 0,15 yap; çember çok küçülür, noktaların yarıdan fazlası gürültü olur. 0,8 yaparsan iki hilal birbirine bağlanıp tek küme olur.

Neden önemli

DBSCAN, LiDAR ve derinlik kamerası nokta bulutlarını engellere ayırmanın en yaygın yollarından biridir: küme sayısını bilmek gerekmez, biçim serbesttir ve tek tük yansımalar gürültü olarak atılır. Otonom araçlarda ve depo robotlarında engel çıkarma, harita temizleme ve GPS izlerinden durak bulma gibi işlerde kullanılır.

ESOF 323, 11. hafta: robotlarda derin öğrenme →
Esc
  • PanelAna sayfaSayfa
  • ModüllerTüm modüllerSayfa
  • ParçalarParça ansiklopedisiSayfa
  • Mühendislik yoluBüyükler için robotik: 128 parça, 7 seviyeSayfa
  • Robotik dersi (ESOF 323)Üniversite robotik dersi, 14 haftaSayfa
  • Drone dersiBüyükler için: parça, simülasyon, yazılım; 10 üniteSayfa
  • Blok atölyesiSerbest blok programlamaAraç
  • Devre laboratuvarıSanal Arduino ve devreAraç
  • Robot arenasıSanal robot sürüşüAraç
  • OyunlarBloklarla 8 öğretici oyunAraç
  • Mikro Kart atölyesiSanal LED kartı bloklarla programlaAraç
  • Robot atölyesiMikro Kart'ı robota tak, bloklarla görev yapAraç