Anasayfa / Büyük Veri / Apache Spark ile Artık İdeal Küme Sayısını Bulmak Daha Kolay

Apache Spark ile Artık İdeal Küme Sayısını Bulmak Daha Kolay

Bildiğimiz gibi makine öğrenmesinde öğrenme yöntemleri genel olarak denetimli (supervised) ve denetimsiz (unsupervised) şeklinde ikiye ayrılıyor. Denetimli yöntemlerde sınıflandırma ağırlık kazanırken denetimsiz yöntemlerde ise kümeleme öne çıkmaktadır. Sınıflandırmada veri içinde etiketlenmiş bir hedef değişken bulunurken kümelemede ise herhangi bir hedef  değişken bulunmaz. Bu nedenle kümeleme daha çok veri içindeki nesnelerin doğal gruplanmalarını ortaya çıkarmaya yöneliktir.

Sınıflandırmaya göre biraz daha zorlu, sonuçları yorumlamaya muhtaç, daha fazla alan bilgisi ve uzmanlık gerektiren kümeleme yöntemleri içinde K-ortalamalar (KMeans) tekniği yaygın olarak kullanılmaktadır. Bu teknik girdi olarak veri seti ile birlikte kullanıcıdan küme sayısı olan k değerini istemektedir. İdeal k sayısını belirlemek çok kolay olmasa da bunun için bazı yöntemler geliştirilmiştir. Spark ML’ye göre daha zengin kütüphanelerden olan Scikit-learn’de k sayısı belirlemek için bazı metrikler (sklearn.metrics.silhouette_score) bulunuyor. Bunlardan birisi de silhouette analizidir. K-ortalamalar tekniğinde ideal k sayısı bu analizle belirlenebilmektedir. Apache Spark ise 2.3.0 sürümüne kadar kümeleme değerlendirme metriği sunmuyordu. 2.3.0 ile beraber ML kütüphanesine ClusteringEvaluator sınıfı eklendi. Bu sınıftan yarattığımız nesne ile artık ideal küme sayısının ne olması gerektiğine dair bir fikir edinebiliyoruz. Bunu bu sınıftan oluşturduğumuz nesnenin evaluate metoduyla yapıyoruz. Bu metod bize bir ondalıklı sayı döndürüyor. Bu sayı [-1,1] arasında değer alıyor. Değerin yüksek olması kümelerin birbirinden daha iyi ayrıştığına işaret ediyor. Bu yazımızda iris veri seti üzerinde basit bir uygulama yapacağız. Bakalım iris verisinde optimal küme sayısı ne çıkacak?

Aşağıdaki kodları: Windows 10 üzerine kurulu Spark 2.3.1, IntelliJ Idea Community Edition ve Scala kullanarak yazdım ve çalıştırdım.

Kodları Veri Bilimi Okulu GitHub deposunda da bulabilirsiniz.

Gerekli kütüphaneleri indirme:

import org.apache.spark.ml.{PipelineModel, Pipeline}
import org.apache.spark.ml.clustering.{KMeans, KMeansModel}
import org.apache.spark.ml.feature.{VectorAssembler, StandardScaler}
import org.apache.spark.ml.evaluation.ClusteringEvaluator
import org.apache.spark.sql.{DataFrame, SparkSession}

Spark session yaratma:

val spark = SparkSession.builder
      .master("local[*]")
      .appName("FindClusterNumber")
      .getOrCreate()

Veri setini yükleme:

val data = spark.read.format("csv").option("inferSchema","true").option("header","true")
      .load("C:\Users\toshiba\SkyDrive\veribilimi.co\Datasets\iris.csv")

Veriye bir göz atalım:

 data.show()
+-------------+------------+-------------+------------+-----------+
|SepalLengthCm|SepalWidthCm|PetalLengthCm|PetalWidthCm|    Species|
+-------------+------------+-------------+------------+-----------+
|          5.1|         3.5|          1.4|         0.2|Iris-setosa|
|          4.9|         3.0|          1.4|         0.2|Iris-setosa|
|          4.7|         3.2|          1.3|         0.2|Iris-setosa|
|          4.6|         3.1|          1.5|         0.2|Iris-setosa|
|          5.0|         3.6|          1.4|         0.2|Iris-setosa|
|          5.4|         3.9|          1.7|         0.4|Iris-setosa|
|          4.6|         3.4|          1.4|         0.3|Iris-setosa|
|          5.0|         3.4|          1.5|         0.2|Iris-setosa|
|          4.4|         2.9|          1.4|         0.2|Iris-setosa|
|          4.9|         3.1|          1.5|         0.1|Iris-setosa|
|          5.4|         3.7|          1.5|         0.2|Iris-setosa|
|          4.8|         3.4|          1.6|         0.2|Iris-setosa|
|          4.8|         3.0|          1.4|         0.1|Iris-setosa|
|          4.3|         3.0|          1.1|         0.1|Iris-setosa|
|          5.8|         4.0|          1.2|         0.2|Iris-setosa|
|          5.7|         4.4|          1.5|         0.4|Iris-setosa|
|          5.4|         3.9|          1.3|         0.4|Iris-setosa|
|          5.1|         3.5|          1.4|         0.3|Iris-setosa|
|          5.7|         3.8|          1.7|         0.3|Iris-setosa|
|          5.1|         3.8|          1.5|         0.3|Iris-setosa|
+-------------+------------+-------------+------------+-----------+

