Spark MLlib Kullanarak Kümeleme Analizi
Komut satırımızı açıyoruz. bir dizin seçiyoruz. Ben /home/cloudera
seçtim. wget "https://raw.githubusercontent.com/erkansirin78/datasets/master/iris.csv"
komutuyla mevcut dizine veri setini indiriyoruz. Iris veri setini hatırlayalım. Toplam 150 kayıt ve 5 nitelikten oluşuyor. İlk dört nitelik nümerik ve yaprak uzunluk ve genişlikleri ile ilgili değerlere sahip. Beşinci değişken ise kategorik ve çiçeğin hangi sınıfta yer aldığına dair değerlere sahip. K-Ortalamalar algoritması numerik nitelikler ile çalıştığı ve beşinci nitelik hedef nitelik olduğu için biz beşinci niteliği kümeleme için kullanmayacağız.
Şuan namenode sunucuda lokal diskte bulunan veri setini HDFS’e aktaralım. Bunun için şu komutları kullanıyorum: hdfs dfs -put /home/cloudera/iris.csv /user/cloudera
Veri seti artık HDFS’te. HDFS dizini olarak /user/cloudera/iris.csv
Veri setini HDFS’e indirmeyi başardıktan sonra şimdi Jupyter’i açıp kümeleme çalışmaya başlayabiliriz. Gerekli kütüphaneleri indirelim.
from pyspark.mllib.clustering import KMeans, KMeansModel from numpy import array from math import sqrt
Veriyi alıp parse edelim ve Spark veri yapısında çalışmaya başlayalım.
data = sc.textFile("/user/cloudera/iris.csv") parsedData = data.map(lambda line: array([x for x in line.split(',')]))
Bakalım veriyi Spark RDD olarak almış mıyız?
parsedData.take(5) [array([u'5.1', u'3.5', u'1.4', u'0.2', u'Iris-setosa'], dtype='<U11'), array([u'4.9', u'3.0', u'1.4', u'0.2', u'Iris-setosa'], dtype='<U11'), array([u'4.7', u'3.2', u'1.3', u'0.2', u'Iris-setosa'], dtype='<U11'), array([u'4.6', u'3.1', u'1.5', u'0.2', u'Iris-setosa'], dtype='<U11'), array([u'5.0', u'3.6', u'1.4', u'0.2', u'Iris-setosa'], dtype='<U11')]
Evet almışız ancak beşinci niteliğimiz olan çiçek sınıfı (Iris-setosa yazıp duran yerler :)) hala duruyor. Onu kaldırıyoruz çünkü denetimsiz öğrenmede hedef değişken ile işimiz yok. İlk dört niteliği float’a çevirip yeni bir RDD’ye atıyoruz.
iris_ilk_dort_nitelik = parsedData.map(lambda x: array([float(x[0]),float(x[1]),float(x[2]),float(x[3])])) [array([ 5.1, 3.5, 1.4, 0.2]), array([ 4.9, 3. , 1.4, 0.2]), array([ 4.7, 3.2, 1.3, 0.2]), array([ 4.6, 3.1, 1.5, 0.2]), array([ 5. , 3.6, 1.4, 0.2])]
Şimdi hata fonksiyonumuzu yazalım. Yani küme merkezine olan uzaklığı hesaplayacak fonksiyon.
def error(point): center = clusters.centers[clusters.predict(point)] return sqrt(sum([x**2 for x in (point - center)]))
Şimdi her bir k değeri (ayırmak istediğimiz küme sayısı) için maliyetimize bir bakalım.
for k in range (1,6): clusters = KMeans.train(iris_ilk_dort_nitelik, k, maxIterations=10, initializationMode="random") WSSSE = iris_ilk_dort_nitelik.map(lambda point: error(point)).reduce(lambda x, y: x + y) print("With "+ str(k)+ " clusters: WSSSE: "+ str(WSSSE)) With 1 clusters: WSSSE: 291.455123856 With 2 clusters: WSSSE: 128.404195237 With 3 clusters: WSSSE: 97.3259242343 With 4 clusters: WSSSE: 83.7861984508 With 5 clusters: WSSSE: 80.4000863093
Bildiğimiz gibi iris veri seti üç doğal kümeden oluşuyor. Bununla ilgili yazımı inceleyebilirsiniz. Yukarıdaki listeye baktığımızda küme sayısı 2’den 3’e çıkınca en küçük kareler toplamı çok keskin bir düşüş yaşıyor. Bu da bize ideal k sayısı hakkında güzel bir işaret veriyor. Kısmet olursa önümüzdeki günlerde k sayısının nasıl seçileceği ve kategorik değişkenlerle nasıl kümeleme analizi yapılacağına dair yazılar yazmayı düşünüyorum. Şayet modelimizi daha sonra da kullanmayı düşünüyorsak modeli kaydedebiliriz.
clusters.save(sc, "K-OrtalamamarModeli-1")
Sonra modeli tekrar çağırmak istersek:
K_OrtalamamarModeli_1 = KMeansModel.load(sc, "K-OrtalamamarModeli-1")
Bu yazıda da bu kadar. Veriyle kalınız…