Downloads · 30 days
6
9% of all-time downloads
nubiaebv/musicbot-emotion-classifier
musicbot-emotion-classifier is a text classification model from nubiaebv. Use it when you need a label for a piece of text. It is set up for transformers. The card lists the license as apache-2.0.
Clasificador multiclase que detecta la emoción predominante en fragmentos de letras de canciones en español e inglés. Fine-tune de distilbert-base-multilingual-cased entrenado sobre un corpus propio de 5 081 canciones…
Downloads · 30 days
6
9% of all-time downloads
All-time downloads
68
Public
Parameters
135M
541 MB on disk
Likes
0
Public
Click a slice to open those files.
.safetensors541 MB · 99%
From the Hugging Face model README
Clasificador multiclase que detecta la emoción predominante en fragmentos de letras de canciones en español e inglés. Fine-tune de distilbert-base-multilingual-cased entrenado sobre un corpus propio de 5 081 canciones etiquetadas mediante un esquema combinado (keywords emocionales + modelo multilingüe de sentimiento).
Forma parte del Proyecto 3 del curso de Minería de Textos del Colegio Universitario de Cartago (2026). Se integra como componente de clasificación dentro del chatbot musical MúsicBot, que combina este modelo con un pipeline RAG (FAISS + Flan-T5) para responder consultas sobre un corpus lírico.
El modelo predice una de 5 emociones:
| ID | Etiqueta | Emoji |
|---|---|---|
| 0 | alegria | 😊 |
| 1 | tristeza | 😢 |
| 2 | amor | ❤️ |
| 3 | rabia | 😠 |
| 4 | nostalgia | 🌅 |
from transformers import AutoTokenizer, AutoModelForSequenceClassification
import torch
MODEL_ID = "nubiaebv/musicbot-emotion-classifier"
tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
model = AutoModelForSequenceClassification.from_pretrained(MODEL_ID)
texto = "Esta noche te escribo llorando, no puedo dejar de pensar en ti"
inputs = tokenizer(texto, return_tensors="pt", truncation=True, max_length=256)
with torch.no_grad():
logits = model(**inputs).logits
probs = torch.softmax(logits, dim=-1)[0]
etiquetas = ["alegria", "tristeza", "amor", "rabia", "nostalgia"]
pred_id = int(probs.argmax())
print(f"Emoción: {etiquetas[pred_id]} ({probs[pred_id]:.1%})")
pipelinefrom transformers import pipeline
clf = pipeline("text-classification",
model="nubiaebv/musicbot-emotion-classifier")
print(clf("Quiero bailar contigo toda la noche"))
# [{'label': 'alegria', 'score': 0.92}]
amor) para que el ratio desbalance/minoritaria no supere 3.0x.| Clase | Muestras | % |
|---|---|---|
| amor | 2 813 | 43.5% |
| rabia | 1 406 | 21.7% |
| nostalgia | 1 140 | 17.6% |
| alegria | 631 | 9.8% |
| tristeza | 476 | 7.4% |
| Total | 6 466 | 100% |
Ratio de desbalance inicial: 5.9× — superior al umbral de 3× definido por el equipo.
| Clase | Muestras | Acción |
|---|---|---|
| amor | 1 428 | submuestreado desde 2 813 |
| rabia | 1 406 | sin cambio |
| nostalgia | 1 140 | sin cambio |
| alegria | 631 | sin cambio |
| tristeza | 476 | sin cambio |
| Total | 5 081 | ratio 3.0× |
| Split | Muestras | % del total |
|---|---|---|
| Train | 3 557 | 70% |
| Validation | 762 | 15% |
| Test | 762 | 15% |
distilbert-base-multilingual-cased (~135M parámetros)AutoModelForSequenceClassification con 5 labelsWeightedTrainer personalizado (pesos inversos a frecuencia de clase) + EarlyStoppingCallback sobre F1 macro de validación| Parámetro | Valor |
|---|---|
| Épocas máximas | 3 (MAX_EPOCHS) con early stopping |
| Batch size | 16 |
| Learning rate | 2e-5 |
| Max length | 256 |
| Optimizador | AdamW |
| Seed | 42 |
WeightedTraineralegria : 1.6430
tristeza : 2.0210
amor : 0.7215
rabia : 0.7289
nostalgia : 0.8783
Los pesos compensan el desbalance residual penalizando más los errores en clases minoritarias (especialmente tristeza).
Sobre el conjunto de test (762 muestras, estratificado).
| Métrica | Baseline (mayoría de clase) | Fine-tuned | Ganancia |
|---|---|---|---|
| Accuracy | 0.3250 | 0.7572 | +0.4322 |
| F1 macro | 0.0981 | 0.7475 | +0.6494 |
El baseline predice siempre la clase más frecuente (amor). El fine-tuning aporta +43 puntos de accuracy y +65 puntos de F1 macro, confirmando que el modelo aprende patrones reales en las letras más allá de la clase mayoritaria.
| Clase | Precision | Recall | F1-score | Support |
|---|---|---|---|---|
| alegria | 0.77 | 0.72 | 0.74 | 102 |
| tristeza | 0.64 | 0.77 | 0.70 | 57 |
| amor | 0.82 | 0.77 | 0.79 | 218 |
| rabia | 0.73 | 0.72 | 0.73 | 204 |
| nostalgia | 0.76 | 0.80 | 0.78 | 181 |
| Macro avg | 0.74 | 0.76 | 0.75 | 762 |
| Weighted avg | 0.76 | 0.76 | 0.76 | 762 |
| Accuracy | 0.76 | 762 |
Filas = etiqueta real, columnas = predicción.
| alegria | tristeza | amor | rabia | nostalgia | |
|---|---|---|---|---|---|
| alegria | 73 | 5 | 5 | 11 | 8 |
| tristeza | 1 | 44 | 4 | 4 | 4 |
| amor | 7 | 5 | 168 | 22 | 16 |
| rabia | 10 | 9 | 19 | 147 | 19 |
| nostalgia | 4 | 6 | 9 | 17 | 145 |
Observaciones:
nostalgia es la clase con mejor recall (80%), probablemente por su vocabulario distintivo (recuerdos, tiempo pasado, pérdida).amor y rabia (22 casos): ambas clases comparten léxico relacional intenso; letras de desamor o celos pueden caer en cualquiera.alegria se confunde frecuentemente con rabia (11 casos) — posiblemente canciones de fiesta con letras enérgicas y agresivas (reggaetón).tristeza (476 muestras) y alegria (631) siguen siendo clases minoritarias. Los class weights compensan parcialmente, pero su precisión y recall son menos fiables que las de amor o nostalgia.Este clasificador se integra en un pipeline RAG + Fine-Tuning dentro de la aplicación MúsicBot:
Código fuente completo: https://github.com/nubiaebv/chatbot-musical-inteligente
Apache 2.0 — libre uso con atribución.
@misc{musicbot_emotion_classifier_2026,
title = {MúsicBot — Clasificador de Emociones en Letras de Canciones},
author = {Brenes Valerín, Nubia Elena and Marín Castillo, Pablo Andrés},
year = {2026},
note = {Proyecto 3 — Minería de Textos, Colegio Universitario de Cartago},
url = {https://huggingface.co/nubiaebv/musicbot-emotion-classifier}
}