KMeans modeli oluşturan bir fonksiyon yazalım. Bu fonksiyon bize bir PipelineModel döndürsün.

 def ComputeKMeansModel(df:DataFrame, k:Int): PipelineModel = {

     // Pick up input columns
      val inputColumns = df.columns.filter(_!="Species")

      val vectorAssembler = new VectorAssembler().
        setInputCols(inputColumns).
        setOutputCol("featureVector")

      val standartScaler = new StandardScaler()
        .setInputCol("featureVector")
        .setOutputCol("scaledFeatureVector")
        .setWithStd(true)
        .setWithMean(false)

      val kmeansObject = new KMeans().
        setSeed(142).
        setK(k).
        setPredictionCol("cluster").
        setFeaturesCol("scaledFeatureVector").
        setMaxIter(40).
        setTol(1.0e-5)

      val pipeline = new Pipeline().setStages(
        Array(vectorAssembler, standartScaler, kmeansObject))
      pipeline.fit(df)

    }

Optimal k sayısı için evaluator nesnesi yaratalım ve bir for döngüsü ile evaluator score hesaplayalım. Bu arada kmeans computecost değerini de hesaplamış olalım.

 val evaluator = new ClusteringEvaluator()
      .setFeaturesCol("scaledFeatureVector")
      .setPredictionCol("cluster")
      .setMetricName("silhouette")

    for(k <- 2 to 7 by 1){
      val pipelineModel =  ComputeKMeansModel(data,k)

      val transformedDF = pipelineModel.transform(data)

      val score = evaluator.evaluate(transformedDF)
      val kmeansModel = pipelineModel.stages.last.asInstanceOf[KMeansModel]
      println("k value:"+k, "Score: "+score, "KMeans ComputeCost: "+ kmeansModel.computeCost(transformedDF))
    }

Sonuç:

(k value:2,Score: 0.7714149126311811,KMeans ComputeCost: 222.24045903184924)
(k value:3,Score: 0.6797395814522242,KMeans ComputeCost: 196.38339394892998)
(k value:4,Score: 0.6156585151435247,KMeans ComputeCost: 128.02116415016857)
(k value:5,Score: 0.5326790461597242,KMeans ComputeCost: 91.08870518145912)
(k value:6,Score: 0.5740571668931305,KMeans ComputeCost: 95.73796235425911)
(k value:7,Score: 0.5678099400784106,KMeans ComputeCost: 87.25990479785739)

Yorum: Bildiğimiz gibi iris çiçeği üç farklı cinsten oluşuyordu. Yukarıda 2’yi saymaz isek en yüksek score değeri k=3 için alınmış. Bu değerlere göre optimal küme sayısı için k değerini 3 seçmek gerekiyor. 2’yi es geçmemizin sebebi bu analizin 2 ve 4 sayıları için kararsızlık eğiliminde olmasıdır[1]. Ayrıca ComputeCost değeri de en büyük sıçramayı 3’üncü kümeden sonra yapmaktadır. Yani dirsek metodunu da kullansak 3’ü seçmemiz isabet olacaktı.

[1] http://scikit-learn.org/stable/auto_examples/cluster/plot_kmeans_silhouette_analysis.html

Hakkında Erkan ŞİRİN

2014'ten beri hem akademik alanda hem de sektörde pratik anlamda büyük veri ve veri bilimi ile ilgili çalışmalar yürütmektedir. Halihazırda İmpektra Bilişim A.Ş.'de büyük veri yöneticisi olarak çalışmakta olup aynı zamanda Gazi Üniversitesi Yönetim Bilişim Sistemleri doktora öğrencisidir. Büyük veri ve veri bilimi ile ilgili birçok kurum ve şirkete eğitimler vermekte ve projeler icra etmektedir. Çalışma alanları: büyük veri platformlarının kurulum ve yönetimi, büyük veri üzerinde makine öğrenmesi, olağan dışılık tespiti, sahtecilik tespiti, veri hazırlama sürecidir.

GÖZ ATMAK İSTEYEBİLİRSİNİZ

IntelliJ IDEA ile Apache Spark Projesini Uzak YARN Cluster Üzerinde Çalıştırmak-1/2

1. Giriş Merhabalar. Uygulama geliştirirken geliştirme(dev), test ve canlı (prod) gibi farklı farklı ortamlar kullanırız. …

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir