Análisis de sentimiento a mi playlist de Spotify | Vicente Chiriguaya

Análisis de sentimiento a mi playlist de Spotify

September 1, 2025 · ES

Read in English

Hace algunas semanas me pregunté, ¿Qué tanto juegan mis emociones con las letras de las canciones que escucho? A veces quiero escuchar canciones con un significado similar pero me gustaría armar una lista de reproducción automáticamente ya que en mi biblioteca de Spotify tengo alrededor de 911 canciones.

Además me pregunté, ¿será que me gustan canciones con letras más depresivas o quizá canciones con letras más positivas?

Fue entonces cuando me puse manos a la obra y salió mi lado investigativo, decidí hacer un pequeño proyecto que me ayude a responder estas preguntas para ello empecé investigando la viabilidad del mismo. Bueno, resulta que Spotify es muy Developer-friendly, lo cual ya es inmediatamente una ventaja, pero, las letras de las canciones suelen estar limitadas a temas de derecho de autor, además no existe una api que pueda simplemente explotarla y listo. Parecía haberme topado con una muralla muy difícil de superar, pero… ¿Y si en lugar de usar directamente las letras utilizo un LLM que me de palabras claves con el título y el artista? Lo probé con una muestra que pudiera manejar y resulta que sí, en este caso ChatGPT en su versión 4-mini, tiene bastante precisión a la hora de pedirle keywords de una canción (incluyendo canciones modernas o poco conocidas –Y canciones en idiomas diferentes al español, incluso openings de ánime–.

Con todo esto empecé a idear mi plan y creé este pequeño tutorial combinando Análisis de sentimiento y Clustering.

Primeros pasos

Lo primero que debemos hacer es tener presente las librerías que utilizaremos, en este caso:

  • DotEnv para manejar variables dentro de .env
  • Pandas para tratar los datos como un dataframe y poder analizarlos de mejor manera.
  • ScikitLearn, numpy, etc. Para temas de análisis.
  • OpenAI para usar LLM.
  • Spotipy para temas de conexión con el API de Spotify.
  • Flask/FastAPI usa tu favorita para temas de exponer una pequeña interfaz web y el callback de nuestro Spotipy.

En general puedes encontrar todo lo que utilicé en el proyecto e instalarlo utilizando el siguiente comando:

pip install python-dotenv pandas transformers torch sentence-transformers scikit-learn numpy openai spotipy flask uvicorn fastapi watchfiles

También deberás tener una cuenta como desarrollador de Spotify, generar una aplicación y tener un endpoint que te permita recibir el callback (si necesitas más información puedes seguir este enlace a la documentación oficial de Spotify); en mi caso este endpoint lo manejé utilizando flask y expuse la url a través de vercel con un dominio personal que llama a través de un relay a la url local a través del puerto 8080. Te dejo el código de ejemplo que utilicé para levantar una pequeña app next en Vercel:

import type { NextApiRequest, NextApiResponse } from "next";
 
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  const { code, state, error } = req.query;
  if (error) return res.status(400).send(`Authorization failed: ${error}`);
  if (!code) return res.status(400).send("Missing 'code' param.");

  // Configure your local receiver (default to 127.0.0.1:8080)
  const base = process.env.LOCAL_CALLBACK_BASE || "http://127.0.0.1:8080";
  const url = new URL("/callback", base);
  url.searchParams.set("code", String(code));
  if (state) url.searchParams.set("state", String(state));

  res.writeHead(302, { Location: url.toString() }).end();
}

Si deseas puedes utilizar el mismo código y montarlo en Vercel a través de este enlace al repositorio.

LLM con OPEN AI

Para este proyecto usaremos como LLM la versión de ChatGPT 4-mini, para ello deberás contar con una API KEY. Para ello puedes ingresar en este enlace dónde podrás crearla (Deberás registrarte y agregar créditos a tu LLM).

Resumen de requisitos

