Emails: &
Linked In: https://www.linkedin.com/in/juenzy-hodawya-a310ab1a3/
Kaggle: https://www.kaggle.com/juenzyhodawya
GitHub: https://github.com/JuenzyHodawya


1 Latar Belakang

Spotify adalah layanan streaming musik digital, podcast, dan video yang memberimu akses ke jutaan lagu dan konten lain dari artis di seluruh dunia.

Cara Spotify menyarankan musik kepada pendengar ternyata memiliki pengaruh besar pada kebiasaan mendengarkan lagu. Motivasi dari penlitian ini adalah untuk memungkinkan siapa pun mendapatkan pengetahuan tentang musik yang mereka dengarkan. Sehingga mereka mendapatkan pemahaman yang lebih baik tentang perilaku musik saat mendengarkan lagu di Spotify.

Tujuan dari analisis ini adalah

  • untuk mengetahui cara Spotify menilai popularitas sebuah lagu,
  • untuk melihat faktor apa saja yang menentukan genre sebuah lagu,
  • untuk melihat karakteristik lagu apa yang dapat menentukan popularitasnya,
  • untuk memprediksi popularitas berdasarkan karakter lagu dengan menggunakan Multiple Linear Regression.

2 Persiapan Data

2.1 Packages

library(tidyverse)
library(ggplot2)
library(ggcorrplot)
library(GGally)
library(dplyr)
library(rsample)
library(psych)
library(DAAG)
library(highcharter)
library(knitr)
library(kableExtra)
library(DT)
library(tm)
library(corrplot)
library(leaps)

2.2 Import Data

Kita akan menggunakan dataset Spotify yang merupakan kumpulan data atau metadata umum seputar lagu dari API Spotify. Data yang kita gunakan tersedia di GitHub.com.

spotify_songs <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-01-21/spotify_songs.csv')

data.frame("total.data" = dim(spotify_songs)[1],
           "total.variabel" = dim(spotify_songs)[2])
##   total.data total.variabel
## 1      32833             23

Dataset ini terdiri dari 32.833 data dengan 23 variabel.

2.3 Deskripsi Variabel

Berikut ini merupakan deskripsi dari masing-masing variabel dari dataset:

Variable Deskripsi
track_id ID Unik
track_name Nama Lagu
track_artist Artis Lagu
track_popularity Popularitas Lagu (0-100) di mana lebih tinggi lebih baik
track_album_id ID Album Unik
track_album_name Nama Album Lagu
track_album_release_date Tanggal saat Album Dirilis
playlist_name Nama Playlist
playlist_id ID Playlist
playlist_genre Genre Playlist
playlist_subgenre Subgenre Playlist
danceability Menggambarkan seberapa cocok sebuah lagu untuk menari berdasarkan kombinasi elemen musik. Nilai 0 paling tidak cocok untuk menari dan 1 paling cocok untuk menari.
energy Energi adalah ukuran dari 0 hingga 1 dan mewakili ukuran persepsi intensitas dan aktivitas.
key Kunci keseluruhan trek yang diperkirakan. Integer memetakan ke pitch menggunakan notasi Kelas Pitch standar.
loudness Tingkat kenyaringan keseluruhan trek dalam desibel (dB).
mode Mode menunjukkan modalitas (mayor atau minor) trek
speechiness Kemampuan berbicara mendeteksi keberadaan kata-kata yang diucapkan di trek.
acousticness Ukuran keyakinan dari 0 hingga 1 untuk mengetahui apakah trek tersebut akustik. 1 menunjukkan keyakinan tinggi bahwa lagu tersebut akustik.
instrumentalness Memprediksi apakah suatu lagu tidak berisi vokal.
liveness Mendeteksi kehadiran penonton dalam rekaman. Nilai kehidupan yang lebih tinggi menunjukkan peningkatan probabilitas bahwa lagu tersebut dimainkan secara langsung. Nilai di atas 0,8 memberikan kemungkinan yang kuat bahwa trek tersebut hidup.
valence Ukuran dari 0 hingga 1 yang mendeskripsikan musik positif yang disampaikan oleh sebuah trek. Lagu dengan valensi tinggi terdengar lebih positif.
tempo Perkiraan Keseluruhan tempo pada trek dalam ketukan per menit (BPM)
duration_ms Durasi Lagu dalam Milidetik

3 Pembersihan Data

3.1 Struktur Data

glimpse(spotify_songs)
## Rows: 32,833
## Columns: 23
## $ track_id                 <chr> "6f807x0ima9a1j3VPbc7VN", "0r7CVbZTWZgbTCY...
## $ track_name               <chr> "I Don't Care (with Justin Bieber) - Loud ...
## $ track_artist             <chr> "Ed Sheeran", "Maroon 5", "Zara Larsson", ...
## $ track_popularity         <dbl> 66, 67, 70, 60, 69, 67, 62, 69, 68, 67, 58...
## $ track_album_id           <chr> "2oCs0DGTsRO98Gh5ZSl2Cx", "63rPSO264uRjW1X...
## $ track_album_name         <chr> "I Don't Care (with Justin Bieber) [Loud L...
## $ track_album_release_date <chr> "2019-06-14", "2019-12-13", "2019-07-05", ...
## $ playlist_name            <chr> "Pop Remix", "Pop Remix", "Pop Remix", "Po...
## $ playlist_id              <chr> "37i9dQZF1DXcZDD7cfEKhW", "37i9dQZF1DXcZDD...
## $ playlist_genre           <chr> "pop", "pop", "pop", "pop", "pop", "pop", ...
## $ playlist_subgenre        <chr> "dance pop", "dance pop", "dance pop", "da...
## $ danceability             <dbl> 0.748, 0.726, 0.675, 0.718, 0.650, 0.675, ...
## $ energy                   <dbl> 0.916, 0.815, 0.931, 0.930, 0.833, 0.919, ...
## $ key                      <dbl> 6, 11, 1, 7, 1, 8, 5, 4, 8, 2, 6, 8, 1, 5,...
## $ loudness                 <dbl> -2.634, -4.969, -3.432, -3.778, -4.672, -5...
## $ mode                     <dbl> 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, ...
## $ speechiness              <dbl> 0.0583, 0.0373, 0.0742, 0.1020, 0.0359, 0....
## $ acousticness             <dbl> 0.10200, 0.07240, 0.07940, 0.02870, 0.0803...
## $ instrumentalness         <dbl> 0.00e+00, 4.21e-03, 2.33e-05, 9.43e-06, 0....
## $ liveness                 <dbl> 0.0653, 0.3570, 0.1100, 0.2040, 0.0833, 0....
## $ valence                  <dbl> 0.518, 0.693, 0.613, 0.277, 0.725, 0.585, ...
## $ tempo                    <dbl> 122.036, 99.972, 124.008, 121.956, 123.976...
## $ duration_ms              <dbl> 194754, 162600, 176616, 169093, 189052, 16...

Berdasarkan struktur data diatas, terdapat variabel-variabel yang tipe datanya perlu disesuaikan lagi berdasar sifat datanya sesuai dengan deskripsi variabel yang sudah dijelaskan adalah:

  • track_id: dari character menjadi factor
  • track_name: dari character menjadi factor
  • track_artist: dari character menjadi factor
  • track_popularity: dari character menjadi integer
  • track_album_id: dari character menjadi factor
  • track_album_name: dari character menjadi factor
  • track_album_release_date: dari character menjadi factor
  • playlist_name: dari integer menjadi factor
  • playlist_id: dari integer menjadi factor
  • playlist_genre: dari integer menjadi factor
  • playlist_subgenre: dari integer menjadi factor
  • key: dari numerik menjadi integer
  • mode: dari numerik menjadi integer
  • duration_ms: dari numerik menjadi integer
spotify_songs <- spotify_songs %>%
  mutate(
    track_id = as.factor(track_id),
    track_name = as.factor(track_name),
    track_artist = as.factor(track_artist),
    track_popularity = as.integer(track_popularity),
    track_album_id = as.factor(track_album_id),
    track_album_name = as.factor(track_album_name),
    track_album_release_date = as.factor(track_album_release_date),
    playlist_name = as.factor(playlist_name),
    playlist_id = as.factor(playlist_id),
    playlist_genre = as.factor(playlist_genre),
    playlist_subgenre = as.factor(playlist_subgenre),
    key = as.integer(key),
    mode = as.integer(mode),
    duration_ms = as.integer(duration_ms)
  )

Berikut ini diperlihatkan struktur dataset setelah dilakukan penyesuaian dengan sifat datanya:

glimpse(spotify_songs)
## Rows: 32,833
## Columns: 23
## $ track_id                 <fct> 6f807x0ima9a1j3VPbc7VN, 0r7CVbZTWZgbTCYdfa...
## $ track_name               <fct> I Don't Care (with Justin Bieber) - Loud L...
## $ track_artist             <fct> Ed Sheeran, Maroon 5, Zara Larsson, The Ch...
## $ track_popularity         <int> 66, 67, 70, 60, 69, 67, 62, 69, 68, 67, 58...
## $ track_album_id           <fct> 2oCs0DGTsRO98Gh5ZSl2Cx, 63rPSO264uRjW1X5E6...
## $ track_album_name         <fct> I Don't Care (with Justin Bieber) [Loud Lu...
## $ track_album_release_date <fct> 2019-06-14, 2019-12-13, 2019-07-05, 2019-0...
## $ playlist_name            <fct> Pop Remix, Pop Remix, Pop Remix, Pop Remix...
## $ playlist_id              <fct> 37i9dQZF1DXcZDD7cfEKhW, 37i9dQZF1DXcZDD7cf...
## $ playlist_genre           <fct> pop, pop, pop, pop, pop, pop, pop, pop, po...
## $ playlist_subgenre        <fct> dance pop, dance pop, dance pop, dance pop...
## $ danceability             <dbl> 0.748, 0.726, 0.675, 0.718, 0.650, 0.675, ...
## $ energy                   <dbl> 0.916, 0.815, 0.931, 0.930, 0.833, 0.919, ...
## $ key                      <int> 6, 11, 1, 7, 1, 8, 5, 4, 8, 2, 6, 8, 1, 5,...
## $ loudness                 <dbl> -2.634, -4.969, -3.432, -3.778, -4.672, -5...
## $ mode                     <int> 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, ...
## $ speechiness              <dbl> 0.0583, 0.0373, 0.0742, 0.1020, 0.0359, 0....
## $ acousticness             <dbl> 0.10200, 0.07240, 0.07940, 0.02870, 0.0803...
## $ instrumentalness         <dbl> 0.00e+00, 4.21e-03, 2.33e-05, 9.43e-06, 0....
## $ liveness                 <dbl> 0.0653, 0.3570, 0.1100, 0.2040, 0.0833, 0....
## $ valence                  <dbl> 0.518, 0.693, 0.613, 0.277, 0.725, 0.585, ...
## $ tempo                    <dbl> 122.036, 99.972, 124.008, 121.956, 123.976...
## $ duration_ms              <int> 194754, 162600, 176616, 169093, 189052, 16...

3.2 Data Duplikat

Setelah diamati ternyata banyak lagu yang diulang lebih dari satu kali dalam dataset ini. Mereka memiliki track_id yang sama dengan playlist_id yang berbeda. Jadi kita perlu menghapus lagu-lagu duplikat tersebut dalam dataset. Karena track_id lagu itu unik dan variabel terukur lainnya dari lagu tersebut tetap sama, kami akan menghapus lagu duplikat tersebut berdasarkan track_id.

table(duplicated(spotify_songs$track_id))
## 
## FALSE  TRUE 
## 28356  4477
spotify_unique = spotify_songs[!duplicated(spotify_songs$track_id),]

3.3 Eliminasi Variabel

Karena sekarang kita tidak memiliki lagu yang berulang dalam playlist, maka untuk menganalisis variabel track_popularity kita dapat menghapus variabel berikut yang tidak berguna dalam analisis ini:

spotify_songs_2 <- spotify_unique[c(-1, -5, -6, -8, -9, -11)]
names(spotify_songs_2)
##  [1] "track_name"               "track_artist"            
##  [3] "track_popularity"         "track_album_release_date"
##  [5] "playlist_genre"           "danceability"            
##  [7] "energy"                   "key"                     
##  [9] "loudness"                 "mode"                    
## [11] "speechiness"              "acousticness"            
## [13] "instrumentalness"         "liveness"                
## [15] "valence"                  "tempo"                   
## [17] "duration_ms"

3.4 Membagi track_album_release_date

Untuk analisis yang lebih mudah, lakukanlah pembagian track_album_release_date menjadi tiga kolom baru yaitu:

  • track_album_release_year
  • track_album_release_month
  • track_album_release_day

Kita hanya akan fokus pada tahun rilis untuk analisis kali ini. Jadi kita akan menghapus track_album_release_month & track_album_release_day dari dataset.

spotify_songs_3 <- spotify_songs_2 %>%
  separate(track_album_release_date,
           c("track_album_release_year","track_album_release_month","track_album_release_day"),
           sep = "-")

spotify_songs_4 <- spotify_songs_3[c(-5, -6)]
head(spotify_songs_4)
## # A tibble: 6 x 17
##   track_name track_artist track_popularity track_album_rel~ playlist_genre
##   <fct>      <fct>                   <int> <chr>            <fct>         
## 1 I Don't C~ Ed Sheeran                 66 2019             pop           
## 2 Memories ~ Maroon 5                   67 2019             pop           
## 3 All the T~ Zara Larsson               70 2019             pop           
## 4 Call You ~ The Chainsm~               60 2019             pop           
## 5 Someone Y~ Lewis Capal~               69 2019             pop           
## 6 Beautiful~ Ed Sheeran                 67 2019             pop           
## # ... with 12 more variables: danceability <dbl>, energy <dbl>, key <int>,
## #   loudness <dbl>, mode <int>, speechiness <dbl>, acousticness <dbl>,
## #   instrumentalness <dbl>, liveness <dbl>, valence <dbl>, tempo <dbl>,
## #   duration_ms <int>

3.5 Data Hilang

Sekarang kita memeriksa nilai yang hilang pada dataset.

colSums(is.na(spotify_songs_4))
##               track_name             track_artist         track_popularity 
##                        4                        4                        0 
## track_album_release_year           playlist_genre             danceability 
##                        0                        0                        0 
##                   energy                      key                 loudness 
##                        0                        0                        0 
##                     mode              speechiness             acousticness 
##                        0                        0                        0 
##         instrumentalness                 liveness                  valence 
##                        0                        0                        0 
##                    tempo              duration_ms 
##                        0                        0

Kita amati ternyata ada 4 data yang hilang dalam variabel track_name dan track_artist. Namun, kita tetap dapat melanjutkan analisis ini, karena dua variabel tersebut tidak akan memengaruhi analisis ini.

3.6 Melihat Dataset

Menampilkan 100 baris dari dataset yang sudah dibersihkan

output_data <- head(spotify_songs_4, n = 100)

datatable(output_data, 
          filter = 'top', 
          options = list(pageLength = 10))

Menampilkan ringkasan (summary) dari dataset

