File size: 16,104 Bytes
ea0e222 52b0ede ea0e222 52b0ede ea0e222 52b0ede ea0e222 46cc63a ea0e222 52b0ede ea0e222 52b0ede ea0e222 52b0ede ea0e222 46cc63a ea0e222 46cc63a ea0e222 46cc63a ea0e222 46cc63a ea0e222 46cc63a ea0e222 46cc63a ea0e222 46cc63a ea0e222 52b0ede ea0e222 46cc63a ea0e222 46cc63a ea0e222 46cc63a ea0e222 52b0ede ea0e222 52b0ede ea0e222 52b0ede ea0e222 52b0ede ea0e222 46cc63a ea0e222 52b0ede ea0e222 46cc63a 52b0ede ea0e222 52b0ede ea0e222 46cc63a ea0e222 52b0ede ea0e222 46cc63a ea0e222 52b0ede ea0e222 52b0ede ea0e222 52b0ede ea0e222 52b0ede ea0e222 52b0ede ea0e222 52b0ede ea0e222 52b0ede ea0e222 52b0ede ea0e222 52b0ede ea0e222 52b0ede ea0e222 46cc63a ea0e222 52b0ede ea0e222 46cc63a ea0e222 46cc63a ea0e222 52b0ede ea0e222 46cc63a ea0e222 46cc63a ea0e222 52b0ede ea0e222 46cc63a ea0e222 46cc63a ea0e222 46cc63a ea0e222 52b0ede ea0e222 52b0ede ea0e222 46cc63a ea0e222 46cc63a ea0e222 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | <div align="center">
<img src="docs/assets/signalmod_logo.png" alt="SignalMod" width="520" />
### ModeraciΓ³n inteligente para comentarios de YouTube
π [English](README.md) Β· **EspaΓ±ol**










