Ana içeriğe geç

R’de K-Means Kümeleme Eğitimi

k-means’in ne olduğunu öğrenin ve veri biliminde neden en çok kullanılan kümeleme algoritmalarından biri olduğunu keşfedin
· 8 dk. oku

Yapay Zeka ile Keşfedin

K-means, veriler içinde kümeleri (benzer veri noktası gruplarını) belirlemeyi sağlayan, popüler bir gözetimsiz makine öğrenmesi tekniğidir. Bu eğitimde tidymodels, ggplot2 ve ggmap kullanarak R’de k-means kümelemeyi öğreneceksiniz. Şunları ele alacağız:

  • k-means kümeleme algoritmasının nasıl çalıştığı
  • bir veri kümesinin kümeleme için uygun aday olup olmadığını görselleştirerek değerlendirme
  • bir Airbnb yorum veri seti kullanarak k-means kümeleme modelini eğitme ve ayarlama üzerine bir vaka çalışması

Daha derine inmeden önce, R Programlamanın temellerini (ör. vektörler ve veri çerçeveleri) tazelemenizi öneririz. Hazırsanız bunu atlayın ve başlayalım!

k-Means Kümelemesine Genel Bakış

Kümeleme modelleri, verileri ayrı “kümelere” veya gruplara ayırmayı amaçlar. Bu, tek başına bir analiz olarak kullanılabilir ya da bir gözetimli öğrenme algoritmasında özellik olarak değerlendirilebilir.

image1.png

Yukarıdaki diyagramın sol tarafında, etiketlenmemiş ancak benzer veri noktaları olarak renklendirilmiş, birbirinden farklı 2 nokta kümesi görüyoruz. Bu veriye (sağ taraf) bir k-means modeli uydurmak, 2 ayrı grubu (hem farklı dairelerle hem de renklerle gösterilen) ortaya çıkarabilir. 

İki boyutta insanlar için bu kümeleri ayırmak kolaydır, ancak boyut sayısı arttıkça bir modele ihtiyaç duyarsınız.

k-means algoritması

Benzer meyvelerden oluşan birkaç meyve salatası hazırlamak istediğinizi hayal edin.

  1. Kaç meyve salatası yapmak istediğinize (k) karar verirsiniz. Örneğin 3 meyve salatası yapmaya karar verirsiniz.
  2. Her salatanın başlangıçtaki "temsilcisi" olarak masadan rastgele 3 meyve seçersiniz.
  3. Şimdi masanın etrafında dolaşır ve her meyveyi en çok benzediği temsilciye sahip salataya atarsınız. Örneğin elmalar armutlarla, portakallar mandalinalarla, muzlar plantainlerle eşleşebilir.
  4. Tüm meyveler atandıktan sonra, her meyve salatasının yeni "merkezini" o gruptaki ortalama meyve özelliklerini (ör. boyut, renk, tat) hesaplayarak bulursunuz. Bu yeni merkezler güncellenmiş temsilciler olur.
  5. 3 ve 4. adımları birkaç kez tekrarlarsınız; meyveleri en benzer temsilciye atar ve gruplamalar artık değişmeyene kadar her seferinde temsilciyi güncellersiniz.

image4.png

Daha genel olarak şunları yaparsınız:

  1. Küme sayısını, k’yı seçin.
  2. Rastgele k nokta (boyutu 1 olan kümeler) seçin.
  3. Her nokta ile merkez arasındaki mesafeyi hesaplayın ve her veri noktasını en yakın kümeye atayın.
  4. Her küme için merkezi (ortalama konumu) hesaplayın.
  5. Kümeler değişmeyene ya da maksimum yineleme sayısına ulaşılana kadar 3–4. adımları tekrarlayın.

k-means kümelerin merkezlerini rastgele seçtiği için, algoritmanın kullanıcı tarafından belirlenen sayıda kez çalıştırılması gerekir. Böylece, bir model kalite ölçütünü en aza indirerek en iyi çözüme ulaşılır. Bu ölçüt, her küme için veri noktaları ile ilgili merkezin arasındaki mesafelerin toplamı olan küme içi kareler toplamı (WCSS) olarak adlandırılır. Ölçütümüz ne kadar küçükse, kazanan modele o kadar çok yaklaşırız.

Airbnb İlanları Veri Seti

Bu eğitimin tüm içeriği, Cape Town’daki Airbnb kiralık ilanları etrafında dönecek olup DataLab’de mevcuttur. Veriler; ev sahipleri, fiyat, yorum sayısı, koordinatlar vb. gibi farklı türde bilgiler içerir. 

Veri seti tatil kiralamaları hakkında derin bilgiler sağlıyor gibi görünse de, hâlâ yanıtlanabilecek net sorular var. Örneğin, Airbnb’in Cape Town’daki platform ilanlarının segmentasyonunu araştırması için veri bilimcilerinden talepte bulunduğunu hayal edelim. 

Her şehir diğerinden farklıdır ve orada yaşayan insanların kültürüne bağlı olarak farklı gereksinimlere sahiptir. Bu şehirde kümelerin belirlenmesi, uygun Müşteri Sadakati Stratejileri ile mevcut müşterilerin memnuniyetini artırabilecek ve müşteri kaybını önleyebilecek yeni içgörüler çıkarmak için yararlı olabilir. Aynı zamanda, uygun kampanyalarla yeni insanları çekmek de kritik önemdedir. 

Airbnb verilerini görselleştirin

k-means uygulamadan önce, korelasyon matrisine bakarak değişkenler arasındaki ilişkiyi daha fazla incelemek isteriz. Görsel kolaylık için, basamakları iki ondalığa yuvarlıyoruz.

library(dplyr)
airbnb |>
  select(price, minimum_nights, number_of_reviews) |>
  cor(use = "pairwise.complete.obs") |>
  round(2)

image8.png

Çıktıdan, fiyat ile yorum sayısı arasında hafif bir negatif ilişki olduğu görülüyor: Fiyat yükseldikçe yorum sayısı düşüyor. Minimum gece sayısı ile yorum sayısı için de aynı durum var. Minimum gece sayısının fiyat üzerinde büyük bir etkisi olmadığından, fiyat ile yorum sayısının nasıl ilişkili olduğunu biraz daha araştırmak istiyoruz:

library(ggplot2)
ggplot(data, aes(number_of_reviews, price, color = room_type, shape = room_type)) +
    geom_point(alpha = 0.25) +
    xlab("Number of reviews") +
    ylab("Price")

image3.png

Saçılım grafiği, özellikle tüm evlerin konaklama maliyetinin, az sayıda yorum olduğunda daha yüksek olduğunu ve yorum sayısı arttıkça azalma eğilimi gösterdiğini ortaya koyuyor. 

Normalizasyon

Modeli uydurmadan önce yapılması gereken bir adım daha var. k-means, birimleri karşılaştırılamayan değişkenlere duyarlıdır ve bu da yanıltıcı sonuçlara yol açabilir. Bu örnekte, yorum sayıları onlarca veya yüzlerce iken fiyat on binler mertebesindedir. Herhangi bir veri işleme olmadan, fiyatlardaki farklar yorumlardaki farklardan daha büyükmüş gibi görünecektir; oysa bu değişkenlerin eşit muamele görmesini isteriz.

Bu sorunu önlemek için, değişkenlerin benzer bir ölçeğe dönüştürülmesi gerekir. Böylece mesafe metriği kullanılarak doğru şekilde karşılaştırılabilirler.

Bu meseleyi ele almak için farklı yöntemler vardır. En bilinen ve en çok kullanılan yöntem standardizasyondur; özellik değerinden ortalama değerin çıkarılması ve ardından standart sapmasına bölünmesiyle yapılır. Bu teknik, ortalaması 0 ve sapması 1 olan özellikler elde etmeyi sağlar. 

Değişkenleri scale() işleviyle ölçekleyebilirsiniz. Bu bir matris döndürdüğünden, kodun tidyverse yerine temel R tarzında yazılması daha temiz olur.