summary(spotify_songs_4)
##     track_name                       track_artist   track_popularity
##  Breathe :   18   Queen                    :  130   Min.   :  0.00  
##  Paradise:   17   Martin Garrix            :   87   1st Qu.: 21.00  
##  Poison  :   16   Don Omar                 :   84   Median : 42.00  
##  Alive   :   15   David Guetta             :   81   Mean   : 39.33  
##  Forever :   14   Dimitri Vegas & Like Mike:   68   3rd Qu.: 58.00  
##  (Other) :28272   (Other)                  :27902   Max.   :100.00  
##  NA's    :    4   NA's                     :    4                   
##  track_album_release_year playlist_genre  danceability        energy        
##  Length:28356             edm  :4877     Min.   :0.0000   Min.   :0.000175  
##  Class :character         latin:4137     1st Qu.:0.5610   1st Qu.:0.579000  
##  Mode  :character         pop  :5132     Median :0.6700   Median :0.722000  
##                           r&b  :4504     Mean   :0.6534   Mean   :0.698388  
##                           rap  :5401     3rd Qu.:0.7600   3rd Qu.:0.843000  
##                           rock :4305     Max.   :0.9830   Max.   :1.000000  
##                                                                             
##       key            loudness            mode         speechiness    
##  Min.   : 0.000   Min.   :-46.448   Min.   :0.0000   Min.   :0.0000  
##  1st Qu.: 2.000   1st Qu.: -8.309   1st Qu.:0.0000   1st Qu.:0.0410  
##  Median : 6.000   Median : -6.261   Median :1.0000   Median :0.0626  
##  Mean   : 5.368   Mean   : -6.818   Mean   :0.5655   Mean   :0.1080  
##  3rd Qu.: 9.000   3rd Qu.: -4.709   3rd Qu.:1.0000   3rd Qu.:0.1330  
##  Max.   :11.000   Max.   :  1.275   Max.   :1.0000   Max.   :0.9180  
##                                                                      
##   acousticness     instrumentalness       liveness         valence      
##  Min.   :0.00000   Min.   :0.0000000   Min.   :0.0000   Min.   :0.0000  
##  1st Qu.:0.01438   1st Qu.:0.0000000   1st Qu.:0.0926   1st Qu.:0.3290  
##  Median :0.07970   Median :0.0000206   Median :0.1270   Median :0.5120  
##  Mean   :0.17718   Mean   :0.0911168   Mean   :0.1910   Mean   :0.5104  
##  3rd Qu.:0.26000   3rd Qu.:0.0065700   3rd Qu.:0.2490   3rd Qu.:0.6950  
##  Max.   :0.99400   Max.   :0.9940000   Max.   :0.9960   Max.   :0.9910  
##                                                                         
##      tempo         duration_ms    
##  Min.   :  0.00   Min.   :  4000  
##  1st Qu.: 99.97   1st Qu.:187742  
##  Median :121.99   Median :216933  
##  Mean   :120.96   Mean   :226576  
##  3rd Qu.:134.00   3rd Qu.:254975  
##  Max.   :239.44   Max.   :517810  
## 

4 Eksplorasi Data Analisis

4.1 Matriks Korelasi

corr_plot_data <- spotify_songs_4 %>% 
          select(track_popularity,
                 danceability, 
                 energy, 
                 key, 
                 loudness, 
                 mode, 
                 speechiness,
                 acousticness,
                 instrumentalness,
                 liveness, 
                 valence, 
                 tempo, 
                 duration_ms)

ggcorr(corr_plot_data,
       label = T,
       size = 3,
       label_size = 3,
       hjust = 0.8) +
  labs(
    title = "Matriks Korelasi"
  ) +
  theme_minimal() + 
  theme(
    plot.title  = element_text(hjust = 0.5),
    axis.title  = element_text(size = 3,
                               face = "bold"), 
    axis.text.y = element_blank()
  )

Dari Matriks Korelasi di atas, dapat kita amati bahwa:

  • Korelasi yang positif tinggi yaitu antaraenergy dan loudness,
  • Korelasi yang positif yaitu antara danceability dan valence,
  • Korelasi yang negatif kuat yaitu antara acousticness dan energy,
  • Korelasi yang negatif tinggi yaitu antara acousticness dan loudness.

Selain itu, kita juga dapat menggunakan matriks korelasi untuk melihat apakah ada korelasi antara popularitas dan karakteristik lagu.

Korelasi Positif antara Popularitas dengan acousticness, danceability, loudness, dan valensi.
Korelasi Negatif antara Popularitas dengan liveness, energy, instrumentalness, dan duration_ms.

Karakter yang tidak termasuk ke dalam dua golongan di atas artinya tidak memiliki korelasi dengan popularitas.

4.2 Distriusi Variabel

feature_names <- names(spotify_songs_4)[c(3,6:17)]

songs <- spotify_songs_4 %>% 
            select(c(feature_names)) %>%
            pivot_longer(cols = feature_names) 

