🔍 Detector de Clickbait BR
📋 Índice
- Visão Geral
- Detalhes do Modelo
- Uso Pretendido
- Dados de Treinamento
- Avaliação
- Arquitetura Técnica
- Como Usar
- Metodologia
- Considerações Éticas
- Limitações e Recomendações
- Citação
- Links
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
A análise exploratória revela padrões interessantes:
📊 Principais Insights
- Distribuição Balanceada: Dataset equilibrado (~50/50) minimiza viés de classe
- Comprimento dos Textos:
- Não-Clickbait: média de ~12 palavras
- Clickbait: média de ~15 palavras (mais descritivo/sensacionalista)
- Densidade de Palavras: Clickbait apresenta maior variabilidade no vocabulário
- 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
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 |
| 4º | SVM | 0.966964 | 0.968453 |
| 5º | Voting (Soft) | 0.966439 | 0.967936 |
| 6º | Voting (Hard) | 0.965915 | 0.967287 |
| 7º | Regressão Logística | 0.959622 | 0.961131 |
| 8º | Naive Bayes | 0.907708 | 0.915870 |
| 9º | Baseline | 0.467750 | 0.000000 |
🏆 = Modelo final publicado
Por que Random Forest Otimizado?
✅ Vantagens:
- Performance Superior: 97.2% F1-Score (melhor entre 9 modelos)
- Alta Precisão: 98.3% - minimiza falsos positivos
- Bom Recall: 96.2% - captura maioria dos clickbaits
- Robusto: Ensemble de 100-500 árvores (reduz overfitting)
- Feature Importance: Identifica features mais relevantes
- Generalização: Cross-validation confirma estabilidade
- Não-linear: Captura interações complexas entre features
- 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 manchetechar_count: Número de caracteres totalexclamation_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
Não detecta sarcasmo/ironia
- Manchetes irônicas podem ser classificadas incorretamente
Sensível a mudanças linguísticas
- Novo vocabulário/gírias podem reduzir performance
Contexto limitado
- Não considera: fonte, autor, histórico do portal
Textos curtos apenas
- Otimizado para manchetes (5-20 palavras)
- Não funciona bem com textos longos (tende a classificar como clickbait)
Limitações Sociais
Definição de clickbait é subjetiva
- O que é "sensacionalista" varia por contexto
Pode impactar liberdade editorial
- Uso indiscriminado pode censurar títulos legítimos
Não substitui julgamento humano
- Sempre requer validação por editores
Problemas Conhecidos
- Falsos Positivos: Títulos legítimos com linguagem emocional
- Falsos Negativos: Clickbaits sutis sem sinais óbvios
- 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
- 🚀 Demo Interativa: Hugging Face Space
- 📚 Datasets: Hugging Face Dataset
- 💻 Código Fonte: GitHub Repository
- 📊 Notebooks: Análise Exploratória + Treinamento
- 📧 Contato: rodrigoaraujo.r@gmail.com
- 🔗 LinkedIn: Rodrigo de Araujo Rosa
📄 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
- -
Dataset used to train rodrigoaraujorosa/detector-clickbait-br-model
Evaluation results
- Accuracy on Custom Brazilian Headlinesself-reported0.971
- F1 Score on Custom Brazilian Headlinesself-reported0.972
- Precision on Custom Brazilian Headlinesself-reported0.983
- Recall on Custom Brazilian Headlinesself-reported0.962