airbnb[, c("price", "number_of_reviews")] = scale(airbnb[, c("price", "number_of_reviews")])

Modeli uydurma ve değerlendirme

Artık k-means ile ilanların kümelerini belirleyebiliriz. Başlangıç için, 3 küme ve nstart’ı 20 olacak şekilde k-means çalıştırmayı deneyelim. Bu son parametre, k-means’in 20 farklı rastgele başlangıç atamasıyla çalıştırılmasını sağlar ve ardından R, toplam küme içi kareler toplamı en iyi olan sonucu otomatik olarak seçecektir. Ayrıca, kodu her çalıştırdığımızda aynı sonuçları tekrarlamak için bir tohum (seed) belirliyoruz.

# Get the two columns of interest
airbnb_2cols <- data[, c("price", "number_of_reviews")]

set.seed(123)
km.out <- kmeans(airbnb_2cols, centers = 3, nstart = 20)
km.out

Çıktı:

K-means clustering with 3 clusters of sizes 785, 37, 16069

Cluster means:
     price number_of_reviews
1 14264.102         5.9401274
2 83051.541         0.6756757
3  1589.879        18.2649200

Clustering vector:
   [1] 3 3 3 3 3 3 3 3 1 3 3 3 3 3 3 3 3 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
  [37] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
  [73] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
 [109] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 3 3 3 3 3 3 3 3 3 3 3 3 3
 [145] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 3 3
...
[16777] 3 3 3 3 3 3 3 3 3 3 1 3 3 1 3 1 3 3 3 3 3 1 3 3 3 3 3 3 3 3 1 3 3 3 3 3
[16813] 3 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 3
[16849] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 3 3 3 3 3 3 3 3 3 3 3
[16885] 3 3 3 3 3 3 3

Within cluster sum of squares by cluster:
[1] 41529148852 49002793251 33286433394
(between_SS / total_SS =  74.5 %)

Available components:

[1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
[6] "betweenss"    "size"         "iter"         "ifault"

Çıktıdan, boyutları 785, 37 ve 16069 olan üç farklı küme bulunduğunu gözlemleyebiliriz. Her küme için, gözlemlerin merkezlere olan kareli mesafeleri hesaplanır. Böylece, her gözlem üç kümeden birine atanacaktır. 

İyi bir sonuç gibi görünse de, en iyi modeli bulmanın yolu farklı sayıda kümeye sahip farklı modelleri denemektir. Bu nedenle, tek kümeli bir modelden başlayıp iki kümeli bir modelle devam etmeli ve böyle sürdürmeliyiz. Tüm bu süreç, x ekseninde küme sayısının, y ekseninde ise WCSS’in çizildiği, “scree plot” adı verilen bir grafikle izlenmelidir. 

Bu vaka çalışmasında, her biri farklı sayıda kümeye sahip olacak şekilde 10 k-means modeli kuruyoruz ve maksimum 10 kümeye ulaşıyoruz. Ayrıca, veri setinin yalnızca bir kısmını kullanacağız; yani yalnızca fiyat ve yorum sayısını dahil edeceğiz. Scree grafiğini çizmek için, tüm modellerin toplam küme içi kareler toplamını wss değişkenine kaydetmemiz gerekir.

# Decide how many clusters to look at
n_clusters <- 10

# Initialize total within sum of squares error: wss
wss <- numeric(n_clusters)

set.seed(123)

# Look over 1 to n possible clusters
for (i in 1:n) {
  # Fit the model: km.out
  km.out <- kmeans(airbnb_2cols, centers = i, nstart = 20)
  # Save the within cluster sum of squares
  wss[i] <- km.out$tot.withinss
}

# Produce a scree plot
wss_df <- tibble(clusters = 1:n, wss = wss)
 
scree_plot <- ggplot(wss_df, aes(x = clusters, y = wss, group = 1)) +
    geom_point(size = 4)+
    geom_line() +
    scale_x_continuous(breaks = c(2, 4, 6, 8, 10)) +
    xlab('Number of clusters')
scree_plot

image6.png

Scree grafiğine bakarak, küme sayısı arttıkça toplam küme içi kareler toplamının azaldığını fark edebiliriz. Kümelerin sayısını seçme ölçütü, bir dirsek (elbow) bulmaktır; yani yeni bir küme ekledikten sonra WCSS’in çok daha yavaş azaldığı noktayı tespit etmektir. Bu durumda çok net değil, bu yüzden daha iyi bir fikir edinmek için yatay çizgiler ekleyeceğiz:

scree_plot +
    geom_hline(
        yintercept = wss, 
        linetype = 'dashed', 
        col = c(rep('#000000',4),'#FF0000', rep('#000000', 5))
    )

image7.png

Tekrar bakarsanız, karar vermek önceye göre çok daha net, değil mi? Bu görselleştirmeden, en iyi seçimin küme sayısını 5 olarak belirlemek olduğunu söyleyebiliriz. k=5’ten sonra modellerdeki iyileşmeler keskin şekilde azalıyor gibi görünüyor. 

# Select number of clusters
k <- 5
set.seed(123)
# Build model with k clusters: km.out
km.out <- kmeans(airbnb_2cols, centers = k, nstart = 20)

Fiyat ile yorum sayısı arasındaki saçılım grafiğini yeniden görselleştirmeyi deneyebiliriz. Noktaları küme kimliğine göre de renklendiriyoruz:

data$cluster_id <- factor(km.out$cluster)
ggplot(data, aes(number_of_reviews, price, color = cluster_id)) +
    geom_point(alpha = 0.25) +
    xlab("Number of reviews") +
    ylab("Price")

image2.png

Şunları gözlemleyebiliriz:

  • Yüksek fiyatlı ve düşük yorum sayısına sahip az sayıda ilan var; yeşil ve fuşya renkle gösteriliyorlar
  • Ayrıca hem düşük fiyatlı hem de az yorumlu veri noktalarından oluşan bir grup var; kırmızıyla işaretlenmiş
  • Bundan sonra, yorum sayısı arttıkça fiyatın dengeleniyor gibi göründüğünü söyleyebiliriz.

K-Means ne zaman başarısız olur?

Dikkat edin, k-means basit ve uygulaması kolaydır, ancak verileri gruplara ayırmak için her zaman en iyi seçim olmayabilir ve başarısız olabilir. Kümelerin küresel (spherical) olduğu varsayımı vardır ve bu durumlarda iyi iş çıkarır; ancak farklı boyut ve yoğunluktaki gruplar bu algoritma tarafından iyi yakalanma eğiliminde değildir. 

Bu koşullar sağlanmadığında, DBSCAN ve BIRCH gibi alternatif yaklaşımlar tercih edilmelidir. Makine Öğrenmesinde Kümeleme: 5 Temel Kümeleme Algoritması, derinlemesine incelemek isterseniz kümeleme yaklaşımlarına harika bir genel bakış sunar.

Bir Sonraki Seviyeye Taşıyın

k-means, her ne kadar her durumda mükemmel olmasa da, farklı alt grupları belirlemek için en çok kullanılan kümeleme algoritmalarından biri olmaya devam ediyor. Artık bunu R ile diğer vaka çalışmalarında uygulayacak bilgiye sahipsiniz. 

Bu yöntemi daha derinlemesine incelemek isterseniz, R’de Gözetimsiz Öğrenme kursuna göz atın. Ayrıca, kapsamlı bir kümeleme yaklaşımı genel görünümü için R’de Küme Analizi ve Python’da Hiyerarşik Kümelemeye Giriş de mevcut; k-means verilerinizden anlamlı içgörüler sunmakta yetersiz kaldığında yararlı olabilir. R ile gözetimli modellere de bakmak isterseniz, bu kurs önerilir!

Eugenia Anello

Yazar

Eugenia Anello

Veri Bilimci - CRIF

Konular

İlgili