You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
639 lines
28 KiB
639 lines
28 KiB
{
|
|
"nbformat": 4,
|
|
"nbformat_minor": 0,
|
|
"metadata": {
|
|
"anaconda-cloud": "",
|
|
"kernelspec": {
|
|
"display_name": "R",
|
|
"language": "R",
|
|
"name": "ir"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": "r",
|
|
"file_extension": ".r",
|
|
"mimetype": "text/x-r-source",
|
|
"name": "R",
|
|
"pygments_lexer": "r",
|
|
"version": "3.4.1"
|
|
},
|
|
"colab": {
|
|
"name": "lesson_14.ipynb",
|
|
"provenance": [],
|
|
"collapsed_sections": [],
|
|
"toc_visible": true
|
|
},
|
|
"coopTranslator": {
|
|
"original_hash": "ad65fb4aad0a156b42216e4929f490fc",
|
|
"translation_date": "2025-09-04T08:15:18+00:00",
|
|
"source_file": "5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb",
|
|
"language_code": "id"
|
|
}
|
|
},
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "GULATlQXLXyR"
|
|
},
|
|
"source": [
|
|
"## Jelajahi Klasterisasi K-Means menggunakan R dan Prinsip Data Tidy\n",
|
|
"\n",
|
|
"### [**Kuis sebelum pelajaran**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/29/)\n",
|
|
"\n",
|
|
"Dalam pelajaran ini, Anda akan belajar cara membuat klaster menggunakan paket Tidymodels dan paket lainnya dalam ekosistem R (kita akan menyebutnya teman 🧑🤝🧑), serta dataset musik Nigeria yang telah Anda impor sebelumnya. Kita akan membahas dasar-dasar K-Means untuk Klasterisasi. Ingatlah bahwa, seperti yang Anda pelajari di pelajaran sebelumnya, ada banyak cara untuk bekerja dengan klaster, dan metode yang Anda gunakan bergantung pada data Anda. Kita akan mencoba K-Means karena ini adalah teknik klasterisasi yang paling umum. Mari kita mulai!\n",
|
|
"\n",
|
|
"Istilah yang akan Anda pelajari:\n",
|
|
"\n",
|
|
"- Skor Silhouette\n",
|
|
"\n",
|
|
"- Metode Elbow\n",
|
|
"\n",
|
|
"- Inersia\n",
|
|
"\n",
|
|
"- Variansi\n",
|
|
"\n",
|
|
"### **Pendahuluan**\n",
|
|
"\n",
|
|
"[Klasterisasi K-Means](https://wikipedia.org/wiki/K-means_clustering) adalah metode yang berasal dari domain pemrosesan sinyal. Metode ini digunakan untuk membagi dan mengelompokkan data ke dalam `k klaster` berdasarkan kesamaan fitur mereka.\n",
|
|
"\n",
|
|
"Klaster dapat divisualisasikan sebagai [diagram Voronoi](https://wikipedia.org/wiki/Voronoi_diagram), yang mencakup sebuah titik (atau 'seed') dan wilayah yang sesuai.\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/voronoi.png\"\n",
|
|
" width=\"500\"/>\n",
|
|
" <figcaption>Infografis oleh Jen Looper</figcaption>\n",
|
|
"\n",
|
|
"Klasterisasi K-Means memiliki langkah-langkah berikut:\n",
|
|
"\n",
|
|
"1. Ilmuwan data memulai dengan menentukan jumlah klaster yang diinginkan untuk dibuat.\n",
|
|
"\n",
|
|
"2. Selanjutnya, algoritma secara acak memilih K observasi dari dataset untuk dijadikan pusat awal klaster (yaitu, centroid).\n",
|
|
"\n",
|
|
"3. Kemudian, setiap observasi yang tersisa diberikan ke centroid terdekatnya.\n",
|
|
"\n",
|
|
"4. Selanjutnya, rata-rata baru dari setiap klaster dihitung dan centroid dipindahkan ke rata-rata tersebut.\n",
|
|
"\n",
|
|
"5. Setelah pusat-pusat diperbarui, setiap observasi diperiksa lagi untuk melihat apakah mungkin lebih dekat ke klaster yang berbeda. Semua objek ditugaskan ulang menggunakan rata-rata klaster yang diperbarui. Langkah penugasan klaster dan pembaruan centroid diulang secara iteratif hingga penugasan klaster berhenti berubah (yaitu, ketika konvergensi tercapai). Biasanya, algoritma berhenti ketika setiap iterasi baru menghasilkan pergerakan centroid yang sangat kecil dan klaster menjadi statis.\n",
|
|
"\n",
|
|
"<div>\n",
|
|
"\n",
|
|
"> Perlu dicatat bahwa karena proses pengacakan observasi awal k yang digunakan sebagai centroid awal, kita bisa mendapatkan hasil yang sedikit berbeda setiap kali kita menerapkan prosedur ini. Oleh karena itu, sebagian besar algoritma menggunakan beberapa *random starts* dan memilih iterasi dengan WCSS terendah. Karena itu, sangat disarankan untuk selalu menjalankan K-Means dengan beberapa nilai *nstart* untuk menghindari *optimum lokal yang tidak diinginkan.*\n",
|
|
"\n",
|
|
"</div>\n",
|
|
"\n",
|
|
"Animasi pendek ini menggunakan [karya seni](https://github.com/allisonhorst/stats-illustrations) dari Allison Horst menjelaskan proses klasterisasi:\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/kmeans.gif\"\n",
|
|
" width=\"550\"/>\n",
|
|
" <figcaption>Karya seni oleh @allison_horst</figcaption>\n",
|
|
"\n",
|
|
"Pertanyaan mendasar yang muncul dalam klasterisasi adalah: bagaimana Anda tahu berapa banyak klaster yang harus digunakan untuk memisahkan data Anda? Salah satu kelemahan menggunakan K-Means adalah Anda perlu menentukan `k`, yaitu jumlah `centroid`. Untungnya, `metode elbow` membantu memperkirakan nilai awal yang baik untuk `k`. Anda akan mencobanya sebentar lagi.\n",
|
|
"\n",
|
|
"### \n",
|
|
"\n",
|
|
"**Prasyarat**\n",
|
|
"\n",
|
|
"Kita akan melanjutkan dari tempat kita berhenti di [pelajaran sebelumnya](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb), di mana kita menganalisis dataset, membuat banyak visualisasi, dan memfilter dataset ke observasi yang menarik. Pastikan untuk memeriksanya!\n",
|
|
"\n",
|
|
"Kita memerlukan beberapa paket untuk menyelesaikan modul ini. Anda dapat menginstalnya dengan: `install.packages(c('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork'))`\n",
|
|
"\n",
|
|
"Sebagai alternatif, skrip di bawah ini akan memeriksa apakah Anda memiliki paket yang diperlukan untuk menyelesaikan modul ini dan menginstalnya untuk Anda jika ada yang belum terpasang.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "ah_tBi58LXyi"
|
|
},
|
|
"source": [
|
|
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\n",
|
|
"\n",
|
|
"pacman::p_load('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork')\n"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "7e--UCUTLXym"
|
|
},
|
|
"source": [
|
|
"Mari kita mulai!\n",
|
|
"\n",
|
|
"## 1. Menari dengan data: Persempit ke 3 genre musik paling populer\n",
|
|
"\n",
|
|
"Ini adalah rangkuman dari apa yang telah kita lakukan di pelajaran sebelumnya. Mari kita olah dan analisis beberapa data!\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "Ycamx7GGLXyn"
|
|
},
|
|
"source": [
|
|
"# Load the core tidyverse and make it available in your current R session\n",
|
|
"library(tidyverse)\n",
|
|
"\n",
|
|
"# Import the data into a tibble\n",
|
|
"df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/5-Clustering/data/nigerian-songs.csv\", show_col_types = FALSE)\n",
|
|
"\n",
|
|
"# Narrow down to top 3 popular genres\n",
|
|
"nigerian_songs <- df %>% \n",
|
|
" # Concentrate on top 3 genres\n",
|
|
" filter(artist_top_genre %in% c(\"afro dancehall\", \"afropop\",\"nigerian pop\")) %>% \n",
|
|
" # Remove unclassified observations\n",
|
|
" filter(popularity != 0)\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"# Visualize popular genres using bar plots\n",
|
|
"theme_set(theme_light())\n",
|
|
"nigerian_songs %>%\n",
|
|
" count(artist_top_genre) %>%\n",
|
|
" ggplot(mapping = aes(x = artist_top_genre, y = n,\n",
|
|
" fill = artist_top_genre)) +\n",
|
|
" geom_col(alpha = 0.8) +\n",
|
|
" paletteer::scale_fill_paletteer_d(\"ggsci::category10_d3\") +\n",
|
|
" ggtitle(\"Top genres\") +\n",
|
|
" theme(plot.title = element_text(hjust = 0.5))\n"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "b5h5zmkPLXyp"
|
|
},
|
|
"source": [
|
|
"🤩 Itu berjalan dengan baik!\n",
|
|
"\n",
|
|
"## 2. Eksplorasi data lebih lanjut.\n",
|
|
"\n",
|
|
"Seberapa bersih data ini? Mari kita periksa outlier menggunakan boxplot. Kita akan fokus pada kolom numerik dengan sedikit outlier (meskipun Anda bisa membersihkan outlier tersebut). Boxplot dapat menunjukkan rentang data dan membantu memilih kolom mana yang akan digunakan. Perlu dicatat, boxplot tidak menunjukkan variansi, elemen penting dari data yang baik untuk pengelompokan. Silakan lihat [diskusi ini](https://stats.stackexchange.com/questions/91536/deduce-variance-from-boxplot) untuk bacaan lebih lanjut.\n",
|
|
"\n",
|
|
"[Boxplot](https://en.wikipedia.org/wiki/Box_plot) digunakan untuk menggambarkan distribusi data `numerik` secara grafis, jadi mari kita mulai dengan *memilih* semua kolom numerik bersama dengan genre musik populer.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "HhNreJKLLXyq"
|
|
},
|
|
"source": [
|
|
"# Select top genre column and all other numeric columns\n",
|
|
"df_numeric <- nigerian_songs %>% \n",
|
|
" select(artist_top_genre, where(is.numeric)) \n",
|
|
"\n",
|
|
"# Display the data\n",
|
|
"df_numeric %>% \n",
|
|
" slice_head(n = 5)\n"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "uYXrwJRaLXyq"
|
|
},
|
|
"source": [
|
|
"Lihat bagaimana pembantu seleksi `where` membuat ini menjadi mudah 💁? Jelajahi fungsi-fungsi lainnya [di sini](https://tidyselect.r-lib.org/).\n",
|
|
"\n",
|
|
"Karena kita akan membuat boxplot untuk setiap fitur numerik dan ingin menghindari penggunaan loop, mari kita ubah format data kita menjadi format *lebih panjang* yang memungkinkan kita memanfaatkan `facets` - subplot yang masing-masing menampilkan satu subset data.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "gd5bR3f8LXys"
|
|
},
|
|
"source": [
|
|
"# Pivot data from wide to long\n",
|
|
"df_numeric_long <- df_numeric %>% \n",
|
|
" pivot_longer(!artist_top_genre, names_to = \"feature_names\", values_to = \"values\") \n",
|
|
"\n",
|
|
"# Print out data\n",
|
|
"df_numeric_long %>% \n",
|
|
" slice_head(n = 15)\n"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "-7tE1swnLXyv"
|
|
},
|
|
"source": [
|
|
"Lebih panjang lagi! Sekarang saatnya untuk beberapa `ggplots`! Jadi, `geom` apa yang akan kita gunakan?\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "r88bIsyuLXyy"
|
|
},
|
|
"source": [
|
|
"# Make a box plot\n",
|
|
"df_numeric_long %>% \n",
|
|
" ggplot(mapping = aes(x = feature_names, y = values, fill = feature_names)) +\n",
|
|
" geom_boxplot() +\n",
|
|
" facet_wrap(~ feature_names, ncol = 4, scales = \"free\") +\n",
|
|
" theme(legend.position = \"none\")\n"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "EYVyKIUELXyz"
|
|
},
|
|
"source": [
|
|
"Easy-gg!\n",
|
|
"\n",
|
|
"Sekarang kita bisa melihat bahwa data ini agak berisik: dengan mengamati setiap kolom sebagai boxplot, kamu bisa melihat adanya outlier. Kamu bisa menelusuri dataset dan menghapus outlier tersebut, tetapi itu akan membuat data menjadi sangat minimal.\n",
|
|
"\n",
|
|
"Untuk saat ini, mari kita pilih kolom mana yang akan kita gunakan untuk latihan clustering kita. Mari pilih kolom numerik dengan rentang yang serupa. Kita bisa mengubah `artist_top_genre` menjadi numerik, tetapi untuk sekarang kita akan mengabaikannya.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "-wkpINyZLXy0"
|
|
},
|
|
"source": [
|
|
"# Select variables with similar ranges\n",
|
|
"df_numeric_select <- df_numeric %>% \n",
|
|
" select(popularity, danceability, acousticness, loudness, energy) \n",
|
|
"\n",
|
|
"# Normalize data\n",
|
|
"# df_numeric_select <- scale(df_numeric_select)\n"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "D7dLzgpqLXy1"
|
|
},
|
|
"source": [
|
|
"## 3. Menghitung klasterisasi k-means di R\n",
|
|
"\n",
|
|
"Kita dapat menghitung k-means di R menggunakan fungsi bawaan `kmeans`, lihat `help(\"kmeans()\")`. Fungsi `kmeans()` menerima data frame dengan semua kolom numerik sebagai argumen utamanya.\n",
|
|
"\n",
|
|
"Langkah pertama saat menggunakan klasterisasi k-means adalah menentukan jumlah klaster (k) yang akan dihasilkan dalam solusi akhir. Kita tahu ada 3 genre lagu yang telah kita pisahkan dari dataset, jadi mari kita coba 3:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "uC4EQ5w7LXy5"
|
|
},
|
|
"source": [
|
|
"set.seed(2056)\n",
|
|
"# Kmeans clustering for 3 clusters\n",
|
|
"kclust <- kmeans(\n",
|
|
" df_numeric_select,\n",
|
|
" # Specify the number of clusters\n",
|
|
" centers = 3,\n",
|
|
" # How many random initial configurations\n",
|
|
" nstart = 25\n",
|
|
")\n",
|
|
"\n",
|
|
"# Display clustering object\n",
|
|
"kclust\n"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "hzfhscWrLXy-"
|
|
},
|
|
"source": [
|
|
"Objek kmeans berisi beberapa informasi yang dijelaskan dengan baik di `help(\"kmeans()\")`. Untuk saat ini, mari kita fokus pada beberapa hal. Kita melihat bahwa data telah dikelompokkan menjadi 3 klaster dengan ukuran 65, 110, 111. Outputnya juga mencakup pusat klaster (rata-rata) untuk 3 kelompok tersebut di 5 variabel.\n",
|
|
"\n",
|
|
"Vektor klaster adalah penugasan klaster untuk setiap observasi. Mari kita gunakan fungsi `augment` untuk menambahkan penugasan klaster ke dalam set data asli.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "0XwwpFGQLXy_"
|
|
},
|
|
"source": [
|
|
"# Add predicted cluster assignment to data set\n",
|
|
"augment(kclust, df_numeric_select) %>% \n",
|
|
" relocate(.cluster) %>% \n",
|
|
" slice_head(n = 10)\n"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "NXIVXXACLXzA"
|
|
},
|
|
"source": [
|
|
"Sempurna, kita baru saja membagi data kita menjadi 3 kelompok. Jadi, seberapa baik pengelompokan kita 🤷? Mari kita lihat `Silhouette score`.\n",
|
|
"\n",
|
|
"### **Silhouette score**\n",
|
|
"\n",
|
|
"[Analisis Silhouette](https://en.wikipedia.org/wiki/Silhouette_(clustering)) dapat digunakan untuk mempelajari jarak pemisahan antara kelompok-kelompok yang dihasilkan. Skor ini berkisar dari -1 hingga 1, dan jika skor mendekati 1, kelompok tersebut padat dan terpisah dengan baik dari kelompok lainnya. Nilai yang mendekati 0 menunjukkan kelompok yang saling tumpang tindih dengan sampel yang sangat dekat dengan batas keputusan kelompok tetangga. [sumber](https://dzone.com/articles/kmeans-silhouette-score-explained-with-python-exam).\n",
|
|
"\n",
|
|
"Metode rata-rata silhouette menghitung rata-rata silhouette dari pengamatan untuk berbagai nilai *k*. Skor rata-rata silhouette yang tinggi menunjukkan pengelompokan yang baik.\n",
|
|
"\n",
|
|
"Fungsi `silhouette` dalam paket cluster digunakan untuk menghitung rata-rata lebar silhouette.\n",
|
|
"\n",
|
|
"> Silhouette dapat dihitung dengan menggunakan [metrik jarak](https://en.wikipedia.org/wiki/Distance \"Distance\") apa pun, seperti [jarak Euclidean](https://en.wikipedia.org/wiki/Euclidean_distance \"Euclidean distance\") atau [jarak Manhattan](https://en.wikipedia.org/wiki/Manhattan_distance \"Manhattan distance\") yang telah kita bahas di [pelajaran sebelumnya](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb).\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "Jn0McL28LXzB"
|
|
},
|
|
"source": [
|
|
"# Load cluster package\n",
|
|
"library(cluster)\n",
|
|
"\n",
|
|
"# Compute average silhouette score\n",
|
|
"ss <- silhouette(kclust$cluster,\n",
|
|
" # Compute euclidean distance\n",
|
|
" dist = dist(df_numeric_select))\n",
|
|
"mean(ss[, 3])\n"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "QyQRn97nLXzC"
|
|
},
|
|
"source": [
|
|
"Skor kita adalah **.549**, jadi berada tepat di tengah. Ini menunjukkan bahwa data kita tidak terlalu cocok untuk jenis pengelompokan ini. Mari kita lihat apakah kita dapat mengonfirmasi dugaan ini secara visual. Paket [factoextra](https://rpkgs.datanovia.com/factoextra/index.html) menyediakan fungsi (`fviz_cluster()`) untuk memvisualisasikan pengelompokan.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "7a6Km1_FLXzD"
|
|
},
|
|
"source": [
|
|
"library(factoextra)\n",
|
|
"\n",
|
|
"# Visualize clustering results\n",
|
|
"fviz_cluster(kclust, df_numeric_select)\n"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "IBwCWt-0LXzD"
|
|
},
|
|
"source": [
|
|
"Tumpang tindih dalam kluster menunjukkan bahwa data kita tidak terlalu cocok untuk jenis pengelompokan ini, tetapi mari kita lanjutkan.\n",
|
|
"\n",
|
|
"## 4. Menentukan jumlah kluster yang optimal\n",
|
|
"\n",
|
|
"Pertanyaan mendasar yang sering muncul dalam pengelompokan K-Means adalah ini - tanpa label kelas yang diketahui, bagaimana kita tahu berapa banyak kluster yang harus digunakan untuk memisahkan data kita?\n",
|
|
"\n",
|
|
"Salah satu cara untuk mencoba mengetahuinya adalah dengan menggunakan sampel data untuk `membuat serangkaian model pengelompokan` dengan jumlah kluster yang meningkat (misalnya dari 1-10), dan mengevaluasi metrik pengelompokan seperti **Silhouette score.**\n",
|
|
"\n",
|
|
"Mari kita tentukan jumlah kluster yang optimal dengan menghitung algoritma pengelompokan untuk berbagai nilai *k* dan mengevaluasi **Within Cluster Sum of Squares** (WCSS). Total within-cluster sum of square (WCSS) mengukur kepadatan pengelompokan, dan kita ingin nilainya sekecil mungkin, dengan nilai yang lebih rendah menunjukkan bahwa titik data lebih dekat satu sama lain.\n",
|
|
"\n",
|
|
"Mari kita eksplorasi efek dari berbagai pilihan `k`, dari 1 hingga 10, pada pengelompokan ini.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "hSeIiylDLXzE"
|
|
},
|
|
"source": [
|
|
"# Create a series of clustering models\n",
|
|
"kclusts <- tibble(k = 1:10) %>% \n",
|
|
" # Perform kmeans clustering for 1,2,3 ... ,10 clusters\n",
|
|
" mutate(model = map(k, ~ kmeans(df_numeric_select, centers = .x, nstart = 25)),\n",
|
|
" # Farm out clustering metrics eg WCSS\n",
|
|
" glanced = map(model, ~ glance(.x))) %>% \n",
|
|
" unnest(cols = glanced)\n",
|
|
" \n",
|
|
"\n",
|
|
"# View clustering rsulsts\n",
|
|
"kclusts\n"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "m7rS2U1eLXzE"
|
|
},
|
|
"source": [
|
|
"Sekarang setelah kita memiliki total jumlah kuadrat dalam kluster (tot.withinss) untuk setiap algoritma pengelompokan dengan pusat *k*, kita menggunakan [metode siku](https://en.wikipedia.org/wiki/Elbow_method_(clustering)) untuk menemukan jumlah kluster yang optimal. Metode ini terdiri dari membuat plot WCSS sebagai fungsi dari jumlah kluster, dan memilih [siku kurva](https://en.wikipedia.org/wiki/Elbow_of_the_curve \"Siku kurva\") sebagai jumlah kluster yang akan digunakan.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "o_DjHGItLXzF"
|
|
},
|
|
"source": [
|
|
"set.seed(2056)\n",
|
|
"# Use elbow method to determine optimum number of clusters\n",
|
|
"kclusts %>% \n",
|
|
" ggplot(mapping = aes(x = k, y = tot.withinss)) +\n",
|
|
" geom_line(size = 1.2, alpha = 0.8, color = \"#FF7F0EFF\") +\n",
|
|
" geom_point(size = 2, color = \"#FF7F0EFF\")\n"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "pLYyt5XSLXzG"
|
|
},
|
|
"source": [
|
|
"Plot menunjukkan penurunan besar dalam WCSS (jadi *kekompakan* yang lebih besar) saat jumlah klaster meningkat dari satu ke dua, dan penurunan yang cukup terlihat lagi dari dua ke tiga klaster. Setelah itu, penurunan menjadi kurang signifikan, menghasilkan sebuah `elbow` 💪 pada grafik di sekitar tiga klaster. Ini adalah indikasi yang baik bahwa terdapat dua hingga tiga klaster data yang cukup terpisah dengan baik.\n",
|
|
"\n",
|
|
"Sekarang kita dapat melanjutkan dan mengekstrak model klastering di mana `k = 3`:\n",
|
|
"\n",
|
|
"> `pull()`: digunakan untuk mengekstrak satu kolom\n",
|
|
">\n",
|
|
"> `pluck()`: digunakan untuk mengindeks struktur data seperti daftar\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "JP_JPKBILXzG"
|
|
},
|
|
"source": [
|
|
"# Extract k = 3 clustering\n",
|
|
"final_kmeans <- kclusts %>% \n",
|
|
" filter(k == 3) %>% \n",
|
|
" pull(model) %>% \n",
|
|
" pluck(1)\n",
|
|
"\n",
|
|
"\n",
|
|
"final_kmeans\n"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "l_PDTu8tLXzI"
|
|
},
|
|
"source": [
|
|
"Bagus! Mari kita visualisasikan klaster yang telah diperoleh. Tertarik dengan interaktivitas menggunakan `plotly`?\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "dNcleFe-LXzJ"
|
|
},
|
|
"source": [
|
|
"# Add predicted cluster assignment to data set\n",
|
|
"results <- augment(final_kmeans, df_numeric_select) %>% \n",
|
|
" bind_cols(df_numeric %>% select(artist_top_genre)) \n",
|
|
"\n",
|
|
"# Plot cluster assignments\n",
|
|
"clust_plt <- results %>% \n",
|
|
" ggplot(mapping = aes(x = popularity, y = danceability, color = .cluster, shape = artist_top_genre)) +\n",
|
|
" geom_point(size = 2, alpha = 0.8) +\n",
|
|
" paletteer::scale_color_paletteer_d(\"ggthemes::Tableau_10\")\n",
|
|
"\n",
|
|
"ggplotly(clust_plt)\n"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "6JUM_51VLXzK"
|
|
},
|
|
"source": [
|
|
"Mungkin kita akan mengharapkan bahwa setiap kluster (diwakili oleh warna yang berbeda) memiliki genre yang berbeda (diwakili oleh bentuk yang berbeda).\n",
|
|
"\n",
|
|
"Mari kita lihat akurasi model.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "HdIMUGq7LXzL"
|
|
},
|
|
"source": [
|
|
"# Assign genres to predefined integers\n",
|
|
"label_count <- results %>% \n",
|
|
" group_by(artist_top_genre) %>% \n",
|
|
" mutate(id = cur_group_id()) %>% \n",
|
|
" ungroup() %>% \n",
|
|
" summarise(correct_labels = sum(.cluster == id))\n",
|
|
"\n",
|
|
"\n",
|
|
"# Print results \n",
|
|
"cat(\"Result:\", label_count$correct_labels, \"out of\", nrow(results), \"samples were correctly labeled.\")\n",
|
|
"\n",
|
|
"cat(\"\\nAccuracy score:\", label_count$correct_labels/nrow(results))\n"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "C50wvaAOLXzM"
|
|
},
|
|
"source": [
|
|
"Akurasi model ini tidak buruk, tetapi juga tidak terlalu baik. Mungkin data ini kurang cocok untuk K-Means Clustering. Data ini terlalu tidak seimbang, kurang berkorelasi, dan terdapat terlalu banyak variasi antar nilai kolom sehingga sulit untuk dikelompokkan dengan baik. Faktanya, klaster yang terbentuk kemungkinan besar sangat dipengaruhi atau terdistorsi oleh tiga kategori genre yang telah kita definisikan sebelumnya.\n",
|
|
"\n",
|
|
"Namun demikian, ini adalah proses pembelajaran yang cukup menarik!\n",
|
|
"\n",
|
|
"Dalam dokumentasi Scikit-learn, Anda dapat melihat bahwa model seperti ini, dengan klaster yang tidak terlalu jelas, memiliki masalah 'varian':\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/problems.png\"\n",
|
|
" width=\"500\"/>\n",
|
|
" <figcaption>Infografis dari Scikit-learn</figcaption>\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"## **Varian**\n",
|
|
"\n",
|
|
"Varian didefinisikan sebagai \"rata-rata dari kuadrat perbedaan terhadap Mean\" [sumber](https://www.mathsisfun.com/data/standard-deviation.html). Dalam konteks masalah clustering ini, varian mengacu pada data di mana angka-angka dalam dataset kita cenderung menyimpang terlalu jauh dari rata-rata.\n",
|
|
"\n",
|
|
"✅ Ini adalah momen yang tepat untuk memikirkan semua cara yang dapat Anda lakukan untuk mengatasi masalah ini. Modifikasi data sedikit lebih banyak? Gunakan kolom yang berbeda? Gunakan algoritma yang berbeda? Petunjuk: Cobalah [menyesuaikan skala data Anda](https://www.mygreatlearning.com/blog/learning-data-science-with-k-means-clustering/) untuk menormalkannya dan uji kolom lainnya.\n",
|
|
"\n",
|
|
"> Cobalah '[kalkulator varian](https://www.calculatorsoup.com/calculators/statistics/variance-calculator.php)' ini untuk memahami konsepnya lebih dalam.\n",
|
|
"\n",
|
|
"------------------------------------------------------------------------\n",
|
|
"\n",
|
|
"## **🚀Tantangan**\n",
|
|
"\n",
|
|
"Luangkan waktu dengan notebook ini, modifikasi parameter. Bisakah Anda meningkatkan akurasi model dengan membersihkan data lebih lanjut (misalnya, menghapus outlier)? Anda dapat menggunakan bobot untuk memberikan lebih banyak pengaruh pada sampel data tertentu. Apa lagi yang dapat Anda lakukan untuk menciptakan klaster yang lebih baik?\n",
|
|
"\n",
|
|
"Petunjuk: Cobalah untuk menyesuaikan skala data Anda. Ada kode yang dikomentari di notebook yang menambahkan skala standar untuk membuat kolom data lebih mirip satu sama lain dalam hal rentang. Anda akan menemukan bahwa meskipun skor siluet menurun, 'tikungan' pada grafik siku menjadi lebih halus. Hal ini terjadi karena membiarkan data tidak disesuaikan skala memungkinkan data dengan varian lebih kecil memiliki pengaruh lebih besar. Baca lebih lanjut tentang masalah ini [di sini](https://stats.stackexchange.com/questions/21222/are-mean-normalization-and-feature-scaling-needed-for-k-means-clustering/21226#21226).\n",
|
|
"\n",
|
|
"## [**Kuis setelah kuliah**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/30/)\n",
|
|
"\n",
|
|
"## **Tinjauan & Studi Mandiri**\n",
|
|
"\n",
|
|
"- Lihatlah Simulator K-Means [seperti ini](https://user.ceng.metu.edu.tr/~akifakkus/courses/ceng574/k-means/). Anda dapat menggunakan alat ini untuk memvisualisasikan titik data sampel dan menentukan centroid-nya. Anda dapat mengedit tingkat keacakan data, jumlah klaster, dan jumlah centroid. Apakah ini membantu Anda memahami bagaimana data dapat dikelompokkan?\n",
|
|
"\n",
|
|
"- Selain itu, lihat [handout tentang K-Means](https://stanford.edu/~cpiech/cs221/handouts/kmeans.html) dari Stanford.\n",
|
|
"\n",
|
|
"Ingin mencoba keterampilan clustering yang baru Anda pelajari pada dataset yang cocok untuk K-Means clustering? Silakan lihat:\n",
|
|
"\n",
|
|
"- [Latih dan Evaluasi Model Clustering](https://rpubs.com/eR_ic/clustering) menggunakan Tidymodels dan teman-temannya\n",
|
|
"\n",
|
|
"- [Analisis Klaster K-Means](https://uc-r.github.io/kmeans_clustering), Panduan Pemrograman R UC Business Analytics\n",
|
|
"\n",
|
|
"- [K-Means clustering dengan prinsip data yang rapi](https://www.tidymodels.org/learn/statistics/k-means/)\n",
|
|
"\n",
|
|
"## **Tugas**\n",
|
|
"\n",
|
|
"[Cobalah metode clustering yang berbeda](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/2-K-Means/assignment.md)\n",
|
|
"\n",
|
|
"## TERIMA KASIH KEPADA:\n",
|
|
"\n",
|
|
"[Jen Looper](https://www.twitter.com/jenlooper) atas pembuatan versi Python asli dari modul ini ♥️\n",
|
|
"\n",
|
|
"[`Allison Horst`](https://twitter.com/allison_horst/) atas ilustrasi luar biasa yang membuat R lebih ramah dan menarik. Temukan lebih banyak ilustrasi di [galerinya](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n",
|
|
"\n",
|
|
"Selamat Belajar,\n",
|
|
"\n",
|
|
"[Eric](https://twitter.com/ericntay), Gold Microsoft Learn Student Ambassador.\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/r_learners_sm.jpeg\"\n",
|
|
" width=\"500\"/>\n",
|
|
" <figcaption>Karya seni oleh @allison_horst</figcaption>\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n---\n\n**Penafian**: \nDokumen ini telah diterjemahkan menggunakan layanan penerjemahan AI [Co-op Translator](https://github.com/Azure/co-op-translator). Meskipun kami berupaya untuk memberikan hasil yang akurat, harap diperhatikan bahwa terjemahan otomatis mungkin mengandung kesalahan atau ketidakakuratan. Dokumen asli dalam bahasa aslinya harus dianggap sebagai sumber yang berwenang. Untuk informasi yang bersifat kritis, disarankan menggunakan jasa penerjemahan manusia profesional. Kami tidak bertanggung jawab atas kesalahpahaman atau penafsiran yang keliru yang timbul dari penggunaan terjemahan ini.\n"
|
|
]
|
|
}
|
|
]
|
|
} |