🔍 Detector de Clickbait BR

📋 Índice

Visão Geral

Modelo de classificação de texto que detecta clickbait em manchetes de notícias em português brasileiro. Desenvolvido com Random Forest otimizado, alcança 97.2% de F1-Score e 98.3% de precisão.

Informações Básicas

  • Desenvolvedor: Rodrigo de Araujo Rosa
  • Data do Modelo: Novembro 2025
  • Versão: 1.0.0
  • Tipo: Random Forest Classifier (Scikit-learn)
  • Idioma: Português Brasileiro (pt-BR)
  • Licença: MIT
  • Repositório: GitHub

Descrição

Este modelo classifica manchetes de notícias em português brasileiro como Clickbait ou Não-Clickbait. Foi treinado usando Random Forest otimizado via RandomizedSearchCV com 50 iterações de busca, testando 9 diferentes arquiteturas de modelos.

Detalhes do Modelo

Uso Pretendido

Casos de Uso Recomendados

  • ✅ Detectar manchetes clickbait em portais de notícias brasileiros
  • ✅ Filtrar conteúdo sensacionalista em agregadores de notícias
  • ✅ Análise de qualidade jornalística
  • ✅ Pesquisa acadêmica em detecção de clickbait

Usuários-Alvo

  • Desenvolvedores de agregadores de notícias
  • Jornalistas e editores
  • Pesquisadores em NLP e jornalismo
  • Plataformas de fact-checking

Casos de Uso Fora do Escopo

  • Outros idiomas: Modelo treinado apenas em português brasileiro
  • Outros domínios: Não testado em e-commerce, redes sociais, marketing
  • Textos longos: Otimizado para manchetes (5-20 palavras)
  • Classificação multiclasse: Apenas binário (clickbait/não-clickbait)
  • Decisões automatizadas sem supervisão humana: Recomenda-se validação manual

Dados de Treinamento

Visão Geral do Dataset

  • Total de exemplos: 9.532 manchetes únicas
  • Fonte: Portais de notícias brasileiros diversos
  • Processo de limpeza:
    • 10.565 manchetes iniciais coletadas
    • 634 duplicatas removidas (6.0%)

Distribuição de Classes

Classe Quantidade Percentual
Não-Clickbait 4.457 46.8%
Clickbait 5.075 53.2%

Divisão Treino/Teste

  • Treino: 7.625 exemplos (80%)
  • Teste: 1.907 exemplos (20%)
  • Estratégia: Stratified split (random_state=42)
  • Validação: 5-fold Stratified Cross-Validation

Coleta de Dados

Manchetes coletadas de múltiplos portais brasileiros para garantir diversidade:

  • Portais generalistas
  • Portais especializados (economia, esportes, entretenimento)

Processo de Anotação

  • Anotação manual seguindo critérios claros
  • Critérios de clickbait:
    • Títulos sensacionalistas
    • Uso excessivo de pontuação emocional
    • Omissão de informações cruciais
    • Linguagem hiperbólica
    • Apelo à curiosidade sem contexto

Exemplos do Dataset

Não-Clickbait:

  • "Banco Central mantém a taxa Selic em 13,75% ao ano"
  • "Governo aprova reforma tributária no Congresso"
  • "Estudo da USP revela novos dados sobre mudanças climáticas"

Clickbait:

  • "O pesadelo dos investidores: a decisão do Banco Central que vai destruir seus lucros!"
  • "Descubra o segredo para emagrecer 10kg em 7 dias!!!"
  • "Este truque simples vai MUDAR sua vida para sempre"

Análise Exploratória de Dados

Distribuição e Padrões dos Dados

Análise Exploratória Completa

A análise exploratória revela padrões interessantes:

📊 Principais Insights

  1. Distribuição Balanceada: Dataset equilibrado (~50/50) minimiza viés de classe
  2. Comprimento dos Textos:
    • Não-Clickbait: média de ~12 palavras
    • Clickbait: média de ~15 palavras (mais descritivo/sensacionalista)
  3. Densidade de Palavras: Clickbait apresenta maior variabilidade no vocabulário
  4. Top 20 Palavras Relevantes: Padrões linguísticos distintos entre classes

