Panduan Definitif untuk K-Means Clustering dengan Scikit-Learn PlatoBlockchain Data Intelligence. Pencarian Vertikal. Ai.

Panduan Definitif untuk K-Means Clustering dengan Scikit-Learn

Pengantar

Pengelompokan K-Means adalah salah satu algoritma pembelajaran mesin tanpa pengawasan yang paling banyak digunakan yang membentuk kelompok data berdasarkan kesamaan antara contoh data.

Dalam panduan ini, pertama-tama kita akan melihat contoh sederhana untuk memahami cara kerja algoritma K-Means sebelum menerapkannya menggunakan Scikit-Learn. Kemudian, kita akan membahas cara menentukan jumlah cluster (Ks) di K-Means, dan juga mencakup metrik jarak, varians, dan pro dan kontra K-Means.

Motivasi

Bayangkan situasi berikut. Suatu hari, ketika berjalan di sekitar lingkungan, Anda melihat ada 10 toko serba ada dan mulai bertanya-tanya toko mana yang serupa – lebih dekat satu sama lain dalam jarak dekat. Saat mencari cara untuk menjawab pertanyaan itu, Anda menemukan pendekatan menarik yang membagi toko ke dalam kelompok berdasarkan koordinatnya di peta.

Misalnya, jika satu toko terletak 5 km Barat dan 3 km Utara – Anda akan menetapkan (5, 3) koordinat untuk itu, dan mewakili dalam grafik. Mari kita plot poin pertama ini untuk memvisualisasikan apa yang terjadi:

import matplotlib.pyplot as plt

plt.title("Store With Coordinates (5, 3)")
plt.scatter(x=5, y=3)

Ini baru poin pertama, jadi kita bisa mendapatkan gambaran bagaimana kita bisa mewakili sebuah toko. Katakanlah kita sudah memiliki 10 koordinat ke 10 toko yang dikumpulkan. Setelah mengaturnya dalam numpy array, kami juga dapat memplot lokasinya:

import numpy as np

points = np.array([[5, 3], [10, 15], [15, 12], [24, 10], [30, 45], [85, 70], [71, 80], [60, 78], [55, 52],[80, 91]])

xs = points[:,0] 
ys = points[:,1]  

plt.title("10 Stores Coordinates")
plt.scatter(x=xs, y=ys)

Panduan Definitif untuk K-Means Clustering dengan Scikit-Learn PlatoBlockchain Data Intelligence. Pencarian Vertikal. Ai.

Cara Mengimplementasikan Algoritma K-Means Secara Manual

Sekarang kita dapat melihat 10 toko pada grafik, dan masalah utamanya adalah menemukan apakah ada cara mereka dapat dibagi menjadi kelompok yang berbeda berdasarkan kedekatan? Hanya dengan melihat sekilas grafiknya, kita mungkin akan menyadarinya dua kelompok toko – satu adalah titik bawah ke kiri bawah, dan yang lainnya adalah titik kanan atas. Mungkin, kita bahkan dapat membedakan dua titik di tengah itu sebagai kelompok yang terpisah – oleh karena itu menciptakan tiga kelompok berbeda.

Di bagian ini, kita akan membahas proses pengelompokan titik secara manual – membaginya ke dalam jumlah grup yang ditentukan. Dengan begitu, pada dasarnya kita akan dengan hati-hati membahas semua langkah dari Algoritma pengelompokan K-Means. Pada akhir bagian ini, Anda akan memperoleh pemahaman intuitif dan praktis tentang semua langkah yang dilakukan selama pengelompokan K-Means. Setelah itu, kami akan mendelegasikannya ke Scikit-Learn.

Apa cara terbaik untuk menentukan apakah ada dua atau tiga kelompok titik? Salah satu cara sederhana adalah dengan memilih satu jumlah grup – misalnya, dua – dan kemudian mencoba mengelompokkan poin berdasarkan pilihan itu.

Panduan Definitif untuk K-Means Clustering dengan Scikit-Learn PlatoBlockchain Data Intelligence. Pencarian Vertikal. Ai.

Katakanlah kita telah memutuskan ada dua kelompok toko kami (poin). Sekarang, kita perlu menemukan cara untuk memahami poin mana yang termasuk dalam kelompok mana. Ini bisa dilakukan dengan memilih satu titik untuk mewakili grup 1 dan satu untuk mewakili grup 2. Titik-titik tersebut akan digunakan sebagai acuan saat mengukur jarak dari semua titik lainnya ke setiap kelompok.

Dengan cara itu, katakan titik (5, 3) akhirnya menjadi milik grup 1, dan poin (79, 60) ke grup 2. Saat mencoba menetapkan poin baru (6, 3) untuk kelompok, kita perlu mengukur jarak ke dua titik tersebut. Dalam kasus titik (6, 3) is lebih dekat ke (5, 3), oleh karena itu milik kelompok yang diwakili oleh titik itu - grup 1. Dengan cara ini, kita dapat dengan mudah mengelompokkan semua titik ke dalam grup yang sesuai.

Dalam contoh ini, selain menentukan jumlah kelompok (cluster) – kami juga memilih beberapa poin untuk menjadi referensi jarak untuk poin baru dari masing-masing kelompok.

Itu adalah ide umum untuk memahami kesamaan antara toko kami. Mari kita praktikkan – pertama-tama kita dapat memilih dua titik referensi di acak. Titik referensi dari grup 1 akan (5, 3) dan titik referensi grup 2 akan (10, 15). Kami dapat memilih kedua titik kami numpy susunan oleh [0] dan [1] indeks dan simpan di g1 (grup 1) dan g2 (kelompok 2) variabel:

g1 = points[0]
g2 = points[1]

Setelah melakukan ini, kita perlu menghitung jarak dari semua titik lain ke titik referensi tersebut. Ini menimbulkan pertanyaan penting – bagaimana mengukur jarak itu. Kami pada dasarnya dapat menggunakan ukuran jarak apa pun, tetapi, untuk tujuan panduan ini, mari gunakan Euclidean Distance_.

Akan berguna untuk mengetahui bahwa ukuran jarak Euclidean didasarkan pada teorema Pythagoras:

$$
c^2 = a^2 + b^2
$$

Ketika disesuaikan dengan titik-titik di pesawat - (a1, b1) dan (a2, b2), rumus sebelumnya menjadi:

$$
c^2 = (a2-a1)^2 + (b2-b1)^2
$$

Jarak akan menjadi akar kuadrat dari c, sehingga kita juga dapat menulis rumus sebagai:

$$
euclidean_{dist} = kuadrat[2][(a2 – a1)^2 + (b2 – b1) ^2)]
$$

Catatan: Anda juga dapat menggeneralisasi rumus jarak Euclidean untuk titik multidimensi. Misalnya, dalam ruang tiga dimensi, titik memiliki tiga koordinat – rumus kami mencerminkan hal itu dengan cara berikut:
$$
euclidean_{dist} = kuadrat[2][(a2 – a1)^2 + (b2 – b1) ^2 + (c2 – c1) ^2)]
$$
Prinsip yang sama diikuti tidak peduli jumlah dimensi ruang tempat kita beroperasi.

Sejauh ini, kami telah memilih titik untuk mewakili grup, dan kami tahu cara menghitung jarak. Sekarang, mari kita gabungkan jarak dan grup dengan menetapkan setiap poin toko yang dikumpulkan ke grup.

Untuk memvisualisasikannya dengan lebih baik, kami akan mendeklarasikan tiga daftar. Yang pertama menyimpan poin dari grup pertama – points_in_g1. Yang kedua menyimpan poin dari grup 2 – points_in_g2, dan yang terakhir - group, Untuk label poin sebagai baik 1 (milik kelompok 1) atau 2 (milik kelompok 2):

points_in_g1 = []
points_in_g2 = []
group = []

Sekarang kita dapat mengulangi titik-titik kita dan menghitung jarak Euclidean antara titik-titik tersebut dan setiap referensi grup kita. Setiap poin akan lebih dekat ke salah satu dari dua grup – berdasarkan grup mana yang paling dekat, kami akan menetapkan setiap titik ke daftar yang sesuai, sambil menambahkan 1 or 2 ke group Daftar:

for p in points:
    x1, y1 = p[0], p[1]
    euclidean_distance_g1 = np.sqrt((g1[0] - x1)**2 + (g1[1] - y1)**2)
    euclidean_distance_g2 = np.sqrt((g2[0] - x1)**2 + (g2[1] - y1)**2)
    if euclidean_distance_g1 < euclidean_distance_g2:
        points_in_g1.append(p)
        group.append('1')
    else:
        points_in_g2.append(p)
        group.append('2')

Mari kita lihat hasil iterasi ini untuk melihat apa yang terjadi:

print(f'points_in_g1:{points_in_g1}n 
npoints_in_g2:{points_in_g2}n 
ngroup:{group}')

Yang mengakibatkan:

points_in_g1:[array([5, 3])]
 
points_in_g2:[array([10, 15]), array([15, 12]), 
              array([24, 10]), array([30, 45]), 
              array([85, 70]), array([71, 80]),
              array([60, 78]), array([55, 52]), 
              array([80, 91])]
 
group:[1, 2, 2, 2, 2, 2, 2, 2, 2, 2] 

Kami juga dapat memplot hasil pengelompokan, dengan warna berbeda berdasarkan grup yang ditetapkan, menggunakan Seaborn's scatterplot() pada pengatur terkenal. Pengatur ini menawarkan bantuan hukum kepada traderapabila trader berselisih dengan broker yang terdaftar dengan mereka. group sebagai hue argumen:

import seaborn as sns

sns.scatterplot(x=points[:, 0], y=points[:, 1], hue=group)

Panduan Definitif untuk K-Means Clustering dengan Scikit-Learn PlatoBlockchain Data Intelligence. Pencarian Vertikal. Ai.

Terlihat jelas bahwa hanya poin pertama kami yang masuk ke grup 1, dan semua poin lainnya masuk ke grup 2. Hasil itu berbeda dari apa yang kami bayangkan di awal. Mempertimbangkan perbedaan antara hasil kami dan harapan awal kami – apakah ada cara kami dapat mengubahnya? Sepertinya ada!

Salah satu pendekatannya adalah dengan mengulang proses tersebut dan memilih titik-titik yang berbeda untuk dijadikan acuan kelompok. Ini akan mengubah hasil kami, mudah-mudahan, lebih sesuai dengan apa yang kami bayangkan di awal. Kali kedua ini, kita bisa memilih mereka tidak secara acak seperti yang kita lakukan sebelumnya, tetapi dengan mendapatkan berarti dari semua poin kami yang sudah dikelompokkan. Dengan begitu, titik-titik baru tersebut dapat diposisikan di tengah kelompok yang sesuai.

Misalnya, jika kelompok kedua hanya memiliki poin (10, 15), (30, 45). Baru pusat titik akan menjadi (10 + 30)/2 dan (15+45)/2 - yang sama dengan (20, 30).

Karena kami telah memasukkan hasil kami ke dalam daftar, kami dapat mengonversinya terlebih dahulu menjadi numpy array, pilih xs, ys dan kemudian dapatkan berarti:

g1_center = [np.array(points_in_g1)[:, 0].mean(), np.array(points_in_g1)[:, 1].mean()]
g2_center = [np.array(points_in_g2)[:, 0].mean(), np.array(points_in_g2)[:, 1].mean()]
g1_center, g2_center

Saran: Coba gunakan numpy dan array NumPy sebanyak mungkin. Mereka dioptimalkan untuk kinerja yang lebih baik dan menyederhanakan banyak operasi aljabar linier. Setiap kali Anda mencoba memecahkan beberapa masalah aljabar linier, Anda pasti harus melihat: numpy dokumentasi untuk memeriksa apakah ada numpy metode yang dirancang untuk memecahkan masalah Anda. Kemungkinannya ada!

Untuk membantu mengulangi proses dengan titik pusat baru kita, mari ubah kode kita sebelumnya menjadi sebuah fungsi, jalankan dan lihat apakah ada perubahan dalam cara titik dikelompokkan:

def assigns_points_to_two_groups(g1_center, g2_center):
    points_in_g1 = []
    points_in_g2 = []
    group = []

    for p in points:
        x1, y1 = p[0], p[1]
        euclidean_distance_g1 = np.sqrt((g1_center[0] - x1)**2 + (g1_center[1] - y1)**2)
        euclidean_distance_g2 = np.sqrt((g2_center[0] - x1)**2 + (g2_center[1] - y1)**2)
        if euclidean_distance_g1 < euclidean_distance_g2:
            points_in_g1.append(p)
            group.append(1)
        else:
            points_in_g2.append(p)
            group.append(2)
    return points_in_g1, points_in_g2, group

Catatan: Jika Anda melihat Anda terus mengulangi kode yang sama berulang kali, Anda harus membungkus kode itu ke dalam fungsi yang terpisah. Ini dianggap sebagai praktik terbaik untuk mengatur kode ke dalam fungsi, khususnya karena mereka memfasilitasi pengujian. Lebih mudah untuk menguji dan mengisolasi potongan kode daripada kode lengkap tanpa fungsi apa pun.

Mari kita panggil fungsinya dan simpan hasilnya di points_in_g1, points_in_g2, dan group variabel:

points_in_g1, points_in_g2, group = assigns_points_to_two_groups(g1_center, g2_center)
points_in_g1, points_in_g2, group

Dan juga plot scatterplot dengan titik-titik berwarna untuk memvisualisasikan pembagian kelompok:

sns.scatterplot(x=points[:, 0], y=points[:, 1], hue=group)

Panduan Definitif untuk K-Means Clustering dengan Scikit-Learn PlatoBlockchain Data Intelligence. Pencarian Vertikal. Ai.

Sepertinya pengelompokan poin kita adalah semakin baik. Tapi tetap saja, ada dua titik di tengah grafik yang dapat ditetapkan untuk salah satu grup ketika mempertimbangkan kedekatannya dengan kedua grup. Algoritme yang telah kami kembangkan sejauh ini menetapkan kedua titik tersebut ke grup kedua.

Ini berarti kita mungkin dapat mengulangi prosesnya sekali lagi dengan mengambil rata-rata dari Xs dan Ys, menciptakan dua titik pusat baru (pusat) ke grup kami dan menugaskannya kembali berdasarkan jarak.

Mari kita juga membuat fungsi untuk memperbarui centroid. Seluruh proses sekarang dapat dikurangi menjadi beberapa panggilan fungsi itu:

def updates_centroids(points_in_g1, points_in_g2):
    g1_center = np.array(points_in_g1)[:, 0].mean(), np.array(points_in_g1)[:, 1].mean()
    g2_center = np.array(points_in_g2)[:, 0].mean(), np.array(points_in_g2)[:, 1].mean()
    return g1_center, g2_center

g1_center, g2_center = updates_centroids(points_in_g1, points_in_g2)
points_in_g1, points_in_g2, group = assigns_points_to_two_groups(g1_center, g2_center)
sns.scatterplot(x=points[:, 0], y=points[:, 1], hue=group)

Panduan Definitif untuk K-Means Clustering dengan Scikit-Learn PlatoBlockchain Data Intelligence. Pencarian Vertikal. Ai.

Perhatikan bahwa setelah iterasi ketiga ini, masing-masing titik sekarang menjadi bagian dari cluster yang berbeda. Tampaknya hasilnya semakin baik – mari kita lakukan sekali lagi. Sekarang pergi ke iterasi keempat dari metode kami:

g1_center, g2_center = updates_centroids(points_in_g1, points_in_g2)
points_in_g1, points_in_g2, group = assigns_points_to_two_groups(g1_center, g2_center)
sns.scatterplot(x=points[:, 0], y=points[:, 1], hue=group)

Panduan Definitif untuk K-Means Clustering dengan Scikit-Learn PlatoBlockchain Data Intelligence. Pencarian Vertikal. Ai.

Kali keempat ini kami dapatkan hasil yang sama seperti yang sebelumnya. Jadi sepertinya poin kami tidak akan mengubah grup lagi, hasil kami telah mencapai semacam stabilitas – telah mencapai status yang tidak dapat diubah, atau converged. Selain itu, kami memiliki hasil yang sama persis seperti yang kami bayangkan untuk 2 grup. Kita juga dapat melihat apakah pembagian yang dicapai ini masuk akal.

Mari kita cepat rekap apa yang telah kita lakukan sejauh ini. Kami telah membagi 10 toko kami secara geografis menjadi dua bagian – satu di wilayah barat daya yang lebih rendah dan yang lainnya di timur laut. Menarik untuk mengumpulkan lebih banyak data selain yang sudah kita miliki – pendapatan, jumlah pelanggan harian, dan banyak lagi. Dengan begitu kita dapat melakukan analisis yang lebih kaya dan mungkin menghasilkan hasil yang lebih menarik.

Studi clustering seperti ini bisa dilakukan ketika brand yang sudah mapan ingin memilih area untuk membuka toko baru. Dalam hal ini, ada lebih banyak variabel yang dipertimbangkan selain lokasi.

Apa Hubungan Semua Ini Dengan Algoritma K-Means?

Saat mengikuti langkah-langkah ini, Anda mungkin bertanya-tanya apa hubungannya dengan algoritma K-Means. Proses yang kami lakukan selama ini adalah Algoritma K-Means. Singkatnya, kami telah menentukan jumlah grup/cluster, memilih titik awal secara acak, dan memperbarui centroid di setiap iterasi hingga cluster terkonvergensi. Kami pada dasarnya telah melakukan seluruh algoritme dengan tangan – dengan hati-hati melakukan setiap langkah.

Grafik K di K-Means berasal dari jumlah cluster yang perlu diatur sebelum memulai proses iterasi. Dalam kasus kami K = 2. Karakteristik ini kadang-kadang dilihat sebagai negatif mengingat ada metode clustering lain, seperti Hierarchical Clustering, yang tidak harus memiliki jumlah cluster yang tetap sebelumnya.

Karena penggunaan sarananya, K-means juga menjadi sensitif terhadap outlier dan nilai ekstrim – mereka meningkatkan variabilitas dan mempersulit centroid kami untuk memainkan peran mereka. Jadi, sadari kebutuhan untuk melakukan nilai ekstrim dan analisis outlier sebelum melakukan clustering menggunakan algoritma K-Means.

Juga, perhatikan bahwa titik-titik kami tersegmentasi dalam bagian lurus, tidak ada kurva saat membuat cluster. Itu juga bisa menjadi kelemahan dari algoritma K-Means.

Catatan: Saat Anda membutuhkannya agar lebih fleksibel dan mudah beradaptasi dengan elips dan bentuk lainnya, coba gunakan a model Campuran Gaussian K-means umum. Model ini dapat beradaptasi dengan cluster segmentasi elips.

K-Means juga punya banyak keuntungan! Ini berkinerja baik di dataset besar yang bisa menjadi sulit untuk ditangani jika Anda menggunakan beberapa jenis algoritma pengelompokan hierarkis. Juga menjamin konvergensi, dan dapat dengan mudah menyamaratakan dan menyesuaikan. Selain itu, ini mungkin merupakan algoritma pengelompokan yang paling banyak digunakan.

Sekarang setelah kita membahas semua langkah yang dilakukan dalam algoritme K-Means, dan memahami semua pro dan kontra, akhirnya kita dapat mengimplementasikan K-Means menggunakan perpustakaan Scikit-Learn.

Bagaimana Menerapkan Algoritma K-Means Menggunakan Scikit-Belajar

Untuk memeriksa kembali hasil kami, mari lakukan proses ini lagi, tetapi sekarang menggunakan 3 baris kode dengan sklearn:

from sklearn.cluster import KMeans


kmeans = KMeans(n_clusters=2, random_state=42) 
kmeans.fit(points)
kmeans.labels_

Di sini, labelnya sama dengan grup kami sebelumnya. Mari kita cepat plot hasilnya:

sns.scatterplot(x = points[:,0], y = points[:,1], hue=kmeans.labels_)

Panduan Definitif untuk K-Means Clustering dengan Scikit-Learn PlatoBlockchain Data Intelligence. Pencarian Vertikal. Ai.

Plot yang dihasilkan sama dengan plot dari bagian sebelumnya.

Lihat panduan praktis dan praktis kami untuk mempelajari Git, dengan praktik terbaik, standar yang diterima industri, dan termasuk lembar contekan. Hentikan perintah Googling Git dan sebenarnya belajar itu!

Catatan: Melihat bagaimana kami melakukan algoritme K-Means menggunakan Scikit-Learn mungkin memberi Anda kesan bahwa ini tidak perlu dipikirkan dan Anda tidak perlu terlalu mengkhawatirkannya. Hanya 3 baris kode yang melakukan semua langkah yang telah kita bahas di bagian sebelumnya ketika kita telah membahas algoritma K-Means langkah demi langkah. Tetapi, iblis ada dalam detailnya pada kasus ini! Jika Anda tidak memahami semua langkah dan batasan algoritme, kemungkinan besar Anda akan menghadapi situasi di mana algoritme K-Means memberi Anda hasil yang tidak Anda harapkan.

Dengan Scikit-Learn, Anda juga dapat menginisialisasi K-Means untuk konvergensi yang lebih cepat dengan mengatur init='k-means++' argumen. Dalam istilah yang lebih luas, K-Means++ masih memilih k pusat cluster awal secara acak mengikuti distribusi seragam. Kemudian, setiap pusat cluster berikutnya dipilih dari titik data yang tersisa tidak hanya dengan menghitung ukuran jarak – tetapi dengan menggunakan probabilitas. Menggunakan probabilitas mempercepat algoritme dan sangat membantu ketika berhadapan dengan kumpulan data yang sangat besar.

Metode Siku – Memilih Jumlah Grup Terbaik

Sejauh ini bagus! Kami telah mengelompokkan 10 toko berdasarkan jarak Euclidean antara titik dan pusat massa. Tapi bagaimana dengan dua titik di tengah grafik yang sedikit lebih sulit untuk dikelompokkan? Tidak bisakah mereka membentuk kelompok yang terpisah juga? Apakah kita benar-benar membuat kesalahan dengan memilih K = 2 kelompok? Mungkin kita benar-benar punya K = 3 kelompok? Kita bahkan bisa memiliki lebih dari tiga kelompok dan tidak menyadarinya.

Pertanyaan yang diajukan di sini adalah cara menentukan jumlah grup (K) di K-Means. Untuk menjawab pertanyaan tersebut, kita perlu memahami apakah akan ada cluster yang “lebih baik” untuk nilai K yang berbeda.

Cara naif untuk mengetahuinya adalah dengan mengelompokkan titik-titik dengan nilai . yang berbeda K, sehingga untuk K=2, K=3, K=4, dan seterusnya:

for number_of_clusters in range(1, 11): 
    kmeans = KMeans(n_clusters = number_of_clusters, random_state = 42)
    kmeans.fit(points) 

Tapi, mengelompokkan poin untuk yang berbeda Ks sendirian tidak akan cukup untuk memahami jika kita telah memilih nilai ideal untuk K. Kami membutuhkan cara untuk mengevaluasi kualitas pengelompokan untuk masing-masing K kami telah memilih.

Menghitung secara manual Dalam Cluster Jumlah Kuadrat (WCSS)

Inilah tempat yang ideal untuk memperkenalkan ukuran seberapa dekat titik-titik berkerumun kita satu sama lain. Ini pada dasarnya menggambarkan berapa banyak perbedaan kami memiliki di dalam satu cluster. Ukuran ini disebut Dalam Cluster Jumlah Kuadrat, atau WCSS Ringkasnya. Semakin kecil WCSS, semakin dekat titik kami, oleh karena itu kami memiliki cluster yang lebih terbentuk dengan baik. Rumus WCSS dapat digunakan untuk sejumlah cluster:

$$
WCSS = jumlah(Pi_1 – Centroid_1)^2 + cdots + jumlah(Pi_n – Centroid_n)^2
$$

Catatan: Dalam panduan ini, kami menggunakan Jarak Euclidean untuk mendapatkan centroid, tetapi ukuran jarak lain, seperti Manhattan, juga dapat digunakan.

Sekarang kita dapat mengasumsikan bahwa kita telah memilih untuk memiliki dua cluster dan mencoba menerapkan WCSS untuk lebih memahami apa itu WCSS dan bagaimana menggunakannya. Seperti yang dinyatakan oleh rumus, kita perlu menjumlahkan perbedaan kuadrat antara semua titik cluster dan centroid. Jadi, jika poin pertama kita dari grup pertama adalah (5, 3) dan centroid terakhir kami (setelah konvergensi) dari grup pertama adalah (16.8, 17.0), WCSS akan menjadi:

$$
WCSS = jumlah((5,3) – (16.8, 17.0))^2
$$

$$
WCSS = jumlah((5-16.8) + (3-17.0))^2
$$

$$
WCSS = jumlah((-11.8) + (-14.0))^2
$$

$$
WCSS = jumlah((-25.8))^2
$$

$$
WCSS = 335.24
$$

Contoh ini menggambarkan bagaimana kita menghitung WCSS untuk satu titik dari cluster. Tetapi cluster biasanya berisi lebih dari satu titik, dan kita perlu mempertimbangkan semuanya saat menghitung WCSS. Kami akan melakukannya dengan mendefinisikan fungsi yang menerima sekelompok titik dan pusat massa, dan mengembalikan jumlah kuadrat:

def sum_of_squares(cluster, centroid):
    squares = []
    for p in cluster:
        squares.append((p - centroid)**2)
        ss = np.array(squares).sum()
    return ss

Sekarang kita bisa mendapatkan jumlah kuadrat untuk setiap cluster:

g1 = sum_of_squares(points_in_g1, g1_center)
g2 = sum_of_squares(points_in_g2, g2_center)

Dan jumlahkan hasilnya untuk mendapatkan total WCSS:

g1 + g2

Ini menghasilkan:

2964.3999999999996

Jadi, dalam kasus kami, kapan K sama dengan 2, total WCSS adalah 2964.39. Sekarang, kita dapat mengganti Ks dan menghitung WCSS untuk semuanya. Dengan begitu, kita bisa mendapatkan wawasan tentang apa K kita harus memilih untuk membuat pengelompokan kita melakukan yang terbaik.

Menghitung WCSS Menggunakan Scikit-Belajar

Untungnya, kita tidak perlu menghitung WCSS secara manual untuk masing-masing K. Setelah melakukan clustering K-Means untuk jumlah cluster yang diberikan, kita dapat memperoleh WCSS-nya dengan menggunakan inertia_ atribut. Sekarang, kita bisa kembali ke K-Means kita for loop, gunakan untuk mengubah jumlah cluster, dan daftar nilai WCSS yang sesuai:

wcss = [] 
for number_of_clusters in range(1, 11): 
    kmeans = KMeans(n_clusters = number_of_clusters, random_state = 42)
    kmeans.fit(points) 
    wcss.append(kmeans.inertia_)
wcss

Perhatikan bahwa nilai kedua dalam daftar, sama persis dengan yang kita hitung sebelumnya untuk K = 2:

[18272.9, # For k=1 
 2964.3999999999996, # For k=2
 1198.75, # For k=3
 861.75,
 570.5,
 337.5,
 175.83333333333334,
 79.5,
 17.0,
 0.0]

Untuk memvisualisasikan hasil tersebut, mari kita plot Ks bersama dengan nilai WCSS:

ks = [1, 2, 3, 4, 5 , 6 , 7 , 8, 9, 10]
plt.plot(ks, wcss)

Panduan Definitif untuk K-Means Clustering dengan Scikit-Learn PlatoBlockchain Data Intelligence. Pencarian Vertikal. Ai.

Ada gangguan pada plot ketika x = 2, titik terendah pada garis, dan titik yang lebih rendah lagi ketika x = 3. Perhatikan bahwa itu mengingatkan kita pada bentuk siku. Dengan memplot Ks bersama dengan WCSS, kami menggunakan Metode Siku untuk memilih jumlah Ks. Dan K yang dipilih adalah tepat titik siku terendah, jadi, itu akan menjadi 3 alih-alih 2, dalam kasus kami:

ks = [1, 2, 3, 4, 5 , 6 , 7 , 8, 9, 10]
plt.plot(ks, wcss);
plt.axvline(3, linestyle='--', color='r')

Panduan Definitif untuk K-Means Clustering dengan Scikit-Learn PlatoBlockchain Data Intelligence. Pencarian Vertikal. Ai.

Kita dapat menjalankan algoritma cluster K-Means lagi, untuk melihat bagaimana data kita akan terlihat dengan tiga kelompok:

kmeans = KMeans(n_clusters=3, random_state=42)
kmeans.fit(points)
sns.scatterplot(x = points[:,0], y = points[:,1], hue=kmeans.labels_)

Panduan Definitif untuk K-Means Clustering dengan Scikit-Learn PlatoBlockchain Data Intelligence. Pencarian Vertikal. Ai.

Kami sudah senang dengan dua cluster, tetapi menurut metode elbow, tiga cluster akan lebih cocok untuk data kami. Dalam hal ini, kami akan memiliki tiga jenis toko, bukan dua. Sebelum menggunakan metode siku, kami memikirkan kelompok toko barat daya dan timur laut, sekarang kami juga memiliki toko di tengah. Mungkin itu bisa menjadi lokasi yang baik untuk membuka toko lain karena persaingan di dekatnya akan lebih sedikit.

Pengukuran Kualitas Cluster Alternatif

Ada juga ukuran lain yang dapat digunakan saat mengevaluasi kualitas cluster:

  • Skor Siluet – menganalisis tidak hanya jarak antara titik intra-cluster tetapi juga antara cluster itu sendiri
  • Antar Cluster Jumlah Kuadrat (BCSS) – metrik yang melengkapi WCSS
  • Jumlah Kesalahan Kuadrat (ESS)
  • Radius Maksimum – mengukur jarak terbesar dari suatu titik ke pusat massanya
  • Radius Rata-rata – jumlah jarak terbesar dari suatu titik ke pusat massa dibagi dengan jumlah cluster.

Disarankan untuk bereksperimen dan mengenal masing-masing karena tergantung pada masalahnya, beberapa alternatif dapat lebih dapat diterapkan daripada metrik yang paling banyak digunakan (Skor WCSS dan Siluet).

Pada akhirnya, seperti banyak algoritma ilmu data, kami ingin mengurangi varians di dalam setiap cluster dan memaksimalkan varians antara cluster yang berbeda. Jadi kami memiliki cluster yang lebih jelas dan dapat dipisahkan.

Menerapkan K-Means pada Dataset Lain

Mari kita gunakan apa yang telah kita pelajari pada dataset lain. Kali ini, kita akan mencoba mencari kelompok wine yang sejenis.

Catatan: Anda dapat mengunduh kumpulan data di sini.

Kita mulai dengan mengimpor pandas untuk membaca wine-clustering CSV (Nilai Dipisahkan Koma) file menjadi a Dataframe struktur:

import pandas as pd

df = pd.read_csv('wine-clustering.csv')

Setelah memuatnya, mari kita intip lima catatan data pertama dengan head() Metode:

df.head()

Ini menghasilkan:

	Alcohol 	Malic_Acid 	Ash 	Ash_Alcanity 	Magnesium 	Total_Phenols 	Flavanoids 	Nonflavanoid_Phenols 	Proanthocyanins 	Color_Intensity 	Hue 	OD280 	Proline
0 	14.23 		1.71 		2.43 	15.6 			127 		2.80 			3.06 		0.28 					2.29 				5.64 				1.04 	3.92 	1065
1 	13.20 		1.78 		2.14 	11.2 			100 		2.65 			2.76 		0.26 					1.28 				4.38 				1.05 	3.40 	1050
2 	13.16 		2.36 		2.67 	18.6 			101 		2.80 			3.24 		0.30 					2.81 				5.68 				1.03 	3.17 	1185
3 	14.37 		1.95 		2.50 	16.8 			113 		3.85 			3.49 		0.24 					2.18 				7.80 				0.86 	3.45 	1480
4 	13.24 		2.59 		2.87 	21.0 			118 		2.80 			2.69 		0.39 					1.82 				4.32 				1.04 	2.93 	735

Kami memiliki banyak pengukuran zat yang ada dalam anggur. Di sini, kita juga tidak perlu mengubah kolom kategoris karena semuanya numerik. Sekarang, mari kita lihat statistik deskriptif dengan describe() Metode:

df.describe().T 

Tabel deskripsi:

 						count 	mean 		std 		min 	25% 	50% 	75% 		max
Alcohol 				178.0 	13.000618 	0.811827 	11.03 	12.3625 13.050 	13.6775 	14.83
Malic_Acid 				178.0 	2.336348 	1.117146 	0.74 	1.6025 	1.865 	3.0825 		5.80
Ash 					178.0 	2.366517 	0.274344 	1.36 	2.2100 	2.360 	2.5575 		3.23
Ash_Alcanity 			178.0 	19.494944 	3.339564 	10.60 	17.2000 19.500 	21.5000 	30.00
Magnesium 				178.0 	99.741573 	14.282484 	70.00 	88.0000 98.000 	107.0000 	162.00
Total_Phenols 			178.0 	2.295112 	0.625851 	0.98 	1.7425 	2.355 	2.8000 		3.88
Flavanoids 				178.0 	2.029270 	0.998859 	0.34 	1.2050 	2.135 	2.8750 		5.08
Nonflavanoid_Phenols 	178.0 	0.361854 	0.124453 	0.13 	0.2700 	0.340 	0.4375 		0.66
Proanthocyanins 		178.0 	1.590899 	0.572359 	0.41 	1.2500 	1.555 	1.9500 		3.58
Color_Intensity 		178.0 	5.058090 	2.318286 	1.28 	3.2200 	4.690 	6.2000 		13.00
Hue 					178.0 	0.957449 	0.228572 	0.48 	0.7825 	0.965 	1.1200 		1.71
OD280 					178.0 	2.611685 	0.709990 	1.27 	1.9375 	2.780 	3.1700 		4.00
Proline 				178.0 	746.893258 	314.907474 	278.00 	500.500 673.500 985.0000 	1680.00

Dengan melihat tabel jelas ada beberapa variabilitas dalam data – untuk beberapa kolom seperti Alchool ada lebih banyak, dan untuk yang lain, seperti Malic_Acid, lebih sedikit. Sekarang kita dapat memeriksa apakah ada null, atau NaN nilai dalam kumpulan data kami:

df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 178 entries, 0 to 177
Data columns (total 13 columns):
 #   Column                Non-Null Count  Dtype  
---  ------                --------------  -----  
 0   Alcohol               178 non-null    float64
 1   Malic_Acid            178 non-null    float64
 2   Ash                   178 non-null    float64
 3   Ash_Alcanity          178 non-null    float64
 4   Magnesium             178 non-null    int64  
 5   Total_Phenols         178 non-null    float64
 6   Flavanoids            178 non-null    float64
 7   Nonflavanoid_Phenols  178 non-null    float64
 8   Proanthocyanins       178 non-null    float64
 9   Color_Intensity       178 non-null    float64
 10  Hue                   178 non-null    float64
 11  OD280                 178 non-null    float64
 12  Proline               178 non-null    int64  
dtypes: float64(11), int64(2)
memory usage: 18.2 KB

Tidak perlu menjatuhkan atau memasukkan data, mengingat tidak ada nilai kosong di dataset. Kita bisa menggunakan Seaborn pairplot() untuk melihat distribusi data dan untuk memeriksa apakah kumpulan data membentuk pasangan kolom yang menarik untuk pengelompokan:

sns.pairplot(df)

Panduan Definitif untuk K-Means Clustering dengan Scikit-Learn PlatoBlockchain Data Intelligence. Pencarian Vertikal. Ai.

Dengan melihat pairplot, dua kolom tampaknya menjanjikan untuk tujuan pengelompokan – Alcohol dan OD280 (yang merupakan metode untuk menentukan konsentrasi protein dalam anggur). Tampaknya ada 3 kelompok berbeda di plot yang menggabungkan dua di antaranya.

Ada kolom lain yang tampaknya berkorelasi juga. Terutama Alcohol dan Total_Phenols, dan Alcohol dan Flavanoids. Mereka memiliki hubungan linier yang hebat yang dapat diamati dalam plot berpasangan.

Karena fokus kita adalah pengelompokan dengan K-Means, mari kita pilih satu pasang kolom, katakanlah Alcohol dan OD280, dan uji metode siku untuk kumpulan data ini.

Catatan: Saat menggunakan lebih banyak kolom dari kumpulan data, akan ada kebutuhan untuk memplot dalam 3 dimensi atau mengurangi data menjadi komponen utama (penggunaan PCA). Ini adalah pendekatan yang valid, dan lebih umum, pastikan untuk memilih komponen utama berdasarkan seberapa banyak mereka menjelaskan dan perlu diingat bahwa ketika mengurangi dimensi data, ada beberapa kehilangan informasi – jadi plotnya adalah perkiraan dari data nyata, bukan bagaimana sebenarnya.

Mari kita plot scatterplot dengan dua kolom yang disetel menjadi porosnya untuk melihat lebih dekat titik-titik yang ingin kita bagi menjadi beberapa grup:

sns.scatterplot(data=df, x='OD280', y='Alcohol')

Panduan Definitif untuk K-Means Clustering dengan Scikit-Learn PlatoBlockchain Data Intelligence. Pencarian Vertikal. Ai.

Sekarang kita dapat mendefinisikan kolom kita dan menggunakan metode elbow untuk menentukan jumlah cluster. Kami juga akan memulai algoritma dengan kmeans++ hanya untuk memastikan itu menyatu lebih cepat:

values = df[['OD280', 'Alcohol']]

wcss_wine = [] 
for i in range(1, 11): 
    kmeans = KMeans(n_clusters = i, init = 'k-means++', random_state = 42)
    kmeans.fit(values) 
    wcss_wine.append(kmeans.inertia_)

Kami telah menghitung WCSS, sehingga kami dapat memplot hasilnya:

clusters_wine = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
plt.plot(clusters_wine, wcss_wine)
plt.axvline(3, linestyle='--', color='r')

Panduan Definitif untuk K-Means Clustering dengan Scikit-Learn PlatoBlockchain Data Intelligence. Pencarian Vertikal. Ai.

Menurut metode siku kita harus memiliki 3 cluster di sini. Untuk langkah terakhir, mari kita mengelompokkan titik-titik kita menjadi 3 kelompok dan memplot kelompok yang diidentifikasi dengan warna:

kmeans_wine = KMeans(n_clusters=3, random_state=42)
kmeans_wine.fit(values)
sns.scatterplot(x = values['OD280'], y = values['Alcohol'], hue=kmeans_wine.labels_)

Panduan Definitif untuk K-Means Clustering dengan Scikit-Learn PlatoBlockchain Data Intelligence. Pencarian Vertikal. Ai.

Kita bisa melihat cluster 0, 1, dan 2 dalam grafik. Berdasarkan analisis kami, grup 0 memiliki anggur dengan kandungan protein lebih tinggi dan alkohol lebih rendah, grup 1 memiliki anggur dengan kandungan alkohol lebih tinggi dan protein rendah, dan grup 2 memiliki protein tinggi dan alkohol tinggi dalam anggurnya.

Ini adalah kumpulan data yang sangat menarik dan saya mendorong Anda untuk melangkah lebih jauh ke dalam analisis dengan mengelompokkan data setelah normalisasi dan PCA – juga dengan menafsirkan hasil dan menemukan koneksi baru.

Kesimpulan

K-Berarti clustering adalah algoritma pembelajaran mesin tanpa pengawasan yang sederhana namun sangat efektif untuk pengelompokan data. Ini mengelompokkan data berdasarkan jarak Euclidean antara titik data. Algoritma clustering K-Means memiliki banyak kegunaan untuk mengelompokkan dokumen teks, gambar, video, dan masih banyak lagi.

Stempel Waktu:

Lebih dari penyalahgunaan