Ahora si, para continuar debes de ya contar con lo siguiente:

  1. El CLIENT ID de nuestra app en Spotify.
  2. Un endpoint válido para redirigir la autenticación de nuestra app en Spotify.
  3. Un API KEY de OPEN AI para usar ChatGPT.

Generalidades

Este proyecto ya está completo por lo que dentro del siguiente enlace puedes encontrar el código, en los siguientes pasos iré explicando brevemente cada parte del mismo. Es importante que sepas que este proyecto tiene dos versiones, la primera está desarrollada dentro de un notebook de Jupyter, y la segunda está desarrollada a través de un pipeline de archivos en Python (dentro de la carpeta pipeline). Este blog se centrará en la versión que desarrollé para Jupyter por motivos de practicidad, pero, son las mismas.

Ambos proyectos usarán SQLite como gestor de Base de datos, también existe un fork para MySQL que es facilmente modificable, pero siéntete libre de crear nuevas versiones con el motor de bases de datos de tu preferencia.

Primero: Variables de entorno

Antes de ejecutar las celdas deberemos crear un archivo .env con las siguientes variables:

SPOTIFY_CLIENT_ID="EL ID DE TU APLICACIÓN DE SPOTIFY"  
SPOTIPY_REDIRECT_URI="LA URL DE REDIRECCIÓN"
SPOTIPY_CACHE_PATH="LA UBICACIÓN DEL CACHE"
OPENAI_API_KEY="TU API KEY DE OPEN AI"

Segundo: Extracción de datos

Ejecutamos la segunda celda:

from pipeline import data_extraction  
data_extraction.main()

Esto se encargará de realizar las siguientes acciones:

  1. Cargará la autenticación de Spotify con Spotipy
  2. Recibirá el Callback de nuestra app.
  3. Al autorizar ejecutará un script que importará los datos de nuestras canciones en una BD de SQLite en diferentes tablas.

Al terminar con la ejecución tendremos nuestras canciones dentro de tablas que podremos usar más adelante para analizar los datos.

Puedes revisar el código de la app pero básicamente lo que se realiza en este paso es llamar a la api de Spotify a través de la función get_spotify_client para luego obtener todos los tracks y almacenar tanto el track, como el artista y el álbum.

Si quieres visualizar los elementos de la tabla basta con abrir app.db con alguna herramienta para gestionar archivos SQLite, también puedes realizar una consulta dentro del código.

Tercero: Obtener las Keywords

Ahora vamos a obtener las keywords, para ello ejecutamos la siguiente celda:

import extract_keywords.extract_from_title_artist as keywords  
keywords.extract_keywords_from_title_artist()

En ella llamaremos a la función extract_keywords_from_title_artist que se encargará de utilizar el LLM con un prompt personalizado para obtener un objeto con 20 palabras claves de la canción. Consideramos 20 para hacer un poco más variado el análisis, pero puedes cambiar este número como gustes.

Ahora, en términos económicos, el cuanto gaste tu modelo dependerá del número de tracks que tengas, en mi caso mi modelo gastó aproximadamente 40 centavos de dólar para obtener keywords de 911 canciones.

Cuarto: Análisis de sentimiento

Análisis Exploratorio

En este punto vamos a analizar un poco más los datos realizando un análisis exploratorio para entender mejor lo que se está haciendo (puedes ejecutar todas las celdas de Exploratory Data Analysis).

Obtenemos los tracks de la base de datos y los transformaremos en un dataframe en el que únicamente dejaremos el track_spotify_id, el artist_name, el title y los keywords.

Si observamos veremos que tenemos resultados muy variados: ---Imagen---

Lo que debemos hacer es tratar de normalizar estas keywords utilizando embeddings, para ello primero encontramos las palabras únicas y creando clusters crearemos un diccionario para normalizar todas las palabras claves.

Al final aplicaremos esta normalización lo cual nos dejará un dataframe más sencillo de manejar: ---Imagen---