Características Textuais

Métrica Não-Clickbait Clickbait
Palavras/manchete (média) 12.3 15.7
Stopwords (%) 35% 30%
Palavras únicas ~2.800 ~3.200

Visualização das Palavras Mais Frequentes

Nuvem de Palavras - Comparação Clickbait vs Não-Clickbait

Comparação visual das palavras mais relevantes (sem stopwords) em manchetes clickbait e não-clickbait. Observe os padrões linguísticos distintos: manchetes clickbait usam mais verbos de ação e palavras de impacto emocional.

Avaliação

Dados de Teste

  • Dataset de teste: 1.907 manchetes (20% do total)
  • Estratificação: Mantém distribuição ~50/50 das classes
  • Sem overlap: Nenhum exemplo do treino aparece no teste

Métricas de Performance

Performance Geral (Test Set)

Métrica Valor
Accuracy 97.1%
Precision 98.3%
Recall 96.2%
F1-Score 97.2%

Matriz de Confusão

                 Predicted
               Non-CB  Clickbait
Actual Non-CB    875      17
       Clickbait  39    976

Validação Cruzada

  • Estratégia: 5-fold Stratified CV
  • F1-Score (CV): 97.0% ± 0.3%
  • Consistência: Alta estabilidade entre folds

Comparação de Modelos

Durante o desenvolvimento, foram treinados e comparados 9 modelos diferentes:

Ranking Modelo Acurácia F1-Score
🥇 RF Otimizado 🏆 0.970635 0.972112
🥈 Random Forest 0.970110 0.971543
🥉 Stacking 0.968013 0.969757
SVM 0.966964 0.968453
Voting (Soft) 0.966439 0.967936
Voting (Hard) 0.965915 0.967287
Regressão Logística 0.959622 0.961131
Naive Bayes 0.907708 0.915870
Baseline 0.467750 0.000000

🏆 = Modelo final publicado

Por que Random Forest Otimizado?

✅ Vantagens:

  1. Performance Superior: 97.2% F1-Score (melhor entre 9 modelos)
  2. Alta Precisão: 98.3% - minimiza falsos positivos
  3. Bom Recall: 96.2% - captura maioria dos clickbaits
  4. Robusto: Ensemble de 100-500 árvores (reduz overfitting)
  5. Feature Importance: Identifica features mais relevantes
  6. Generalização: Cross-validation confirma estabilidade
  7. Não-linear: Captura interações complexas entre features
  8. Menos sensível a outliers: Natureza ensemble do RF

📊 Comparação com Alternativas:

  • vs. Stacking (3º lugar): +0.2% F1, mais simples de interpretar
  • vs. SVM (4º): +0.4% F1, mais rápido para treinar
  • vs. Voting Soft (5º): +0.4% F1, modelo único (mais fácil deploy)
  • vs. Regressão Logística (7º): +1.1% F1, captura não-linearidades

Arquitetura Técnica

Especificações do Modelo

Modelo Final: Random Forest Otimizado

Características:

  • Tipo: RandomForestClassifier (Scikit-learn)
  • Otimização: RandomizedSearchCV
  • Iterações de busca: 50 combinações testadas
  • Validação cruzada: 5-fold StratifiedKFold
  • Métrica de otimização: F1-Score
  • Espaço de busca: 576 combinações possíveis

Hiperparâmetros Testados:

  • n_estimators: [100, 200, 300, 500]
  • max_depth: [None, 10, 20, 30, 50]
  • min_samples_split: [2, 5, 10]
  • min_samples_leaf: [1, 2, 4]
  • max_features: ['sqrt', 'log2', None]
  • bootstrap: [True, False]

Features (204 dimensões)

