Scikit-Learn PlatoBlockchain Veri Zekası ile K-Means Kümelenmesine İlişkin Kesin Kılavuz. Dikey Arama. Ai.

Scikit-Learn ile K-Means Kümeleme için Kesin Kılavuz

Giriş

K-Kümeleme anlamına gelir veri örnekleri arasındaki benzerliğe dayalı veri kümeleri oluşturan en yaygın kullanılan denetimsiz makine öğrenimi algoritmalarından biridir.

Bu kılavuzda, Scikit-Learn kullanarak uygulamadan önce K-Means algoritmasının nasıl çalıştığını anlamak için ilk olarak basit bir örneğe bakacağız. Ardından, K-Ortalamalardaki kümelerin (Ks) sayısının nasıl belirleneceğini tartışacağız ve ayrıca mesafe ölçümlerini, varyansı ve K-Ortalamaları artılarını ve eksilerini ele alacağız.

Motivasyon

Aşağıdaki durumu hayal edin. Bir gün mahallede dolaşırken 10 bakkal olduğunu fark ettiniz ve hangi mağazaların birbirine yakın olduğunu merak etmeye başladınız - birbirine yakın. Bu soruyu yanıtlamanın yollarını ararken, mağazaları bir harita üzerinde koordinatlarına göre gruplara ayıran ilginç bir yaklaşımla karşılaştınız.

Örneğin, bir mağaza 5 km Batı ve 3 km Kuzeyde bulunuyorsa, (5, 3) koordinatlar ve bir grafikte temsil eder. Neler olduğunu görselleştirmek için bu ilk noktayı çizelim:

import matplotlib.pyplot as plt

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

Bu sadece ilk nokta, böylece bir mağazayı nasıl temsil edebileceğimize dair bir fikir edinebiliriz. Diyelim ki toplanan 10 mağazanın 10 koordinatı var. Bunları bir düzende düzenledikten sonra numpy dizi, konumlarını da çizebiliriz:

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)

Scikit-Learn PlatoBlockchain Veri Zekası ile K-Means Kümelenmesine İlişkin Kesin Kılavuz. Dikey Arama. Ai.

K-Means Algoritmasını Manuel Olarak Uygulama

Şimdi bir grafik üzerinde 10 mağazaya bakabiliriz ve asıl sorun, yakınlıklarına göre farklı gruplara ayrılmalarının bir yolu var mı? Sadece grafiğe hızlı bir göz atarak muhtemelen fark edeceğiz iki grup mağaza – biri sol alttaki alt noktalar, diğeri ise sağ üst noktalar. Belki de ortadaki bu iki noktayı ayrı bir grup olarak ayırabiliriz - bu nedenle üç farklı grup.

Bu bölümde, noktaları verilen sayıda gruba ayırarak manuel olarak kümeleme sürecini gözden geçireceğiz. Bu şekilde, sürecin tüm adımlarını esasen dikkatli bir şekilde gözden geçireceğiz. K-Means kümeleme algoritması. Bu bölümün sonunda, K-Means kümelemesi sırasında gerçekleştirilen tüm adımlar hakkında hem sezgisel hem de pratik bir anlayış kazanacaksınız. Ondan sonra, onu Scikit-Learn'e devredeceğiz.

İki veya üç nokta grubu olup olmadığını belirlemenin en iyi yolu ne olabilir? Basit bir yol, sadece bir grup – örneğin iki – seçmek ve ardından bu seçime göre puanları gruplandırmaya çalışmak olacaktır.

Scikit-Learn PlatoBlockchain Veri Zekası ile K-Means Kümelenmesine İlişkin Kesin Kılavuz. Dikey Arama. Ai.

