Text Classification
Scikit-learn
Portuguese
clickbait-detection
portuguese
random-forest
Eval Results (legacy)
Instructions to use rodrigoaraujorosa/detector-clickbait-br-model with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Scikit-learn
How to use rodrigoaraujorosa/detector-clickbait-br-model with Scikit-learn:
from huggingface_hub import hf_hub_download import joblib model = joblib.load( hf_hub_download("rodrigoaraujorosa/detector-clickbait-br-model", "sklearn_model.joblib") ) # only load pickle files from sources you trust # read more about it here https://skops.readthedocs.io/en/stable/persistence.html - Notebooks
- Google Colab
- Kaggle
Commit ·
f03f4d9
0
Parent(s):
Initial commit with local files
Browse files- .gitattributes +1 -0
- LICENSE +19 -0
- README.md +362 -0
- config.json +185 -0
- melhor_modelo.pkl +3 -0
- model_card.md +337 -0
- requirements.txt +4 -0
- scaler.pkl +3 -0
- tfidf_vectorizer.pkl +3 -0
.gitattributes
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Copyright (c) 2018 The Python Packaging Authority
|
| 2 |
+
|
| 3 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 4 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 5 |
+
in the Software without restriction, including without limitation the rights
|
| 6 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 7 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 8 |
+
furnished to do so, subject to the following conditions:
|
| 9 |
+
|
| 10 |
+
The above copyright notice and this permission notice shall be included in all
|
| 11 |
+
copies or substantial portions of the Software.
|
| 12 |
+
|
| 13 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 14 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 15 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 16 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 17 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 18 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 19 |
+
SOFTWARE.
|
README.md
ADDED
|
@@ -0,0 +1,362 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
language: pt
|
| 3 |
+
license: mit
|
| 4 |
+
tags:
|
| 5 |
+
- text-classification
|
| 6 |
+
- clickbait-detection
|
| 7 |
+
- portuguese
|
| 8 |
+
- sklearn
|
| 9 |
+
- random-forest
|
| 10 |
+
datasets:
|
| 11 |
+
- custom
|
| 12 |
+
metrics:
|
| 13 |
+
- accuracy
|
| 14 |
+
- f1
|
| 15 |
+
- precision
|
| 16 |
+
- recall
|
| 17 |
+
model-index:
|
| 18 |
+
- name: Detector de Clickbait BR
|
| 19 |
+
results:
|
| 20 |
+
- task:
|
| 21 |
+
type: text-classification
|
| 22 |
+
name: Text Classification
|
| 23 |
+
metrics:
|
| 24 |
+
- type: accuracy
|
| 25 |
+
value: 0.970
|
| 26 |
+
name: Accuracy
|
| 27 |
+
- type: f1
|
| 28 |
+
value: 0.972
|
| 29 |
+
name: F1 Score
|
| 30 |
+
- type: precision
|
| 31 |
+
value: 0.982
|
| 32 |
+
name: Precision
|
| 33 |
+
- type: recall
|
| 34 |
+
value: 0.961
|
| 35 |
+
name: Recall
|
| 36 |
+
---
|
| 37 |
+
|
| 38 |
+
# 🔍 Detector de Clickbait BR - Model
|
| 39 |
+
|
| 40 |
+
Modelo de Machine Learning para detecção de manchetes clickbait em português brasileiro.
|
| 41 |
+
|
| 42 |
+
## 📊 Descrição
|
| 43 |
+
|
| 44 |
+
Este modelo foi treinado para classificar manchetes de notícias em duas categorias:
|
| 45 |
+
- **Não-Clickbait** (0): Manchetes informativas e objetivas
|
| 46 |
+
- **Clickbait** (1): Manchetes sensacionalistas e enganosas
|
| 47 |
+
|
| 48 |
+
## 🎯 Performance
|
| 49 |
+
|
| 50 |
+
| Métrica | Valor |
|
| 51 |
+
|---------|-------|
|
| 52 |
+
| **Acurácia** | 97.1% |
|
| 53 |
+
| **Precisão** | 98.3% |
|
| 54 |
+
| **Recall** | 96.2% |
|
| 55 |
+
| **F1-Score** | 97.2% |
|
| 56 |
+
|
| 57 |
+
### 📈 Comparação de Modelos
|
| 58 |
+
|
| 59 |
+
Durante o desenvolvimento, foram treinados e comparados 9 modelos diferentes:
|
| 60 |
+
|
| 61 |
+
|Ranking | Modelo | Acurácia | F1-Score |
|
| 62 |
+
|--------|--------------------|----------|----------|
|
| 63 |
+
| 🥇 |**RF Otimizado** 🏆 | 0.970635 | 0.972112 |
|
| 64 |
+
| 🥈 |Random Forest | 0.970110 | 0.971543 |
|
| 65 |
+
| 🥉 |Stacking | 0.968013 | 0.969757 |
|
| 66 |
+
| 4º |SVM | 0.966964 | 0.968453 |
|
| 67 |
+
| 5º |Voting (Soft) | 0.966439 | 0.967936 |
|
| 68 |
+
| 6º |Voting (Hard) | 0.965915 | 0.967287 |
|
| 69 |
+
| 7º |Regressão Logística | 0.959622 | 0.961131 |
|
| 70 |
+
| 8º |Naive Bayes | 0.907708 | 0.915870 |
|
| 71 |
+
| 9º |Baseline | 0.467750 | 0.000000 |
|
| 72 |
+
|
| 73 |
+
*🏆 = Modelo final publicado*
|
| 74 |
+
|
| 75 |
+
## 🧠 Arquitetura
|
| 76 |
+
|
| 77 |
+
### Modelo Final: Random Forest Otimizado
|
| 78 |
+
|
| 79 |
+
**Características:**
|
| 80 |
+
- **Tipo:** RandomForestClassifier (Scikit-learn)
|
| 81 |
+
- **Otimização:** RandomizedSearchCV
|
| 82 |
+
- **Iterações de busca:** 50 combinações testadas
|
| 83 |
+
- **Validação cruzada:** 5-fold StratifiedKFold
|
| 84 |
+
- **Métrica de otimização:** F1-Score
|
| 85 |
+
|
| 86 |
+
**Hiperparâmetros Otimizados:**
|
| 87 |
+
O modelo testou combinações de:
|
| 88 |
+
- `n_estimators`: [100, 200, 300, 500]
|
| 89 |
+
- `max_depth`: [None, 10, 20, 30, 50]
|
| 90 |
+
- `min_samples_split`: [2, 5, 10]
|
| 91 |
+
- `min_samples_leaf`: [1, 2, 4]
|
| 92 |
+
- `max_features`: ['sqrt', 'log2', None]
|
| 93 |
+
- `bootstrap`: [True, False]
|
| 94 |
+
|
| 95 |
+
**Features de Entrada:** 204 dimensões
|
| 96 |
+
|
| 97 |
+
**1. TF-IDF Features (200 dimensões):**
|
| 98 |
+
- Vocabulário: 5.000 termos mais frequentes
|
| 99 |
+
- N-grams: unigramas e bigramas (1-2)
|
| 100 |
+
- Min Document Frequency: 2
|
| 101 |
+
- Analyzer: word-level
|
| 102 |
+
|
| 103 |
+
**2. Features Numéricas (4 dimensões):**
|
| 104 |
+
- `word_count`: Número de palavras na manchete
|
| 105 |
+
- `char_count`: Número de caracteres total
|
| 106 |
+
- `exclamation_count`: Quantidade de pontos de exclamação (!)
|
| 107 |
+
- `question_count`: Quantidade de pontos de interrogação (?)
|
| 108 |
+
|
| 109 |
+
**Pré-processamento:**
|
| 110 |
+
- Normalização: StandardScaler (features numéricas)
|
| 111 |
+
- Text processing: lowercase, stopwords removal (português), tokenização
|
| 112 |
+
- TF-IDF vectorization aplicada ao texto processado
|
| 113 |
+
|
| 114 |
+
## 📚 Dataset
|
| 115 |
+
|
| 116 |
+
- **Total**: 9.532 manchetes
|
| 117 |
+
- **Fonte**: Portais de notícias brasileiros (diversos domínios)
|
| 118 |
+
- **Distribuição de Classes**:
|
| 119 |
+
- Não-Clickbait: 4.457 (46.76%)
|
| 120 |
+
- Clickbait: 5.075 (53.24%)
|
| 121 |
+
- **Split**: 80% treino (7.625) / 20% teste (1.907)
|
| 122 |
+
- **Estratégia de Validação**: 5-fold cross-validation
|
| 123 |
+
- **Random State**: 42 (reprodutibilidade garantida)
|
| 124 |
+
|
| 125 |
+
### Exemplos do Dataset
|
| 126 |
+
|
| 127 |
+
**Não-Clickbait:**
|
| 128 |
+
- "Banco Central mantém a taxa Selic em 13,75% ao ano"
|
| 129 |
+
- "Governo aprova reforma tributária no Congresso"
|
| 130 |
+
- "Estudo da USP revela novos dados sobre mudanças climáticas"
|
| 131 |
+
|
| 132 |
+
**Clickbait:**
|
| 133 |
+
- "O pesadelo dos investidores: a decisão do Banco Central que vai destruir seus lucros!"
|
| 134 |
+
- "Descubra o segredo para emagrecer 10kg em 7 dias!!!"
|
| 135 |
+
- "Este truque simples vai MUDAR sua vida para sempre"
|
| 136 |
+
|
| 137 |
+
## 🚀 Como Usar
|
| 138 |
+
|
| 139 |
+
### Instalação
|
| 140 |
+
|
| 141 |
+
```bash
|
| 142 |
+
pip install scikit-learn nltk pandas numpy huggingface_hub
|
| 143 |
+
```
|
| 144 |
+
|
| 145 |
+
### Carregar Modelo
|
| 146 |
+
|
| 147 |
+
```python
|
| 148 |
+
from huggingface_hub import hf_hub_download
|
| 149 |
+
import pickle
|
| 150 |
+
|
| 151 |
+
# Download dos arquivos
|
| 152 |
+
modelo_path = hf_hub_download(
|
| 153 |
+
repo_id="rodrigoaraujorosa/detector-clickbait-br-model",
|
| 154 |
+
filename="melhor_modelo.pkl"
|
| 155 |
+
)
|
| 156 |
+
tfidf_path = hf_hub_download(
|
| 157 |
+
repo_id="rodrigoaraujorosa/detector-clickbait-br-model",
|
| 158 |
+
filename="tfidf_vectorizer.pkl"
|
| 159 |
+
)
|
| 160 |
+
scaler_path = hf_hub_download(
|
| 161 |
+
repo_id="rodrigoaraujorosa/detector-clickbait-br-model",
|
| 162 |
+
filename="scaler.pkl"
|
| 163 |
+
)
|
| 164 |
+
|
| 165 |
+
# Carregar
|
| 166 |
+
with open(modelo_path, 'rb') as f:
|
| 167 |
+
modelo = pickle.load(f)
|
| 168 |
+
with open(tfidf_path, 'rb') as f:
|
| 169 |
+
tfidf = pickle.load(f)
|
| 170 |
+
with open(scaler_path, 'rb') as f:
|
| 171 |
+
scaler = pickle.load(f)
|
| 172 |
+
```
|
| 173 |
+
|
| 174 |
+
### Fazer Predição
|
| 175 |
+
|
| 176 |
+
```python
|
| 177 |
+
import re
|
| 178 |
+
import numpy as np
|
| 179 |
+
import pandas as pd
|
| 180 |
+
from nltk.corpus import stopwords
|
| 181 |
+
|
| 182 |
+
# Configurar
|
| 183 |
+
stop_words = set(stopwords.words('portuguese'))
|
| 184 |
+
|
| 185 |
+
def preprocessar_texto(texto):
|
| 186 |
+
texto = texto.lower()
|
| 187 |
+
texto_limpo = re.sub(r'[^\w\s]', ' ', texto)
|
| 188 |
+
palavras = [p for p in texto_limpo.split() if p not in stop_words and p.strip()]
|
| 189 |
+
return ' '.join(palavras)
|
| 190 |
+
|
| 191 |
+
def extrair_features_numericas(texto):
|
| 192 |
+
return [len(texto.split()), len(texto), texto.count('!'), texto.count('?')]
|
| 193 |
+
|
| 194 |
+
def prever(texto):
|
| 195 |
+
# Features numéricas
|
| 196 |
+
features_num = extrair_features_numericas(texto)
|
| 197 |
+
|
| 198 |
+
# TF-IDF
|
| 199 |
+
texto_proc = preprocessar_texto(texto)
|
| 200 |
+
tfidf_feat = tfidf.transform([texto_proc]).toarray()
|
| 201 |
+
|
| 202 |
+
# Normalizar
|
| 203 |
+
features_scaled = scaler.transform([features_num])
|
| 204 |
+
|
| 205 |
+
# Combinar
|
| 206 |
+
features_final = np.hstack([tfidf_feat, features_scaled])
|
| 207 |
+
|
| 208 |
+
# Criar DataFrame com nomes de features
|
| 209 |
+
feature_names = list(tfidf.get_feature_names_out()) + ['word_count', 'char_count', 'exclamation_count', 'question_count']
|
| 210 |
+
features_df = pd.DataFrame(features_final, columns=feature_names)
|
| 211 |
+
|
| 212 |
+
# Predição
|
| 213 |
+
pred = modelo.predict(features_df)[0]
|
| 214 |
+
prob = modelo.predict_proba(features_df)[0]
|
| 215 |
+
|
| 216 |
+
return {
|
| 217 |
+
'classe': 'Clickbait' if pred == 1 else 'Não-Clickbait',
|
| 218 |
+
'confianca': float(prob[pred]),
|
| 219 |
+
'probabilidades': {
|
| 220 |
+
'nao_clickbait': float(prob[0]),
|
| 221 |
+
'clickbait': float(prob[1])
|
| 222 |
+
}
|
| 223 |
+
}
|
| 224 |
+
|
| 225 |
+
# Exemplo
|
| 226 |
+
resultado = prever("Você não vai acreditar no que aconteceu!")
|
| 227 |
+
print(resultado)
|
| 228 |
+
# {'classe': 'Clickbait', 'confianca': 0.97, 'probabilidades': {'nao_clickbait': 0.03, 'clickbait': 0.97}}
|
| 229 |
+
```
|
| 230 |
+
|
| 231 |
+
## 📝 Exemplos de Uso
|
| 232 |
+
|
| 233 |
+
```python
|
| 234 |
+
# Não-Clickbait
|
| 235 |
+
prever("Banco Central mantém a taxa Selic em 13,75% ao ano")
|
| 236 |
+
# {'classe': 'Não-Clickbait', 'confianca': 0.98}
|
| 237 |
+
|
| 238 |
+
prever("Governo aprova reforma tributária no Congresso")
|
| 239 |
+
# {'classe': 'Não-Clickbait', 'confianca': 0.96}
|
| 240 |
+
|
| 241 |
+
# Clickbait
|
| 242 |
+
prever("Descubra o segredo que ninguém te conta!!!")
|
| 243 |
+
# {'classe': 'Clickbait', 'confianca': 0.99}
|
| 244 |
+
|
| 245 |
+
prever("Este truque simples vai MUDAR sua vida para sempre")
|
| 246 |
+
# {'classe': 'Clickbait', 'confianca': 0.95}
|
| 247 |
+
```
|
| 248 |
+
|
| 249 |
+
## 🔬 Metodologia
|
| 250 |
+
|
| 251 |
+
### 1. Coleta de Dados
|
| 252 |
+
- Raw Dataset: 10.565 manchetes iniciais coletadas
|
| 253 |
+
- 634 duplicatas removidas (6.0%)
|
| 254 |
+
- Dataset final: 9.532 manchetes únicas
|
| 255 |
+
- Balanceamento ~50/50 entre classes
|
| 256 |
+
|
| 257 |
+
### 2. Pré-processamento
|
| 258 |
+
- **Limpeza:** Remoção de duplicatas
|
| 259 |
+
- **Text processing:**
|
| 260 |
+
- Conversão para lowercase
|
| 261 |
+
- Remoção de pontuação (após extração de features)
|
| 262 |
+
- Remoção de stopwords em português (NLTK)
|
| 263 |
+
- Tokenização
|
| 264 |
+
- Stemming: não aplicado (testes mostraram performance similar)
|
| 265 |
+
|
| 266 |
+
### 3. Engenharia de Features
|
| 267 |
+
- **TF-IDF Vectorization:**
|
| 268 |
+
- Max features: 5.000 termos
|
| 269 |
+
- N-grams: 1-2 (unigramas e bigramas)
|
| 270 |
+
- Min DF: 2 (termo aparece em ≥2 documentos)
|
| 271 |
+
- Result: 200 features mais relevantes selecionadas
|
| 272 |
+
|
| 273 |
+
- **Features Numéricas:**
|
| 274 |
+
- Contagem de palavras, caracteres, pontuação
|
| 275 |
+
- Normalização com StandardScaler
|
| 276 |
+
- Total: 4 features numéricas
|
| 277 |
+
|
| 278 |
+
### 4. Treinamento
|
| 279 |
+
- **Modelos testados:** 9 (baseline + 4 individuais + RF otimizado + 3 ensembles)
|
| 280 |
+
- **Otimização:** RandomizedSearchCV
|
| 281 |
+
- 50 iterações
|
| 282 |
+
- 5-fold cross-validation
|
| 283 |
+
- Busca em espaço de 576 combinações possíveis
|
| 284 |
+
- **Hardware:** CPU (tempo de treinamento: ~22 minutos)
|
| 285 |
+
- **Best model selection:** Baseado em F1-Score
|
| 286 |
+
|
| 287 |
+
### 5. Avaliação
|
| 288 |
+
- **Métricas:** Accuracy, Precision, Recall, F1-Score
|
| 289 |
+
- **Test set:** 1.907 exemplos (20% do dataset)
|
| 290 |
+
- **Validation:** 5-fold Stratified Cross-Validation
|
| 291 |
+
- **Análise de erros:** Identificação de falsos positivos/negativos
|
| 292 |
+
|
| 293 |
+
## 🏆 Por que Random Forest Otimizado?
|
| 294 |
+
|
| 295 |
+
### ✅ Vantagens:
|
| 296 |
+
|
| 297 |
+
1. **Performance Superior:** 97.2% F1-Score (melhor entre 9 modelos)
|
| 298 |
+
2. **Alta Precisão:** 98.3% - minimiza falsos positivos
|
| 299 |
+
3. **Bom Recall:** 96.2% - captura maioria dos clickbaits
|
| 300 |
+
4. **Robusto:** Ensemble de 100-500 árvores (reduz overfitting)
|
| 301 |
+
5. **Feature Importance:** Identifica features mais relevantes
|
| 302 |
+
6. **Generalização:** Cross-validation confirma estabilidade
|
| 303 |
+
7. **Não-linear:** Captura interações complexas entre features
|
| 304 |
+
8. **Menos sensível a outliers:** Natureza ensemble do RF
|
| 305 |
+
|
| 306 |
+
### 📊 Comparação com Alternativas:
|
| 307 |
+
|
| 308 |
+
- **vs. Stacking (3º lugar):** +0.2% F1, mais simples de interpretar
|
| 309 |
+
- **vs. SVM (4º):** +0.4% F1, mais rápido para treinar
|
| 310 |
+
- **vs. Voting Soft (5º):** +0.4% F1, modelo único (mais fácil deploy)
|
| 311 |
+
- **vs. Regressão Logística (7º):** +1.1% F1, captura não-linearidades
|
| 312 |
+
-
|
| 313 |
+
## ⚠️ Limitações
|
| 314 |
+
|
| 315 |
+
- ✅ **Idioma:** Apenas português brasileiro
|
| 316 |
+
- ✅ **Domínio:** Otimizado para manchetes de notícias
|
| 317 |
+
- ⚠️ **Generalização:** Pode ter performance reduzida em outros domínios (e-commerce, redes sociais, etc.)
|
| 318 |
+
- ⚠️ **Contexto:** Não considera contexto temporal ou autoria
|
| 319 |
+
- ⚠️ **Sarcasmo/Ironia:** Pode ter dificuldade com textos irônicos
|
| 320 |
+
|
| 321 |
+
## 📈 Melhorias Futuras
|
| 322 |
+
|
| 323 |
+
- [ ] Aumentar dataset (→10k+ exemplos)
|
| 324 |
+
- [ ] Testar modelos Transformer (BERTimbau, mBERT)
|
| 325 |
+
- [ ] Adicionar features contextuais (fonte, timestamp, autor)
|
| 326 |
+
- [ ] Expandir para outros idiomas (espanhol, inglês)
|
| 327 |
+
- [ ] Fine-tuning com dados mais recentes
|
| 328 |
+
- [ ] Deploy em produção com monitoramento de drift
|
| 329 |
+
- [ ] A/B testing de modelos em produção
|
| 330 |
+
|
| 331 |
+
## 📄 Licença
|
| 332 |
+
|
| 333 |
+
MIT License - Uso livre para fins acadêmicos e comerciais.
|
| 334 |
+
|
| 335 |
+
## 🤝 Citação
|
| 336 |
+
|
| 337 |
+
```bibtex
|
| 338 |
+
@misc{detector-clickbait-br-model,
|
| 339 |
+
author = {Rodrigo de Araujo Rosa},
|
| 340 |
+
title = {Detector de Clickbait BR: Modelo de ML para Detecção de Clickbait em Português},
|
| 341 |
+
year = {2025},
|
| 342 |
+
publisher = {Hugging Face},
|
| 343 |
+
journal = {Hugging Face Model Hub},
|
| 344 |
+
howpublished = {\url{https://huggingface.co/rodrigoaraujorosa/detector-clickbait-br-model}}
|
| 345 |
+
}
|
| 346 |
+
```
|
| 347 |
+
|
| 348 |
+
### APA
|
| 349 |
+
```
|
| 350 |
+
ROSA, Rodrigo de Araujo. (2025). Detector de Clickbait BR: Random Forest Classifier for Brazilian Portuguese Clickbait Detection. Hugging Face Model Hub. https://huggingface.co/rodrigoaraujorosa/detector-clickbait-br-model
|
| 351 |
+
```
|
| 352 |
+
|
| 353 |
+
## 🔗 Links
|
| 354 |
+
|
| 355 |
+
- **🚀 Demo Interativa:** [Hugging Face Space](https://huggingface.co/spaces/rodrigoaraujorosa/detector-clickbait-br)
|
| 356 |
+
- **💻 Código Fonte:** [GitHub Repository](https://github.com/rodrigoaraujorosa/detector-clickbait-br)
|
| 357 |
+
- **📊 Notebooks:** [Análise Exploratória + Treinamento](https://github.com/rodrigoaraujorosa/detector-clickbait-br/notebooks)
|
| 358 |
+
- **📚 Raw Dataset:**
|
| 359 |
+
- **📧 Contato:** rodrigoaraujo.r@gmail.com
|
| 360 |
+
- **🔗LinkedIn:** [Rodrigo de Araujo Rosa](https://www.linkedin.com/in/rodrigoaraujorosa/)
|
| 361 |
+
|
| 362 |
+
---
|
config.json
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"model_name": "detector-clickbait-br-model",
|
| 3 |
+
"version": "1.0.0",
|
| 4 |
+
"model_type": "sklearn",
|
| 5 |
+
"task": "text-classification",
|
| 6 |
+
"framework": "scikit-learn",
|
| 7 |
+
"sklearn_version": "1.7.2",
|
| 8 |
+
"language": "pt",
|
| 9 |
+
"license": "mit",
|
| 10 |
+
"pipeline": {
|
| 11 |
+
"preprocessor": "tfidf_vectorizer.pkl",
|
| 12 |
+
"scaler": "scaler.pkl",
|
| 13 |
+
"model": "melhor_modelo.pkl"
|
| 14 |
+
},
|
| 15 |
+
"model_architecture": {
|
| 16 |
+
"type": "Random Forest Classifier (Optimized)",
|
| 17 |
+
"base_model": "RandomForestClassifier",
|
| 18 |
+
"optimization": {
|
| 19 |
+
"method": "RandomizedSearchCV",
|
| 20 |
+
"n_iter": 50,
|
| 21 |
+
"cv_folds": 5,
|
| 22 |
+
"scoring": "f1",
|
| 23 |
+
"random_state": 42
|
| 24 |
+
},
|
| 25 |
+
"hyperparameters": {
|
| 26 |
+
"note": "Optimized via RandomizedSearchCV",
|
| 27 |
+
"search_space": {
|
| 28 |
+
"n_estimators": [100, 200, 300, 500],
|
| 29 |
+
"max_depth": ["None", 10, 20, 30, 50],
|
| 30 |
+
"min_samples_split": [2, 5, 10],
|
| 31 |
+
"min_samples_leaf": [1, 2, 4],
|
| 32 |
+
"max_features": ["sqrt", "log2", "None"],
|
| 33 |
+
"bootstrap": [true, false]
|
| 34 |
+
}
|
| 35 |
+
},
|
| 36 |
+
"best_params": "See model object for details"
|
| 37 |
+
},
|
| 38 |
+
"features": {
|
| 39 |
+
"tfidf": {
|
| 40 |
+
"max_features": 5000,
|
| 41 |
+
"ngram_range": [1, 2],
|
| 42 |
+
"min_df": 2,
|
| 43 |
+
"vocabulary_size": 200,
|
| 44 |
+
"analyzer": "word"
|
| 45 |
+
},
|
| 46 |
+
"numeric": [
|
| 47 |
+
"word_count",
|
| 48 |
+
"char_count",
|
| 49 |
+
"exclamation_count",
|
| 50 |
+
"question_count"
|
| 51 |
+
],
|
| 52 |
+
"total_features": 204
|
| 53 |
+
},
|
| 54 |
+
"dataset": {
|
| 55 |
+
"total_samples": 9532,
|
| 56 |
+
"train_samples": 7625,
|
| 57 |
+
"test_samples": 1907,
|
| 58 |
+
"train_test_split": 0.8,
|
| 59 |
+
"random_state": 42,
|
| 60 |
+
"stratified": true,
|
| 61 |
+
"class_distribution": {
|
| 62 |
+
"non_clickbait": {
|
| 63 |
+
"count": 4457,
|
| 64 |
+
"percentage": 46.76
|
| 65 |
+
},
|
| 66 |
+
"clickbait": {
|
| 67 |
+
"count": 5075,
|
| 68 |
+
"percentage": 53.24
|
| 69 |
+
}
|
| 70 |
+
}
|
| 71 |
+
},
|
| 72 |
+
"performance": {
|
| 73 |
+
"test_set": {
|
| 74 |
+
"accuracy": 0.9706,
|
| 75 |
+
"precision": 0.9829,
|
| 76 |
+
"recall": 0.9616,
|
| 77 |
+
"f1_score": 0.9721,
|
| 78 |
+
"note": "Best performing model among 9 tested"
|
| 79 |
+
},
|
| 80 |
+
"cross_validation": {
|
| 81 |
+
"cv_folds": 5,
|
| 82 |
+
"cv_strategy": "StratifiedKFold",
|
| 83 |
+
"note": "Used during RandomizedSearchCV"
|
| 84 |
+
}
|
| 85 |
+
},
|
| 86 |
+
"classes": {
|
| 87 |
+
"0": "Não-Clickbait",
|
| 88 |
+
"1": "Clickbait"
|
| 89 |
+
},
|
| 90 |
+
"preprocessing": {
|
| 91 |
+
"text": {
|
| 92 |
+
"lowercase": true,
|
| 93 |
+
"remove_stopwords": true,
|
| 94 |
+
"stopwords_language": "portuguese",
|
| 95 |
+
"stemming": false,
|
| 96 |
+
"remove_punctuation": false,
|
| 97 |
+
"note": "Punctuation preserved for feature extraction"
|
| 98 |
+
},
|
| 99 |
+
"numeric_features": {
|
| 100 |
+
"scaler": "StandardScaler",
|
| 101 |
+
"features_scaled": [
|
| 102 |
+
"word_count",
|
| 103 |
+
"char_count",
|
| 104 |
+
"exclamation_count",
|
| 105 |
+
"question_count"
|
| 106 |
+
]
|
| 107 |
+
}
|
| 108 |
+
},
|
| 109 |
+
"model_comparison": {
|
| 110 |
+
"models_tested": 9,
|
| 111 |
+
"ranking_by_f1": [
|
| 112 |
+
{
|
| 113 |
+
"rank": 1,
|
| 114 |
+
"model": "RF Otimizado",
|
| 115 |
+
"f1_score": 0.9721,
|
| 116 |
+
"accuracy": 0.9706
|
| 117 |
+
},
|
| 118 |
+
{
|
| 119 |
+
"rank": 2,
|
| 120 |
+
"model": "Random Forest",
|
| 121 |
+
"f1_score": 0.9715,
|
| 122 |
+
"accuracy": 0.9701
|
| 123 |
+
},
|
| 124 |
+
{
|
| 125 |
+
"rank": 3,
|
| 126 |
+
"model": "Stacking",
|
| 127 |
+
"f1_score": 0.9698,
|
| 128 |
+
"accuracy": 0.9680
|
| 129 |
+
},
|
| 130 |
+
{
|
| 131 |
+
"rank": 4,
|
| 132 |
+
"model": "SVM",
|
| 133 |
+
"f1_score": 0.9685,
|
| 134 |
+
"accuracy": 0.9670
|
| 135 |
+
},
|
| 136 |
+
{
|
| 137 |
+
"rank": 5,
|
| 138 |
+
"model": "Voting (Soft)",
|
| 139 |
+
"f1_score": 0.9679,
|
| 140 |
+
"accuracy": 0.9664
|
| 141 |
+
},
|
| 142 |
+
{
|
| 143 |
+
"rank": 6,
|
| 144 |
+
"model": "Voting (Hard)",
|
| 145 |
+
"f1_score": 0.9673,
|
| 146 |
+
"accuracy": 0.9659
|
| 147 |
+
},
|
| 148 |
+
{
|
| 149 |
+
"rank": 7,
|
| 150 |
+
"model": "Regressão Logística",
|
| 151 |
+
"f1_score": 0.9611,
|
| 152 |
+
"accuracy": 0.9596
|
| 153 |
+
},
|
| 154 |
+
{
|
| 155 |
+
"rank": 8,
|
| 156 |
+
"model": "Naive Bayes",
|
| 157 |
+
"f1_score": 0.9159,
|
| 158 |
+
"accuracy": 0.9077
|
| 159 |
+
},
|
| 160 |
+
{
|
| 161 |
+
"rank": 9,
|
| 162 |
+
"model": "Baseline",
|
| 163 |
+
"f1_score": 0.4678,
|
| 164 |
+
"accuracy": 0.0000
|
| 165 |
+
}
|
| 166 |
+
]
|
| 167 |
+
},
|
| 168 |
+
"inference": {
|
| 169 |
+
"input_format": "string (headline text)",
|
| 170 |
+
"output_format": {
|
| 171 |
+
"prediction": "string (Clickbait or Não-Clickbait)",
|
| 172 |
+
"probabilities": {
|
| 173 |
+
"non_clickbait": "float",
|
| 174 |
+
"clickbait": "float"
|
| 175 |
+
}
|
| 176 |
+
},
|
| 177 |
+
"preprocessing_required": true
|
| 178 |
+
},
|
| 179 |
+
"training_info": {
|
| 180 |
+
"date": "2025",
|
| 181 |
+
"training_time": "~22 minutes (optimization included)",
|
| 182 |
+
"hardware": "CPU",
|
| 183 |
+
"random_state": 42
|
| 184 |
+
}
|
| 185 |
+
}
|
melhor_modelo.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:070ef58afcd8b3e96d103270c0ebdd3bba1fb759a146e62e2088c7530beddd9d
|
| 3 |
+
size 5601765
|
model_card.md
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
language: pt
|
| 3 |
+
license: mit
|
| 4 |
+
tags:
|
| 5 |
+
- text-classification
|
| 6 |
+
- clickbait-detection
|
| 7 |
+
- portuguese
|
| 8 |
+
- sklearn
|
| 9 |
+
- random-forest
|
| 10 |
+
datasets:
|
| 11 |
+
- custom
|
| 12 |
+
metrics:
|
| 13 |
+
- accuracy
|
| 14 |
+
- f1
|
| 15 |
+
- precision
|
| 16 |
+
- recall
|
| 17 |
+
model-index:
|
| 18 |
+
- name: Detector de Clickbait BR
|
| 19 |
+
results:
|
| 20 |
+
- task:
|
| 21 |
+
type: text-classification
|
| 22 |
+
name: Text Classification
|
| 23 |
+
dataset:
|
| 24 |
+
name: Custom Brazilian Headlines
|
| 25 |
+
type: custom
|
| 26 |
+
metrics:
|
| 27 |
+
- type: accuracy
|
| 28 |
+
value: 0.9706
|
| 29 |
+
name: Accuracy
|
| 30 |
+
- type: f1
|
| 31 |
+
value: 0.9721
|
| 32 |
+
name: F1 Score
|
| 33 |
+
- type: precision
|
| 34 |
+
value: 0.9829
|
| 35 |
+
name: Precision
|
| 36 |
+
- type: recall
|
| 37 |
+
value: 0.9616
|
| 38 |
+
name: Recall
|
| 39 |
+
---
|
| 40 |
+
|
| 41 |
+
# Model Card: Detector de Clickbait BR
|
| 42 |
+
|
| 43 |
+
## Model Details
|
| 44 |
+
|
| 45 |
+
### Basic Information
|
| 46 |
+
- **Developed by:** [Rodrigo de Araujo Rosa] ([GitHub](https://github.com/rodrigoaraujorosa))
|
| 47 |
+
- **Model date:** November 2025
|
| 48 |
+
- **Model version:** 1.0.0
|
| 49 |
+
- **Model type:** Random Forest Classifier (Scikit-learn)
|
| 50 |
+
- **Language:** Portuguese (pt-BR)
|
| 51 |
+
- **License:** MIT
|
| 52 |
+
- **Repository:** [GitHub](https://github.com/rodrigoaraujorosa/detector-clickbait-br)
|
| 53 |
+
|
| 54 |
+
### Model Description
|
| 55 |
+
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, alcançando 97.2% de F1-Score.
|
| 56 |
+
|
| 57 |
+
## Intended Use
|
| 58 |
+
|
| 59 |
+
### Primary Intended Uses
|
| 60 |
+
- ✅ Detectar manchetes clickbait em portais de notícias brasileiros
|
| 61 |
+
- ✅ Filtrar conteúdo sensacionalista em agregadores de notícias
|
| 62 |
+
- ✅ Análise de qualidade jornalística
|
| 63 |
+
- ✅ Pesquisa acadêmica em detecção de clickbait
|
| 64 |
+
|
| 65 |
+
### Primary Intended Users
|
| 66 |
+
- Desenvolvedores de agregadores de notícias
|
| 67 |
+
- Jornalistas e editores
|
| 68 |
+
- Pesquisadores em NLP e jornalismo
|
| 69 |
+
- Plataformas de fact-checking
|
| 70 |
+
|
| 71 |
+
### Out-of-Scope Use Cases
|
| 72 |
+
- ❌ **Outros idiomas:** Modelo treinado apenas em português brasileiro
|
| 73 |
+
- ❌ **Outros domínios:** Não testado em e-commerce, redes sociais, marketing
|
| 74 |
+
- ❌ **Textos longos:** Otimizado para manchetes (5-20 palavras)
|
| 75 |
+
- ❌ **Classificação multiclasse:** Apenas binário (clickbait/não-clickbait)
|
| 76 |
+
- ❌ **Decisões automatizadas sem supervisão humana:** Recomenda-se validação manual
|
| 77 |
+
|
| 78 |
+
## Training Data
|
| 79 |
+
|
| 80 |
+
### Dataset Overview
|
| 81 |
+
- **Total de exemplos:** 9.532 manchetes únicas
|
| 82 |
+
- **Fonte:** Portais de notícias brasileiros diversos
|
| 83 |
+
- **Processo de limpeza:**
|
| 84 |
+
- 10,565 manchetes iniciais coletadas
|
| 85 |
+
- 634 duplicatas removidas (6.0%)
|
| 86 |
+
|
| 87 |
+
### Class Distribution
|
| 88 |
+
| Classe | Quantidade | Percentual |
|
| 89 |
+
|--------|-----------|-----------|
|
| 90 |
+
| Não-Clickbait | 4.457 | 46.8% |
|
| 91 |
+
| Clickbait | 5.075 | 53.2% |
|
| 92 |
+
|
| 93 |
+
### Train/Test Split
|
| 94 |
+
- **Treino:** 7.625 exemplos (80%)
|
| 95 |
+
- **Teste:** 1.907 exemplos (20%)
|
| 96 |
+
- **Estratégia:** Stratified split (random_state=42)
|
| 97 |
+
- **Validação:** 5-fold Stratified Cross-Validation
|
| 98 |
+
|
| 99 |
+
### Data Collection
|
| 100 |
+
Manchetes coletadas de múltiplos portais brasileiros para garantir diversidade:
|
| 101 |
+
- Portais generalistas
|
| 102 |
+
- Portais especializados (economia, esportes, entretenimento)
|
| 103 |
+
|
| 104 |
+
### Annotation Process
|
| 105 |
+
- Anotação manual por [especificar processo]
|
| 106 |
+
- Critérios de clickbait:
|
| 107 |
+
- Títulos sensacionalistas
|
| 108 |
+
- Uso excessivo de pontuação emocional
|
| 109 |
+
- Omissão de informações cruciais
|
| 110 |
+
- Linguagem hiperbólica
|
| 111 |
+
- Apelo à curiosidade sem contexto
|
| 112 |
+
|
| 113 |
+
## Evaluation
|
| 114 |
+
|
| 115 |
+
### Testing Data
|
| 116 |
+
- **Dataset de teste:** 1.907 manchetes (20% do total)
|
| 117 |
+
- **Estratificação:** Mantém distribuição ~50/50 das classes
|
| 118 |
+
- **Sem overlap:** Nenhum exemplo do treino no teste
|
| 119 |
+
|
| 120 |
+
### Metrics
|
| 121 |
+
|
| 122 |
+
#### Overall Performance (Test Set)
|
| 123 |
+
| Métrica | Valor |
|
| 124 |
+
|---------|-------|
|
| 125 |
+
| **Accuracy** | 97.1% |
|
| 126 |
+
| **Precision** | 98.3% |
|
| 127 |
+
| **Recall** | 96.2% |
|
| 128 |
+
| **F1-Score** | 97.2% |
|
| 129 |
+
|
| 130 |
+
#### Confusion Matrix
|
| 131 |
+
```
|
| 132 |
+
Predicted
|
| 133 |
+
Non-CB Clickbait
|
| 134 |
+
Actual Non-CB 875 17
|
| 135 |
+
Clickbait 39 976
|
| 136 |
+
```
|
| 137 |
+
|
| 138 |
+
#### Cross-Validation
|
| 139 |
+
- **Strategy:** 5-fold Stratified CV
|
| 140 |
+
- **F1-Score (CV):** 97.0% ± 0.3%
|
| 141 |
+
- **Consistency:** Alta estabilidade entre folds
|
| 142 |
+
|
| 143 |
+
### Model Comparison
|
| 144 |
+
Durante o desenvolvimento, 9 modelos foram testados:
|
| 145 |
+
|
| 146 |
+
|Ranking | Modelo | F1-Score |
|
| 147 |
+
|--------|--------------------|----------|
|
| 148 |
+
| 🥇 |**RF Otimizado** 🏆 | 97,2% |
|
| 149 |
+
| 🥈 |Random Forest | 97,2% |
|
| 150 |
+
| 🥉 |Stacking | 97,0% |
|
| 151 |
+
| 4º |SVM | 96,8% |
|
| 152 |
+
| 5º |Voting (Soft) | 96,8% |
|
| 153 |
+
| 6º |Voting (Hard) | 96,7% |
|
| 154 |
+
| 7º |Regressão Logística | 96,1% |
|
| 155 |
+
| 8º |Naive Bayes | 91,6% |
|
| 156 |
+
| 9º |Baseline | 00,0% |
|
| 157 |
+
|
| 158 |
+
O **Random Forest Otimizado** foi selecionado por:
|
| 159 |
+
- ✅ Melhor F1-Score
|
| 160 |
+
- ✅ Alta precisão (98.3%)
|
| 161 |
+
- ✅ Boa generalização (CV estável)
|
| 162 |
+
- ✅ Interpretabilidade (feature importance)
|
| 163 |
+
|
| 164 |
+
## Technical Specifications
|
| 165 |
+
|
| 166 |
+
### Model Architecture
|
| 167 |
+
- **Type:** RandomForestClassifier (Scikit-learn)
|
| 168 |
+
- **Optimization:** RandomizedSearchCV
|
| 169 |
+
- 50 iterações
|
| 170 |
+
- Espaço de busca: 576 combinações
|
| 171 |
+
- Métrica: F1-Score
|
| 172 |
+
- CV: 5-fold Stratified
|
| 173 |
+
|
| 174 |
+
### Features (204 dimensões)
|
| 175 |
+
1. **TF-IDF Features (200):**
|
| 176 |
+
- Vocabulário: 5,000 termos
|
| 177 |
+
- N-grams: 1-2 (unigramas + bigramas)
|
| 178 |
+
- Min DF: 2
|
| 179 |
+
|
| 180 |
+
2. **Numeric Features (4):**
|
| 181 |
+
- word_count
|
| 182 |
+
- char_count
|
| 183 |
+
- exclamation_count
|
| 184 |
+
- question_count
|
| 185 |
+
|
| 186 |
+
### Preprocessing Pipeline
|
| 187 |
+
```
|
| 188 |
+
Texto Raw → Lowercase → Remove Stopwords → TF-IDF
|
| 189 |
+
Features Numéricas → StandardScaler
|
| 190 |
+
Combine → Random Forest → Predição
|
| 191 |
+
```
|
| 192 |
+
|
| 193 |
+
### Hardware & Software
|
| 194 |
+
- **Framework:** Scikit-learn 1.7.2
|
| 195 |
+
- **Python:** 3.8+
|
| 196 |
+
- **Hardware:** CPU (treinamento ~22 min)
|
| 197 |
+
- **Dependencies:** numpy, pandas, nltk
|
| 198 |
+
|
| 199 |
+
## Ethical Considerations
|
| 200 |
+
|
| 201 |
+
### Potential Biases
|
| 202 |
+
|
| 203 |
+
#### Data Bias
|
| 204 |
+
- ⚠️ **Viés de Fonte:** Dataset coletado de portais mainstream brasileiros
|
| 205 |
+
- ⚠️ **Viés Regional:** Predominantemente português do Brasil
|
| 206 |
+
- ⚠️ **Viés de Domínio:** Focado em jornalismo (não generaliza para marketing)
|
| 207 |
+
|
| 208 |
+
#### Model Bias
|
| 209 |
+
- ⚠️ **Precisão Alta (98.3%):** Pode rejeitar alguns clickbaits legítimos
|
| 210 |
+
- ⚠️ **Recall Bom (96.2%):** ~4% de clickbaits passam despercebidos
|
| 211 |
+
- ⚠️ **Feature Dependency:** Modelo sensível a contagem de pontuação (! e ?)
|
| 212 |
+
|
| 213 |
+
### Limitations
|
| 214 |
+
|
| 215 |
+
#### Technical Limitations
|
| 216 |
+
1. **Não detecta sarcasmo/ironia**
|
| 217 |
+
- Manchetes irônicas podem ser classificadas incorretamente
|
| 218 |
+
|
| 219 |
+
2. **Sensível a mudanças linguísticas**
|
| 220 |
+
- Novo vocabulário/gírias podem reduzir performance
|
| 221 |
+
|
| 222 |
+
3. **Contexto limitado**
|
| 223 |
+
- Não considera: fonte, autor, histórico do portal
|
| 224 |
+
|
| 225 |
+
4. **Textos curtos apenas**
|
| 226 |
+
- Otimizado para manchetes (5-20 palavras)
|
| 227 |
+
- Não funciona bem com textos longos (classifica textos longos como clickbait na maioria das vezes)
|
| 228 |
+
|
| 229 |
+
#### Social Limitations
|
| 230 |
+
1. **Definição de clickbait é subjetiva**
|
| 231 |
+
- O que é "sensacionalista" varia por contexto
|
| 232 |
+
|
| 233 |
+
2. **Pode impactar liberdade editorial**
|
| 234 |
+
- Uso indiscriminado pode censurar títulos legítimos
|
| 235 |
+
|
| 236 |
+
3. **Não substitui julgamento humano**
|
| 237 |
+
- Sempre requer validação por editores
|
| 238 |
+
|
| 239 |
+
### Recommendations
|
| 240 |
+
|
| 241 |
+
#### For Developers
|
| 242 |
+
- ✅ **Sempre mostrar probabilidades** (não apenas classe)
|
| 243 |
+
- ✅ **Implementar threshold ajustável** (balancear precisão/recall)
|
| 244 |
+
- ✅ **Adicionar revisão humana** antes de ações automatizadas
|
| 245 |
+
- ✅ **Monitorar concept drift** (retreinar periodicamente)
|
| 246 |
+
- ✅ **Testar em seu domínio específico** antes de deploy
|
| 247 |
+
|
| 248 |
+
#### For Users
|
| 249 |
+
- ⚠️ **Não confiar 100% nas predições**
|
| 250 |
+
- ⚠️ **Validar casos de alta incerteza** (prob ~50%)
|
| 251 |
+
- ⚠️ **Considerar contexto da fonte**
|
| 252 |
+
- ⚠️ **Reportar erros sistemáticos** para melhoria contínua
|
| 253 |
+
|
| 254 |
+
## Caveats and Recommendations
|
| 255 |
+
|
| 256 |
+
### Known Issues
|
| 257 |
+
1. **Falsos Positivos:** Títulos legítimos com linguagem emocional
|
| 258 |
+
2. **Falsos Negativos:** Clickbaits sutis sem sinais óbvios
|
| 259 |
+
3. **Drift Temporal:** Performance pode degradar com o tempo
|
| 260 |
+
|
| 261 |
+
### Maintenance
|
| 262 |
+
- 🔄 **Retreinamento:** Recomendado a cada 6 meses
|
| 263 |
+
- 📊 **Monitoramento:** Acompanhar métricas em produção
|
| 264 |
+
- 🐛 **Feedback Loop:** Coletar erros para próxima versão
|
| 265 |
+
|
| 266 |
+
### Usage Guidelines
|
| 267 |
+
```python
|
| 268 |
+
# ✅ BOM: Mostrar probabilidades
|
| 269 |
+
resultado = model.predict_proba(texto)
|
| 270 |
+
if resultado[1] > 0.7:
|
| 271 |
+
print("Alta confiança: Clickbait")
|
| 272 |
+
elif resultado[1] > 0.5:
|
| 273 |
+
print("Média confiança: Revisar manualmente")
|
| 274 |
+
|
| 275 |
+
# ❌ RUIM: Decisão binária automática
|
| 276 |
+
if model.predict(texto) == 1:
|
| 277 |
+
deletar_manchete() # Perigoso!
|
| 278 |
+
```
|
| 279 |
+
|
| 280 |
+
## How to Use
|
| 281 |
+
|
| 282 |
+
### Installation
|
| 283 |
+
```bash
|
| 284 |
+
pip install scikit-learn nltk pandas numpy
|
| 285 |
+
```
|
| 286 |
+
|
| 287 |
+
### Quick Start
|
| 288 |
+
```python
|
| 289 |
+
from huggingface_hub import hf_hub_download
|
| 290 |
+
import pickle
|
| 291 |
+
|
| 292 |
+
# Download model
|
| 293 |
+
model = hf_hub_download(repo_id="rodrigoaraujorosa/detector-clickbait-br-model",
|
| 294 |
+
filename="melhor_modelo.pkl")
|
| 295 |
+
|
| 296 |
+
# Load
|
| 297 |
+
with open(model, 'rb') as f:
|
| 298 |
+
clf = pickle.load(f)
|
| 299 |
+
|
| 300 |
+
# Predict
|
| 301 |
+
resultado = clf.predict(["Você não vai acreditar!"])
|
| 302 |
+
print(resultado) # [1] = Clickbait
|
| 303 |
+
```
|
| 304 |
+
|
| 305 |
+
**Documentação completa:** Ver [README.md](README.md)
|
| 306 |
+
|
| 307 |
+
## Citation
|
| 308 |
+
|
| 309 |
+
### BibTeX
|
| 310 |
+
```bibtex
|
| 311 |
+
@misc{detector-clickbait-br-model,
|
| 312 |
+
author = {Rodrigo de Araujo Rosa},
|
| 313 |
+
title = {Detector de Clickbait BR: Random Forest Classifier for Brazilian Portuguese Clickbait Detection},
|
| 314 |
+
year = {2025},
|
| 315 |
+
publisher = {Hugging Face},
|
| 316 |
+
journal = {Hugging Face Model Hub},
|
| 317 |
+
howpublished = {\url{https://huggingface.co/rodrigoaraujorosa/detector-clickbait-br-model}}
|
| 318 |
+
}
|
| 319 |
+
```
|
| 320 |
+
|
| 321 |
+
### APA
|
| 322 |
+
```
|
| 323 |
+
ROSA, Rodrigo de Araujo. (2025). Detector de Clickbait BR: Random Forest Classifier for Brazilian Portuguese Clickbait Detection. Hugging Face Model Hub. https://huggingface.co/rodrigoaraujorosa/detector-clickbait-br-model
|
| 324 |
+
```
|
| 325 |
+
|
| 326 |
+
## More Information
|
| 327 |
+
|
| 328 |
+
- **Repository:** [GitHub](https://github.com/rodrigoaraujorosa/detector-clickbait-br)
|
| 329 |
+
- **Demo:** [Hugging Face Space](https://huggingface.co/spaces/rodrigoaraujorosa/detector-clickbait-br)
|
| 330 |
+
- **Contact:** rodrigoaraujo.r@gmail.com
|
| 331 |
+
- **Paper:** [Link se houver]
|
| 332 |
+
|
| 333 |
+
## Model Card Authors
|
| 334 |
+
- [Rodrigo de Araujo Rosa] - Developer & Maintainer
|
| 335 |
+
|
| 336 |
+
## Model Card Contact
|
| 337 |
+
For questions or feedback: rodrigoaraujo.r@gmail.com
|
requirements.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
scikit-learn
|
| 2 |
+
numpy
|
| 3 |
+
pandas
|
| 4 |
+
nltk
|
scaler.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d066df16a09bd3841bb71ae2899dad05321d9531b8ee760ed64a5df7d457a0c1
|
| 3 |
+
size 546
|
tfidf_vectorizer.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:9e9fd48e2e391843ef76023f98d61443c58ce071fa79d9fd5405ef6fddbce68e
|
| 3 |
+
size 8311
|