Classificador de Sentimento com Python e Transformers
Exemplo completo de análise de sentimento em português usando Hugging Face Transformers em poucas linhas de código.
O que vamos construir
Um classificador que analisa textos em português e retorna se o sentimento é positivo, negativo ou neutro.
Código Completo
"""
Classificador de Sentimento em Português
Usa o modelo multilingual da Hugging Face
"""
from transformers import pipeline
# Carregar o pipeline de análise de sentimento
classifier = pipeline(
"sentiment-analysis",
model="nlptown/bert-base-multilingual-uncased-sentiment"
)
# Textos para analisar
textos = [
"Adorei esse produto! Funciona perfeitamente.",
"Péssimo atendimento, nunca mais volto.",
"O produto é ok, nada de especial.",
"Melhor compra que já fiz na vida!",
"Chegou quebrado e o suporte não resolveu.",
]
# Analisar cada texto
print("=" * 60)
print("ANÁLISE DE SENTIMENTO")
print("=" * 60)
for texto in textos:
resultado = classifier(texto)[0]
# Converter score de 1-5 estrelas para sentimento
stars = int(resultado["label"].split()[0])
if stars >= 4:
sentimento = "😊 Positivo"
elif stars <= 2:
sentimento = "😠 Negativo"
else:
sentimento = "😐 Neutro"
confianca = resultado["score"] * 100
print(f"\nTexto: {texto}")
print(f" → {sentimento} (confiança: {confianca:.1f}%)")
print("\n" + "=" * 60)
Saída Esperada
============================================================
ANÁLISE DE SENTIMENTO
============================================================
Texto: Adorei esse produto! Funciona perfeitamente.
→ 😊 Positivo (confiança: 72.3%)
Texto: Péssimo atendimento, nunca mais volto.
→ 😠 Negativo (confiança: 65.8%)
Texto: O produto é ok, nada de especial.
→ 😐 Neutro (confiança: 48.2%)
...
Versão com API (para produção)
"""
API de Sentimento com FastAPI
"""
from fastapi import FastAPI
from pydantic import BaseModel
from transformers import pipeline
app = FastAPI(title="API de Sentimento")
classifier = pipeline("sentiment-analysis", model="nlptown/bert-base-multilingual-uncased-sentiment")
class TextoInput(BaseModel):
texto: str
class SentimentoOutput(BaseModel):
texto: str
sentimento: str
confianca: float
@app.post("/analisar", response_model=SentimentoOutput)
def analisar(input: TextoInput):
resultado = classifier(input.texto)[0]
stars = int(resultado["label"].split()[0])
sentimento = "positivo" if stars >= 4 else "negativo" if stars <= 2 else "neutro"
return SentimentoOutput(
texto=input.texto,
sentimento=sentimento,
confianca=round(resultado["score"], 4)
)
Como rodar
# Instalar dependências
pip install transformers torch fastapi uvicorn
# Rodar script simples
python classificador.py
# Rodar API
uvicorn api_sentimento:app --reload
Pronto! Em menos de 30 linhas você tem um classificador de sentimento funcional. 🚀
Análise em Batch com Relatório
Para analisar grandes volumes de texto (reviews de produto, comentários de redes sociais, feedback de clientes), use esta versão em batch:
"""
Análise de sentimento em batch com geração de relatório.
Processa listas de textos e gera estatísticas consolidadas.
"""
import csv
from collections import Counter
from pathlib import Path
from transformers import pipeline
classifier = pipeline(
"sentiment-analysis",
model="nlptown/bert-base-multilingual-uncased-sentiment",
)
def analisar_batch(textos: list[str]) -> list[dict]:
"""Analisa uma lista de textos e retorna resultados estruturados."""
resultados = []
for texto in textos:
pred = classifier(texto)[0]
stars = int(pred["label"].split()[0])
if stars >= 4:
sentimento = "positivo"
elif stars <= 2:
sentimento = "negativo"
else:
sentimento = "neutro"
resultados.append({
"texto": texto,
"sentimento": sentimento,
"estrelas": stars,
"confianca": round(pred["score"], 4),
})
return resultados
def gerar_relatorio(resultados: list[dict], output_path: str = "relatorio.csv"):
"""Gera relatório CSV + resumo estatístico."""
# Salvar CSV
path = Path(output_path)
with open(path, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["texto", "sentimento", "estrelas", "confianca"])
writer.writeheader()
writer.writerows(resultados)
# Estatísticas
contagem = Counter(r["sentimento"] for r in resultados)
total = len(resultados)
media_confianca = sum(r["confianca"] for r in resultados) / total
print(f"\n📊 RELATÓRIO DE SENTIMENTO ({total} textos)")
print(f"{'=' * 45}")
print(f" 😊 Positivos: {contagem['positivo']:>4} ({contagem['positivo']/total*100:.1f}%)")
print(f" 😐 Neutros: {contagem.get('neutro', 0):>4} ({contagem.get('neutro', 0)/total*100:.1f}%)")
print(f" 😠 Negativos: {contagem['negativo']:>4} ({contagem['negativo']/total*100:.1f}%)")
print(f" 📈 Confiança média: {media_confianca*100:.1f}%")
print(f" 💾 Relatório salvo em: {path}")
return contagem
# Exemplo de uso
reviews = [
"Produto excelente, superou minhas expectativas!",
"Entrega rápida e embalagem perfeita.",
"Não gostei, qualidade muito abaixo do esperado.",
"Razoável pelo preço, nada demais.",
"Horrível! Veio com defeito e o suporte ignorou.",
"Ótimo custo-benefício, recomendo para todos.",
"Funciona bem mas o acabamento poderia ser melhor.",
"Pior compra que já fiz, quero meu dinheiro de volta.",
]
resultados = analisar_batch(reviews)
gerar_relatorio(resultados)
Modelo Fine-Tuned para Português
Para maior acurácia em textos em português, use um modelo treinado especificamente para PT-BR:
"""
Versão com modelo fine-tuned para português brasileiro.
Usa o pysentimiento, treinado com dados de redes sociais em PT.
"""
from transformers import pipeline
# Modelo treinado especificamente para sentimento em português
classifier_pt = pipeline(
"sentiment-analysis",
model="pysentimiento/bertweet-pt-sentiment",
)
def analisar_pt(texto: str) -> dict:
"""Análise otimizada para português brasileiro."""
resultado = classifier_pt(texto)[0]
label_map = {"POS": "positivo", "NEG": "negativo", "NEU": "neutro"}
return {
"texto": texto,
"sentimento": label_map.get(resultado["label"], resultado["label"]),
"confianca": round(resultado["score"], 4),
}
# Teste com gírias e expressões brasileiras
testes_br = [
"Esse restaurante é top demais, mano!",
"Que lixo de atendimento, tô indignado",
"Foi ok, nada de mais",
"Cara, melhor app que já usei na vida!",
"Péssimo, não recomendo pra ninguém",
]
for texto in testes_br:
r = analisar_pt(texto)
print(f"[{r['sentimento'].upper():>9}] ({r['confianca']*100:.0f}%) {r['texto']}")
Conclusão
A análise de sentimento com Transformers é surpreendentemente simples de implementar e produz resultados de alta qualidade. Com menos de 30 linhas você tem um classificador funcional, e com as extensões que construímos — API REST, análise em batch e modelos específicos para português — você pode integrar análise de sentimento em qualquer pipeline de dados.
O segredo está na escolha do modelo: para textos multilíngues, o nlptown/bert-base-multilingual-uncased-sentiment funciona muito bem; para textos especificamente em português brasileiro (redes sociais, reviews, atendimento ao cliente), modelos como o pysentimiento/bertweet-pt-sentiment entregam resultados superiores.
Próximos Passos
- Análise de aspectos: em vez de classificar o sentimento geral, identificar sentimento por aspecto ("comida boa, atendimento ruim")
- Dashboard em tempo real: criar um painel com Streamlit que analisa menções da sua marca em redes sociais
- Fine-tuning no seu domínio: treinar o modelo com dados rotulados do seu negócio para maior acurácia no seu contexto específico
- Monitoramento de NPS: integrar com pesquisas de satisfação para calcular NPS automaticamente a partir de comentários abertos
- Comparação temporal: acompanhar a evolução do sentimento ao longo do tempo para medir impacto de ações de melhoria
- Pipeline de alertas: criar alertas automáticos quando o sentimento negativo ultrapassar um threshold crítico