Spotify adalah layanan music digital yang menyediakan akses untuk jutaan lagu dari berbagai artis di dunia. Oleh karena tersedia banyak lagu yang dapat diakses , dapat membuat kita binggung dalam memilih lagu yang ingin kita dengar.
Artikel ini akan membantu anda dalam mengcluster lagu-lagu sehingga dapat membantu pembaca dalam memilih lagu yang sesuai dengan kriteria yang kita inginkan
Dekripsi Data :
Akustik: Apakah trek akustik (Nilai lebih tinggi trek akustik)
Danceability: Seberapa cocok lagu untuk berbasis menari (Nilai yang lebih tinggi adalah yang paling bisa menari)
Energi: Mewakili ukuran persepsi dari intensitas dan aktivitas (Musik death metal memiliki energi tinggi)
instrumentalness: Apakah sebuah lagu tidak mengandung vokal (Nilai yang lebih tinggi dari lagu tersebut adalah instrumental)
Kehidupan: Kehadiran penonton dalam rekaman (Lagu dibawakan secara langsung)
Kenyaringan: Tingkat kenyaringan keseluruhan trek dalam desibel (dB)
Kemampuan Berbicara: Kehadiran kata-kata yang diucapkan dalam sebuah trek (Trek mungkin berisi musik atau ucapan)
Valensi: Musik positif yang disampaikan oleh sebuah lagu (Lagu dengan valensi tinggi artinya bahagia atau ceria)
The data I get from Kaggle with this following link:
library(tidyverse)
library(FactoMineR)
library(factoextra)
data_spotify <- read.csv("SpotifyFeatures.csv")
popular_song <- data_spotify %>% filter(popularity >= 75)
Pemilihan angka 75 merupakan Subjektif, jadi bisa disesuai dengan angka yang teman-teman inginkan
Memilih variabel yang digunakan dengan tipe numerik / angka
data_clean <- popular_song %>%
select(c(acousticness,danceability,energy,instrumentalness,liveness,loudness,speechiness,valence))
head(data_clean)
glimpse(data_clean)
## Rows: 3,593
## Columns: 8
## $ acousticness <dbl> 0.023300, 0.422000, 0.544000, 0.619000, 0.031900, 0.0~
## $ danceability <dbl> 0.845, 0.552, 0.515, 0.672, 0.731, 0.818, 0.559, 0.56~
## $ energy <dbl> 0.709, 0.650, 0.479, 0.588, 0.861, 0.705, 0.345, 0.93~
## $ instrumentalness <dbl> 0.00e+00, 2.75e-04, 5.98e-03, 2.41e-01, 0.00e+00, 2.3~
## $ liveness <dbl> 0.0940, 0.3720, 0.1910, 0.0992, 0.0829, 0.6130, 0.141~
## $ loudness <dbl> -4.547, -7.199, -7.458, -9.573, -5.881, -6.679, -13.4~
## $ speechiness <dbl> 0.0714, 0.1280, 0.0261, 0.1330, 0.0323, 0.1770, 0.045~
## $ valence <dbl> 0.6200, 0.3160, 0.2840, 0.2040, 0.7800, 0.7720, 0.458~
anyNA(data_clean)
## [1] FALSE
Mantap!, Tidak ada data yang kosong.
summary(data_clean)
## acousticness danceability energy instrumentalness
## Min. :0.0000183 Min. :0.217 Min. :0.0511 Min. :0.0000000
## 1st Qu.:0.0302000 1st Qu.:0.588 1st Qu.:0.5280 1st Qu.:0.0000000
## Median :0.1180000 Median :0.690 Median :0.6560 Median :0.0000000
## Mean :0.2024467 Mean :0.680 Mean :0.6426 Mean :0.0069187
## 3rd Qu.:0.3070000 3rd Qu.:0.775 3rd Qu.:0.7690 3rd Qu.:0.0000332
## Max. :0.9890000 Max. :0.965 Max. :0.9890 Max. :0.9280000
## liveness loudness speechiness valence
## Min. :0.0215 Min. :-22.320 Min. :0.0228 Min. :0.0352
## 1st Qu.:0.0949 1st Qu.: -7.513 1st Qu.:0.0417 1st Qu.:0.3190
## Median :0.1200 Median : -5.934 Median :0.0676 Median :0.4840
## Mean :0.1681 Mean : -6.347 Mean :0.1126 Mean :0.4911
## 3rd Qu.:0.2010 3rd Qu.: -4.706 3rd Qu.:0.1470 3rd Qu.:0.6570
## Max. :0.8320 Max. : 0.175 Max. :0.6810 Max. :0.9800
as.data.frame(var(data_clean))
plot(prcomp(data_clean))
Setelah nilai cek dan varians plot, kita dapat melihat rata-rata semua variabel adalah selisih dan variabel data varians kenyaringan memiliki sangat tinggi dibandingkan variabel lainnya.
Data dengan variabel perbedaan skala tinggi kurang baik untuk analisis clustering karena bersifat bias. Variabel akan dipertimbangkan untuk menangkap varian tertinggi dan variabel lain akan mempertimbangkan untuk tidak memberikan informasi.
Oleh karena itu, kita harus melakukan penskalaan sebelum melakukan clustering.
data_scale <- data_clean %>% scale() %>% as.data.frame()
summary(data_scale)
## acousticness danceability energy instrumentalness
## Min. :-0.9176 Min. :-3.32076 Min. :-3.49675 Min. :-0.1473
## 1st Qu.:-0.7808 1st Qu.:-0.65987 1st Qu.:-0.67755 1st Qu.:-0.1473
## Median :-0.3828 Median : 0.07169 Median : 0.07912 Median :-0.1473
## Mean : 0.0000 Mean : 0.00000 Mean : 0.00000 Mean : 0.0000
## 3rd Qu.: 0.4739 3rd Qu.: 0.68133 3rd Qu.: 0.74713 3rd Qu.:-0.1466
## Max. : 3.5654 Max. : 2.04405 Max. : 2.04766 Max. :19.6156
## liveness loudness speechiness valence
## Min. :-1.2151 Min. :-6.5843 Min. :-0.8859 Min. :-2.06955
## 1st Qu.:-0.6068 1st Qu.:-0.4807 1st Qu.:-0.6995 1st Qu.:-0.78120
## Median :-0.3988 Median : 0.1702 Median :-0.4441 Median :-0.03216
## Mean : 0.0000 Mean : 0.0000 Mean : 0.0000 Mean : 0.00000
## 3rd Qu.: 0.2725 3rd Qu.: 0.6764 3rd Qu.: 0.3388 3rd Qu.: 0.75319
## Max. : 5.5019 Max. : 2.6884 Max. : 5.6048 Max. : 2.21950
var(data_scale)
## acousticness danceability energy instrumentalness
## acousticness 1.00000000 -0.09576913 -0.50927988 0.06354763
## danceability -0.09576913 1.00000000 -0.11096113 -0.05304323
## energy -0.50927988 -0.11096113 1.00000000 -0.04490081
## instrumentalness 0.06354763 -0.05304323 -0.04490081 1.00000000
## liveness -0.05826970 -0.02498200 0.11930980 0.05359032
## loudness -0.39806260 0.03988425 0.72216648 -0.10517355
## speechiness -0.07090832 0.29456501 -0.08833202 -0.07638406
## valence -0.11123881 0.19362683 0.40562633 -0.08849891
## liveness loudness speechiness valence
## acousticness -0.05826970 -0.39806260 -0.07090832 -0.11123881
## danceability -0.02498200 0.03988425 0.29456501 0.19362683
## energy 0.11930980 0.72216648 -0.08833202 0.40562633
## instrumentalness 0.05359032 -0.10517355 -0.07638406 -0.08849891
## liveness 1.00000000 0.06423751 0.06311147 0.08597184
## loudness 0.06423751 1.00000000 -0.05822185 0.24135328
## speechiness 0.06311147 -0.05822185 1.00000000 0.03003683
## valence 0.08597184 0.24135328 0.03003683 1.00000000
plot(prcomp(data_scale))
Mantap!. Data siap diolah
Fungsi Principal Component Analysis (PCA) adalah untuk mereduksi dimensi data tetapi tetap menyimpan informasi awal, dengan membuat sumbu baru yang dapat menangkap informasi sebanyak mungkin. Sumbu yang dibuat disebut Komponen Utama (PC), di mana sebagian besar informasi ditangkap oleh PC1, diikuti oleh PC2, PC3, PC4, dll
data_pca <- PCA(data_scale,scale.unit = F, graph = F)
plot.PCA(data_pca,
choix = "ind",
select = "contrib 5",
habillage = 1)
Dari plot yang diperlihatkan kita bisa melihat data outlier 477 , 1557 , 1582 , 2438 , 493
Untuk melihat kontribusi variabel daru setiap pc, dan meilihat koerlasi antara variable
plot.PCA(data_pca, choix = "var")
fviz_contrib(X = data_pca,
choice = "var",
axes = 1)
fviz_contrib(X = data_pca,
choice = "var",
axes = 2)
Dari plot di atas, kita mendapatkan wawasan:
Dua variabel yang paling diringkas oleh PC1: energi & kenyaringan
Dua variabel yang paling diringkas oleh PC2: kemampuan menari & ucapan
Variabel dengan korelasi positif tinggi:
energi & kenyaringan
kemampuan menari & berbicara
Variabel dengan korelasi negatif tinggi:
energi & ucapan
kemampuan menari & kehidupan
Sebelum kita melakukan analisis cluster, terlebih dahulu kita perlu menentukan jumlah cluster yang optimal. Dalam metode clustering, kami berusaha untuk meminimalkan jumlah kuadrat dalam cluster (artinya jarak antara observasi dalam cluster yang sama minimal). Untuk mendapatkan jumlah cluster yang optimal dapat digunakan 3 metode yaitu metode elbow, metode siluet, dan statistik gap. Tetapi disini kita akan menggunakan metode elbow
Memilih jumlah cluster menggunakan metode elbow adalah sewenang-wenang. Aturan praktisnya adalah kita memilih jumlah cluster di area “tikungan siku”, dimana grafik jumlah dalam jumlah kotak mulai stagnan dengan bertambahnya jumlah cluster.
RNGkind(sample.kind = "Rounding")
set.seed(417)
fviz_nbclust(data_scale, kmeans, method = "wss")
Dengan metode elbow, diketahui bahwa 8 cluster sudah cukup baik karena tidak ada penurunan yang signifikan dalam jumlah kotak dalam cluster pada jumlah cluster yang lebih banyak.
Berikut algoritma di balik K-Means Clustering:
Tetapkan nomor secara acak, dari 1 hingga K, untuk setiap pengamatan. Ini berfungsi sebagai tugas cluster awal untuk observasi. Iteratre sampai tugas cluster berhenti berubah. Untuk setiap cluster K, hitung pusat cluster. Centroid cluster K adalah vektor sarana fitur p untuk pengamatan pada cluster k. Tetapkan setiap observasi ke cluster yang sentroidnya paling dekat (menggunakan jarak euclidean atau pengukuran jarak lainnya)
RNGkind(sample.kind = "Rounding")
set.seed(417)
# k-means clustering
data_clust <- kmeans(data_clean, centers = 8)
Hasil pengelompokan dapat dilihat dari 3 nilai Within Sum of Squares ($ withinss): jumlah jarak kuadrat dari setiap observasi ke centroid dari setiap cluster. Between Sum of Squares ($ betweenss): jumlah jarak kuadrat dari setiap sentroid ke rata-rata global. Berdasarkan jumlah observasi di cluster. Total Jumlah Kuadrat ($ tots): jumlah kuadrat jarak dari setiap pengamatan ke rata-rata global.
data_clust$withinss
## [1] 120.9976 191.9313 142.4012 211.1565 112.2179 178.3662 130.6765 166.0838
data_clust$betweenss
## [1] 20504.64
data_clust$totss
## [1] 21758.47
check ration clustering
((data_clust$betweenss)/ (data_clust$totss))*100
## [1] 94.2375
fviz_cluster(object=data_clust,
data = data_clean,
labelsize = 7)
popular_song$cluster <- data_clust$cluster
popular_song %>%
select(cluster, acousticness, danceability, energy, instrumentalness, liveness, loudness, speechiness, valence) %>%
group_by(cluster) %>%
summarise_all(mean)
Profiling:
Cluster 1: Lagu dengan banyak kemampuan menari dan energi, tetapi sedikit instrumental dan kenyaringan
Cluster 2: Lagu dengan banyak energi dan valensi, tetapi sedikit instrumental dan ucapan
Cluster 3: Lagu dengan banyak akustik dan instrumental, tetapi sedikit energi dan kenyaringan
Cluster 4: Lagu dengan banyak energi dan semangat, tetapi sedikit akustik dan instrumental
Cluster 5: Lagu dengan banyak instrumentalitas dan akustik, tetapi sedikit energi dan kenyaringan
Cluster 6: Lagu dengan banyak akustik dan kemampuan menari, tetapi sedikit bersemangat dan kenyaringan
Cluster 7: Lagu dengan banyak kemampuan menari dan ucapan, tetapi sedikit instrumentalitas dan valensi
Cluster 8: Lagu dengan banyak energi dan valensi, tetapi sedikit akustik dan instrumental
Example Case 1
popular_song %>%
filter(artist_name == "Linkin Park" & track_name == "Numb") %>% head(5)
Hasil dari artis “Linkin Park” dan nama lagu “Numb” kami memiliki 3 genre dengan cluster yang sama. Dari segi hasil clustering didapatkan hasil yang sama artinya 3 lagu tersebut berada pada cluster 3. Karena lagunya memiliki 3 genre, membuat Anda lebih memiliki pilihan untuk memilih genre yang ingin Anda dengar.
Misalnya, Anda memilih genre “Alternatif” dan musik apa yang selanjutnya akan disarankan?
popular_song %>%
filter(cluster == 3 & ï..genre == "Alternative") %>% head(5)
You can filter song with “cluster 3” and genre “Alternative”. After that you can see 5 song with similar taste and composition.
Contoh Kasus 22
Jika kamu sedang mendengarkan track “How Deep Is Your Love” dengan tempo lebih dari “100” tetapi belum tahu harus memilih musik selanjutnya setelah ini, model ini akan menunjukkan musik selanjutnya dengan komposisi dan rasa yang mirip.
popular_song %>%
filter(track_name == "How Deep Is Your Love" & tempo > 100)
Hasil dari track_name “How Deep Is Your Love” dan tempo lebih dari 100, kami punya 3 genre dengan cluster yang sama. Dari segi hasil clustering didapatkan hasil yang sama artinya 2 lagu berada pada cluster 8. Karena lagunya memiliki 2 genre, membuat Anda lebih memiliki pilihan untuk memilih genre yang ingin Anda dengar.
Misalnya, Anda memilih genre “Pop” dan musik apa yang selanjutnya akan disarankan?
popular_song %>%
filter(cluster == 8 & ï..genre == "Pop") %>% head() %>% as.data.frame()
Anda dapat memfilter lagu dengan “cluster 8” dan genre “Dance”. Setelah itu Anda bisa melihat 115 lagu dengan rasa dan komposisi yang mirip.
Dari analisis pembelajaran tanpa pengawasan di atas, dapat disimpulkan bahwa:
Reduksi dimensi dapat dilakukan dengan menggunakan dataset ini. Untuk melakukan reduksi dimensionalitas, kita dapat memilih PC dari total 8 PC sesuai dengan total informasi yang ingin kita simpan.
Kami dapat memisahkan data kami menjadi 8 cluster berdasarkan semua fitur numerik, dengan pengelompokan akurasi lebih dari 94,2%.