Genero las conexiones a MongoDB a la nueva colección

library(mongolite)

conexion_facts_avg_lab06 = mongo(collection = "facts_avg_lab06", db = "SPOTIFY_UBA" )
data = conexion_facts_avg_lab06$find('{}')

Agrupo las variables entre categóricas y numéricas

library(tidyverse)
library(knitr)

numericas <- data %>% select_if(is.numeric) %>% as.data.frame()
categoricas <- data %>% select_if(negate(is.numeric)) %>% as.data.frame()

# Omitimos potenciales faltantes
numericas = na.omit(numericas)
categoricas = na.omit(categoricas)


1.a) Indague sobre la varianza de cada uno de los atributos que conforman el dataset. ¿Cuáles son los dos atributos que podrían ser eliminados de acuerdo a la técnica de Low Variance Factor?

# Normalizamos los datos (Min-Max) a un rango 0-1
# Otra alternativa es usar scales::rescale sobre vectores

for(i in 1:ncol(numericas)) {
  numericas[,i] <- (numericas[,i]-min(numericas[,i]))/(max(numericas[,i])-min(numericas[,i]))
  }

# Calculamos la varianza para cada atributo, redondeamos a 4 decimales, y ordenamos de menor a mayor
varianzas<-sort(round(apply(numericas, 2, var),4))

print(varianzas)
#> f_instrumentalness         f_liveness         f_loudness        avg_streams 
#>             0.0112             0.0115             0.0127             0.0204 
#>           f_energy      f_speechiness          f_valence     f_danceability 
#>             0.0208             0.0215             0.0244             0.0273 
#>     f_acousticness       avg_position 
#>             0.0286             0.0442


2.b) Evalúe la relación entre atributos a partir del coeficiente de correlación de Pearson y un análisis gráfico de heatmap para estudiar la posibilidad de eliminar redundancia en el dataset.

library(gplots)

matriz.correlacion<-round(cor(numericas, use = "complete.obs"),3)


# Excluyo triangulo inferior para mayor claridad
matriz.correlacion[lower.tri(matriz.correlacion)] <- NA

heatmap.2(abs(matriz.correlacion), 
          cellnote = round(matriz.correlacion,2), 
          notecol="black", 
          main = "Correlación",
          trace="none",        
          margins =c(11,11),  
          col=terrain.colors(4,rev = FALSE),  
          dendrogram="none",
          symm= T, 
          Rowv=F,# Ordena la diagonal (en vez de dendograma)  
          breaks=c(0.6, 0.7, 0.8, 0.99, 1))


2.c) Aplique la función FindCorrelation con un umbral de 0.75 e identifique las variables candidatas a ser eliminadas según esta técnica.

library(caret)
alta.correlacion <- findCorrelation(cor(numericas, use = "complete.obs"), cutoff=0.75, names=TRUE, verbose= TRUE)
#> Compare row 3  and column  6 with corr  0.755 
#>   Means:  0.284 vs 0.178 so flagging column 3 
#> Compare row 9  and column  10 with corr  0.845 
#>   Means:  0.155 vs 0.161 so flagging column 10 
#> All correlations <= 0.75
#> [1] "f_energy"     "avg_position"


2.d) Suponiendo que quiere predecir si un artista ocupara un lugar entre las 100 mejores posiciones, compare la importancia de cada uno de los atributos utilizando la técnica de Random Forest de forma gráfica y analítica. Trabaje la variable objetivo como tipo factor para generar un modelo de clasificación.


library(randomForest)

# Genero una variable target según la posicion media en el ranking
numericas$top = as.factor(ifelse(data$avg_position<=100,"S","N" ))

# Ajusto un modelo de clasificación 
model_rf<-randomForest( top ~ ., data = na.exclude(numericas[,c(1:9,11)]), importance=TRUE) #Excluyo avg_position

importance(model_rf)
#>                             N           S MeanDecreaseAccuracy MeanDecreaseGini
#> f_danceability      3.7159121  10.3238474            9.8160963        10.416911
#> f_loudness          5.1678374   3.7648852            6.2687200         8.458530
#> f_energy            3.8802794   3.7970648            5.7624114         8.709225
#> f_speechiness       4.1185587   2.7684000            5.0104280        10.172447
#> f_liveness          1.1630608   3.1449124            2.9093765         8.798626
#> f_acousticness     -0.4624584   1.3594254            0.5869551         8.644080
#> f_instrumentalness  0.3200009  -0.1817424            0.2241521         7.038072
#> f_valence           1.5187864   1.7491414            2.2287374         9.522665
#> avg_streams        88.8190853 110.6679033          114.7959265       140.906712
varImpPlot(model_rf)