Makine Öğrenmesi - Kümeleme İçin Model Değerlendirmesi
Silhouette Score
Silhouette Score (siluet puanı), kümeleme algoritmalarını kullanalarak oluşturulan veri seti kümeleme işlemlerinin kalitesini ve veri setindeki her satırın birbirine benzeten diğer satırlara göre ne kadar iyi kümelendiğini ölçmek için kullanılır. Sonuç değerleri -1 ve 1 aralığındadır. En iyi değer 1, en kötü değer de -1'dir.
- Sonucun 1 değerine yakınlaşması, kümeleme işleminin başarılı bir şekilde oluştuğunu ve her kümenin birbirinde ayırt edici özelliklerinin olduğunu gösterir.
- Sonucun 0 değerine yakınlaşması, birbiriyle örtüşen kümeleri gösterir. Yani kümeler arasında ayırt edici farkların bulunmadığını gösterir.
- Sonucun -1 değerine yakınlaşması, kümeleme işleminin yanlış yapıldığını gösterir.
Kümeleme işlemlerinde silhouette_score'nin kullanılabilmesi için kütüphanesinin içe aktarılması gerekmtektedir
from sklearn.metrics import silhouette_score
Söz dizimi: silhouette_score(X, labels, *, metric='euclidean', sample_size=None, random_state=None, **kwds)
- X, veri setini temsil etmektedir.
- labels, tahmin edilen küme sırasını temsil etmektedir.
Örnek-1: Silhouette Score'u daha iyi anlamak için sonraki konularda işleyeceğimiz KMeans kümeleme algoritması üzerinden silhouette_score değerini bulalım.
import numpy as np
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
%matplotlib inline
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
#100 tane 0-1 aralığında 2 sütun rasgele veri
x=pd.DataFrame(np.random.rand(100,2),columns=["S1","S2"])
#100 tane 0-1 aralığında 2 sütun rasgele veriye 2 ekle
y=pd.DataFrame(2+np.random.rand(100,2),columns=["S1","S2"])
#x ve y DataFrame'leri birleştir.
df=pd.concat([x,y])
#Örnek 5 satır
df.sample(5)
Çıktı:
#Grafik olarak df değerlerini inceleyelim
sns.scatterplot(x=df["S1"],y=df["S2"])
Çıktı:
Veriler yukarıdaki grafikde de görüldüğü gibi değerlerine göre 2 farklı küme halinde gibi görülmektedir.
#KMeans ataması yapılır
#n_clusters küme sayısını temsil eder
KM=KMeans(n_clusters=2)
#Model eğitme işlemi
KM.fit_predict(df)
#Kümeleme tahmin işlemi
predict_KM=KM.predict(df)
predict_KM
Çıktı:
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
Aşağıdaki çıktı da görüldüğü gibi ilk 100 satırı 1. küme diğer 100 satırı da 2. küme olarak atama yapılmış oldu.
#Veri seti değerlerinin kümeleme sonrası kümeleme dağılım grafiği
plt.figure(figsize=(10,6))
plt.scatter(df["S1"],df["S2"],c=predict_KM)
plt.title("Veri seti değerlerinin kümeleme sonrası kümeleme dağılım grafiği")
plt.colorbar()
plt.show()
Çıktı:
#silhouette_score değeri
silhouette_score(df,predict_KM)
Çıktı:
0.8217122409936863
silhouette_score değeri 0.82 olarak bulundu ve bu değer de doğru bir kümeleme işlemi yapıldığı anlamına gelmektedir.
Kümeleme sayısına göre silhouette_score değeri ve grafiklemesi
Ayrılacak küme sayısı (n_clusters) 2 olarak seçildi ama en uygun kümeleme sayısı ne olmalı konusunu grafiksel olarak görmeye çalışalım.
allscore=[] #skor listesi
allclusters=[] #kümeleme sayısı(n_clusters) listesi
sum_of_squared_distances = [] #en yakın küme merkezine olan uzaklıklarının karesi toplamı listesi
#cluster_count'a kadar her kümeleme sayısı sonucunda elde edilen değerleri listelendiren fonksiyon
#x: veri seti
#cluster_count: kümeleme sayısı
def cluster(x,cluster_count):
for no_of_cluster in np.arange(1,cluster_count):
no_of_cluster+=1
model=KMeans(n_clusters=no_of_cluster)
model.fit(x)
predict_model=model.predict(x)
sum_of_squared_distances.append(model.inertia_)
score=silhouette_score(x,predict_model)
print ("Kümeleme sayısı: {}, silhouette_score değeri: {}".format(no_of_cluster,score))
allscore.append(score)
allclusters.append(no_of_cluster)
#df veri setini 10 kümeye kadar ayır
cluster(df,10)
Çıktı:
Kümeleme sayısı: 2, silhouette_score değeri: 0.8217122409936863 Kümeleme sayısı: 3, silhouette_score değeri: 0.5981328933848098 Kümeleme sayısı: 4, silhouette_score değeri: 0.3855076729842598 Kümeleme sayısı: 5, silhouette_score değeri: 0.4014482497509434 Kümeleme sayısı: 6, silhouette_score değeri: 0.40437286198726097 Kümeleme sayısı: 7, silhouette_score değeri: 0.4213049370381368 Kümeleme sayısı: 8, silhouette_score değeri: 0.42751567813672936 Kümeleme sayısı: 9, silhouette_score değeri: 0.4519536157183377 Kümeleme sayısı: 10, silhouette_score değeri: 0.43787714416902385
Bu veri seti için kümeleme sayısı 2 den daha fazla olduğunda silhouette_score değerinde çok büyük düşüşler meydana gelmiştir. Yani bu veri setini 2 kümeye bölmek daha doğru olacaktır.
plt.plot(allclusters,allscore,marker="x")
plt.xlabel('Kümeleme sayısı')
plt.ylabel('Silhoutte_Score')
plt.title('Silhouette Metotu')
plt.show()
Çıktı:
#Uzaklıklarının karesi toplamı grafiklemesi
plt.plot(allclusters,sum_of_squared_distances,marker="x")
plt.xlabel('Kümeleme sayısı')
plt.ylabel('Uzaklıklarının karesi toplamı')
plt.title('Uzaklıklarının karesi toplamı metotu')
plt.show()
Çıktı: