Kursus
K-means adalah teknik machine learning tanpa pengawasan yang populer untuk mengidentifikasi klaster (kelompok titik data yang serupa) dalam data. Dalam tutorial ini, Anda akan mempelajari klasterisasi k-means di R menggunakan tidymodels, ggplot2, dan ggmap. Kita akan membahas:
- cara kerja algoritma klasterisasi k-means
- cara memvisualisasikan data untuk menentukan apakah data tersebut cocok untuk diklaster
- studi kasus pelatihan dan penyetelan model klasterisasi k-means menggunakan dataset ulasan Airbnb
Sebelum masuk lebih dalam, kami sarankan Anda menyegarkan kembali dasar-dasar Pemrograman R, seperti vektor dan data frame. Jika Anda sudah siap, lewati saja dan mari mulai!
Gambaran Umum Klasterisasi k-Means
Model klasterisasi bertujuan mengelompokkan data ke dalam “klaster” atau kelompok yang berbeda. Ini dapat digunakan sebagai analisis tersendiri, atau dapat digunakan sebagai fitur dalam algoritma pembelajaran terawasi.

Di sisi kiri diagram di atas, kita dapat melihat 2 set titik yang berbeda yang tidak berlabel dan diwarnai sebagai titik data yang serupa. Memasang model k-means pada data ini (sisi kanan) dapat mengungkapkan 2 kelompok yang berbeda (ditunjukkan dalam dua lingkaran dan warna yang berbeda).
Dalam dua dimensi, manusia mudah membagi klaster-klaster ini, tetapi dengan lebih banyak dimensi, Anda perlu menggunakan model.
Algoritma k-means
Bayangkan Anda ingin membuat beberapa salad buah, masing-masing terdiri dari buah-buahan yang serupa.
- Anda memutuskan jumlah salad buah yang ingin dibuat (k). Misalnya, Anda memutuskan membuat 3 salad buah.
- Anda secara acak memilih 3 buah dari meja sebagai "perwakilan" awal untuk setiap salad.
- Sekarang, Anda mengelilingi meja dan menetapkan setiap buah ke salad yang perwakilannya paling mirip. Misalnya, apel mungkin digabungkan dengan pir, jeruk dengan jeruk keprok, dan pisang dengan pisang tanduk.
- Setelah semua buah ditetapkan, Anda mencari "pusat" baru setiap salad buah dengan menghitung rata-rata karakteristik buah di setiap grup (misalnya ukuran, warna, rasa). Pusat baru ini menjadi perwakilan yang diperbarui.
- Anda mengulangi langkah 3 dan 4 beberapa kali, menetapkan buah ke perwakilan yang paling mirip dan memperbarui perwakilan setiap kali hingga pengelompokan tidak lagi berubah.

Secara umum, Anda:
- Memilih jumlah klaster, k.
- Memilih k titik (klaster berukuran 1) secara acak.
- Menghitung jarak antara setiap titik dan centroid lalu menetapkan tiap titik data ke klaster terdekat.
- Menghitung centroid (posisi rata-rata) untuk setiap klaster.
- Terus mengulangi langkah 3–4 hingga klaster tidak berubah atau jumlah iterasi maksimum tercapai.
Karena k-means memilih pusat klaster secara acak, algoritme ini perlu dijalankan beberapa kali, jumlahnya ditetapkan oleh pengguna. Dengan cara ini, solusi terbaik akan dicapai dengan meminimalkan ukuran kualitas model. Ukuran ini disebut total within-cluster sum of squares (WCSS), yaitu jumlah jarak antara titik data dan centroid yang sesuai untuk setiap klaster. Semakin kecil ukuran kualitas model, semakin besar kemungkinan kita memperoleh model terbaik.
Dataset Listing Airbnb
Seluruh konten tutorial ini berpusat pada listing sewa Airbnb di Cape Town, tersedia di DataLab. Data berisi berbagai jenis informasi, seperti host, harga, jumlah ulasan, koordinat, dan lain-lain.
Meskipun dataset tampak memberikan informasi mendalam tentang sewa liburan, masih ada beberapa pertanyaan jelas yang bisa dijawab. Misalnya, bayangkan Airbnb meminta data scientist-nya menyelidiki segmentasi listing dalam platform ini di Cape Town.
Setiap kota berbeda satu sama lain dan memiliki kebutuhan berbeda bergantung pada budaya masyarakatnya. Identifikasi klaster di kota ini dapat berguna untuk mengekstrak wawasan baru, yang dapat meningkatkan kepuasan pelanggan saat ini melalui Strategi Loyalitas Pelanggan yang tepat, sehingga menghindari churn. Pada saat yang sama, penting juga untuk menarik orang baru dengan promosi yang sesuai.
Memvisualisasikan data Airbnb
Sebelum menerapkan k-means, kami ingin menyelidiki lebih jauh hubungan antarvariabel dengan melihat matriks korelasi. Demi kemudahan tampilan, kami membulatkan digit hingga dua angka desimal.
library(dplyr)
airbnb |>
select(price, minimum_nights, number_of_reviews) |>
cor(use = "pairwise.complete.obs") |>
round(2)

Dari output, tampaknya ada hubungan negatif kecil antara harga dan jumlah ulasan: Semakin tinggi harga, semakin rendah jumlah ulasan. Hal yang sama untuk minimum nights dan jumlah ulasan. Karena minimum nights tidak berdampak besar pada harga, kita ingin menyelidiki lebih lanjut bagaimana harga dan jumlah ulasan saling terkait:
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")

Scatterplot menunjukkan bahwa biaya akomodasi, khususnya rumah seutuhnya, lebih tinggi ketika jumlah ulasannya sedikit, dan tampak menurun saat jumlah ulasan meningkat.
Normalisasi
Sebelum memasang model, ada satu langkah lagi. k-means sensitif terhadap variabel yang memiliki satuan tak sebanding, yang dapat menghasilkan hasil menyesatkan. Pada contoh ini, jumlah ulasan bernilai puluhan atau ratusan, tetapi harga bernilai puluhan ribu. Tanpa pemrosesan data, perbedaan harga akan tampak lebih besar daripada perbedaan ulasan, padahal kita ingin variabel-variabel ini diperlakukan setara.
Untuk menghindari masalah ini, variabel perlu ditransformasikan agar berada pada skala yang serupa. Dengan begitu, variabel dapat dibandingkan dengan benar menggunakan metrik jarak.
Ada berbagai metode untuk mengatasi isu ini. Yang paling dikenal dan banyak digunakan adalah standarisasi, yaitu mengurangkan nilai rata-rata dari nilai fitur lalu membaginya dengan simpangan baku. Teknik ini menghasilkan fitur dengan mean 0 dan deviasi 1.
Anda dapat menskalakan variabel dengan fungsi scale(). Karena fungsi ini mengembalikan matriks, kode akan lebih rapi menggunakan gaya base R daripada tidyverse.
airbnb[, c("price", "number_of_reviews")] = scale(airbnb[, c("price", "number_of_reviews")])
Memasang dan mengevaluasi model
Kita akhirnya dapat mengidentifikasi klaster listing dengan k-means. Untuk memulai, mari mencoba menjalankan k-means dengan menetapkan 3 klaster dan nstart sama dengan 20. Parameter terakhir ini diperlukan untuk menjalankan k-means dengan 20 penetapan awal acak yang berbeda, lalu R akan otomatis memilih hasil terbaik berdasarkan total within-cluster sum of squares. Kita juga menetapkan seed agar hasil yang sama dapat direplikasi setiap kali menjalankan kode.
# 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
Output:
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"
Dari output, kita dapat mengamati bahwa tiga klaster berbeda telah ditemukan dengan ukuran 785, 37, dan 16069. Untuk tiap klaster, jarak kuadrat antara observasi ke centroid dihitung. Jadi, setiap observasi akan ditetapkan ke salah satu dari tiga klaster tersebut.
Meski tampak sebagai hasil yang baik, cara terbaik untuk menemukan model terbaik adalah mencoba berbagai model dengan jumlah klaster yang berbeda. Jadi, kita perlu mulai dari model dengan satu klaster, kemudian mencoba model dengan dua klaster, dan seterusnya. Seluruh prosedur ini perlu dilacak menggunakan representasi grafis yang disebut scree plot, di mana jumlah klaster diplot pada sumbu x, sedangkan WCSS pada sumbu y.
Dalam studi kasus ini, kita membangun 10 model k-means, masing-masing dengan jumlah klaster berbeda, hingga maksimum 10 klaster. Selain itu, kita hanya akan menggunakan sebagian dari dataset, yaitu hanya harga dan jumlah ulasan. Untuk memplot scree plot, kita perlu menyimpan total within-cluster sum of squares dari semua model ke dalam variabel wss.
# 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

