library(dplyr)
library(tidyr)
library(GGally)
library(gridExtra)
library(factoextra)
library(FactoMineR)
library(plotly)
options(scipen = 100, max.print = 1e+06)Pada LBB (Learning by Building) ini akan dilakukan analisis clustering dan principle component analysis dari dataset spotify (https://www.kaggle.com/datasets/bricevergnou/spotify-recommendation).
Hal paling pertama yang harus dilakukan adalah pastikan lokasi folder dataset yang ingin diinput sama dengan Rmd ini. Kemudian, lanjut dengan read dataset.
spotify <- read.csv("spotifyrecom.csv")Dataset telah terbaca dan terinput dengan nama spotify. Untuk mengetahui isi dataset tersebut, lakukan ke tahap selanjutnya yaitu dengan cara menginspeksi data.
head(spotify,3)dim (spotify)#> [1] 195 14
Terlihat bahwa data terdiri dari 195 baris dan 14 kolom. Kemudian, cek missing value apakah ada atau tidak
anyNA(spotify)#> [1] FALSE
colSums(is.na(spotify))#> danceability energy key loudness
#> 0 0 0 0
#> mode speechiness acousticness instrumentalness
#> 0 0 0 0
#> liveness valence tempo duration_ms
#> 0 0 0 0
#> time_signature liked
#> 0 0
Terlihat bahwa tidak ada missing value, sehingga data siap diolah ke tahap selanjutnya.
glimpse(spotify)#> Rows: 195
#> Columns: 14
#> $ danceability <dbl> 0.803, 0.762, 0.261, 0.722, 0.787, 0.778, 0.666, 0.92~
#> $ energy <dbl> 0.6240, 0.7030, 0.0149, 0.7360, 0.5720, 0.6320, 0.589~
#> $ key <int> 7, 10, 1, 3, 1, 8, 0, 7, 7, 3, 9, 1, 1, 6, 8, 5, 8, 8~
#> $ loudness <dbl> -6.764, -7.951, -27.528, -6.994, -7.516, -6.415, -8.4~
#> $ mode <int> 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1,~
#> $ speechiness <dbl> 0.0477, 0.3060, 0.0419, 0.0585, 0.2220, 0.1250, 0.324~
#> $ acousticness <dbl> 0.4510000, 0.2060000, 0.9920000, 0.4310000, 0.1450000~
#> $ instrumentalness <dbl> 0.00073400, 0.00000000, 0.89700000, 0.00000118, 0.000~
#> $ liveness <dbl> 0.1000, 0.0912, 0.1020, 0.1230, 0.0753, 0.0912, 0.114~
#> $ valence <dbl> 0.6280, 0.5190, 0.0382, 0.5820, 0.6470, 0.8270, 0.776~
#> $ tempo <dbl> 95.968, 151.329, 75.296, 89.860, 155.117, 140.951, 74~
#> $ duration_ms <int> 304524, 247178, 286987, 208920, 179413, 224029, 14605~
#> $ time_signature <int> 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,~
#> $ liked <int> 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0,~
Hapus kolom yang tidak diperlukan
spotify1 <- spotify %>%
select(-c(key, mode, time_signature, liked, loudness, tempo, duration_ms))Kemudian, cek isi data yang baru apakah sudah sesuai dengan yang diharapkan
head(spotify1,3)Apakah antar variabel memiliki skala yang sama? Mari kita cek range untuk tiap kolom:
summary(spotify1)#> danceability energy speechiness acousticness
#> Min. :0.1300 Min. :0.0024 Min. :0.0278 Min. :0.000003
#> 1st Qu.:0.4625 1st Qu.:0.5335 1st Qu.:0.0568 1st Qu.:0.042200
#> Median :0.7050 Median :0.6590 Median :0.0962 Median :0.213000
#> Mean :0.6367 Mean :0.6384 Mean :0.1490 Mean :0.319093
#> 3rd Qu.:0.7990 3rd Qu.:0.8375 3rd Qu.:0.2305 3rd Qu.:0.504000
#> Max. :0.9460 Max. :0.9960 Max. :0.5400 Max. :0.995000
#> instrumentalness liveness valence
#> Min. :0.0000000 Min. :0.0331 Min. :0.0353
#> 1st Qu.:0.0000000 1st Qu.:0.0840 1st Qu.:0.2690
#> Median :0.0000076 Median :0.1050 Median :0.5250
#> Mean :0.1923373 Mean :0.1485 Mean :0.4936
#> 3rd Qu.:0.0975000 3rd Qu.:0.1770 3rd Qu.:0.7175
#> Max. :0.9690000 Max. :0.6330 Max. :0.9800
Lihat variance yang dirangkum tiap PC
plot(prcomp(spotify1))
Lakukan normalisasi/standarisasi skala dari variabel numerik dengan
fungsi ‘scale()’
spotify1_scale <- scale(spotify1)
summary(spotify1_scale)#> danceability energy speechiness acousticness
#> Min. :-2.3390 Min. :-2.44537 Min. :-1.0062 Min. :-0.9947
#> 1st Qu.:-0.8040 1st Qu.:-0.40343 1st Qu.:-0.7653 1st Qu.:-0.8632
#> Median : 0.3155 Median : 0.07908 Median :-0.4381 Median :-0.3307
#> Mean : 0.0000 Mean : 0.00000 Mean : 0.0000 Mean : 0.0000
#> 3rd Qu.: 0.7495 3rd Qu.: 0.76537 3rd Qu.: 0.6772 3rd Qu.: 0.5764
#> Max. : 1.4281 Max. : 1.37476 Max. : 3.2475 Max. : 2.1071
#> instrumentalness liveness valence
#> Min. :-0.5555 Min. :-1.0885 Min. :-1.7121
#> 1st Qu.:-0.5555 1st Qu.:-0.6082 1st Qu.:-0.8391
#> Median :-0.5555 Median :-0.4101 Median : 0.1172
#> Mean : 0.0000 Mean : 0.0000 Mean : 0.0000
#> 3rd Qu.:-0.2739 3rd Qu.: 0.2694 3rd Qu.: 0.8363
#> Max. : 2.2432 Max. : 4.5723 Max. : 1.8169
plot(prcomp(spotify1_scale))
Cek hubungan antar variabel yang ada
library(GGally)
ggcorr(spotify1_scale, label = T)
Kesimpulan: Terdapat korelasi yang kuat antar variabel yaitu valence dan
danceability.
Principal Component Analysis
spotify_pca <- prcomp(spotify1_scale, scale. = F)
summary(spotify_pca)#> Importance of components:
#> PC1 PC2 PC3 PC4 PC5 PC6 PC7
#> Standard deviation 1.6986 1.2490 0.9606 0.8953 0.66258 0.47836 0.4030
#> Proportion of Variance 0.4122 0.2229 0.1318 0.1145 0.06272 0.03269 0.0232
#> Cumulative Proportion 0.4122 0.6351 0.7669 0.8814 0.94411 0.97680 1.0000
Ingin mempertahankan informasi pada data sebanyak ~80%, PC1 sampai 4 akan dipertahankan
Buat dataset baru hasil PC yang dipertahankan, simpanlah dalam object
spotify_wbcd
spotify_wbcd <- as.data.frame(spotify_pca$x[, 1:4])
head(spotify_wbcd)*Menggunakan PCA() dari library FactoMineR,
dan jangan lupa untuk scaling hanya dilakukan sekali saja
# your code here
library(FactoMineR)
spotify_pca1 <- PCA(X = spotify1_scale,
scale.unit = F,
graph = F)Visualize
Visualisasikan individual factor plot, dan identifikasi 5 outlier terluar
plot.PCA(x = spotify_pca1,
choix = "ind",
select="contrib 5")
Kesimpulan: Tidak ada outlier.
fviz_contrib(X = spotify_pca1,
choice = "var",
axes = 1)
Kesimpulan: 3 variabel yang paling berkontribusi pada PC 1
berdasarkan korelasi antara variabel dengan PC 1 adalah
instrumentalness, danceability dan valence.
Choose Optimum K
# function
RNGkind(sample.kind = "Rounding")
kmeansTunning <- function(data, maxK) {
withinall <- NULL
total_k <- NULL
for (i in 1:maxK) {
set.seed(4)
temp <- kmeans(data,i)$tot.withinss
withinall <- append(withinall, temp)
total_k <- append(total_k,i)
}
plot(x = total_k, y = withinall, type = "o", xlab = "Number of Cluster", ylab = "Total within")
}
# apply function
# kmeansTunning(your_data, maxK = 5)
kmeansTunning(spotify1_scale, maxK = 5)
Dipilih titik dimana penurunan total within sum of squares tidak lagi
signifikan/melandai (titik elbow). Berdasarkan hasil elbow
plot kita akan memilih nilai k = 2.
K-means Clustering
Lakukan k-means clustering berdasarkan elbow method sebelumnya dan
simpan hasilnya pada objek ws_kmeans
RNGkind(sample.kind = "Rounding")
set.seed(333)
# your code here
ws_kmeans <- kmeans(x = spotify1_scale,
centers = 2)Cluster Profiling
Kembalikan label cluster masing-masing observasi ke data awal sebelum di-scale, namun yang outliernya sudah di-remove
# your code here
spotify1$kelompok <- ws_kmeans$clusterLakukan profiling cluster dengan mencari nilai rata-rata untuk masing-masing produk
# your code here
spotify1 %>%
group_by(kelompok) %>%
summarise_all(mean)Profiling:
library(ggiraphExtra)
ggRadar(data=spotify1, aes(colour=kelompok), interactive=TRUE)Dengan menggunakan PCA diperoleh 3 variabel yang paling berkontribusi pada PC 1 berdasarkan korelasi antara variabel dengan PC 1 adalah instrumentalness, danceability dan valence.
Dengan menggunakan K-means Clustering, diperoleh 2 cluster yaitu: