DistilBERT Multilingual

Model-Based Features

Author

Marlon

Published

May 7, 2026

Configuração

Parâmetro Valor Path
Entrada messages_enriched.parquet ~/whatsapp-interaction-analysis/data/processed/export_2024-10_2025-10
Saída messages_with_models.parquet ~/whatsapp-interaction-analysis/data/processed/export_2024-10_2025-10

Introdução

Este notebook cria features baseadas em modelos de Machine Learning que complementam as features estruturais criadas no notebook anterior.

⚠️ IMPORTANTE: Todas as análises deste notebook são:

  • Computacionalmente custosas (podem levar vários minutos)

  • Totalmente opcionais (não são necessárias para EDA básico)

  • Requerem hardware adequado (GPU recomendada para alguns modelos)

As features de modelos não são executadas automaticamente durante o render. Para aplicá-las, você deve executar os blocos manualmente ou via scripts.


Carregamento dos Dados

Métrica Valor
Mensagens 91,924
Colunas 43
Período 19/10/2024 → 20/10/2025

Modelo 2: DistilBERT Multilingual

Modelo leve otimizado via destilação de conhecimento, 60% menor e 2x mais rápido que modelos BERT tradicionais.

Características

  • Treinamento: Destilado de BERT multilingual (~50 idiomas incluindo PT)
  • Otimização: Velocidade mantendo ~95% da performance
  • Classes: 3 (positive, neutral, negative)
  • Especial: 66M parâmetros vs 270M do RoBERTa (75% menor)

Script: scripts/sentiment_distilbert.py

Features Criadas

Feature Tipo Definição Valores Uso
sentimento_distilbert_label category Classificação do sentimento em 3 classes (DistilBERT) positive, neutral, negative Comparação de velocidade vs precisão com RoBERTa
sentimento_distilbert_score float Score de confiança do DistilBERT (0-1) 0.0 a 1.0 Análise de trade-off velocidade/confiança

DistilBERT usa knowledge distillation: um modelo menor (student) aprende a imitar um modelo grande (teacher). Resultado: 60% menor, 60% mais rápido, mantendo ~95% da performance.

Execução

Script: scripts/sentiment_distilbert.py

Para executar a análise de sentimento com DistilBERT:

import subprocess

print("🤖 Iniciando análise de sentimento...")
print("📦 Modelo: DistilBERT Multilingual")
print("⏱️  Tempo estimado: 10-15 minutos (CPU) ou 3-5 minutos (GPU)")
print("⚡ ~2x mais rápido que Twitter-RoBERTa\n")

# Executa script específico
result = subprocess.run(['python', 'scripts/sentiment_distilbert.py'])

if result.returncode == 0:
    print("\n✅ Análise concluída com sucesso!")
    print(f"📁 Arquivo atualizado: {OUTPUT_FILE}")
else:
    print("\n❌ Erro na execução. Verifique os logs acima.")

Ou via terminal:

python scripts/sentiment_distilbert.py

Resultados

Resultados da classificação de sentimento aplicada às mensagens.

📊 Distribuição de Sentimentos
Sentimento Quantidade Percentual Confiança Média
😊 Positive 38,182 62.1% 0.580
😢 Negative 20,222 32.9% 0.516
😐 Neutral 3,078 5.0% 0.473
🔍 Exemplos por Sentimento
Mensagem Confiança
https://www.localiza.com/brasil/pt-br/reservas/passo-2 0.540
Arrasou 0.551
confortável 0.915
esse vai de boas 0.894
Tem um outro lá tbm mas mesmo preco 0.363
Mensagem Confiança
Total tá, não por pessoa 0.507
parece que não vão mais 0.429
Nossa tava sem.voz e ainda não voltou 0.432
ou eu pago e não vou 0.446
Ai não rola kkkkkk 0.569
Mensagem Confiança
A movida tem ai tbm? 0.444
tem as do aeroporto q tem todas iguais as daí 0.444
Se tiver mto absurdo dá pra vc ver se n tem sua trupe daí tbm q tope ir, sla Mais tarde te dou um salve dnv 0.609
Criei essa lista do que tô vendo no Airbnb dps entra lá 0.402
Demoro! Vou dar uma olhada mais tarde e a gnt se fala depois 0.501
Tip💡 Interpretação dos Resultados

Tom Geral: POLARIZADO E OTIMISTA 🎭

  • Positivo (62%) 🟢 → Maioria das interações vistas como positivas
  • Negativo (33%) 🔴 → Parte significativa com tom negativo
  • Neutro (5%) ⚪ → Quase não identifica neutralidade

Características do DistilBERT:

  • ⚡ Modelo polarizador - força interpretação para positivo/negativo
  • 🎯 Captura nuances sutis que podem passar despercebidas
  • 📊 Confiança média moderada (~54%) - menos certeza que RoBERTa
  • 🔄 Reduz neutralidade ao mínimo (5% vs 49% do RoBERTa)

🎯 Insights Principais:

  • Modelo funcionou rapidamente - ~14 minutos (2x mais rápido!)
  • Distribuição polarizada - tende a escolher um lado
  • Confiança moderada - 54% (menor que RoBERTa)
  • Quase elimina categoria neutral - foco em positivo/negativo
  • Processamento eficiente - 66M params vs 270M do RoBERTa

⚖️ Trade-off Identificado:

  • ✅ Velocidade: 2x mais rápido
  • ⚠️ Confiança: ~20% menor
  • 🔀 Viés diferente: Prefere polarizar ao invés de neutralizar

📌 Observação:

Este modelo tem uma “personalidade” diferente do RoBERTa. Enquanto RoBERTa é conservador e neutro, DistilBERT é ousado e polarizador. Ambas as visões são válidas e revelam aspectos diferentes das conversas.

Informações técnicas sobre a execução da análise de sentimento.

📋 Informações do Processamento
Métrica Valor
Modelo distilbert-base-multilingual-cased-sentiments-student
Executado em 01/12/2025 14:21:12
Device CPU
Tempo total 13.62 minutos
Batch size 100
📈 Estatísticas Gerais
Métrica Quantidade Percentual
Total de mensagens 91,924 100.0%
Processadas 61,482 66.9%
Puladas 30,442 33.1%

Este código mostra como validar os resultados após executar a análise.

import json

# Caminhos
output_file = PATHS['processed'] / 'messages_with_models.parquet'
metadata_file = PATHS['processed'] / 'sentiment_distilbert_metadata.json'

# Verifica se arquivos existem
if output_file.exists() and metadata_file.exists():
    
    # 1. Carrega metadados
    with open(metadata_file, 'r') as f:
        metadata = json.load(f)
    
    print("📋 Informações do Processamento:")
    print(f"   Modelo: {metadata['modelo'].split('/')[-1]}")
    print(f"   Device: {metadata['device']}")
    print(f"   Tempo: {metadata['tempo_total_minutos']:.2f} min")
    print(f"   Processadas: {metadata['mensagens_processadas']:,}")
    
    # 2. Carrega dados
    df = pd.read_parquet(output_file)
    
    # 3. Verifica colunas
    if 'sentimento_distilbert_label' in df.columns:
        print("\n✅ Análise encontrada!\n")
        
        # Distribuição
        print("📊 Distribuição:")
        display(df['sentimento_distilbert_label'].value_counts())
        
        # Estatísticas de confiança
        print("\n📈 Confiança:")
        display(df['sentimento_distilbert_score'].describe())
        
        # Exemplos
        print("\n🔍 Exemplos:")
        for label in ['positive', 'neutral', 'negative']:
            if label in df['sentimento_distilbert_label'].values:
                print(f"\n{label.upper()}:")
                exemplos = df[df['sentimento_distilbert_label'] == label][
                    ['conteudo', 'sentimento_distilbert_score']
                ].head(3)
                display(exemplos)
    else:
        print("⚠️  Colunas não encontradas no DataFrame")
        
else:
    print("⚠️  Arquivos não encontrados.")
    print("\n💡 Execute primeiro:")
    print("   python scripts/sentiment_distilbert.py")