Dengan melihat scree plot, kita dapat melihat bagaimana total within-cluster sum of squares menurun seiring bertambahnya jumlah klaster. Kriteria untuk memilih jumlah klaster adalah menemukan siku (elbow) sehingga Anda dapat menemukan titik di mana WCSS menurun jauh lebih lambat setelah menambah satu klaster lagi. Dalam kasus ini, tidak terlalu jelas, jadi kita akan menambahkan garis horizontal untuk mendapatkan gambaran yang lebih baik:
scree_plot +
geom_hline(
yintercept = wss,
linetype = 'dashed',
col = c(rep('#000000',4),'#FF0000', rep('#000000', 5))
)

Jika Anda melihat lagi, keputusan yang harus diambil menjadi jauh lebih jelas, bukan? Dari visualisasi ini, kita dapat mengatakan bahwa pilihan terbaik adalah menetapkan jumlah klaster sama dengan 5. Setelah k=5, peningkatan model tampak menurun tajam.
# 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)
Kita dapat kembali memvisualisasikan scatterplot antara harga dan jumlah ulasan. Kita juga memberi warna pada titik berdasarkan id klaster:
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")

Kita dapat mengamati bahwa:
- Ada beberapa listing dengan harga tinggi dan ulasan rendah, berwarna hijau dan fuchsia
- Ada juga sekelompok titik data dengan harga dan ulasan sama-sama rendah, ditandai merah
- Setelah itu, harga tampak stabil begitu jumlah ulasan meningkat.
Kapan K-Means akan gagal?
Harap perhatikan bahwa k-means sederhana dan mudah diterapkan, namun tidak selalu pilihan terbaik untuk membagi data ke dalam kelompok karena bisa gagal. Ada asumsi bahwa klaster berbentuk sferis dan algoritme bekerja baik untuk kasus ini, sementara kelompok dengan ukuran dan kepadatan berbeda cenderung tidak tertangkap dengan baik oleh algoritme ini.
Saat kondisi ini tidak terpenuhi, lebih baik mencari pendekatan alternatif, seperti DBSCAN dan BIRCH. Clustering in Machine Learning: 5 Essential Clustering Algorithms memberikan gambaran hebat tentang pendekatan klasterisasi jika Anda ingin menggali lebih dalam.
Naik ke Tingkat Berikutnya
Kita dapat menyimpulkan bahwa k-means tetap menjadi salah satu algoritma klasterisasi yang paling banyak digunakan untuk mengidentifikasi subkelompok yang berbeda, meskipun tidak selalu sempurna di semua situasi. Sekarang, Anda memiliki pengetahuan untuk menerapkannya dengan R dalam studi kasus lain
Jika Anda ingin mempelajari metode ini lebih dalam, lihat kursus Unsupervised Learning in R. Ada juga Cluster Analysis in R dan An Introduction to Hierarchical Clustering in Python untuk mendapatkan gambaran lengkap tentang pendekatan klasterisasi yang tersedia, yang dapat berguna saat k-means tidak cukup untuk memberikan wawasan bermakna dari data Anda. Jika Anda juga ingin mengeksplorasi model terawasi dengan R, kursus ini direkomendasikan!

