Ml_spotify

library(readr)
Warning: package 'readr' was built under R version 4.4.3
spotify <- read_csv("C:/Users/OMAR DANIEL MEDINA V/Downloads/data.csv")
Rows: 3441197 Columns: 7
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr  (4): Track Name, Artist, URL, Region
dbl  (2): Position, Streams
date (1): Date

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
library(janitor)
Warning: package 'janitor' was built under R version 4.4.3

Adjuntando el paquete: 'janitor'
The following objects are masked from 'package:stats':

    chisq.test, fisher.test
spotify <- spotify |> clean_names()
names(spotify)
[1] "position"   "track_name" "artist"     "streams"    "url"       
[6] "date"       "region"    
summary(spotify)
    position       track_name           artist             streams        
 Min.   :  1.00   Length:3441197     Length:3441197     Min.   :    1001  
 1st Qu.: 45.00   Class :character   Class :character   1st Qu.:    3322  
 Median : 92.00   Mode  :character   Mode  :character   Median :    9227  
 Mean   : 94.64                                         Mean   :   51892  
 3rd Qu.:143.00                                         3rd Qu.:   29658  
 Max.   :200.00                                         Max.   :11381520  
     url                 date               region         
 Length:3441197     Min.   :2017-01-01   Length:3441197    
 Class :character   1st Qu.:2017-04-05   Class :character  
 Mode  :character   Median :2017-07-10   Mode  :character  
                    Mean   :2017-07-08                     
                    3rd Qu.:2017-10-10                     
                    Max.   :2018-01-09                     
anyNA(spotify) 
[1] TRUE
sum(is.na(spotify))
[1] 1322
library(dplyr)
Warning: package 'dplyr' was built under R version 4.4.3

Adjuntando el paquete: 'dplyr'
The following objects are masked from 'package:stats':

    filter, lag
The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
spotify_clean <- spotify |>
  filter(!is.na(track_name), !is.na(artist)) |>
  select(-url)

# Verificamos que quedó sin NA
sum(is.na(spotify_clean))
[1] 0
summary(spotify_clean$streams)
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
    1001     3321     9226    51885    29656 11381520 
library(ggplot2)
Warning: package 'ggplot2' was built under R version 4.4.3
spotify_clean |>
  count(track_name, sort = TRUE) |>
  slice_head(n = 10) |>
  ggplot(aes(x = reorder(track_name, n), y = n)) +
  geom_col(fill = "steelblue") +
  coord_flip() +
  labs(title = "Top 10 canciones más recurrentes", x = "Canción", y = "Apariciones") +
  theme_minimal()

ggplot(spotify_clean, aes(x = "", y = position)) +
  geom_boxplot(fill = "steelblue", outlier.color = "red") +
  labs(
    title = "Distribución de posiciones en el Top 200",
    x = "",
    y = "Posición"
  ) +
  theme_minimal()

library(dplyr)
library(ggplot2)

spotify_clean |>
  group_by(date) |>
  summarise(streams_totales = sum(streams)) |>
  ggplot(aes(x = date, y = streams_totales)) +
  geom_line(color = "darkgreen") +
  labs(title = "Evolución diaria de streams", x = "Fecha", y = "Streams") +
  theme_minimal()

library(dplyr)
library(ggplot2)

# Diccionario para traducir los códigos de región
region_labels <- c(
  at = "Austria",
  au = "Australia",
  be = "Bélgica",
  fi = "Finlandia",
  tr = "Turquía",
  fr = "Francia",
  de = "Alemania",
  us = "Estados Unidos",
  gb = "Reino Unido",
  ca = "Canadá",
  mx = "México",
  es = "España",
  ar = "Argentina",
  br = "Brasil",
  co = "Colombia",
  cl = "Chile"
)

# Agrupar por región y sumar streams
top_regiones_streams <- spotify_clean |>
  filter(region != "global") |>  
  group_by(region) |>
  summarise(total_streams = sum(streams, na.rm = TRUE)) |>
  slice_max(total_streams, n = 4) |> # Las 4 más potentes
  mutate(
    region_nombre = recode(region, !!!region_labels),
    porcentaje = round(total_streams / sum(total_streams) * 100, 1),
    etiqueta = paste0(region_nombre, " (", porcentaje, "%)")
  )

