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

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

k-means: etiketsiz gruplar

LiDAR noktalarını nesnelere ayırmak, tek bir cevap verilmeden

Veri. Robot süpürgenin LiDAR'ı odayı taradı ve 600 nokta gördü: 250'si duvarda, 200'ü kanepede, 150'si masa ayaklarında. Program hangi noktanın hangi nesneye ait olduğunu hiç görmez; yalnız kaç grup arayacağını bilir: k = 3.

cevap verilmedi600 nokta · k = 3
1 / 69
kmeans.pypython
  1. import numpy as np
  2. X = np.genfromtxt('lidar-2b.csv', delimiter=',', skip_header=1) # 600 nokta (x, y), metre
  3. k = 3 # bulunacak grup sayısı
  4. rng = np.random.default_rng(17)
  5. best = np.inf # henüz deneme yok
  6. for start in range(10): # on rastgele başlangıç
  7. C = X[rng.choice(len(X), k, replace=False)] # üç nokta merkez olur
  8. while True:
  9. old = C.copy() # merkezleri hatırla
  10. d = ((X[:, None] - C) ** 2).sum(2) # her merkeze uzaklık²
  11. g = d.argmin(1) # en yakın merkez kazanır
  12. C = np.array([X[g == j].mean(0) for j in range(k)]) # ortalamaya taşı
  13. if np.allclose(C, old): break # kimse kıpırdamadı
  14. s = d.min(1).sum() # toplam kare uzaklık
  15. if s < best: best, keep = s, g # en sıkısını sakla
  16. print(np.bincount(keep)) # grup başına nokta
  17. history = {'k': [], 'inertia': [], 'silhouette': []} # dirsek: k = 1…8 için aynı on deneme
  18. D = np.sqrt(((X[:, None] - X) ** 2).sum(2)) # 600 × 600 uzaklık (siluet için)
  19. for kk in range(1, 9):
  20. rng, bs = np.random.default_rng(17), np.inf
  21. for start in range(10):
  22. C = X[rng.choice(len(X), kk, replace=False)]
  23. while True:
  24. old, g = C.copy(), ((X[:, None] - C) ** 2).sum(2).argmin(1)
  25. C = np.array([X[g == j].mean(0) if (g == j).any() else C[j] for j in range(kk)]) # boş grup yerinde kalır
  26. if np.allclose(C, old): break
  27. s = ((X - C[g]) ** 2).sum() # inertia: grup içi kare uzaklık
  28. if s < bs: bs, bg = s, g
  29. M = np.eye(kk)[bg]; n = M.sum(0); S = D @ M # her noktadan her gruba toplam uzaklık
  30. a = (S * M).sum(1) / np.maximum(n[bg] - 1, 1) # kendi grubuna ortalama uzaklık
  31. b = np.where((M > 0) | (n == 0), np.inf, S / np.maximum(n, 1)).min(1) # en yakın diğer gruba
  32. sil = ((b - a) / np.maximum(a, b))[n[bg] > 1].sum() / len(X) if kk > 1 else 0.0 # siluet skoru (−1…1)
  33. for key, v in zip(history, (kk, bs, sil)): history[key].append(float(v))
  34. print(f'k={kk} inertia={bs:9.1f} siluet={sil:.3f}') # son ölçümler tablosu
  35. import csv
  36. with open('egitim_gecmisi.csv', 'w', newline='') as f: # geçmişi CSV'ye yaz
  37. csv.writer(f).writerows([list(history), *zip(*history.values())]) # satır başına bir k
  38. try:
  39. import matplotlib.pyplot as plt # varsa grafik çiz
  40. fig, (a1, a2) = plt.subplots(1, 2, figsize=(9, 3.5))
  41. a1.plot(history['k'], history['inertia'], 'o-'); a1.set_title('elbow'); a2.plot(history['k'], history['silhouette'], 'o-')
  42. a2.set_title('silhouette'); plt.show()
  43. except ImportError:
  44. 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.

  • Oda taraması (2B LiDAR)lidar-2b.csv · 600 satır · 2 sütun
    Veri setini indir
  • Çiçek ölçüleri (iris benzeri)alıştırmacicek-olculeri.csv · 150 satır · 5 sütun
    Veri setini indir
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.

kmeans.pypython

Çıktı

Çıktı burada görünecek.

Nasıl çalışır

  1. Her deneme rastgele üç noktayı merkez seçerek başlar.
  2. Her nokta en yakın merkeze katılır.
  3. Her merkez, kendi noktalarının ortalamasına taşınır. Hiçbir merkez kıpırdamayana kadar tekrar.
  4. Bazı denemeler kötü bir başlangıçta takılır. Bu yüzden on deneme yapılır, toplam kare uzaklığı en küçük olan kalır.
  5. Şunu dene: k’yı 2 yap. İki grup tek gruba birleşir (200 · 400 nokta). Sonra 5 yap: büyük gruplar ikiye bölünür. k-ortalamalar grup sayısını kendisi bulamaz, onu sen verirsin; doğru k’yı seçmek için grafiğe bakmak ya da farklı k’ları karşılaştırmak gerekir.

Neden önemli

Cevap gerektirmez: kimsenin etiketlemediği verideki grupları bulur. Robotikte LiDAR ve derinlik kamerası noktalarını engellere ayırmakta, renk kümelemede ve harita sıkıştırmada kullanılır. Vektör arama kütüphanesi FAISS da devasa koleksiyonları k-means ile gruplara böler; arama yalnız en yakın birkaç gruba bakar.

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ç