songs %>%
  ggplot(aes(x = value)) +
  geom_histogram() +
  facet_wrap(~name, ncol = 5, scales = 'free') +
  labs(title = 'Plot Frekuensi Pola Fitur Audio', x = '', y = '') +
  theme(axis.text.y = element_blank())

Kita membuat Histogram untuk meringkas distribusi variabel dalam dataset. Maka hasil pengamatannya adalah:

  • Durasi dan Valensi didistribusikan secara normal
  • Danceability, Enery, dan Loudness miring ke kiri
  • Akustik, Liveness, dan Ucapan miring ke kanan
  • Kunci mengikuti distribusi sisir karena batangnya tinggi dan pendek secara bergantian. Menunjukkan data yang dibulatkan.

4.3 Karakteristik Genre (Density)

songs_data <- names(spotify_songs_4)[c(6:9,11:17)]

songs <- spotify_songs_4 %>%
            select(c('playlist_genre', songs_data)) %>%
            pivot_longer(cols = songs_data) 

songs %>%
  ggplot(aes(x = value)) +
  geom_density(aes(color = playlist_genre)) +
  facet_wrap(~name, ncol = 4, scales = 'free') +
  labs(title = 'Karakteristik Lagu',x = '', y = '') +
  theme(axis.text.x = element_text(angle = 50, 
                                   hjust = 1),
        axis.text.y = element_blank())

Dari visualisasi di atas, dapat kita amati bahwa lagu-lagu dari genre yang berbeda ternyata mengikuti pola karakteristik yang berbeda pula. Hasil pengamatannya adalah:

  • Genre edm memiliki tingkat energi dan tempo yang tinggi,
  • Genre latin memiliki tingkat valensi dan danceability yang tinggi,
  • Genre rock kemungkinan besar akan direkam secara langsung dan memiliki danceability yang rendah,
  • Genre r&b, rap, dan rock lebih cenderung memiliki durasi yang lebih pendek dibandingkan dengan pop, latin, dan edm.

Klasifikasi Genre
Berdasarkan plot density, nampaknya energy, valence, dan danceability dapat memberikan pemisahan yang paling banyak antar genre selama klasifikasi. Sedangkan, instrumentalness dan key mungkin tidak banyak berdampak.

Jadi kombinasi dari semua karakteristik lagu ini berkontribusi pada pengklasifikasiannya ke dalam genre masing-masing.

4.4 Genre Terpopuler di Spotify

spotify_songs_4 %>%
  filter(!is.na(track_artist)) %>%
  count(playlist_genre) %>%
  ggplot() +
  geom_col(aes(x = playlist_genre, 
               y = n, 
               fill = playlist_genre)) +
  coord_polar() +
  theme(axis.text.x = element_text(hjust = 1), 
        axis.text.y = element_text(hjust = 1)) + 
  ggtitle("Jumlah Lagu di Semua Genre") + 
  xlab("Genre Lagu") + 
  ylab("Jumlah Lagu")

Grafik ini menunjukkan bahwa jumlah lagu terbanyak di Spotify (secara berurutan), yaitu rap, pop, edm, r&b, rock, dan latin.

4.5 Karakteristik dari Lagu Populer

feature_names <- names(spotify_songs_4)[c(6,7,9,11:16)]

songs <- spotify_songs_4 %>% 
  arrange(desc(track_popularity)) %>%
  head(n = 500) %>%
  pivot_longer(cols = feature_names) 

songs %>%
  ggplot(aes(x = name, y = value)) +
  geom_jitter(aes(color = playlist_genre)) +
  facet_wrap(~name, ncol = 3, scales = 'free') +
  labs(title = 'Plot Frekuensi Pola Audio', x = '', y = '') +
  theme(axis.text.y = element_blank())

Dari plot jitter di atas, dapat kita amati bahwa lagu paling populer di Spotify memiliki karakteristik sebagai berikut:

  • loud, danceable tinggi, energetic tinggi,
  • acousticness rendah, speechiness rendah, instrumentalness rendah

4.6 10 Lagu Teratas di Spotify

Kita akan menentukan 10 lagu teratas di Spotify.