</div>
---
## DescripciΓ³n del proyecto
**SignalMod** es un asistente de moderaciΓ³n inteligente para comentarios de YouTube. Clasifica automΓ‘ticamente cada comentario como **Seguro** o **TΓ³xico**, devuelve una probabilidad entre 0 y 1 y etiqueta categorΓas de toxicidad (insulto, amenaza, odio identitario, contenido obsceno).
EstΓ‘ construido alrededor del modelo **hybrid meta-feature stacking** del equipo β embeddings de Toxic-BERT congelado combinados con metadatos y una regresiΓ³n logΓstica regularizada β que alcanza **F1 = 0,805** con una brecha trainβtest de **2,54 pp** sobre el split de 200 muestras del proyecto.
El producto se entrega como una API REST con FastAPI y una SPA React que imita la experiencia de YouTube Watch: eliges un vΓdeo, la API descarga los 50 comentarios mΓ‘s recientes vΓa la YouTube Data API, los puntΓΊa y persiste cada predicciΓ³n en Supabase para que cualquier visitante pueda ver el histΓ³rico completo.
---
## Herramientas y lenguajes
### Lenguajes
- **Python 3.12** β backend, pipelines de ML, evaluaciΓ³n.
- **TypeScript + React 18** β SPA del frontend.
- **SQL (PostgreSQL vΓa Supabase)** β persistencia de predicciones.
### Backend
- **FastAPI 0.136** β API REST, esquemas Pydantic, carga del modelo en lifespan.
- **Uvicorn** β servidor ASGI con hot reload.
- **scikit-learn 1.8** β baseline TF-IDF + meta-learner LogisticRegression.
- **Optuna** β bΓΊsqueda de hiperparΓ‘metros del baseline TF-IDF.
- **PyTorch 2.x + Transformers 5.9** β `unitary/toxic-bert` congelado para embeddings CLS.
- **spaCy + NLTK** β lematizaciΓ³n, stopwords, limpieza basada en regex.
- **MLflow** β tracking de experimentos.
- **Supabase Python SDK** β persistencia de predicciones con polΓticas RLS anΓ³nimas.
- **google-api-python-client** β integraciΓ³n con YouTube Data API v3.
### Frontend
- **React 18 + Vite 5 + TypeScript** β SPA con hot module reload.
- **CSS modules** β tema oscuro estilo YouTube.
### Tooling y operaciones
- **uv** β gestor de paquetes y entorno virtual de Python (`pyproject.toml` + `uv.lock`).
- **pnpm** β gestor de paquetes del frontend.
- **Docker + Docker Compose** β despliegue en un ΓΊnico contenedor sirviendo API + SPA construida.
- **GNU Make** β `make dev`, `make install`, `make build`, `make docker`.
- **Render** β despliegue gratuito vΓa blueprint `render.yaml`.
- **Pytest** β tests unitarios de contratos de API y preprocesado.
---
## Arquitectura del proyecto
```
Project_9_Equipo3/
βββ configs/ # Configs YAML para pipelines y catΓ‘logo de inferencia
β βββ pipeline.yaml # Rutas de datos, target, folds de CV
β βββ features.yaml # Preprocesado y ajustes de TF-IDF
β βββ model_catalog.yaml # CatΓ‘logo de inferencia (3 modelos intercambiables)
β βββ best_params.yaml # Ganador de Optuna para el baseline LR
β βββ suggested_videos.yaml # IDs de YouTube del rail "Up next"
β βββ *_training.yaml # Perfiles de entrenamiento (golden, expert, hybrid, β¦)
βββ data/ # Datasets crudos y procesados (git-ignored)
βββ docs/ # API.md, PIPELINE.md, ARCHITECTURE.md, DEPLOY.md
β βββ assets/signalmod_logo.png # Activos de marca
βββ frontend/ # SPA React + Vite
β βββ public/signalmod_logo.png # Logo servido como activo estΓ‘tico
β βββ src/
β βββ api/ # Cliente HTTP tipado
β βββ components/ # Layout, CommentRow, SuggestedRail, ModelBanner
β βββ context/ # Estado global (modelo activo, umbral)
β βββ hooks/ # useDebouncedPredict
β βββ pages/ # WatchPage, HubPage, SettingsPage
β βββ utils/ # toxicityColor, randomUsername, relativeTime
βββ models/
β βββ baseline/lr_tfidf.joblib # Baseline LR ajustado con Optuna
β βββ production_final/ # meta_stack_final.joblib β artefacto de producciΓ³n
βββ notebooks/
β βββ 01β04 # EDA, preprocesado, TF-IDF, baseline LR
β βββ 12 # Golden baseline (Toxic-BERT congelado)
β βββ 14 # Meta-stacking final β artefacto de producciΓ³n
β βββ archive_attempts/ # Experimentos anteriores conservados para reproducibilidad
βββ reports/ # MΓ©tricas, grΓ‘ficos, figuras EDA, summary.csv
βββ src/
β βββ api/ # App FastAPI
β β βββ main.py # Lifespan, CORS, montaje del SPA estΓ‘tico
β β βββ routes/ # health, models, predict (+ /predictions), videos
β β βββ schemas.py # Modelos Pydantic request/response
β β βββ services.py # predict_single, to_predict_response
β β βββ state.py # Estado compartido de la app
β β βββ youtube.py # Fetch a YouTube Data API + metadatos sugeridos
β βββ data/ # Loader, dual loader para pipelines hΓbridos
β βββ db/ # Cliente Supabase + helpers save_prediction
β βββ evaluation/ # Evaluator, threshold tuning, CV estable
β βββ experiments/ # Versiones script de los notebooks 13 / 14
β βββ features/ # text_preprocessor, vectorizer, metadata, augmentation
β βββ models/ # baseline (LR/RF/XGBoost), hybrid_ensemble, metadata_lr
β βββ pipeline/ # run_pipeline + variantes por estrategia
β βββ service/ # ModelService, meta_stack_predictor, model_catalog
β βββ utils/ # Logger
βββ supabase/predictions_setup.sql # SQL para crear la tabla predictions + polΓticas RLS
βββ tests/ # Suite Pytest
βββ Dockerfile # Build multi-stage (frontend + backend con uv)
βββ docker-compose.yml # Despliegue de un contenedor (API + SPA)
βββ render.yaml # Blueprint de Render (web service + static site)
βββ Procfile # DeclaraciΓ³n de proceso para Render
βββ Makefile # make dev / install / build / docker / test
βββ pyproject.toml + uv.lock # Dependencias Python fijadas con uv
βββ README.md / README.es.md # DocumentaciΓ³n en inglΓ©s / espaΓ±ol
```
### Flujo de datos
```
ββββββββββββββββββββββββββββββββββββββββββββββββββ
β SPA React (Vite) http://localhost:5173β
β Layout Β· Watch Β· Hub Β· Settings β
ββββββββββββββββββββ¬ββββββββββββββββββββββββββββββ
β HTTP JSON (proxy Vite β :8000)
ββββββββββββββββββββΌββββββββββββββββββββββββββββββ
β FastAPI http://localhost:8000β
β /predict /predict-batch /predict-video β
β /predictions (GET β histΓ³rico de Supabase) β
β /models /models/select /model-info β
β /videos/suggested /health β
ββββββββ¬ββββββββββββββββββββββββββββββ¬ββββββββββββ
β β
ββββββββββββββββΌββββββββββββββ βββββββββββββββΌβββββββββββββββ
β ModelService β β YouTube Data API v3 β
β Β· local joblib β β Β· metadatos de vΓdeo β
β Β· hf_remote β β Β· 50 comentarios + nuevos β
β Β· meta_stack (producciΓ³n) β β β
ββββββββ¬ββββββββββββββββββββββ ββββββββββββββββββββββββββββββ
β
ββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββ
β Supabase (PostgreSQL) β
β tabla: predictions(id, created_at, text, video_id, β
β probability, is_toxic, labels, β¦) β
β RLS: insert anΓ³nimo + select anΓ³nimo β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
### CatΓ‘logo de modelos (intercambiable desde la UI)
| Modelo | Tipo | F1 (test) | Brecha trainβtest | Umbral | Latencia | Default |
| -------------------------------- | ----------- | --------- | ----------------- | --------- | -------- | ------- |
| **Meta-Feature Stacking** | HΓbrido | **0,805** | **2,54 pp** | **0,381** | ~400 ms | **SΓ** |
| Frozen Toxic-BERT | Transformer | 0,790 | 0,16 pp | 0,120 | ~400 ms | No |
| LR + TF-IDF (Optuna) | sklearn | 0,758 | 4,76 pp | 0,500 | < 50 ms | No |
El modelo de producciΓ³n concatena el embedding `[CLS]` congelado de `unitary/toxic-bert` (768-d) con metadatos hechos a mano (longitud, ratio de mayΓΊsculas, densidad de emojisβ¦), los escala con `StandardScaler` y los pasa por un meta-learner `LogisticRegression(C=0,001)`.
---
## InstalaciΓ³n y ejecuciΓ³n
### 1. Requisitos previos
| Herramienta | macOS / Linux | Windows |
| ------------ | ----------------------------------- | -------------------------------------------------------- |
| **Python 3.12** | `brew install [email protected]` | [python.org/downloads](https://www.python.org/downloads/) (marca *Add Python to PATH*) |
| **uv** | `curl -LsSf https://astral.sh/uv/install.sh \| sh` | `powershell -c "irm https://astral.sh/uv/install.ps1 \| iex"` |
| **Node.js 18+** | `brew install node` | [nodejs.org](https://nodejs.org/) (LTS) |
| **pnpm** | `npm i -g pnpm` | `npm i -g pnpm` |
| **Make** *(opcional)* | ya instalado | `winget install GnuWin32.Make` (o usa WSL) |
### 2. Clonar y configurar
```bash
git clone https://github.com/Bootcamp-IA-P6/Project_9_Equipo3.git
cd Project_9_Equipo3
cp .env.example .env
# Rellena: YOUTUBE_API_KEY, SUPABASE_URL, SUPABASE_KEY
```
> **PowerShell de Windows**: sustituye `cp` por `Copy-Item .env.example .env`.
Pega `supabase/predictions_setup.sql` en el editor SQL de Supabase antes del primer arranque (crea la tabla `predictions` + polΓticas RLS).
### 3. Arranque β tres opciones
#### OpciΓ³n A β Con Makefile (recomendada en macOS / Linux / WSL)
```bash
make install # uv sync + pnpm install
make dev # FastAPI :8000 + Vite :5173
```
| Comando | QuΓ© hace |
| ------------- | ---------------------------------------------- |
| `make install`| Instala deps de Python + frontend |
| `make dev` | Arranca API y UI en paralelo (Ctrl+C los para) |
| `make api` | Solo la API |
| `make ui` | Solo la UI |
| `make build` | Compila el SPA a `frontend/dist` |
| `make test` | Ejecuta Pytest |
| `make docker` | `docker compose up --build` |
| `make stop` | Mata procesos en los puertos 8000 / 5173 |
| `make clean` | Borra `.venv`, `node_modules`, `dist` |
#### OpciΓ³n B β Manual (macOS / Linux)
Dos terminales.
**Terminal 1 β API**
```bash
uv sync
uv run uvicorn src.api.main:app --reload --port 8000
```
**Terminal 2 β Frontend**
```bash
cd frontend
pnpm install
pnpm dev
```
#### OpciΓ³n C β Manual (PowerShell de Windows)
Dos terminales.
**Terminal 1 β API**
```powershell
uv sync
uv run uvicorn src.api.main:app --reload --port 8000
```
**Terminal 2 β Frontend**
```powershell
cd frontend
pnpm install
pnpm dev
```
> Si `uv` no se reconoce tras instalarlo, cierra y vuelve a abrir PowerShell para que se recargue el `PATH`.
### 4. Abrir la aplicaciΓ³n
| URL | QuΓ© verΓ‘s |
| ------------------------------ | ---------------------------------------- |
| http://localhost:5173 | SPA React β Watch / Hub / Settings |
| http://localhost:8000/docs | Swagger de FastAPI |
| http://localhost:8000/health | Health check |
### 5. Docker (un solo contenedor β API + SPA compilada)
Mismos comandos en **macOS / Linux / Windows**:
```bash
# Normal β deja imΓ‘genes y volΓΊmenes para builds rΓ‘pidos
docker compose up --build
# β http://localhost:8000 Β· Ctrl+C para parar Β· docker compose down
# Demo efΓmera β Ctrl+C borra contenedor + imagen + volΓΊmenes
make docker-demo
# Limpieza manual completa
make docker-clean
# (equivale a: docker compose down --rmi local --volumes --remove-orphans)
```
---
MΓ‘s detalle: [docs/PIPELINE.es.md](docs/PIPELINE.es.md) para entrenamiento, [docs/API.es.md](docs/API.es.md) para endpoints, [docs/DEPLOY.md](docs/DEPLOY.md) para despliegue en Render.
---
## Colaboradores
<table>
<tr>
<td align="center" width="25%">
<b>AndrΓ©s Torrez</b><br/>
<sub>Backend Developer</sub>
</td>
<td align="center" width="25%">
<b>Mirae Kang</b><br/>
<sub>Scrum Master</sub>
</td>
<td align="center" width="25%">
<b>Jonathan Brasales</b><br/>
<sub>AI Developer</sub>
</td>
<td align="center" width="25%">
<b>Roberto Molero</b><br/>
<sub>Product Owner</sub>
</td>
</tr>
</table>
---
<div align="center">
**SignalMod** β Bootcamp IA P6 Β· Equipo 3 Β· 2026
</div>
|