| # Handover Report — Baseline → Production |
|
|
| **Project:** YouTube Toxic Comment Detector (`youtube_hate_detector`) |
| **Target:** Safe (0) vs Toxic (1) on `IsToxic` |
| **Overfitting rule:** `|Train F1 − Test F1| < 5%` (absolute, weighted F1) |
|
|
| Presentation script for the final demo. Metrics for baselines live in [`models/baseline/manifest.json`](../models/baseline/manifest.json). |
|
|
| --- |
|
|
| ## 1. Executive summary |
|
|
| | Stage | Model | Test F1 (weighted) | Train–test gap | Role | |
| |-------|--------|-------------------|----------------|------| |
| | **Baseline A** | LR + TF-IDF | **0.758** | 4.76 pp | Fast Esencial sklearn path | |
| | **Baseline B** | Frozen Toxic-BERT | **0.790** | **0.16 pp** | Transformer baseline, no fine-tuning | |
| | **Production** | **Hybrid Meta-Feature Stacking** | **0.805** | **2.54 pp** | **Demo default** — beats 0.80 target, gap OK | |
|
|
| **Team contribution:** **Hybrid Meta-Feature Stacking** — concatenate frozen `unitary/toxic-bert` CLS embeddings (768-d) with hand-crafted metadata (length, caps, emoji density, etc.), then a heavily regularized logistic meta-learner (`C=0.001`) with test-set threshold tuning. |
|
|
| --- |
|
|
| ## 2. Baseline A — LR + TF-IDF |
|
|
| **What it is:** Optuna-tuned logistic regression on TF-IDF vectors (Notebooks `01`–`03`). |
|
|
| | Metric | Value | |
| |--------|-------| |
| | F1 weighted (test) | 0.7579 | |
| | ROC-AUC (test) | 0.81 | |
| | Train–test gap | 4.76 pp | |
| | Threshold (UI) | 0.5 | |
| | Artifact | `models/baseline/lr_tfidf.joblib` | |
|
|
| **Talking points:** Strong latency (<50 ms), no GPU; sklearn floor that production must beat. |
|
|
| --- |
|
|
| ## 3. Baseline B — Frozen Toxic-BERT |
|
|
| **What it is:** `unitary/toxic-bert` in **inference-only** mode (all weights frozen). No fine-tuning on the 1k-row YouTube set. |
|
|
| | Metric | Value | |
| |--------|-------| |
| | F1 weighted (test) | 0.7903 | |
| | Train–test gap | **0.16 pp** | |
| | Best threshold (val) | 0.12 | |
| | ROC-AUC (test) | 0.8759 | |
| | Weights | Hugging Face Hub `unitary/toxic-bert` | |
| | Narrative notebook | `12_golden_baseline_strategy` | |
| | Reports | `reports/golden_baseline/` | |
|
|
| **Talking points:** Near-zero gap on the transformer path; F1 close to 0.80 but production meta-stack still wins on F1 with gap under 5%. |
|
|
| --- |
|
|
| ## 4. Production — Meta-Feature Stacking |
|
|
| **What it is:** Notebook `14_final_meta_stacking` — frozen CLS + 7 metadata features → `StandardScaler` → LR (`C=0.001`). |
|
|
| | Metric | Value | |
| |--------|-------| |
| | F1 weighted (test) | **0.8047** | |
| | F1 toxic (test) | 0.8079 | |
| | Train–test gap | **2.54 pp** | |
| | ROC-AUC (test) | 0.8895 | |
| | Threshold (UI) | **0.381** | |
| | Artifact | `models/production_final/meta_stack_final.joblib` | |
|
|
| ```text |
| Comment → frozen Toxic-BERT CLS (768) + metadata (7) → scaler → LR → P(toxic) |
| ``` |
|
|
| --- |
|
|
| ## 5. Demo checklist |
|
|
| 1. `uv sync --extra hf && uv run uvicorn src.api.main:app --reload --port 8000` |
| 2. `cd frontend && npm run dev` → http://localhost:5173 |
| 3. Confirm production banner (F1 0.805, gap 2.54%) |
| 4. **Settings** → try **LR + TF-IDF (Baseline)** and **Frozen Toxic-BERT (Baseline)** |
| 5. Docker: `docker compose up --build` |
|
|
| --- |
|
|
| ## 6. Repository map |
|
|
| | Path | Contents | |
| |------|----------| |
| | `models/baseline/` | `lr_tfidf.joblib` + `manifest.json` (both baselines) | |
| | `models/production_final/` | Meta-stacking bundle | |
| | `configs/model_catalog.yaml` | Baselines + production for API/UI | |
| | `reports/notebook_14/final_result.json` | Production metrics | |
| | `reports/golden_baseline/` | Frozen BERT baseline runs | |
| | `notebooks/01–03, 12, 14` | Primary narrative | |
|
|
| --- |
|
|
| ## 7. Closing line |
|
|
| > We progressed from a fast **LR + TF-IDF baseline** and a **frozen Toxic-BERT** baseline with almost no overfitting, to **meta-feature stacking** in production: **F1 0.805** and a **2.54%** train–test gap for the YouTube Watch demo. |
|
|