# Gráfico de pastel
ggplot(top_regiones_streams, aes(x = "", y = total_streams, fill = etiqueta)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y") +
  theme_void() +
  labs(title = "Top 4 regiones con más streams totales") +
  theme(legend.title = element_blank())

A partir de las medidas estadísticas y visualizaciones generadas, se pueden destacar los siguientes hallazgos:

Modelo de Clasificación

Este análisis busca comprender qué factores influyen en la cantidad de reproducciones que recibe una canción en Spotify. Para ello, se construirá un modelo de regresión múltiple que considere variables relevantes como:

  • La posición de la canción en el ranking.

  • La fecha de aparición en el top 200.

  • La región geográfica donde fue popular.

Objetivo:

Desarrollar un modelo de regresión múltiple que permita predecir la cantidad de streams que puede alcanzar una canción en Spotify, a partir de sus características contextuales: posición en el ranking, fecha y región.

library(dplyr)
library(fastDummies)
Warning: package 'fastDummies' was built under R version 4.4.3
# Convertir la fecha a número (días desde el origen)
spotify_reg <- spotify_clean %>%
  mutate(
    date_num = as.numeric(as.Date(date))
  )

# Crear variables dummy para la región (solo top 5 regiones más comunes para no sobrecargar)
top5_regiones <- spotify_reg %>%
  count(region, sort = TRUE) %>%
  slice_head(n = 5) %>%
  pull(region)

spotify_reg <- spotify_reg %>%
  filter(region %in% top5_regiones) %>%
  dummy_cols(select_columns = "region", remove_first_dummy = TRUE)  # evitar multicolinealidad
library(dplyr)
library(fastDummies)


top5_regiones <- spotify_clean |>
  count(region, sort = TRUE) |>
  slice_head(n = 5) |>
  pull(region)

spotify_reg <- spotify_clean |>
  filter(region %in% top5_regiones) |>
  mutate(date_num = as.numeric(as.Date(date)))


spotify_reg <- fastDummies::dummy_cols(
  spotify_reg,
  select_columns = "region",
  remove_first_dummy = TRUE,
  remove_selected_columns = TRUE
)


dummy_cols <- names(spotify_reg)[grepl("region_", names(spotify_reg))]
print(dummy_cols)  # para que veas qué usar en el modelo
[1] "region_au" "region_be" "region_fi" "region_tr"
formula_final <- as.formula(
  paste("streams ~ position + date_num +", paste(dummy_cols, collapse = " + "))
)

modelo_regresion <- lm(formula_final, data = spotify_reg)

# Paso 6: Ver resumen del modelo
summary(modelo_regresion)

Call:
lm(formula = formula_final, data = spotify_reg)

Residuals:
   Min     1Q Median     3Q    Max 
-26377  -8357  -2976   5588 459813 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -2.194e+05  4.064e+03  -53.98   <2e-16 ***
position    -2.010e+02  4.395e-01 -457.28   <2e-16 ***
date_num     1.407e+01  2.342e-01   60.10   <2e-16 ***
region_au    4.080e+04  8.024e+01  508.52   <2e-16 ***
region_be    2.864e+03  8.024e+01   35.69   <2e-16 ***
region_fi    1.215e+04  8.024e+01  151.45   <2e-16 ***
region_tr    7.854e+03  8.024e+01   97.88   <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 15450 on 370947 degrees of freedom
Multiple R-squared:  0.5953,    Adjusted R-squared:  0.5953 
F-statistic: 9.093e+04 on 6 and 370947 DF,  p-value: < 2.2e-16

Se destacan los principales hallazgos:

  • R² ajustado = 0.5953, lo cual indica que aproximadamente el 59.5% de la variabilidad en el número de streams es explicada por el modelo. Esto sugiere un buen nivel de ajuste para un fenómeno complejo como el consumo musical.

  • La variable position tiene un efecto negativo y altamente significativo. Esto confirma que las canciones con mejor posición (más cercanas al top 1) tienden a recibir más streams. Por cada unidad que baja en el ranking, se estima una disminución de ~201 streams, manteniendo las demás variables constantes.

  • La variable date_num tiene un coeficiente positivo, lo que indica que las canciones más recientes en el dataset tienden a tener ligeramente más reproducciones.

  • En cuanto a las regiones:

-    Canciones en **Australia**, **Bélgica**, **Finlandia** y **Turquía** tienden a recibir **más streams que la región de referencia** (Estados Unidos)

-    La región con el mayor impacto positivo fue **Australia**, con un estimado de +40,800 streams adicionales, en promedio.
  • Todos los coeficientes del modelo son estadísticamente significativos (p < 0.001), lo que respalda su relevancia en la predicción.

Resumen ejecutivo

En este trabajo se exploraron datos de Spotify para analizar los factores asociados al éxito musical medido en número de streams. Se realizó un análisis descriptivo de variables clave como la posición en el ranking, región geográfica y fecha de aparición. A través de visualizaciones como gráficos de barras, pastel, líneas y cajas, se identificaron patrones de comportamiento en distintas regiones y momentos del año.

Posteriormente, se construyó un modelo de regresión múltiple que permitió predecir la cantidad de streams utilizando como predictores la posición, la fecha y la región. El modelo obtuvo un R² ajustado de 0.595, lo cual indica un buen poder explicativo. Las variables fueron significativas y coherentes con el comportamiento esperado del fenómeno. Finalmente, se realizó una validación gráfica del modelo, confirmando que cumple con los supuestos estadísticos básicos.

Conclusiones y recomendaciones

  • La posición en el ranking tiene un efecto fuertemente negativo sobre el número de reproducciones: mientras más baja sea la posición, menor es el número de streams.
  • Las canciones publicadas en fechas más recientes tienden a obtener más reproducciones, posiblemente por el crecimiento de usuarios y tendencias de consumo.
  • Las diferencias regionales en el número de streams son significativas, lo que sugiere que el éxito musical depende también del contexto geográfico.
  • El modelo desarrollado puede ser útil para identificar tendencias y optimizar estrategias de marketing musical.