Luego podemos observar los resultados y estos se almacenarán en nuestra base de datos.

Análisis de sentimientos

Si ejecutamos todas las celdas dentro de Sentimental Analysis obtendremos un porcentaje basado en el sentimiento de la canción referente a sus keywords. Esto se almacenará en el campo emotions dentro de la base de datos.

Ten en cuenta que la cantidad de emociones dependerá del modelo que utilicemos, en el caso del ejemplo utilizo el modelo joeddav/distilbert-base-uncased-go-emotions-student el cual brinda 28 tipo de emociones.

Luego del análisis se creará también una tabla de emociones y un diccionario de emociones. En el caso del diccionario usamos el LLM para que nos sugiera también una forma de agruparlas en 5 grupos Muy Positivas (FP), Positivas (MP), Neutrales (N), Negativas (MN) y Muy Negativas (FN), esto nos servirá para tener un informe más reducido de las emociones.

Quinto: Clustering

Ahora crearemos clusters para agrupar nuestras canciones en diferentes grupos. Ejecutaremos las celdas de clustering, que se encargarán de:

  1. Normalizar las keywords por pista (minúsculas, trimming y deduplicación).
  2. Vectorizar cada conjunto de keywords con un modelo de Sentence Transformers (all-MiniLM-L6-v2).
  3. Promediar los embeddings de las keywords por canción para obtener un solo vector representativo por track.
  4. Agrupar todos los vectores con KMeans en k clusters y calcular el Silhouette Score como métrica rápida de calidad.
  5. Anotar el DataFrame con una nueva columna cluster_emb que contiene el cluster de cada pista.
  6. Interpretar los clusters extrayendo el top-N de keywords más frecuentes por grupo y ejemplos representativos “Artista — Título” para revisión manual.
  7. Asignar un titulo y descripción a cada Cluster creado a través de un modelo de LLM.

Sexto: Visualización de datos

Ya con todo lo demás ejecutado puedes proceder a la parte de visualizar los resultados, el programa ya incluye una aplicación con VUE que te permitirá no solo visualizar sino también crear la lista de reproducción basada en los resultados. Al ejecutar la última celda se abrirán los resultados.

Conclusiones

Este proyecto me confirmó algo que ya sospechaba: mis emociones tienen mucho que ver con lo que escucho. Mi biblioteca de 911 canciones no es una colección al azar, sino un reflejo bastante claro de mis estados de ánimo. Al aplicar el análisis de sentimientos a las keywords descubrí patrones entre letras positivas, neutrales y depresivas que encajan con lo que suelo reproducir.

También aprendí que la limitación de los derechos de autor no era un muro imposible. Aunque no exista una API que entregue las letras completas, usar un LLM para extraer keywords de los títulos y artistas resultó práctico, económico y sorprendentemente preciso. Con apenas unos centavos pude generar la base para el análisis.

El pipeline que construí terminó siendo modular y fácil de replicar: extracción de datos, obtención de palabras clave, análisis de sentimientos, clustering y visualización. Gracias a esa estructura, lo que empezó como un experimento personal puede adaptarse fácilmente a otros casos.

El clustering me ayudó a darle orden al caos. Pasar de cientos de canciones dispersas a grupos temáticos con títulos, descripciones y ejemplos representativos me permitió entender mejor mi propia música y armar playlists mucho más coherentes con mi estado de ánimo.

Finalmente, la visualización cerró el círculo. Con la app en VUE no solo logré analizar los datos, sino también construir una herramienta real que me responde directamente la pregunta inicial: ¿mis gustos se inclinan hacia lo positivo o hacia lo negativo?

En definitiva, lo que comenzó como una curiosidad terminó convirtiéndose en un prototipo con verdadero potencial. Mezclé ciencia de datos, LLMs y experiencia de usuario para darle forma a algo que no solo me sirve a mí, sino que podría ser útil para cualquiera que quiera organizar su música según cómo se siente.