1. TF-IDF Features (200 dimensões):

  • Vocabulário: 5.000 termos mais frequentes
  • N-grams: unigramas e bigramas (1-2)
  • Min Document Frequency: 2
  • Analyzer: word-level

2. Features Numéricas (4 dimensões):

  • word_count: Número de palavras na manchete
  • char_count: Número de caracteres total
  • exclamation_count: Quantidade de pontos de exclamação (!)
  • question_count: Quantidade de pontos de interrogação (?)

Pipeline de Pré-processamento

Texto Raw → Lowercase → Remove Stopwords → TF-IDF (200 features)
                                                ↓
Features Numéricas → StandardScaler (4 features)
                                                ↓
                        Combine (204 features total)
                                                ↓
                        Random Forest Classifier
                                                ↓
                            Predição Final

Pré-processamento:

  • Normalização: StandardScaler (features numéricas)
  • Text processing: lowercase, stopwords removal (português), tokenização
  • TF-IDF vectorization aplicada ao texto processado

Hardware & Software

  • Framework: Scikit-learn 1.7.2
  • Python: 3.8+
  • Hardware: CPU (tempo de treinamento: ~22 minutos)
  • Dependencies: numpy, pandas, nltk, scikit-learn

Como Usar

Instalação

python -m venv .venv
source ./.venv/Scripts/activate
pip install scikit-learn nltk pandas numpy huggingface_hub ipywidgets

Carregar Modelo

from huggingface_hub import hf_hub_download
import pickle

# Download dos arquivos
modelo_path = hf_hub_download(
    repo_id="rodrigoaraujorosa/detector-clickbait-br-model",
    filename="melhor_modelo.pkl"
)
tfidf_path = hf_hub_download(
    repo_id="rodrigoaraujorosa/detector-clickbait-br-model",
    filename="tfidf_vectorizer.pkl"
)
scaler_path = hf_hub_download(
    repo_id="rodrigoaraujorosa/detector-clickbait-br-model",
    filename="scaler.pkl"
)

# Carregar
with open(modelo_path, 'rb') as f:
    modelo = pickle.load(f)
with open(tfidf_path, 'rb') as f:
    tfidf = pickle.load(f)
with open(scaler_path, 'rb') as f:
    scaler = pickle.load(f)

Fazer Predição

import re
import numpy as np
import pandas as pd
from nltk.corpus import stopwords

# Configurar
stop_words = set(stopwords.words('portuguese'))

def preprocessar_texto(texto):
    texto = texto.lower()
    texto_limpo = re.sub(r'[^\w\s]', ' ', texto)
    palavras = [p for p in texto_limpo.split() if p not in stop_words and p.strip()]
    return ' '.join(palavras)

def extrair_features_numericas(texto):
    return [len(texto.split()), len(texto), texto.count('!'), texto.count('?')]

def prever(texto):
    # Features numéricas
    features_num = extrair_features_numericas(texto)
    
    # TF-IDF
    texto_proc = preprocessar_texto(texto)
    tfidf_feat = tfidf.transform([texto_proc]).toarray()
    
    # Normalizar
    features_scaled = scaler.transform([features_num])
    
    # Combinar
    features_final = np.hstack([tfidf_feat, features_scaled])
    
    # Criar DataFrame com nomes de features CORRETOS
    num_tfidf_features = tfidf_feat.shape[1]
    feature_names = [f'tfidf_{i}' for i in range(num_tfidf_features)] + ['word_count', 'char_count', 'exclamation_count', 'question_count']
    features_df = pd.DataFrame(features_final, columns=feature_names)
    
    # Predição
    pred = modelo.predict(features_df)[0]
    prob = modelo.predict_proba(features_df)[0]
    
    return {
        'classe': 'Clickbait' if pred == 1 else 'Não-Clickbait',
        'confianca': float(prob[pred]),
        'probabilidades': {
            'nao_clickbait': float(prob[0]),
            'clickbait': float(prob[1])
        }
    }

# Exemplo
resultado = prever("Você não vai acreditar no que aconteceu!")
print(resultado)
# {'classe': 'Clickbait', 'confianca': 0.8987131189991938, 'probabilidades': {'nao_clickbait': 0.10128688100080614, 'clickbait': 0.8987131189991938}}

Exemplos de Uso

# Não-Clickbait
prever("Banco Central mantém a taxa Selic em 13,75% ao ano")
# {'classe': 'Não-Clickbait', 'confianca': 0.9920440982603037, 'probabilidades': {'nao_clickbait': 0.9920440982603037, 'clickbait': 0.007955901739696425}}

prever("Governo aprova reforma tributária no Congresso")
# {'classe': 'Não-Clickbait', 'confianca': 0.913968871656202, 'probabilidades': {'nao_clickbait': 0.913968871656202, 'clickbait': 0.08603112834379795}}

# Clickbait
prever("Descubra o segredo que ninguém te conta!!!")
# {'classe': 'Clickbait', 'confianca': 0.9680289203901227, 'probabilidades': {'nao_clickbait': 0.031971079609877356, 'clickbait': 0.9680289203901227}}

prever("Este truque simples vai MUDAR sua vida para sempre")
# {'classe': 'Clickbait', 'confianca': 0.8685656910625081, 'probabilidades': {'nao_clickbait': 0.13143430893749186, 'clickbait': 0.8685656910625081}}

Metodologia

1. Coleta de Dados

  • Raw Dataset: 10.565 manchetes iniciais coletadas
  • 634 duplicatas removidas (6.0%)
  • Dataset final: 9.532 manchetes únicas
  • Balanceamento ~50/50 entre classes

2. Pré-processamento

  • Limpeza: Remoção de duplicatas
  • Text processing:
    • Conversão para lowercase
    • Remoção de pontuação (após extração de features)
    • Remoção de stopwords em português (NLTK)
    • Tokenização
    • Stemming: não aplicado (testes mostraram performance similar)

3. Engenharia de Features

  • TF-IDF Vectorization:

    • Max features: 5.000 termos
    • N-grams: 1-2 (unigramas e bigramas)
    • Min DF: 2 (termo aparece em ≥2 documentos)
    • Result: 200 features mais relevantes selecionadas
  • Features Numéricas:

    • Contagem de palavras, caracteres, pontuação
    • Normalização com StandardScaler
    • Total: 4 features numéricas

4. Treinamento

  • Modelos testados: 9 (baseline + 4 individuais + RF otimizado + 3 ensembles)
  • Otimização: RandomizedSearchCV
    • 50 iterações
    • 5-fold cross-validation
    • Busca em espaço de 576 combinações possíveis
  • Hardware: CPU (tempo de treinamento: ~22 minutos)
  • Best model selection: Baseado em F1-Score

5. Avaliação

  • Métricas: Accuracy, Precision, Recall, F1-Score
  • Test set: 1.907 exemplos (20% do dataset)
  • Validation: 5-fold Stratified Cross-Validation
  • Análise de erros: Identificação de falsos positivos/negativos

Considerações Éticas

Vieses Potenciais

Viés de Dados

  • ⚠️ Viés de Fonte: Dataset coletado de portais mainstream brasileiros
  • ⚠️ Viés Regional: Predominantemente português do Brasil
  • ⚠️ Viés de Domínio: Focado em jornalismo (não generaliza para marketing)

Viés do Modelo

  • ⚠️ Precisão Alta (98.3%): Pode rejeitar alguns clickbaits legítimos
  • ⚠️ Recall Bom (96.2%): ~4% de clickbaits passam despercebidos
  • ⚠️ Dependência de Features: Modelo sensível a contagem de pontuação (! e ?)

Recomendações de Uso

Para Desenvolvedores

  • Sempre mostrar probabilidades (não apenas classe)
  • Implementar threshold ajustável (balancear precisão/recall)
  • Adicionar revisão humana antes de ações automatizadas
  • Monitorar concept drift (retreinar periodicamente)
  • Testar em seu domínio específico antes de deploy

Para Usuários

  • ⚠️ Não confiar 100% nas predições
  • ⚠️ Validar casos de alta incerteza (prob ~50%)
  • ⚠️ Considerar contexto da fonte
  • ⚠️ Reportar erros sistemáticos para melhoria contínua

Exemplo de Uso Responsável

# ✅ BOM: Mostrar probabilidades e permitir revisão
resultado = prever(texto)
if resultado['probabilidades']['clickbait'] > 0.7:
    print("⚠️ Alta confiança: Provável Clickbait")
    print(f"Confiança: {resultado['confianca']:.2%}")
elif resultado['probabilidades']['clickbait'] > 0.5:
    print("⚡ Média confiança: Revisar manualmente")
    print(f"Confiança: {resultado['confianca']:.2%}")
else:
    print("✅ Baixa probabilidade de Clickbait")

# ❌ RUIM: Decisão binária automática sem contexto
if modelo.predict(texto) == 1:
    deletar_manchete()  # Perigoso! Pode censurar conteúdo legítimo

Limitações e Recomendações

⚠️ Limitações Conhecidas

Limitações Técnicas

  1. Não detecta sarcasmo/ironia

    • Manchetes irônicas podem ser classificadas incorretamente
  2. Sensível a mudanças linguísticas

    • Novo vocabulário/gírias podem reduzir performance
  3. Contexto limitado

    • Não considera: fonte, autor, histórico do portal
  4. Textos curtos apenas

    • Otimizado para manchetes (5-20 palavras)
    • Não funciona bem com textos longos (tende a classificar como clickbait)

Limitações Sociais

  1. Definição de clickbait é subjetiva

    • O que é "sensacionalista" varia por contexto
  2. Pode impactar liberdade editorial

    • Uso indiscriminado pode censurar títulos legítimos
  3. Não substitui julgamento humano

    • Sempre requer validação por editores

Problemas Conhecidos

  1. Falsos Positivos: Títulos legítimos com linguagem emocional
  2. Falsos Negativos: Clickbaits sutis sem sinais óbvios
  3. Drift Temporal: Performance pode degradar com o tempo

Manutenção Recomendada

  • 🔄 Retreinamento: Recomendado a cada 6 meses
  • 📊 Monitoramento: Acompanhar métricas em produção
  • 🐛 Feedback Loop: Coletar erros para próxima versão

Melhorias Futuras

  • Aumentar dataset (→10k+ exemplos)
  • Testar modelos Transformer (BERTimbau, mBERT)
  • Adicionar features contextuais (fonte, timestamp, autor)
  • Expandir para outros idiomas (espanhol, inglês)
  • Fine-tuning com dados mais recentes
  • Deploy em produção com monitoramento de drift
  • A/B testing de modelos em produção

Citação

BibTeX

@misc{detector-clickbait-br-model,
  author = {Rodrigo de Araujo Rosa},
  title = {Detector de Clickbait BR: Datasets utilizados no treinamento do Modelo de ML para Detecção de Clickbait em Português},
  year = {2025},
  publisher = {Hugging Face},
  journal = {Hugging Face Model Hub},
  howpublished = {\url{https://huggingface.co/rodrigoaraujorosa/detector-clickbait-br-model}}
}

APA

ROSA, Rodrigo de Araujo. (2025). Modelo de ML para Detecção de Clickbait em Português. Hugging Face Model Hub. https://huggingface.co/rodrigoaraujorosa/detector-clickbait-br-model

Links

📄 Licença

MIT License - Uso livre para fins acadêmicos e comerciais.

Autores

  • Rodrigo de Araujo Rosa - Desenvolvedor & Mantenedor

Contato

Para dúvidas ou feedback: rodrigoaraujo.r@gmail.com


Última atualização: Novembro 2025

Downloads last month
-
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Dataset used to train rodrigoaraujorosa/detector-clickbait-br-model

Evaluation results