Diyelim ki var olduğuna karar verdik iki grup mağazalarımızdan (puan). Şimdi, hangi noktaların hangi gruba ait olduğunu anlamanın bir yolunu bulmamız gerekiyor. Bu, temsil edilecek bir nokta seçilerek yapılabilir. grup 1 ve temsil edecek biri grup 2. Bu noktalar, diğer tüm noktalardan her bir gruba olan mesafeyi ölçerken referans olarak kullanılacaktır.

Bu şekilde, noktayı söyle (5, 3) grup 1'e ait olur ve nokta (79, 60) 2. gruba yeni bir nokta atamaya çalışırken (6, 3) gruplara, bu iki noktaya olan mesafesini ölçmemiz gerekiyor. Nokta durumunda (6, 3) is yakın için (5, 3), bu nedenle o nokta tarafından temsil edilen gruba aittir – grup 1. Bu şekilde, tüm noktaları ilgili gruplara kolayca gruplayabiliriz.

Bu örnekte, grup sayısını belirlemenin yanı sıra (kümeler) – biz de bazı noktaları seçiyoruz. referans Her grubun yeni noktaları için mesafe.

Mağazalarımız arasındaki benzerlikleri anlamak için genel fikir budur. Haydi bunu uygulamaya koyalım – önce şu iki referans noktasını seçebiliriz: rasgele. referans noktası grup 1 olacak (5, 3) ve referans noktası grup 2 olacak (10, 15). Her iki noktamızı da seçebiliriz numpy dizi [0] ve [1] dizinler ve bunları depolar g1 (grup 1) ve g2 (grup 2) değişkenler:

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

Bunu yaptıktan sonra, diğer tüm noktalardan o referans noktalarına olan mesafeyi hesaplamamız gerekiyor. Bu, önemli bir soruyu gündeme getiriyor - bu mesafenin nasıl ölçüleceği. Esasen herhangi bir mesafe ölçüsü kullanabiliriz, ancak bu kılavuzun amacı için Öklid Mesafesini kullanalım.

Öklid mesafe ölçüsünün Pisagor teoremine dayandığını bilmek faydalı olabilir:

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

Bir düzlemdeki noktalara uyarlandığında – (a1, b1) ve (a2, b2), önceki formül şöyle olur:

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

Mesafe karekökü olacak c, böylece formülü şu şekilde de yazabiliriz:

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

Not: Öklid uzaklık formülünü çok boyutlu noktalar için de genelleştirebilirsiniz. Örneğin, üç boyutlu bir uzayda noktaların üç koordinatı vardır - formülümüz bunu şu şekilde yansıtır:
$$
öklid_{dist} = sqrt[2][(a2 – a1)^2 + (b2 – b1) ^2 + (c2 – c1) ^2)]
$$
İçinde bulunduğumuz alanın boyutları ne olursa olsun aynı prensip izlenir.

Şimdiye kadar grupları temsil edecek noktaları seçtik ve mesafeleri nasıl hesaplayacağımızı biliyoruz. Şimdi topladığımız mağaza noktalarımızın her birini bir gruba atayarak mesafeleri ve grupları bir araya getirelim.

Bunu daha iyi görselleştirmek için üç liste ilan edeceğiz. İlk grubun puanlarını depolayan ilk kişi – points_in_g1. 2. gruptaki puanları depolamak için ikincisi – points_in_g2, ve sonuncusu - groupe etiket puanlar ya 1 (grup 1'e aittir) veya 2 (grup 2'ye aittir):

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

Artık noktalarımızı yineleyebilir ve bunlar ile grup referanslarımızın her biri arasındaki Öklid mesafesini hesaplayabiliriz. Her nokta olacak yakın iki gruptan birine - hangi grubun en yakın olduğuna bağlı olarak, her noktayı ilgili listeye atayacağız ve ayrıca 1 or 2 için group liste:

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')

Ne olduğunu görmek için bu yinelemenin sonuçlarına bakalım:

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

Hangi sonuç:

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] 

Seaborn's'u kullanarak, atanan gruplara göre farklı renklerle kümeleme sonucunu da çizebiliriz. scatterplot() ile group bir şekilde hue argüman:

import seaborn as sns

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

Scikit-Learn PlatoBlockchain Veri Zekası ile K-Means Kümelenmesine İlişkin Kesin Kılavuz. Dikey Arama. Ai.

Sadece ilk puanımızın 1. gruba atandığı ve diğer tüm puanların 2. gruba atandığı açıkça görülüyor. Bu sonuç, başlangıçta öngördüğümüzden farklı. Sonuçlarımız ile ilk beklentilerimiz arasındaki farkı göz önünde bulundurursak, bunu değiştirmenin bir yolu var mı? Var gibi görünüyor!

Bir yaklaşım, süreci tekrarlamak ve grupların referansları olarak farklı noktaları seçmektir. Bu, sonuçlarımızı, umarız, başlangıçta öngördüğümüze göre daha fazla değiştirecektir. Bu ikinci kez, daha önce yaptığımız gibi rastgele değil, bir ortalama zaten gruplanmış tüm noktalarımız. Bu şekilde, bu yeni noktalar ilgili grupların ortasına yerleştirilebilir.

Örneğin, ikinci grubun sadece puanları varsa (10, 15), (30, 45). Yeni merkezi nokta olurdu (10 + 30)/2 ve (15+45)/2 - şuna eşittir: (20, 30).

Sonuçlarımızı listelere koyduğumuz için, önce onları dönüştürebiliriz. numpy diziler, xs, ys'lerini seçin ve ardından ortalama:

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

Önerileri: Kullanmaya çalışmak numpy ve mümkün olduğunca NumPy dizileri. Daha iyi performans için optimize edilmişlerdir ve birçok lineer cebir işlemini basitleştirirler. Ne zaman bir lineer cebir problemini çözmeye çalışıyorsanız, kesinlikle şuna bir göz atmalısınız. numpy olup olmadığını kontrol etmek için belgeler numpy Sorununuzu çözmek için tasarlanmış bir yöntem. Şans var ki!

İşlemi yeni merkez noktalarımızla tekrarlamaya yardımcı olmak için önceki kodumuzu bir fonksiyona dönüştürelim, yürütelim ve noktaların nasıl gruplandırıldığına dair herhangi bir değişiklik olup olmadığına bakalım:

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

Not: Sürekli aynı kodu tekrarladığınızı fark ederseniz, o kodu ayrı bir fonksiyona sarmanız gerekir. Özellikle testi kolaylaştırdıkları için kodu işlevler halinde düzenlemek en iyi uygulama olarak kabul edilir. Herhangi bir işlevi olmayan tam bir koddan daha kolay test ve izole kod parçası.

Fonksiyonu çağıralım ve sonuçlarını içinde saklayalım. points_in_g1, points_in_g2, ve group değişkenleri:

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

Ayrıca gruplar bölümünü görselleştirmek için dağılım grafiğini renkli noktalarla çizin:

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

Scikit-Learn PlatoBlockchain Veri Zekası ile K-Means Kümelenmesine İlişkin Kesin Kılavuz. Dikey Arama. Ai.

Görünüşe göre noktalarımızın kümelenmesi daha iyi olmak. Ancak yine de, grafiğin ortasında, her iki gruba da yakınlıkları göz önüne alındığında her iki gruba atanabilecek iki nokta vardır. Şimdiye kadar geliştirdiğimiz algoritma, bu noktaların her ikisini de ikinci gruba atar.

Bu, X'ler ve Y'lerin ortalamalarını alarak, iki yeni merkezi nokta oluşturarak işlemi muhtemelen bir kez daha tekrarlayabileceğimiz anlamına gelir. (merkezler) gruplarımıza ve mesafeye göre yeniden atama.

Ayrıca centroidleri güncellemek için bir fonksiyon oluşturalım. Artık tüm süreç, bu işlevin birden çok çağrısına indirgenebilir:

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)

Scikit-Learn PlatoBlockchain Veri Zekası ile K-Means Kümelenmesine İlişkin Kesin Kılavuz. Dikey Arama. Ai.

Bu üçüncü yinelemeden sonra, noktaların her birinin artık farklı kümelere ait olduğuna dikkat edin. Görünüşe göre sonuçlar daha iyi hale geliyor – hadi bir kez daha yapalım. Şimdi gidiyor dördüncü yineleme bizim yöntemimiz:

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)

Scikit-Learn PlatoBlockchain Veri Zekası ile K-Means Kümelenmesine İlişkin Kesin Kılavuz. Dikey Arama. Ai.

Bu dördüncü kez aldık aynı sonuç önceki gibi. Yani puanlarımız artık grupları değiştirmeyecek gibi görünüyor, sonucumuz bir tür istikrara ulaştı – değişmez bir duruma geldi veya yakınsama. Bunun yanı sıra, 2 grup için öngördüğümüzle tamamen aynı sonuca sahibiz. Bu ulaşılan bölünmenin mantıklı olup olmadığını da görebiliriz.

Şimdiye kadar yaptıklarımızı hızlıca özetleyelim. 10 mağazamızı coğrafi olarak iki bölüme ayırdık - alt güneybatı bölgelerinde ve diğerleri kuzeydoğuda. Halihazırda sahip olduklarımızın (gelir, günlük müşteri sayısı ve daha fazlası) yanı sıra daha fazla veri toplamak ilginç olabilir. Bu şekilde daha zengin bir analiz yapabilir ve muhtemelen daha ilginç sonuçlar üretebiliriz.

Halihazırda kurulmuş bir marka yeni bir mağaza açmak için bir alan seçmek istediğinde bu tür kümeleme çalışmaları yapılabilir. Bu durumda konumun yanı sıra dikkate alınan daha birçok değişken vardır.

Bütün bunların K-Means Algoritması ile Ne ilgisi Var?

Bu adımları takip ederken bunların K-Means algoritmasıyla ne ilgisi olduğunu merak etmiş olabilirsiniz. Şimdiye kadar gerçekleştirdiğimiz süreç, K-Ortalamalar algoritması. Kısacası, grupların/kümelerin sayısını belirledik, rastgele başlangıç ​​noktalarını seçtik ve kümeler yakınsayana kadar her yinelemede güncelleştirilmiş merkez noktaları. Temel olarak tüm algoritmayı elle gerçekleştirdik – her adımı dikkatli bir şekilde yürüttük.

The K K-Means'te küme sayısı yineleme işlemine başlamadan önce ayarlanması gerekir. bizim durumumuzda K = 2. Bu özellik bazen şu şekilde görülür: negatif Önceden sabit sayıda kümeye sahip olması gerekmeyen Hiyerarşik Kümeleme gibi başka kümeleme yöntemleri olduğu düşünülürse.

Araç kullanımı nedeniyle, K-araçları da olur aykırı değerlere ve uç değerlere duyarlı – değişkenliği arttırırlar ve ağırlık merkezilerimizin kendi rollerini oynamasını zorlaştırırlar. Yani, gerçekleştirme ihtiyacının bilincinde olun uç değerler ve aykırı değer analizi K-Means algoritmasını kullanarak bir kümeleme gerçekleştirmeden önce.

Ayrıca, noktalarımızın düz kısımlara ayrıldığına dikkat edin, kümeleri oluştururken eğriler yoktur. Bu aynı zamanda K-Means algoritmasının bir dezavantajı da olabilir.

Not: Elipslere ve diğer şekillere daha esnek ve uyarlanabilir olması gerektiğinde, bir genelleştirilmiş K-ortalamaları Gauss Karışım modeli. Bu model, eliptik segmentasyon kümelerine uyum sağlayabilir.

K-Means ayrıca birçok avantajları! üzerinde iyi performans gösterir büyük veri setleri bazı hiyerarşik kümeleme algoritmaları kullanıyorsanız, bu işlemin yapılması zorlaşabilir. Ayrıca yakınsamayı garanti eder, ve kolayca genelleştirmek ve uyarlamak. Bunun yanında, muhtemelen en çok kullanılan kümeleme algoritmasıdır.

Artık K-Means algoritmasında gerçekleştirilen tüm adımları gözden geçirdiğimize ve tüm artılarını ve eksilerini anladığımıza göre, sonunda Scikit-Learn kütüphanesini kullanarak K-Means'i uygulayabiliriz.

K-Means Algoritmasını Kullanarak Nasıl Uygulanır? Scikit-Öğren

Sonucumuzu tekrar kontrol etmek için bu işlemi tekrar yapalım, ancak şimdi 3 satırlık kod kullanarak sklearn:

from sklearn.cluster import KMeans


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

Burada etiketler önceki gruplarımızla aynıdır. Sonucu hızlıca çizelim:

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

Scikit-Learn PlatoBlockchain Veri Zekası ile K-Means Kümelenmesine İlişkin Kesin Kılavuz. Dikey Arama. Ai.

Ortaya çıkan arsa, önceki bölümdeki ile aynıdır.

En iyi uygulamalar, endüstri tarafından kabul edilen standartlar ve dahil edilen hile sayfası ile Git'i öğrenmek için uygulamalı, pratik kılavuzumuza göz atın. Googling Git komutlarını durdurun ve aslında öğrenmek o!

Not: Scikit-Learn'i kullanarak K-Means algoritmasını nasıl uyguladığımıza bakmak bile size bunun basit olduğu ve bu konuda çok fazla endişelenmenize gerek olmadığı izlenimini verebilir. Sadece 3 satırlık kod, K-Means algoritmasını adım adım incelediğimizde, önceki bölümde tartıştığımız tüm adımları gerçekleştirir. Fakat, şeytan Ayrıntıda bu durumda! Algoritmanın tüm adımlarını ve sınırlamalarını anlamadıysanız, büyük olasılıkla K-Means algoritmasının size beklemediğiniz sonuçları verdiği durumla karşı karşıya kalacaksınız.

Scikit-Learn ile, daha hızlı yakınsama için K-Means'i aşağıdakileri ayarlayarak da başlatabilirsiniz. init='k-means++' argüman. Daha geniş anlamda, K-Ortalamaları++ hala seçiyor k tekdüze bir dağılımın ardından rastgele ilk küme merkezleri. Ardından, sonraki her küme merkezi, yalnızca bir mesafe ölçüsü hesaplanarak değil, olasılık kullanılarak kalan veri noktalarından seçilir. Olasılığı kullanmak algoritmayı hızlandırır ve çok büyük veri kümeleriyle uğraşırken yardımcı olur.

Dirsek Metodu – En İyi Grup Sayısını Seçme

Çok uzak çok iyi! Noktalar ve merkezler arasındaki Öklid mesafesine dayalı olarak 10 mağazayı kümelendirdik. Peki ya grafiğin ortasında kümelenmesi biraz daha zor olan iki nokta? Onlar da ayrı bir grup oluşturamazlar mı? Seçerek gerçekten bir hata mı yaptık? K = 2 gruplar? Belki gerçekten sahiptik K = 3 gruplar? Hatta üçten fazla grubumuz olabilir ve bunun farkında olmayabiliriz.

Burada sorulan soru şu K-Means'te grup sayısı (K) nasıl belirlenir. Bu soruyu cevaplamak için, farklı bir K değeri için "daha iyi" bir küme olup olmayacağını anlamamız gerekir.

Bunu bulmanın naif yolu, farklı değerlere sahip noktaları kümelemektir. K, için böylece K=2, K=3, K=4, vb.:

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