top_songs <- spotify_songs_4 %>%
  select(track_name, 
         track_artist,
         playlist_genre, 
         track_popularity) %>%
  group_by(playlist_genre) %>%
  arrange(desc(track_popularity)) %>%
  head(n = 10)

top_songs %>% 
  ggplot(mapping = aes(x = track_name, 
                       y = track_popularity, 
                       color = track_name)) +
  geom_point() +
  coord_polar() +
  theme_minimal() +
  labs(x = 'track_name', 
       y = 'track_popularity', 
       title = '10 Lagu Teratas di Spotify') +
  theme(plot.title = element_text(hjust = 0.5),
        legend.position = 'right')

top_songs %>%
  kable() %>%
  kable_styling()
track_name track_artist playlist_genre track_popularity
Dance Monkey Tones and I pop 100
ROXANNE Arizona Zervas latin 99
Tusa KAROL G pop 98
Memories Maroon 5 pop 98
Blinding Lights The Weeknd pop 98
Circles Post Malone pop 98
The Box Roddy Ricch rap 98
everything i wanted Billie Eilish pop 97
Don’t Start Now Dua Lipa pop 97
Falling Trevor Daniel pop 97

Dari hasil pengamatan, menunjukkan bahwa lagu Dance Monkey dari Tones and I dengan genre musik pop memiliki popularitas paling tinggi di Spotify.

5 Split Data

Dari 28.356 data pengamatan, kita split dataset menjadi 80% data train dan 20% data test. Data train digunakan untuk melakukan pemodelan dan data test dianggap sebagai unseen data yang digunakan untuk menguji seberapa baik model yang dibuat.

set.seed(123)
split <- initial_split(spotify_songs_4, prop = 0.8, strata = "track_popularity")
spo_train <- training(split)
spo_test <- testing(split)

df_split <- rbind(
data.frame(table(spo_train$track_popularity),"type"="train"),
data.frame(table(spo_test$track_popularity),"type"="test")) %>% 
  mutate(
    Var1 = as.factor(Var1),
    type = as.factor(type)
  ) 

dim(spo_train)
## [1] 22687    17
dim(spo_test)
## [1] 5669   17

Data train sebesasr 22.687 dan data test sebesar 5.669.

6 Pemodelan (Multiple Linear Regression)

6.1 Model Awal

Multiple Linear Regression bertujuan untuk memprediksi nilai variabel dependen track_popularity berdasarkan variabel independen yaitu karakteristik lagu.

model <- lm(track_popularity ~ danceability + energy + key + loudness + mode + speechiness + acousticness + instrumentalness + liveness + valence + tempo + duration_ms,
            data = spotify_songs_4)

summary(model)
## 
## Call:
## lm(formula = track_popularity ~ danceability + energy + key + 
##     loudness + mode + speechiness + acousticness + instrumentalness + 
##     liveness + valence + tempo + duration_ms, data = spotify_songs_4)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -54.62 -17.22   2.95  18.10  60.54 
## 
## Coefficients:
##                    Estimate Std. Error t value Pr(>|t|)    
## (Intercept)       6.783e+01  1.704e+00  39.805  < 2e-16 ***
## danceability      3.721e+00  1.072e+00   3.470 0.000522 ***
## energy           -2.321e+01  1.220e+00 -19.028  < 2e-16 ***
## key               3.190e-03  3.844e-02   0.083 0.933870    
## loudness          1.156e+00  6.527e-02  17.711  < 2e-16 ***
## mode              8.616e-01  2.809e-01   3.067 0.002161 ** 
## speechiness      -6.328e+00  1.380e+00  -4.587 4.52e-06 ***
## acousticness      4.331e+00  7.466e-01   5.801 6.67e-09 ***
## instrumentalness -9.292e+00  6.255e-01 -14.856  < 2e-16 ***
## liveness         -4.280e+00  8.990e-01  -4.761 1.93e-06 ***
## valence           1.788e+00  6.565e-01   2.724 0.006458 ** 
## tempo             2.609e-02  5.239e-03   4.979 6.42e-07 ***
## duration_ms      -4.342e-05  2.294e-06 -18.925  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 23.01 on 28343 degrees of freedom
## Multiple R-squared:  0.05808,    Adjusted R-squared:  0.05768 
## F-statistic: 145.6 on 12 and 28343 DF,  p-value: < 2.2e-16

