- Conceitos e Exemplos Práticos
A. Filtragem Baseada em Conteúdo (Content-Based Filtering)
Conceito: É o método de recomendação que utiliza as características do item (no nosso caso, o "humor" da letra) para encontrar correspondências com o interesse do usuário. Se o usuário pede algo "feliz", o sistema busca itens com o metadado "feliz".
Exemplo Prático: Um usuário em Piracanjuba quer ouvir algo animado. O sistema consulta o CSV gerado na Etapa 1 e filtra todas as linhas onde sentiment_label é igual a 5 stars ou Joy.
B. Aprendizado por Reforço Implícito (Feedback Loop)
Conceito: Ajustar o comportamento do sistema sem que o usuário precise dar uma nota explícita. "Pular" uma música é um sinal negativo forte; "ouvir até o fim" é um sinal positivo.
Exemplo Prático: Se o sistema recomenda uma música triste e o usuário a pula nos primeiros 5 segundos, o peso daquela categoria para o perfil atual do usuário diminui temporariamente.
- Resumo da Aula: Etapa 2 - Implementação
Tópicos Principais:
Mapeamento de Sentimentos: Tradução das labels do modelo (ex: "1 star") para categorias humanas (ex: "Melancólico").
Mecanismo de Busca: Uso do pandas para consultas rápidas (queries) no dataset.
Persistência de Feedback: Criação de uma estrutura para armazenar o histórico de interações (likes/dislikes).
Código Fonte: Motor de Recomendação e Feedback
Este código implementa a lógica de filtragem e o sistema de registro de feedback.
Python
import pandas as pd
import random
1. CARREGAMENTO E PREPARAÇÃO
Big O: O(N) para carregar o dataset
try:
df_catalog = pd.read_csv("sentiment_results.csv")
except FileNotFoundError:
# Mock caso o arquivo não exista para demonstração
df_catalog = pd.DataFrame({
"id": range(5),
"sentiment_label": ["5 stars", "1 star", "4 stars", "2 stars", "5 stars"],
"title": ["Alegria Geral", "Tristeza Profunda", "Vibe Positiva", "Solidão", "Festa em Goiás"]
})
Dicionário de Mapeamento Emocional
MOOD_MAP = {
"feliz": ["4 stars", "5 stars"],
"melancolico": ["1 star", "2 stars"],
"neutro": ["3 stars"]
}
class PlaycatchRecommender:
def init(self, catalog):
self.catalog = catalog
self.feedback_log = [] # Armazena interações
def get_recommendations(self, user_mood, top_n=3):
"""
Filtra músicas com base no humor solicitado.
Big O: O(N) onde N é o tamanho do catálogo.
"""
target_labels = MOOD_MAP.get(user_mood.lower(), ["3 stars"])
# Filtragem booleana do Pandas
filtered_df = self.catalog[self.catalog['sentiment_label'].isin(target_labels)]
if filtered_df.empty:
return "Nenhuma música encontrada para esse humor."
# Seleção aleatória das top_n para variar a experiência
recommendations = filtered_df.sample(min(top_n, len(filtered_df)))
return recommendations[['id', 'title']].to_dict(orient='records')
def register_feedback(self, music_id, liked=True):
"""
Sistema de feedback para ajuste futuro (Etapa 4).
"""
status = "LIKE" if liked else "SKIP"
self.feedback_log.append({"music_id": music_id, "action": status})
print(f"Feedback registrado para música {music_id}: {status}")
--- EXECUÇÃO PRÁTICA ---
if name == "main":
recommender = PlaycatchRecommender(df_catalog)
# Simulação: Usuário pede música feliz
print("--- Sugestões para humor 'Feliz' ---")
sugestoes = recommender.get_recommendations("feliz")
print(sugestoes)
# Simulação: Feedback (Usuário gostou da primeira, pulou a segunda)
if isinstance(sugestoes, list):
recommender.register_feedback(sugestoes[0]['id'], liked=True)
recommender.register_feedback(sugestoes[1]['id'], liked=False)
Revisão de Tutor Sênior (Code Review)
Complexidade Espacial: O catálogo é mantido em memória RAM via DataFrame. Para uma startup como a Playcatch crescendo, o próximo passo seria migrar isso para uma Query SQL (usando WHERE sentiment IN (...)), o que reduziria o consumo de memória do servidor.
Escalabilidade do Feedback: Atualmente, o feedback_log é uma lista volátil. Em produção, esses eventos seriam enviados para um barramento de dados (como Kafka) e salvos em um banco NoSQL para treinar modelos de Deep Recommenders futuramente.
UX/UI: No Gradio (que usaremos na Etapa 3), o feedback poderá ser implementado com botões de "Polegar para cima/baixo", tornando a coleta de dados invisível e natural para o ouvinte.