Ancak, farklı kümelenme noktaları Ks tek başına yeterli olmayacak için ideal değeri seçip seçmediğimizi anlamak için K. Her biri için kümeleme kalitesini değerlendirmek için bir yola ihtiyacımız var. K biz seçtik.

Elle Hesaplama Küme Kareler Toplamı İçinde (WCSS)

Kümelenmiş noktalarımızın birbirine ne kadar yakın olduğunun bir ölçüsünü tanıtmak için ideal yer burasıdır. Esasen ne kadar olduğunu açıklar varyans tek bir kümenin içinde var. Bu ölçü denir Küme Kareler Toplamı İçindeya da WCSS kısaca. WCSS ne kadar küçükse, noktalarımız o kadar yakın olur, bu nedenle daha iyi biçimlendirilmiş bir kümemiz olur. WCSS formülü herhangi bir sayıda küme için kullanılabilir:

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

Not: Bu kılavuzda, kullandığımız Öklid mesafesi sentroidleri elde etmek için, ancak Manhattan gibi diğer mesafe ölçüleri de kullanılabilir.

Şimdi, iki kümeye sahip olmayı seçtiğimizi ve WCSS'nin ne olduğunu ve nasıl kullanılacağını daha iyi anlamak için WCSS'yi uygulamaya çalıştığımızı varsayabiliriz. Formülün belirttiği gibi, tüm küme noktaları ve merkezler arasındaki kare farklarını toplamamız gerekiyor. Öyleyse, ilk gruptan ilk noktamız ise (5, 3) ve ilk grubun son merkezimiz (yakınsama sonrası) (16.8, 17.0), WCSS şu şekilde olacaktır:

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

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

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

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

$$
WCSS = 335.24
$$

Bu örnek, kümeden bir nokta için WCSS'yi nasıl hesapladığımızı gösterir. Ancak küme genellikle birden fazla nokta içerir ve WCSS'yi hesaplarken hepsini dikkate almamız gerekir. Bunu, noktalar ve merkezler kümesini alan ve karelerin toplamını döndüren bir fonksiyon tanımlayarak yapacağız:

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

Şimdi her küme için karelerin toplamını alabiliriz:

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

Ve toplamı elde etmek için sonuçları toplayın WCSS:

g1 + g2

Bunun sonucu:

2964.3999999999996

Yani, bizim durumumuzda, ne zaman K 2'ye eşittir, toplam WCSS 2964.39. Şimdi, K'leri değiştirebilir ve hepsi için WCSS'yi hesaplayabiliriz. Bu şekilde, neyin ne olduğu hakkında bir fikir edinebiliriz. K kümelememizi en iyi şekilde gerçekleştirmeyi seçmeliyiz.

Hesaplanıyor WCSS kullanma Scikit-Öğren

Neyse ki, her biri için WCSS'yi manuel olarak hesaplamamıza gerek yok. K. Verilen küme sayısı için K-Ortalamalar kümelemesini yaptıktan sonra, WCSS'sini aşağıdakileri kullanarak elde edebiliriz: inertia_ bağlanmak. Şimdi, K-Means'imize geri dönebiliriz. for döngü, küme sayısını değiştirmek için kullanın ve karşılık gelen WCSS değerlerini listeleyin:

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

Listedeki ikinci değerin, daha önce hesapladığımızla tamamen aynı olduğuna dikkat edin. 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]

Bu sonuçları görselleştirmek için, Ks WCSS değerleriyle birlikte:

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

Scikit-Learn PlatoBlockchain Veri Zekası ile K-Means Kümelenmesine İlişkin Kesin Kılavuz. Dikey Arama. Ai.

Bir arsa üzerinde bir kesinti olduğunda x = 2, hatta düşük bir nokta ve daha da düşük bir nokta x = 3. Bize şunu hatırlattığına dikkat edin. dirsek şekli. K'leri WCSS ile birlikte çizerek, Dirsek Yöntemi Ks sayısını seçmek için. Ve seçilen K tam olarak en düşük dirsek noktasıdır, yani, olurdu 3 yerine 2, bizim durumumuzda:

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

