--- language: pt license: mit tags: - text-classification - clickbait-detection - portuguese - sklearn - random-forest datasets: - rodrigoaraujorosa/detector-clickbait-br-datasets metrics: - accuracy - f1 - precision - recall model-index: - name: Detector de Clickbait BR results: - task: type: text-classification name: Text Classification dataset: name: Custom Brazilian Headlines type: custom metrics: - type: accuracy value: 0.9706 name: Accuracy - type: f1 value: 0.9721 name: F1 Score - type: precision value: 0.9829 name: Precision - type: recall value: 0.9616 name: Recall --- # 🔍 Detector de Clickbait BR ## 📋 Índice - [Visão Geral](#visão-geral) - [Detalhes do Modelo](#detalhes-do-modelo) - [Uso Pretendido](#uso-pretendido) - [Dados de Treinamento](#dados-de-treinamento) - [Avaliação](#avaliação) - [Arquitetura Técnica](#arquitetura-técnica) - [Como Usar](#como-usar) - [Metodologia](#metodologia) - [Considerações Éticas](#considerações-éticas) - [Limitações e Recomendações](#limitações-e-recomendações) - [Citação](#citação) - [Links](#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](https://github.com/rodrigoaraujorosa) - **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](https://github.com/rodrigoaraujorosa/detector-clickbait-br) ### 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](assets/eda_dashboard.png) 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](assets/wordcloud_comparison.png) *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: 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 ```bash python -m venv .venv source ./.venv/Scripts/activate pip install scikit-learn nltk pandas numpy huggingface_hub ipywidgets ``` ### Carregar Modelo ```python 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 ```python 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 ```python # 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 ```python # ✅ 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 ```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](https://huggingface.co/spaces/rodrigoaraujorosa/detector-clickbait-br) - **📚 Datasets:** [Hugging Face Dataset](https://huggingface.co/datasets/rodrigoaraujorosa/detector-clickbait-br-datasets) - **💻 Código Fonte:** [GitHub Repository](https://github.com/rodrigoaraujorosa/detector-clickbait-br) - **📊 Notebooks:** [Análise Exploratória + Treinamento](https://github.com/rodrigoaraujorosa/detector-clickbait-br/tree/develop/notebooks) - **📧 Contato:** rodrigoaraujo.r@gmail.com - **🔗 LinkedIn:** [Rodrigo de Araujo Rosa](https://www.linkedin.com/in/rodrigoaraujorosa/) ## 📄 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