Machine learning bertujuan untuk membuat mesin yang belajar berdasarkan data.
LBB ini akan menganalisa pengelompokan berdasarkan karakteristik fitur-fitur audio dalam lagu yang diputar di Spotify, menggunakan data dari link berikut: https://www.kaggle.com/zaheenhamidani/ultimate-spotify-tracks-db
he spotify API allows us to create a simple server-side application that accesses user related data from the Spotify app. It also gives you access to information that is not available on the app, such as artist popularity, song metrics, album cover images, etc. It allows you to create, delete and modify existing playlists in a user’s account.
The goal of this project is to use a clustering algorithm to break down a large playlist into smaller ones. For this, song metrics such as ‘danceability’, ‘valence’, ‘tempo’, ‘liveness’, ‘speechiness’ are used.
In this project, we employ two main techniques to analyze and categorize songs based on their audio characteristics in the Spotify dataset. The first technique is k-means clustering, which groups songs with similar audio features into clusters. This step allows us to identify natural groupings of songs with comparable musical traits.
The second technique we utilize is Principal Component Analysis (PCA). PCA helps us reduce the high-dimensional audio feature space into a lower-dimensional space represented by principal components. These principal components capture the most significant variations in the data, making it easier to visualize and comprehend.
By integrating PCA with k-means clustering, we gain a comprehensive understanding of the relationships between songs and their audio characteristics. The reduced dimensionality through PCA allows us to create visual representations that reveal the underlying structure of the song data in a more interpretable manner. Furthermore, the principal components give us valuable insights into the key audio features that heavily influence the clustering of songs, thereby providing valuable information about the main traits that define each group of songs.
Kita menggunakan pendekatan Unsupervised Learning yang mempunyai ciri:
Tidak memiliki target variable.
Tujuannya untuk mencari pola dalam data, yang berguna untuk menghasilkan informasi.
Tidak ada ground truth sehingga tidak ada evaluasi model
Before diving into the project, we’ll need to import the required libraries to facilitate our analysis.
library(tidyverse) # For data processing and visualization
library(tidyr)
library(ggplot2) # ggplot visualization
library(ggthemes) # ggplot theme
library(GGally) # ggplot2 for correlation matrix and survival plots
library(FactoMineR) # PCA exploratory multivariate data analysis
library(corrplot) # correlation plot
library(factoextra) # plot fviz contribution, elbow method of PCA
library(caret) # Confusion Matrix # pre-process and scale the data
library(ggiraphExtra) # Make advance visualize : Radar
options(scipen=999)And then import our data
## [1] 232725 18
## Rows: 232,725
## Columns: 18
## $ genre <chr> "Movie", "Movie", "Movie", "Movie", "Movie", "Movie",…
## $ artist_name <chr> "Henri Salvador", "Martin & les fées", "Joseph Willia…
## $ track_name <chr> "C'est beau de faire un Show", "Perdu d'avance (par G…
## $ track_id <chr> "0BRjO6ga9RKCKjfDqeFgWV", "0BjC1NfoEOOusryehmNudP", "…
## $ popularity <int> 0, 1, 3, 0, 4, 0, 2, 15, 0, 10, 0, 2, 4, 3, 0, 0, 0, …
## $ acousticness <dbl> 0.61100, 0.24600, 0.95200, 0.70300, 0.95000, 0.74900,…
## $ danceability <dbl> 0.389, 0.590, 0.663, 0.240, 0.331, 0.578, 0.703, 0.41…
## $ duration_ms <int> 99373, 137373, 170267, 152427, 82625, 160627, 212293,…
## $ energy <dbl> 0.9100, 0.7370, 0.1310, 0.3260, 0.2250, 0.0948, 0.270…
## $ instrumentalness <dbl> 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.123…
## $ key <chr> "C#", "F#", "C", "C#", "F", "C#", "C#", "F#", "C", "G…
## $ liveness <dbl> 0.3460, 0.1510, 0.1030, 0.0985, 0.2020, 0.1070, 0.105…
## $ loudness <dbl> -1.828, -5.559, -13.879, -12.178, -21.150, -14.970, -…
## $ mode <chr> "Major", "Minor", "Minor", "Major", "Major", "Major",…
## $ speechiness <dbl> 0.0525, 0.0868, 0.0362, 0.0395, 0.0456, 0.1430, 0.953…
## $ tempo <dbl> 166.969, 174.003, 99.488, 171.758, 140.576, 87.479, 8…
## $ time_signature <chr> "4/4", "4/4", "5/4", "4/4", "4/4", "4/4", "4/4", "4/4…
## $ valence <dbl> 0.8140, 0.8160, 0.3680, 0.2270, 0.3900, 0.3580, 0.533…
Metadata:
Data ini berisi lagu yang ada di streaming platform spotify yang diberikan fitur audio yang penjelasannya dapat dilihat pada link berikut : https://developer.spotify.com/documentation/web-api/reference/tracks/get-audio-features/
acousticness: A confidence measure from 0.0 to 1.0
of whether the track is acoustic. 1.0 represents high confidence the
track is acoustic.
danceability: Danceability describes how suitable a
track is for dancing based on a combination of musical elements
including tempo, rhythm stability, beat strength, and overall
regularity. A value of 0.0 is least danceable and 1.0 is most
danceable.
energy: Energy is a measure from 0.0 to 1.0 and
represents a perceptual measure of intensity and activity. Typically,
energetic tracks feel fast, loud, and noisy. For example, death metal
has high energy, while a Bach prelude scores low on the scale.
Perceptual features contributing to this attribute include dynamic
range, perceived loudness, timbre, onset rate, and general
entropy.
instrumentalness: Predicts whether a track contains
no vocals. “Ooh” and “aah” sounds are treated as instrumental in this
context. Rap or spoken word tracks are clearly “vocal”. The closer the
instrumentalness value is to 1.0, the greater likelihood the track
contains no vocal content. Values above 0.5 are intended to represent
instrumental tracks, but confidence is higher as the value approaches
1.0.
key: The key the track is in. Integers map to
pitches using standard Pitch Class notation. E.g. 0 = C, 1 = C♯/D♭, 2 =
D, and so on. If no key was detected, the value is -1.
liveness: Detects the presence of an audience in the
recording. Higher liveness values represent an increased probability
that the track was performed live. A value above 0.8 provides strong
likelihood that the track is live.
loudness: The overall loudness of a track in
decibels (dB). Loudness values are averaged across the entire track and
are useful for comparing relative loudness of tracks. Loudness is the
quality of a sound that is the primary psychological correlate of
physical strength (amplitude). Values typically range between -60 and 0
db.
mode: Mode indicates the modality (major or minor)
of a track, the type of scale from which its melodic content is derived.
Major is represented by 1 and minor is 0.
speechiness: Speechiness detects the presence of
spoken words in a track. The more exclusively speech-like the recording
(e.g. talk show, audio book, poetry), the closer to 1.0 the attribute
value. Values above 0.66 describe tracks that are probably made entirely
of spoken words. Values between 0.33 and 0.66 describe tracks that may
contain both music and speech, either in sections or layered, including
such cases as rap music. Values below 0.33 most likely represent music
and other non-speech-like tracks.
tempo: The overall estimated tempo of a track in
beats per minute (BPM). In musical terminology, tempo is the speed or
pace of a given piece and derives directly from the average beat
duration.
time_signature: An estimated time signature. The
time signature (meter) is a notational convention to specify how many
beats are in each bar (or measure). The time signature ranges from 3 to
7 indicating time signatures of “3/4”, to “7/4”.
valence: A measure from 0.0 to 1.0 describing the
musical positiveness conveyed by a track. Tracks with high valence sound
more positive (e.g. happy, cheerful, euphoric), while tracks with low
valence sound more negative (e.g. sad, depressed, angry).
Summary :
Data Spotify terdiri dari 232725 baris dan 18 kolom dengan deskripsi masing-masing kolom sebagai berikut:
genre: Genre dari lagu dalam bentuk teks
(chr).
artist_name: Nama artis yang membuat lagu dalam
bentuk teks (chr).
track_name: Nama lagu dalam bentuk teks
(chr).
track_id: ID unik yang mengidentifikasi lagu dalam
bentuk teks (chr).
popularity: Tingkat popularitas lagu dalam bentuk
angka (int).
acousticness: Ukuran tingkat akustik dari lagu dalam
bentuk angka (dbl).
danceability: Ukuran tingkat kesesuaian untuk menari
dari lagu dalam bentuk angka (dbl).
duration_ms: Durasi lagu dalam milidetik dalam
bentuk angka (int).
energy: Ukuran tingkat energi lagu dalam bentuk
angka (dbl).
instrumentalness: Ukuran tingkat instrumental dari
lagu dalam bentuk angka (dbl).
key: Kunci musik lagu dalam bentuk teks
(chr).
liveness: Ukuran tingkat kesan pertunjukan langsung
dari lagu dalam bentuk angka (dbl).
loudness: Ukuran tingkat volume lagu dalam bentuk
angka (dbl).
mode: Kategori apakah lagu berada di mode mayor atau
minor dalam bentuk teks (chr).
speechiness: Ukuran tingkat ucapan dalam lagu dalam
bentuk angka (dbl).
tempo: Tempo atau kecepatan lagu dalam bentuk angka
(dbl).
time_signature: Tanda waktu lagu dalam bentuk teks
(chr).
valence: Ukuran tingkat kesenangan atau positivitas
lagu dalam bentuk angka (dbl).
Data ini memberikan informasi yang penting untuk melakukan analisis clustering dan menganalisis fitur audio yang mempengaruhi popularitas sebuah lagu di platform Spotify.
Pada tahap ini, kita memeriksa tipe data dari setiap kolom, apakah sudah sesuai dengan format yang diharapkan atau tidak. Hal ini perlu dilakukan untuk memastikan bahwa semua data telah diatur dengan benar dan sesuai dengan analisis yang akan dilakukan selanjutnya.
Ada beberapa kolom yang belum sesuai tipe datanya dan harus diubah ketipe data yang sesuai:
genre tipe data chart diubah menjadi
factor
key tipe data chart menjadi
factor
mode tipe data chart menjadi
factor
valence tipe data chart menjadi
factor
Selain itu kita juga akan membuang kolom yang tidak diperlukan.
Membuang kolom yang tidak relevan untuk dianalisa:
track_id, track_name,
time_signature, artist_name
spotify_clean <- spotify %>%
mutate(genre = as.factor(genre),
key = as.factor(key),
mode = as.factor(mode)) %>%
select(-track_id, -time_signature, -artist_name, -track_name)Untuk mengurangi beban komputasi dan memfasilitasi analisis eksplorasi pada pembentukan cluster, diputuskan untuk menggunakan hanya 2000 data secara acak dari keseluruhan data yang tersedia. Dengan melakukan sampel sebanyak itu, kita tetap dapat memperoleh wawasan yang relevan dari dataset yang sangat besar ini tanpa mengorbankan kualitas analisis. Sampel acak ini akan mencerminkan variasi data asli dan memungkinkan kita untuk menjalankan algoritma clustering dengan lebih efisien dan cepat.
# pemilihan data untuk dilakukan clustering
set.seed(50)
n=2000
intrain <- sample(nrow(spotify_clean), nrow(spotify_clean)*(n/nrow(spotify_clean)))
spotify_sample <- spotify_clean[intrain,]
rownames(spotify_sample) <- c(1:nrow(spotify_sample))
dim(spotify_sample)## [1] 2000 14
Pada tahap ini, pertama kita akan melihat apakah terdapat missing value atau tidak.
## genre popularity acousticness danceability
## 0 0 0 0
## duration_ms energy instrumentalness key
## 0 0 0 0
## liveness loudness mode speechiness
## 0 0 0 0
## tempo valence
## 0 0
Dari hasil sebelumnya, dapat disimpulkan bahwa dataset “spotify” telah berhasil diolah sehingga tidak terdapat nilai yang hilang (missing value). Langkah selanjutnya yang akan diambil adalah memeriksa skala antar variabel dalam dataset ini. Tujuan dari langkah ini adalah untuk memastikan bahwa nilai-nilai dari berbagai variabel memiliki rentang yang serupa atau setidaknya dapat dibandingkan secara langsung. Dengan memeriksa skala antar variabel, kita dapat mengidentifikasi apakah ada perbedaan besar dalam ukuran nilai antar fitur audio seperti tempo, energy, atau loudness. Dengan demikian, analisis clustering nantinya dapat dilakukan dengan lebih akurat dan hasilnya menjadi lebih bermakna.
## genre popularity acousticness danceability
## Pop : 98 Min. : 0.00 Min. :0.0000048 Min. :0.0603
## Hip-Hop : 95 1st Qu.:30.00 1st Qu.:0.0363000 1st Qu.:0.4340
## Rock : 89 Median :44.00 Median :0.2200000 Median :0.5720
## Blues : 88 Mean :41.62 Mean :0.3623156 Mean :0.5595
## Children’s Music: 87 3rd Qu.:55.00 3rd Qu.:0.7122500 3rd Qu.:0.7010
## Reggaeton : 85 Max. :89.00 Max. :0.9960000 Max. :0.9640
## (Other) :1458
## duration_ms energy instrumentalness key
## Min. : 29707 Min. :0.00151 Min. :0.000000 C :254
## 1st Qu.: 185549 1st Qu.:0.39975 1st Qu.:0.000000 G :236
## Median : 223419 Median :0.61100 Median :0.000043 A :231
## Mean : 237219 Mean :0.57455 Mean :0.141778 D :210
## 3rd Qu.: 267870 3rd Qu.:0.78700 3rd Qu.:0.029200 C# :193
## Max. :2640040 Max. :0.99900 Max. :0.983000 F :168
## (Other):708
## liveness loudness mode speechiness
## Min. :0.00967 Min. :-41.136 Major:1322 Min. :0.02280
## 1st Qu.:0.09617 1st Qu.:-11.469 Minor: 678 1st Qu.:0.03680
## Median :0.12800 Median : -7.706 Median :0.05155
## Mean :0.21665 Mean : -9.422 Mean :0.12106
## 3rd Qu.:0.27300 3rd Qu.: -5.498 3rd Qu.:0.10800
## Max. :0.99100 Max. : 0.000 Max. :0.96000
##
## tempo valence
## Min. : 44.56 Min. :0.0258
## 1st Qu.: 93.01 1st Qu.:0.2515
## Median :115.82 Median :0.4490
## Mean :117.85 Mean :0.4584
## 3rd Qu.:139.37 3rd Qu.:0.6600
## Max. :212.14 Max. :0.9860
##
Data Spotify perlu dilakukan proses scaling karena nilai dalam setiap
kolomnya memiliki skala yang berbeda. Oleh karena itu, untuk
mengaplikasikan metode k-means, kita hanya akan menggunakan data yang
memiliki tipe numerik. Untuk itu, kita menyimpan kolom-kolom dengan tipe
data numerik dari dataset Spotify ke dalam
variabel spotify_num.
# Memilih hanya kolom-kolom numerik dari data spotify_clean
spotify_num <- spotify_sample %>% select_if(is.numeric)
# Normalisasi data numerik menggunakan scale()
spotify_scale <- spotify_num %>% scale()
summary(spotify_scale)## popularity acousticness danceability duration_ms
## Min. :-2.3053 Min. :-1.0283 Min. :-2.65950 Min. :-1.7389
## 1st Qu.:-0.6435 1st Qu.:-0.9253 1st Qu.:-0.66878 1st Qu.:-0.4330
## Median : 0.1320 Median :-0.4039 Median : 0.06636 Median :-0.1156
## Mean : 0.0000 Mean : 0.0000 Mean : 0.00000 Mean : 0.0000
## 3rd Qu.: 0.7413 3rd Qu.: 0.9932 3rd Qu.: 0.75355 3rd Qu.: 0.2568
## Max. : 2.6247 Max. : 1.7985 Max. : 2.15456 Max. :20.1348
## energy instrumentalness liveness loudness
## Min. :-2.2162 Min. :-0.4783 Min. :-1.0338 Min. :-5.5027
## 1st Qu.:-0.6760 1st Qu.:-0.4783 1st Qu.:-0.6017 1st Qu.:-0.3552
## Median : 0.1410 Median :-0.4782 Median :-0.4428 Median : 0.2977
## Mean : 0.0000 Mean : 0.0000 Mean : 0.0000 Mean : 0.0000
## 3rd Qu.: 0.8216 3rd Qu.:-0.3798 3rd Qu.: 0.2814 3rd Qu.: 0.6808
## Max. : 1.6415 Max. : 2.8381 Max. : 3.8674 Max. : 1.6347
## speechiness tempo valence
## Min. :-0.53894 Min. :-2.37428 Min. :-1.67316
## 1st Qu.:-0.46215 1st Qu.:-0.80471 1st Qu.:-0.80028
## Median :-0.38125 Median :-0.06603 Median :-0.03645
## Mean : 0.00000 Mean : 0.00000 Mean : 0.00000
## 3rd Qu.:-0.07164 3rd Qu.: 0.69697 3rd Qu.: 0.77959
## Max. : 4.60138 Max. : 3.05436 Max. : 2.04039
Dengan cara ini, kita dapat memastikan bahwa data yang akan digunakan dalam analisis clustering memiliki karakteristik yang seragam dalam skala sehingga hasil clustering menjadi lebih relevan dan akurat.
Ada terdapat beberapa fitur yang memiliki korelasi tinggi
yaitu acousticness dengan energy dan loudness, energy dengan loudness dan
lainnya. Dari hasil tersebut, kita akan mencoba mengurangi dimensi
menggunakan PCA.
Clustering adalah proses pengelompokan data berdasarkan karakteristik atau atributnya yang mirip. Tujuan utama dari clustering adalah untuk membentuk kelompok atau cluster yang terdiri dari observasi atau data yang memiliki kesamaan atau kedekatan dalam karakteristik tertentu. Dalam proses clustering, observasi yang termasuk dalam satu cluster diharapkan memiliki kemiripan yang tinggi antara satu sama lain, sedangkan observasi yang termasuk dalam cluster yang berbeda seharusnya memiliki perbedaan karakteristik yang signifikan. Sebelum masuk menggunakan k-means, terlebih dahulu kita akan memilih k-optimum.
K-means Clustering K-means adalah centroid-based clustering algorithms, artinya tiap cluster memiliki satu centroid (titik pusat) yang mewakili cluster tersebut. K-means merupakan proses yang berulang dari:
Random initialization: meletakkan k centroid secara random
Cluster assignment: assign masing-masing observasi ke cluster terdekat, berdasarkan perhitungan jarak
Centroid update: menggeser centroid ke rata-rata (means) dari cluster yang terbentuk
Ulangi langkah 2 dan 3 sampai tidak ada observasi yang clusternya berubah lagi
💡 Banyaknya cluster k ditentukan oleh user.
Bagaimana menentukan k optimum?
Kebutuhan dari segi bisnis, dibutuhkan menjadi berapa kelompok. Seperti yang sudah dikerjakan di atas, ditetapkan kelompok audio spotify dibagi enjadi 3 cluster.
Secara objektif, jumlah cluster bisa ditentukan dengan Elbow
method, visualisasi dengan fviz_nbclust()
Dalam menentukan k-optimum kita akan menggunakan elbow method. Elbow Plot merupakan plot antara banyak klaster dengan total dari simpangan/variasi per kluster (total WSS).
fviz_nbclust(
x = spotify_scale, #data untuk clustering
FUNcluster = kmeans, #algoritma kmeans
method = "wss" #berdasarkan wss
)Pada tahap pemilihan nilai k untuk analisis clustering, kita ingin mencari nilai k yang tepat di mana penurunan total within sum of squares tidak lagi menurun secara drastis dan cenderung melandai. Nilai k ini dapat dianggap sebagai nilai k optimum yang paling cocok untuk data whisky.
fviz_nbclust(
x = spotify_scale, #data untuk clustering
FUNcluster = kmeans, #algoritma kmeans
method = "silhouette" #berdasarkan silhouette
)fviz_nbclust(
x = spotify_scale, #data untuk clustering
FUNcluster = kmeans, #algoritma kmeans
method = "gap_stat" #berdasarkan gap_stat
)Setelah melakukan analisis, nilai k optimum dari elbow method yang dipilih untuk data whisky adalah 6. Ini berarti bahwa lagu-lagu dalam dataset Spotify telah dikelompokkan menjadi 6 kluster berdasarkan fitur-fitur audio yang relevan.
K-means adalah salah satu algoritma centroid-based dalam proses clustering, yang bertujuan untuk membentuk kelompok data dengan masing-masing kelompok memiliki satu titik pusat yang disebut centroid yang merepresentasikan kelompok tersebut. Proses K-means terdiri dari beberapa langkah berulang yang dimulai dengan random initialization, yaitu penempatan awal k� centroid secara acak. Setelah itu, langkah berikutnya adalah cluster assignment, di mana setiap observasi atau data diatribusikan ke cluster terdekat berdasarkan perhitungan jarak terhadap centroid. Kemudian, dilakukan centroid update dengan menggeser posisi centroid ke rata-rata (means) dari kelompok yang terbentuk. Proses cluster assignment dan centroid update diulangi secara berulang sampai tidak ada lagi perubahan kluster untuk observasi tertentu, yang menunjukkan konvergensi algoritma. K-means merupakan algoritma yang efisien dan sering digunakan dalam berbagai aplikasi, namun, keberhasilan algoritma ini sangat tergantung pada inisialisasi yang baik dan dapat menghasilkan hasil yang berbeda-beda tergantung pada kondisi awalnya. Oleh karena itu, ada juga variasi K-means yang mencoba mengatasi masalah inisialisasi ini.
formula = kmeans(x, centers)
Parameter:
x: dataset
centers: banyaknya centroid k
Note: perlu dilakukan set.seed() karena terdapat random
initialization pada tahap awal k-means
RNGkind(sample.kind = "Rounding")
set.seed(50)
# k-means dengan k optimum
spotify_cluster <- kmeans(spotify_scale,centers =5)Lalu kita menerapkan algoritma K-means pada data spotify_scale dengan menggunakan 5 centroid sebagai jumlah kluster yang diinginkan. Hasil dari proses K-means akan disimpan dalam variabel spotify_cluster, yang akan berisi informasi tentang kluster yang terbentuk serta posisi centroid dari masing-masing kluster.
Hasil k-means:
## [1] 399 717 274 530 80
## popularity acousticness danceability duration_ms energy instrumentalness
## 1 -0.1369137 0.8557210 -0.01533762 -0.16733187 -0.8147957 -0.2232388
## 2 0.4302967 -0.5746923 0.79950794 -0.05718683 0.4217739 -0.3147369
## 3 -0.7832094 1.3078878 -1.33563747 0.30803437 -1.4956169 1.6511282
## 4 0.1066062 -0.7367364 -0.36998922 0.05433459 0.7488169 -0.1876555
## 5 -1.1974510 1.2841337 -0.06335659 -0.06787968 0.4452211 -0.4776634
## liveness loudness speechiness tempo valence
## 1 -0.2976753 -0.3276683 -0.25535580 -0.1318640 -0.21094628
## 2 -0.1930031 0.4701582 -0.05731679 -0.2793185 0.63829081
## 3 -0.2150444 -1.7709898 -0.41153930 -0.5698096 -1.16817371
## 4 0.1962056 0.5891838 -0.15182244 0.8571556 -0.07456426
## 5 2.6511110 -0.4172496 4.20263456 -0.5659941 -0.17360367
## 1 2 3 4 5 6
## 2 2 2 2 2 4
## [1] 5
Kebaikan hasil clustering dapat dilihat dari 3 nilai:
Within Sum of Squares ($withinss): jumlah jarak
kuadrat dari tiap observasi ke centroid tiap cluster.
Between Sum of Squares ($betweenss): jumlah jarak
kuadrat terbobot dari tiap centroid ke rata-rata global. Dibobotkan
berdasarkan banyaknya observasi pada cluster.
Total Sum of Squares ($totss): jumlah jarak kuadrat
dari tiap observasi ke rata-rata global.
## [1] 2325.8986 3301.2286 3050.8137 3037.1602 500.8611
## [1] 12215.96
## [1] 9773.038
## [1] 21989
## [1] 0.4444512
Clustering yang baik:
Clustering yang "baik":
WSS semakin rendah: jarak observasi di 1 kelompok yang sama semakin rendah, artinya tiap cluster memiliki karakteristik yang semakin mirip
BSS/TSS mendekati 1, karena kelompok hasil clustering semakin mewakili persebaran data yang sesungguhnya
Pemilihan k (banyaknya cluster) sangat mempengaruhi performa clustering
Pemilihan banyak k akan membuat bss/tss bagus, namun tidak reprentatif karena bisa jadi ada satu cluster yang beranggotakan satu observasi sendiri (tujuan clustering tidak tercapai)
Dari hasil diatas, nilai proporsi sebesar 0.46 (atau 46%) menunjukkan bahwa model K-means telah berhasil menjelaskan sekitar 46% variasi dalam data berdasarkan kluster yang dibentuk. Hal ini menandakan bahwa pengelompokan yang dilakukan oleh algoritma K-means cukup baik dalam menggambarkan pola-pola atau kelompok-kelompok yang ada dalam data Spotify.
Membuat kolom baru yang berisikan informasi label dari cluster yang terbentuk menggunakan k optimum
Grouping data based on cluster label
Melakukan grouping berdasarkan cluster yang terbentuk, untuk mengetahui karakteristik dari masing-masing cluster
# melakukan profiling cluster dari data asli (supaya nantinya jika ketemu dengan perlu data yg perlu discaling sebelum kmeans nya , interpretasinya tidak salah)
spotify_centroid <- spotify_num %>%
group_by(cluster) %>%
summarise_all(mean)
spotify_centroidUntuk mempermudah profiling: tabel yang menampilkan cluster dengan nilai terendah dan tertinggi untuk masing-masing karakteristik fitur audio spotify.
spotify_centroid %>%
pivot_longer(-cluster) %>%
group_by(name) %>%
summarize(
kelompok_min = which.min(value),
kelompok_max = which.max(value))💡 Profiling tiap cluster :
Berikut adalah label untuk setiap cluster berdasarkan hasil analisis K-means pada data Spotify:
Cluster 1 : - Paling tinggi di fitur audio : popularity - Paling rendah di fitur audio : acousticness, danceability, energy, instrumentalness, liveness, loudness, speechiness, tempo, duration_ms - Label : “Highly Popular Tracks”
Cluster 2 : - Paling tinggi di fitur audio : speechiness, liveness - Paling rendah di fitur audio : duration_ms, instrumentalness, tempo, acousticness - Label : “Live or Spoken Word Tracks”
Cluster 3 : - Paling tinggi di fitur audio : instrumentalness - Paling rendah di fitur audio : danceability, energy, liveness, loudness, speechiness, acousticness - Label : “Instrumental Tracks”
Cluster 4 : - Paling tinggi di fitur audio : acousticness - Paling rendah di fitur audio : popularity, energy, danceability, instrumentalness, liveness, loudness, speechiness, tempo, duration_ms - Label : “Acoustic and Mellow Tracks”
Cluster 5 : - Paling tinggi di fitur audio : duration_ms, energy, loudness, tempo - Paling rendah di fitur audio : acousticness, popularity, danceability, instrumentalness, liveness, speechiness - Label : “Energetic and Upbeat Tracks”
Cluster 6 : - Paling tinggi di fitur audio : danceability - Paling rendah di fitur audio : acousticness, energy, instrumentalness, liveness, loudness, speechiness, tempo, duration_ms, popularity - Label : “Danceable Tracks”
Untuk mempermudah profiling: radar plot
Plot radat (radar plot) adalah jenis grafik yang digunakan untuk memvisualisasikan variasi nilai dari beberapa variabel atau atribut pada data dalam bentuk poligon dengan sumbu radial. Setiap sumbu mewakili satu atribut, dan jarak dari pusat poligon ke titik di setiap sumbu mencerminkan nilai atribut tersebut.
Interpretasi hasil sebelumnya (hasil K-means) berdasarkan plot radat ini dapat memberikan wawasan tentang karakteristik audio dari masing-masing kluster. Pada plot radat ini, kita dapat melihat seberapa tinggi atau rendah nilai atribut pada masing-masing kluster.
Misalnya, jika pada plot radat, kluster 1 menunjukkan poligon yang tinggi pada atribut “popularity”, tetapi rendah pada atribut “acousticness” dan “danceability”, ini menunjukkan bahwa kluster tersebut memiliki lagu-lagu yang sangat populer, namun cenderung tidak akustik dan kurang cocok untuk menari.
Next, melakukan visualisasi untuk hasil dari algoritma k-means clustering. Kita akan menggunakan grafik batang untuk menunjukkan profil masing-masing kluster berdasarkan nilai rata-rata dari fitur-fiturnya.
# Reshape the data frame for plotting
spotify_num_melted <- spotify_centroid %>%
gather(variable, value, -cluster) %>%
filter(variable %in% c("acousticness", "danceability", "energy", "instrumentalness", "valence"))
ggplot(spotify_num_melted, aes(x = cluster, y = value, fill = variable)) +
geom_bar(stat = "identity", position = "dodge") +
labs(x = "Cluster Label", y = "Mean Value", fill = "Variable") +
ggtitle("Cluster Profiles")# Perform PCA on the scaled data
pca_result <- prcomp(spotify_scale)
# Subset the cluster labels to match the number of data points in PCA
cluster_labels <- as.factor(spotify_cluster$cluster)[1:nrow(pca_result$x)]
# Add cluster labels to PCA results
pca_result$cluster_label <- cluster
# Create the combined plot
fviz_pca_biplot(pca_result, habillage = cluster_labels, addEllipses = TRUE, col.var = "navy")# Analisis hubungan antara variabel dalam kluster
cluster_correlation <- spotify_num %>%
select(acousticness, danceability, energy, instrumentalness, valence, cluster)
# Korelasi antara variabel dalam kluster
cor_matrix <- cor(cluster_correlation[, -6])
print(cor_matrix)## acousticness danceability energy instrumentalness
## acousticness 1.0000000 -0.3476629 -0.7136474 0.2896917
## danceability -0.3476629 1.0000000 0.2758371 -0.3435965
## energy -0.7136474 0.2758371 1.0000000 -0.3693889
## instrumentalness 0.2896917 -0.3435965 -0.3693889 1.0000000
## valence -0.3185333 0.5360824 0.4155703 -0.3249176
## valence
## acousticness -0.3185333
## danceability 0.5360824
## energy 0.4155703
## instrumentalness -0.3249176
## valence 1.0000000
💡 Insight :
Acousticness dan Energy memiliki korelasi negatif yang kuat
(nilai -0.73), yang menunjukkan bahwa
lagu-lagu dengan tingkat akustik yang tinggi cenderung memiliki tingkat energi yang rendah,
dan sebaliknya.
Danceability dan Valence memiliki korelasi positif yang moderat
(nilai 0.55), menunjukkan bahwa
lagu-lagu yang mudah untuk ditari cenderung memiliki tingkat keceriaan atau positivitas yang tinggi.
Acousticness dan Instrumentalness memiliki korelasi positif yang
moderat (nilai 0.32), yang menunjukkan bahwa
lagu-lagu dengan tingkat akustik yang tinggi juga cenderung memiliki tingkat unsur instrumental yang lebih tinggi.
Danceability dan Acousticness memiliki korelasi negatif yang
moderat (nilai -0.36), menunjukkan bahwa
lagu-lagu yang mudah untuk ditari cenderung memiliki tingkat akustik yang lebih rendah.
Energy dan Valence memiliki korelasi positif yang moderat (nilai
0.44), yang menunjukkan bahwa
lagu-lagu dengan tingkat energi yang tinggi juga cenderung memiliki tingkat keceriaan atau positivitas yang tinggi.
Machine learning semakin banyak diadopsi di bidang yang berhubungan dengan high-dimensional data.
Kesulitan yang dihadapi pada high-dimensional data:
Menyulitkan pengolahan data (feature selection)
Memerlukan waktu dan komputasi yang besar dalam melakukan pemodelan - Melakukan visualisasi lebih dari tiga dimensi
Dimensionality reduction bertujuan untuk mereduksi dimensi data, namun tetap mempertahankan sebanyak mungkin informasi yang ada.
Principal Component Analysis (PCA) adalah suatu metode dalam analisis multivariat yang bertujuan untuk mengurangi dimensi dari suatu dataset dengan tetap mempertahankan sebanyak mungkin informasi yang terkandung dalam variabel-variabel awal. Ide dasar dari PCA adalah mencari sumbu baru yang disebut Principal Component (PC) yang dapat menjelaskan sebanyak mungkin varians dari data asli. Dengan menggunakan beberapa PC yang memiliki varians yang tinggi, kita dapat merangkum informasi yang signifikan dari data awal tanpa harus menggunakan seluruh variabelnya.
Ide dasar dari PCA adalah untuk membuat sumbu (axis) baru yang dapat menangkap informasi (variance) sebesar mungkin dari variabel-variabel awal. Sumbu baru ini adalah yang dinamakan sebagai Principal Component (PC). Untuk melakukan dimensionality reduction, akan diambil beberapa PC saja yang merangkum jumlah informasi yang dibutuhkan.
💡 Highlight Points:
PC dibuat untuk merangkum sebanyak mungkin informasi dari data.
PC1 akan menangkap variansi paling tinggi dari data, dilanjutkan dengan PC2, dan seterusnya.
PC yang dihasilkan adalah sebanyak jumlah variabel awal.
antar PC yang dihasilkan tidak berkorelasi
PCA cocok untuk data yang antar variabelnya saling berkorelasi
Kemudian, dikarenakan analisis PCA menggunakan nilai variance, kita hanya menggunakan kolom bertipe data numerik.
Mari kita cek juga matriks covariance
dari spotify_num:
## popularity acousticness danceability duration_ms energy
## popularity 1.00000000 -0.36420178 0.262283600 0.00490733 0.24578752
## acousticness -0.36420178 1.00000000 -0.347662885 0.02399114 -0.71364739
## danceability 0.26228360 -0.34766288 1.000000000 -0.14799978 0.27583707
## duration_ms 0.00490733 0.02399114 -0.147999780 1.00000000 -0.03152385
## energy 0.24578752 -0.71364739 0.275837075 -0.03152385 1.00000000
## instrumentalness -0.18155988 0.28969170 -0.343596522 0.09867697 -0.36938892
## liveness -0.15612859 0.07399033 -0.061666869 0.06617733 0.19767801
## loudness 0.36772994 -0.68788858 0.404980656 -0.05644562 0.80174503
## speechiness -0.14310871 0.15385233 0.123437862 -0.03493767 0.15548117
## tempo 0.10472760 -0.24840415 0.008594191 -0.06557549 0.25295914
## valence 0.08061507 -0.31853332 0.536082382 -0.14111889 0.41557032
## instrumentalness liveness loudness speechiness
## popularity -0.18155988 -0.15612859 0.367729940 -0.143108712
## acousticness 0.28969170 0.07399033 -0.687888583 0.153852334
## danceability -0.34359652 -0.06166687 0.404980656 0.123437862
## duration_ms 0.09867697 0.06617733 -0.056445623 -0.034937666
## energy -0.36938892 0.19767801 0.801745029 0.155481173
## instrumentalness 1.00000000 -0.11638937 -0.485551141 -0.173571274
## liveness -0.11638937 1.00000000 0.037930936 0.501470430
## loudness -0.48555114 0.03793094 1.000000000 0.002733133
## speechiness -0.17357127 0.50147043 0.002733133 1.000000000
## tempo -0.11515529 -0.05100143 0.230806548 -0.067907954
## valence -0.32491756 0.01074234 0.386326925 0.024993736
## tempo valence
## popularity 0.104727602 0.08061507
## acousticness -0.248404145 -0.31853332
## danceability 0.008594191 0.53608238
## duration_ms -0.065575493 -0.14111889
## energy 0.252959144 0.41557032
## instrumentalness -0.115155292 -0.32491756
## liveness -0.051001429 0.01074234
## loudness 0.230806548 0.38632692
## speechiness -0.067907954 0.02499374
## tempo 1.000000000 0.12719229
## valence 0.127192289 1.00000000
Catatan: variansi dan covariance dari spotify_num skalanya juga berbeda jauh
Nilai variance dan covariance dipengaruhi oleh skala dari data. Semakin tinggi skala, nilai variance atau covariance akan semakin tinggi.
Data dengan perbedaan skala antar variabel yang tinggi tidak baik untuk langsung dianalisis PCA karena dapat menimbulkan bias. PC1 akan dianggap menangkap variansi tertinggi dan PC selanjutnya dianggap tidak memberikan informasi.
Kita dapat melihat seberapa besar variansi yang dirangkum tiap PC
menggunakan plot(prcomp(data)). Perhatikan plot berikut
yang menunjukkan bahwa semua informasi untuk data
spotify_num dirangkum oleh PC1.
Plot tersebut menunjukkan dominasi PC1 dalam menagkap variance. Hal ini terjadi jika kita tidak melakukan scaling pada data yang skalanya berbeda jauh. Mka kita harus melakukan proses scaling.
Scaling perlu dilakukan sebelum melakukan PCA agar antar variabel memiliki skala yang tidak jauh berbeda. Proses scaling yang digunakan adalah Z-score (mean = 0, standar deviasi = 1)
Sekarang PC1 sudah tidak mendominasi PC lainnya dalam besaran variance yang ditangkap.
Terdapat tiga komponen utama dari fungsi prcomp():
1️⃣ pca$sdev: standar deviasi (akar variance) dari tiap
PC. Variance (eigen value) yang dirangkum oleh tiap PC
dapat dicari dengan mengkuadratkan nilai ini.
## [1] 1.8825438 1.3013809 1.1042295 1.0043551 0.9125239 0.8643640 0.8165305
## [8] 0.7075220 0.6223867 0.5226939 0.3559160
## [1] 3.5439710 1.6935922 1.2193227 1.0087291 0.8326999 0.7471252 0.6667221
## [8] 0.5005874 0.3873652 0.2732089 0.1266762
Notes: PC1 akan secara otomatis merangkum paling banyak informasi (nilai variancenya paling besar), kemudian diikuti oleh PC2, PC3, …, dst.
2️⃣ pca$rotation: matrix rotasi, berisi eigen
vector yang akan menjadi formula untuk setiap PC, digunakan
untuk mengetahui kontribusi masing-masing variabel ke
PC.
## PC1 PC2 PC3 PC4 PC5
## popularity -0.24103613 -0.28940232 0.08870937 -0.33401642 0.61726922
## acousticness 0.42176280 0.18390112 -0.22177447 0.01055167 0.03408220
## danceability -0.32254512 0.03814080 -0.48894422 -0.26822596 -0.10859702
## duration_ms 0.07277629 -0.00812848 0.53964891 -0.56026287 -0.48887030
## energy -0.44494519 0.11452937 0.28150625 0.07514442 -0.06172381
## instrumentalness 0.31798977 -0.18975382 0.13018058 0.04520256 -0.16386886
## liveness -0.02324983 0.62332243 0.25536930 0.01512113 0.06588817
## loudness -0.46805233 -0.01971856 0.16504493 -0.02756158 0.04884274
## speechiness -0.03021673 0.64743101 -0.01764530 -0.01026207 0.19941899
## tempo -0.17018625 -0.13851511 0.25999303 0.70247260 -0.10640595
## valence -0.32573350 0.06715187 -0.39510195 0.01518990 -0.52777815
## PC6 PC7 PC8 PC9 PC10
## popularity 0.30234499 0.33252446 -0.31285585 -0.23218647 -0.055417285
## acousticness 0.30507470 -0.06087074 -0.15842764 -0.28162330 0.681137556
## danceability 0.21292249 0.29758333 0.24818133 0.55067998 0.174986986
## duration_ms 0.37661292 -0.02644545 0.08691876 -0.01944708 0.007549237
## energy -0.31283675 0.04470089 0.08652732 -0.24291764 0.116430691
## instrumentalness -0.36499495 0.79590896 0.07561440 -0.03783293 0.181115253
## liveness -0.07337966 0.15870180 -0.58509227 0.40676671 0.023547309
## loudness -0.17354800 -0.13704208 0.10272595 -0.03605428 0.633708423
## speechiness 0.17153955 0.24025765 0.51606004 -0.34668457 -0.176249299
## tempo 0.57389982 0.18690432 0.03677206 0.11152025 0.037088535
## valence 0.05445377 0.15612184 -0.41726827 -0.45091550 -0.146164500
## PC11
## popularity -0.029066270
## acousticness -0.269637671
## danceability -0.205791921
## duration_ms 0.001108803
## energy -0.721309539
## instrumentalness 0.101925201
## liveness 0.047199437
## loudness 0.536483713
## speechiness 0.187120040
## tempo 0.002261829
## valence 0.168408284
Formula yang dihasilkan mirip seperti pada regresi linear, namun tanpa intercept:
PC1 = 0.2360.264 * popularity + (-0.459) * acousticness + … + 0.15 * tempo
Variabel yang memiliki kontribusi besar terhadap PC1 adalah loudness, energy, acousticness.
3️⃣ pca$x: nilai hasil proyeksi titik ke PC untuk tiap
baris (nilai data baru)
# perbandingan dengan data awal (spotify_scale) dan nilai baru di tiap PC
head(as.data.frame(spotify_scale))Kita ingin mereduksi 11 dimensi tersebut dengan mempertahankan sebanyak mungkin informasi, Berapakah dimensi baru yaitu PC yang akan digunakan? Hal ini dapat dilakukan dengan melihat cumulative variance dengan fungsi summary().
## Importance of components:
## PC1 PC2 PC3 PC4 PC5 PC6 PC7
## Standard deviation 1.8825 1.3014 1.1042 1.0044 0.9125 0.86436 0.81653
## Proportion of Variance 0.3222 0.1540 0.1109 0.0917 0.0757 0.06792 0.06061
## Cumulative Proportion 0.3222 0.4761 0.5870 0.6787 0.7544 0.82231 0.88292
## PC8 PC9 PC10 PC11
## Standard deviation 0.70752 0.62239 0.52269 0.35592
## Proportion of Variance 0.04551 0.03522 0.02484 0.01152
## Cumulative Proportion 0.92843 0.96365 0.98848 1.00000
Keterangan:
Standard deviation: standar deviasi yang
ditangkap oleh masing-masing PC (ekual pca$sdev)
Proportion of Variance: informasi yang ditangkap oleh tiap PC.
Cumulative Proportion: jumlah informasi yang ditangkap secara kumulatif dari PC1 hingga PC tersebut.
Jika ingin mempertahankan minimal 85% informasi dari data kita akan menggunakan 7 PC (PC1 sampai PC7)
Setelah menerapkan PCA dan mereduksi dimensi dari dataset yang awalnya memiliki 10 dimensi, kita memutuskan untuk mempertahankan 92% informasi dari data tersebut. Untuk mencapai tujuan ini, kami memilih untuk menggunakan PC1 hingga PC7, yang dapat dilihat dari hasil Cumulative Proportion pada analisis PCA. Dengan menggunakan 7 principal component ini, kami yakin bahwa kami masih dapat mempertahankan sebagian besar informasi yang relevan dalam data asli, sambil mengurangi jumlah dimensi sehingga memudahkan dalam analisis dan interpretasi data. Pemilihan 7 principal component ini akan membantu kami dalam mengidentifikasi pola dan hubungan penting dalam dataset, serta mengurangi kompleksitas data tanpa mengorbankan informasi yang signifikan.
Setelah dipilih PC yang merangkum informasi yang dibutuhkan, PC dapat digabung dengan data awal dan digunakan untuk analisis lebih lanjut (misalnya: supervised learning).
head(spotify_sample %>%
select_if(~!is.numeric(.)) %>% #Pilih kolom yang tipe datanya bukan numeric
cbind(pc_keep) )#Menggabungkan kolom dari pc_keep dan kolom data spotify yang bukan numericKelebihan dan kekurangan melakukan metode PCA:
(+) Beban komputasi apabila dilakukan pemodelan relatif lebih rendah.
(+) Bisa menjadi salah satu teknik untuk improve model, namun tidak selalu menjadi lebih baik.
(+) Mengurangi resiko terjadinya multikolinearitas, karena nilai antar PC sudah tidak saling berkorelasi. Dibuktikan dengan tabel korelasi sebagai berikut:
Observasi berdekatan: observasi yang saling berdekatan memiliki karakteristik yang mirip.
Outlier detection: observasi yang jauh dari gerombolan data mengindikasikan outlier dari keseluruhan data.
Observasi searah panah mengindikasikan observasi tersebut nilainya tinggi pada variabel tersebut. Bila bertolak belakang, maka nilainya rendah pada variable tersebut
Sekarang kita coba melihat dengan observasi data sejumlah 100 baris (agar tidak terlalu menumpuk).
# subset 100 data pertama agar tidak terlalu menumpuk
prop_small <- spotify_scale %>% head(100)
# melakukan PCA
pca_small <- prcomp(prop_small, scale = T)kita coba menambahkan PCA versi FactorMiner
Dalam analisis biplot, beberapa hal dapat diamati untuk memberikan wawasan lebih lanjut tentang data yang direduksi menggunakan PCA.
Observasi berdekatan: Berdasarkan biplot, kita dapat melihat bahwa beberapa observasi berdekatan dalam grafik, menunjukkan bahwa observasi-observasi tersebut memiliki karakteristik yang mirip. Sebagai contoh, observasi dengan indeks 224995, 10404, 176826, dan 84837 terlihat berdekatan dalam grafik, menunjukkan bahwa lagu-lagu ini memiliki atribut dan fitur audio yang serupa.
Outlier detection: Biplot juga membantu dalam mendeteksi adanya outliers atau data yang jauh dari gerombolan data utama. Dalam grafik, terdapat beberapa observasi seperti 126471, 122302, 125155, dan 168639 yang berada jauh dari kluster data lainnya. Hal ini mengindikasikan bahwa lagu-lagu dengan indeks tersebut memiliki atribut audio yang sangat berbeda dari mayoritas lagu dalam dataset.
Observasi searah panah: Pada biplot, arah panah menunjukkan bagaimana observasi berkontribusi terhadap variabel-variabel yang ada. Jika suatu observasi menunjuk ke arah variabel tertentu, itu berarti nilai observasi tersebut tinggi pada variabel tersebut. Sebaliknya, jika observasi menunjuk ke arah yang berlawanan dengan variabel, itu menandakan nilai observasi rendah pada variabel tersebut. Sebagai contoh, observasi dengan indeks 14309 dan 101854 menunjuk ke arah variabel danceability, yang berarti lagu-lagu tersebut memiliki nilai tinggi pada atribut danceability.
Dengan menganalisis biplot, kita dapat lebih memahami hubungan antara variabel-variabel dan observasi dalam dataset yang telah direduksi dimensinya menggunakan PCA. Informasi ini sangat berharga dalam memahami pola data, mengidentifikasi outlier, dan menggambarkan karakteristik khusus dari lagu-lagu yang ada dalam data Spotify.
Loading score: panah merah yang menunjukkan kontribusi variabel tersebut terhadap PC, atau banyaknya informasi variabel tersebut yang dirangkum oleh PC.
Dari hasil analisis di atas, kita dapat mengetahui bahwa variabel-variabel yang paling berkontribusi terhadap pembentukan Principal Component 1 (PC1) adalah loudness, energy, acousticness, dan instrumentalness. Variabel-variabel ini memiliki panah merah yang panjang dan menunjuk ke arah yang dominan pada PC1. Hal ini menandakan bahwa atribut-atribut tersebut memiliki pengaruh besar dalam menentukan variasi dan pola data pada sumbu PC1.
Sementara itu, untuk Principal Component 2 (PC2), variabel-variabel yang paling berkontribusi adalah speechiness, duration_ms, dan danceability. Variabel-variabel ini juga memiliki panah merah yang panjang dan menunjuk ke arah yang dominan pada PC2, menandakan bahwa atribut-atribut tersebut memiliki pengaruh besar dalam membentuk variasi dan pola data pada sumbu PC2.
Panah saling berdekatan (sudut antar panah mendekati 0 derajat), maka korelasi tinggi positif
Panah saling tegak lurus (sudut antar panah = 90 derajat), maka tidak berkorelasi
Panah saling bertolak belakang (sudut antar panah mendekati 180 derajat), maka korelasi negatif
💡 Panah yang berhimpit pada biplot: (korelasi tinggi positif)
speechiness x danceability
energy x loudness
💡 Panah yang (hampir) tegak lurus: (hampir tidak punya korelasi)
energy x danceability
loudness x speechiness
💡 Panah yang bertolak belakang (korelasi negatif)
acousticness x energy
acousticness x loudness
Kesimpulan dari hasil proyek di atas adalah sebagai berikut:
Melalui analisis clustering menggunakan metode k-means, lagu-lagu dalam dataset Spotify berhasil dikelompokkan menjadi enam kluster berdasarkan karakteristik dan fitur audio tertentu. Setiap kluster memiliki ciri khasnya sendiri, seperti “Highly Popular Tracks”, “Live or Spoken Word Tracks”, “Instrumental Tracks”, “Acoustic and Mellow Tracks”, “Energetic and Upbeat Tracks”, dan “Danceable Tracks”.
Integrasi metode Principal Component Analysis (PCA) dengan k-means Clustering membantu mereduksi dimensi data Spotify dan memvisualisasikan data dalam bentuk biplot. Dengan menggunakan 7 principal components, kita dapat mempertahankan 92% informasi dari data asli. Analisis biplot membantu memahami hubungan antara variabel-variabel dan observasi dalam data yang telah direduksi.
Dari analisis biplot, dapat diamati bahwa variabel loudness, energy, acousticness, dan instrumentalness berkontribusi besar terhadap pembentukan Principal Component 1 (PC1), sedangkan variabel speechiness, duration_ms, dan danceability berkontribusi besar pada Principal Component 2 (PC2). Selain itu, dapat diidentifikasi korelasi antar variabel berdasarkan sudut antar panah pada biplot.
Hasil analisis ini memberikan wawasan berharga bagi para musisi dan industri musik dalam menciptakan lagu-lagu yang lebih menarik dan populer di platform Spotify. Dengan pemahaman karakteristik utama dari setiap kluster dan pengaruh fitur audio terhadap popularitas, musisi dapat mengarahkan strategi penciptaan musik yang lebih tepat sasaran untuk menarik minat pendengar.
Dengan demikian, proyek ini memberikan kontribusi penting dalam analisis data musik di platform Spotify, serta membuka potensi untuk penggunaan analisis clustering dan PCA dalam memahami lebih dalam pola-pola musik dan preferensi pendengar di dunia industri musik.