Scikit-Learn PlatoBlockchain Veri Zekası ile K-Means Kümelenmesine İlişkin Kesin Kılavuz. Dikey Arama. Ai.

Verilerimizin nasıl görüneceğini görmek için K-Means küme algoritmasını tekrar çalıştırabiliriz. üç küme:

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

Scikit-Learn PlatoBlockchain Veri Zekası ile K-Means Kümelenmesine İlişkin Kesin Kılavuz. Dikey Arama. Ai.

İki kümeden zaten memnunduk, ancak dirsek yöntemine göre, verilerimiz için üç küme daha uygun olurdu. Bu durumda iki yerine üç çeşit mağazamız olurdu. Dirsek yöntemini kullanmadan önce güneybatı ve kuzeydoğu mağaza kümelerini düşündük, şimdi merkezde de mağazalarımız var. Belki bu, yakınlarda daha az rekabet olacağı için başka bir mağaza açmak için iyi bir yer olabilir.

Alternatif Küme Kalite Ölçüleri

Küme kalitesini değerlendirirken kullanılabilecek başka ölçüler de vardır:

  • Siluet Puanı – yalnızca küme içi noktalar arasındaki mesafeyi değil, aynı zamanda kümelerin kendi aralarındaki mesafeyi de analiz eder
  • Kümeler Arası Kareler Toplamı (BCSS) – WCSS'yi tamamlayıcı metrik
  • Kareler Toplamı Hatası (ESS)
  • Maksimum Yarıçap - bir noktadan merkez noktasına olan en büyük mesafeyi ölçer
  • Ortalama Yarıçap - bir noktadan ağırlık merkezine olan en büyük mesafenin toplamının küme sayısına bölümü.

Soruna bağlı olarak, bazı alternatifler en yaygın olarak kullanılan metriklerden daha uygulanabilir olabileceğinden, her birini denemeniz ve tanımanız önerilir. (WCSS ve Siluet Puanı).

Sonuç olarak, birçok veri bilimi algoritmasında olduğu gibi, her kümenin içindeki varyansı azaltmak ve farklı kümeler arasındaki varyansı en üst düzeye çıkarmak istiyoruz. Yani daha tanımlı ve ayrılabilir kümelerimiz var.

K-Means'i Başka Bir Veri Kümesine Uygulamak

Öğrendiklerimizi başka bir veri kümesinde kullanalım. Bu sefer benzer şarap gruplarını bulmaya çalışacağız.

Not: Veri setini indirebilirsiniz okuyun.

ithal ederek başlıyoruz pandas okumak için wine-clustering CSV (Virgülle Ayrılmış Değerler) dosyaya bir Dataframe yapısı:

import pandas as pd

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

Yükledikten sonra, ilk beş veri kaydına bir göz atalım. head() yöntem:

df.head()

Bunun sonucu:

	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

Şaraplarda bulunan birçok madde ölçümüne sahibiz. Burada ayrıca kategorik sütunları dönüştürmemiz gerekmeyecek çünkü hepsi sayısal. Şimdi betimsel istatistiklere bir göz atalım. describe() yöntem:

df.describe().T 

Açıklama tablosu:

 						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

Tabloya bakınca bazı şeyler olduğu açıkça görülüyor. verilerdeki değişkenlik – gibi bazı sütunlar için Alchool daha fazlası var ve diğerleri için, örneğin Malic_Acid, az. şimdi var mı diye kontrol edebiliriz nullya da NaN veri kümemizdeki değerler:

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

Veri kümesinde boş değerler olmadığı düşünüldüğünde, verileri düşürmeye veya girmeye gerek yoktur. Seaborn kullanabiliriz pairplot() veri dağılımını görmek ve veri kümesinin kümeleme için ilginç olabilecek sütun çiftleri oluşturup oluşturmadığını kontrol etmek için:

sns.pairplot(df)

Scikit-Learn PlatoBlockchain Veri Zekası ile K-Means Kümelenmesine İlişkin Kesin Kılavuz. Dikey Arama. Ai.

Çift grafiğine bakıldığında, iki sütun kümeleme amaçları için umut verici görünüyor – Alcohol ve OD280 (bu, şaraplardaki protein konsantrasyonunu belirlemek için bir yöntemdir). Görünüşe göre, ikisini birleştiren parsellerde 3 ayrı küme var.

Korelasyon içinde gibi görünen başka sütunlar da var. en önemlisi Alcohol ve Total_Phenols, ve Alcohol ve Flavanoids. Çift grafiğinde gözlemlenebilen büyük doğrusal ilişkilere sahiptirler.

Odak noktamız K-Means ile kümelenmek olduğundan, bir çift sütun seçelim, diyelim Alcohol ve OD280ve bu veri kümesi için dirsek yöntemini test edin.

Not: Veri kümesinin daha fazla sütununu kullanırken, ya 3 boyutlu olarak çizim yapmaya ya da verileri ana bileşenler (PCA kullanımı). Bu geçerli ve daha yaygın bir yaklaşımdır, ana bileşenleri ne kadar açıkladıklarına göre seçtiğinizden emin olun ve veri boyutlarını azaltırken bir miktar bilgi kaybı olduğunu unutmayın - bu nedenle arsa bir tahmin gerçek verilerden, gerçekte olduğu gibi değil.

Gruplara bölmek istediğimiz noktalara daha yakından bakmak için bu iki sütun ekseni olacak şekilde dağılım grafiğini çizelim:

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

Scikit-Learn PlatoBlockchain Veri Zekası ile K-Means Kümelenmesine İlişkin Kesin Kılavuz. Dikey Arama. Ai.

Artık sütunlarımızı tanımlayabilir ve küme sayısını belirlemek için dirsek yöntemini kullanabiliriz. Algoritmayı da başlatacağız kmeans++ sadece daha hızlı birleştiğinden emin olmak için:

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_)

WCSS'yi hesapladık, böylece sonuçları çizebiliriz:

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

Scikit-Learn PlatoBlockchain Veri Zekası ile K-Means Kümelenmesine İlişkin Kesin Kılavuz. Dikey Arama. Ai.

Dirsek yöntemine göre burada 3 kümemiz olmalıdır. Son adım için, noktalarımızı 3 kümeye ayıralım ve renklerle tanımlanan bu kümeleri çizelim:

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_)

Scikit-Learn PlatoBlockchain Veri Zekası ile K-Means Kümelenmesine İlişkin Kesin Kılavuz. Dikey Arama. Ai.

kümeleri görebiliriz 0, 1, ve 2 grafikte. Analizimize dayanarak, grup 0 daha yüksek protein içeriğine ve daha düşük alkole sahip şaraplara sahiptir, grup 1 daha yüksek alkol içeriği ve düşük protein içeren şaraplara sahiptir ve grup 2 şaraplarında hem yüksek protein hem de yüksek alkol bulunur.

Bu çok ilginç bir veri kümesidir ve normalleştirme ve PCA'dan sonra verileri kümeleyerek - ayrıca sonuçları yorumlayarak ve yeni bağlantılar bularak - analizde daha ileri gitmenizi tavsiye ederim.

Sonuç

K-anlamına gelir Kümeleme, veri kümeleme için basit ama çok etkili bir denetimsiz makine öğrenimi algoritmasıdır. Veri noktaları arasındaki Öklid mesafesine dayalı olarak verileri kümeler. K-Means kümeleme algoritması, metin belgelerini, resimleri, videoları ve çok daha fazlasını gruplamak için birçok kullanıma sahiptir.

Zaman Damgası:

Den fazla Yığın kötüye kullanımı