6.2 Pemilihan Variabel

model_new <- regsubsets(track_popularity ~ danceability + energy + key + loudness + mode + speechiness + acousticness + instrumentalness + liveness + valence + tempo + duration_ms, 
             data = spotify_songs_4,
             nbest = 7)

plot(model_new, scale = "bic")

Dapat dilihat pada plot di atas bahwa semua variabel adalah signifikan secara statistik dalam memprediksi track_popularity kecuali variabel key.

6.3 Model Akhir

model_final <- lm(track_popularity ~ danceability + energy + loudness + mode + speechiness + acousticness + instrumentalness + liveness + valence + tempo + duration_ms, 
             data = spotify_songs_4)

summary(model_final)
## 
## Call:
## lm(formula = track_popularity ~ danceability + energy + loudness + 
##     mode + speechiness + acousticness + instrumentalness + liveness + 
##     valence + tempo + duration_ms, data = spotify_songs_4)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -54.624 -17.226   2.949  18.099  60.533 
## 
## Coefficients:
##                    Estimate Std. Error t value Pr(>|t|)    
## (Intercept)       6.785e+01  1.692e+00  40.113  < 2e-16 ***
## danceability      3.720e+00  1.072e+00   3.469 0.000523 ***
## energy           -2.321e+01  1.219e+00 -19.030  < 2e-16 ***
## loudness          1.156e+00  6.527e-02  17.712  < 2e-16 ***
## mode              8.576e-01  2.765e-01   3.101 0.001930 ** 
## speechiness      -6.326e+00  1.379e+00  -4.586 4.54e-06 ***
## acousticness      4.331e+00  7.465e-01   5.803 6.60e-09 ***
## instrumentalness -9.292e+00  6.254e-01 -14.856  < 2e-16 ***
## liveness         -4.280e+00  8.990e-01  -4.761 1.93e-06 ***
## valence           1.789e+00  6.564e-01   2.726 0.006414 ** 
## tempo             2.608e-02  5.239e-03   4.979 6.44e-07 ***
## duration_ms      -4.342e-05  2.294e-06 -18.928  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 23.01 on 28344 degrees of freedom
## Multiple R-squared:  0.05808,    Adjusted R-squared:  0.05771 
## F-statistic: 158.9 on 11 and 28344 DF,  p-value: < 2.2e-16

7 Prediksi

Sekarang kita gunakan model yang sudah dibuat untuk membuat suatu prediksi tentang track_popularity.

new_popularity <- data.frame(danceability = 0.718,
                             energy = 0.93,
                             loudness = -3.778,
                             mode = 1,
                             speechiness = 0.102,
                             acousticness = 0.0287,
                             instrumentalness = 0,
                             liveness = 0.204,
                             valence = 0.277,
                             tempo = 121.956,
                             duration_ms = 169093)

print(paste0("Popularitas yang Diamati: ",60))
## [1] "Popularitas yang Diamati: 60"
predicted <- predict(model_final, newdata = new_popularity)
print(paste0("Popularitas yang Diprediksi: ",(predicted)))
## [1] "Popularitas yang Diprediksi: 40.3716218419876"

8 Kesimpulan

Popularitas sebuah lagu paling dipengaruhi oleh danceability, loudness, dan valence dari lagu tersebut. Kita dapatkan kesimpulan ini dari Matriks Korelasi dan Plot Jitter dari lagu-lagu yang terpopuler di Spotify.

Faktor-faktor yang menentukan genre lagu adalah danceability, energy, dan valence. Kita dapatkan kesimpulan ini dari Plot Density karakteristik lagu.

Spotify dapat menentukan popularitas lagu berdasarkan semua karakteristik selain ‘kunci’. Kita mendapatkan kesimpulan ini dari model yang kita buat menggunakan Multiple Linear Regression melalui metode Pemilihan Variabel.