CoolFace
Apppublic

rajanchauhan/clickbait-detector

sourceHugging Faceupdated 5mo agoView on Hugging Face
0likes
App README

๐ŸŽฏ YouTube Clickbait Detector

Multimodal AI System โ€” Text + Vision + Semantics

Author: Rajan Chauhan | Bennett University | B.Tech Computer Science Built: March 2026 | Accuracy: 80.51% | Dataset: 1,177 YouTube Videos

Overview

A full end-to-end multimodal machine learning system that detects whether a YouTube video is clickbait by analyzing its title, transcript, thumbnail image, thumbnail text (OCR), and viewer comments simultaneously.

The system classifies videos into three categories:

LabelDescription
Not ClickbaitTitle accurately and plainly describes the content
Good ClickbaitTitle is dramatic but the video genuinely delivers
Bad ClickbaitTitle promises something the video does not deliver

Architecture

YouTube URL
    โ”‚
    โ”œโ”€โ”€โ”€ YouTube Data API v3 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Title, Description, Thumbnail URL
    โ”œโ”€โ”€โ”€ YouTube Transcript API โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Full video transcript
    โ”œโ”€โ”€โ”€ YouTube Comments API โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Top 20 viewer comments
    โ””โ”€โ”€โ”€ Thumbnail Download + OCR โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Embedded text in thumbnail
              โ”‚
              โ–ผ
    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚                  PREPROCESSING                       โ”‚
    โ”‚  Lowercase ยท Remove URLs ยท Remove punctuation        โ”‚
    โ”‚  Remove noise ยท Clean per field separately           โ”‚
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
              โ”‚
              โ”œโ”€โ”€โ”€ Text Embeddings (MiniLM-L6-v2, 384-dim each)
              โ”‚       โ”œโ”€โ”€ Title embedding
              โ”‚       โ”œโ”€โ”€ Transcript embedding
              โ”‚       โ”œโ”€โ”€ Thumbnail text embedding
              โ”‚       โ””โ”€โ”€ Comments embedding
              โ”‚
              โ”œโ”€โ”€โ”€ Image Embedding (CLIP ViT-B/32, 512-dim)
              โ”‚       โ””โ”€โ”€ Thumbnail visual features
              โ”‚
              โ””โ”€โ”€โ”€ Claim Verification
                      โ””โ”€โ”€ Cosine similarity (title vs transcript) โ†’ 1-dim
              โ”‚
              โ–ผ
    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚              MULTIMODAL FUSION                       โ”‚
    โ”‚  Concatenation: 384+384+384+384+512+1 = 2049 dims   โ”‚
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
              โ”‚
              โ–ผ
    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚            MLP CLASSIFIER                            โ”‚
    โ”‚  2049 โ†’ 512 โ†’ 256 โ†’ 128 โ†’ 3 (Softmax)               โ”‚
    โ”‚  Class-weighted ยท Early stopping ยท Adam optimizer    โ”‚
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
              โ”‚
              โ–ผ
    Not Clickbait / Good Clickbait / Bad Clickbait

Project Structure

clickbait-detector/
โ”‚
โ”œโ”€โ”€ config/
โ”‚   โ””โ”€โ”€ config.py                  # API keys, paths, constants, search queries
โ”‚
โ”œโ”€โ”€ data/
โ”‚   โ”œโ”€โ”€ raw/
โ”‚   โ”‚   โ”œโ”€โ”€ metadata.json          # Phase 1 โ€” 1177 video metadata records
โ”‚   โ”‚   โ”œโ”€โ”€ transcripts.json       # Phase 2 โ€” 825 transcripts (70.1%)
โ”‚   โ”‚   โ”œโ”€โ”€ comments.json          # Phase 5 โ€” 1108 comment sets (94.1%)
โ”‚   โ”‚   โ””โ”€โ”€ thumbnail_text.json    # Phase 4 โ€” 354 OCR extractions
โ”‚   โ”œโ”€โ”€ thumbnails/                # Phase 3 โ€” 1176 downloaded JPG images
โ”‚   โ””โ”€โ”€ processed/
โ”‚       โ”œโ”€โ”€ dataset.csv            # Phase 6 โ€” unified dataset
โ”‚       โ”œโ”€โ”€ dataset_labeled.csv    # Phase 7 โ€” auto-labeled dataset
โ”‚       โ”œโ”€โ”€ dataset_preprocessed.csv # Phase 9 โ€” cleaned dataset
โ”‚       โ”œโ”€โ”€ embeddings/            # Phase 10โ€“11 โ€” .npy embedding files
โ”‚       โ””โ”€โ”€ models/                # Phase 14 โ€” trained classifier + scaler
โ”‚
โ”œโ”€โ”€ collection/
โ”‚   โ”œโ”€โ”€ youtube_scraper.py         # Phase 1 โ€” metadata via YouTube Data API v3
โ”‚   โ”œโ”€โ”€ transcript_extractor.py    # Phase 2 โ€” transcripts via youtube-transcript-api
โ”‚   โ”œโ”€โ”€ thumbnail_downloader.py    # Phase 3 โ€” thumbnail images via requests
โ”‚   โ”œโ”€โ”€ ocr_extractor.py           # Phase 4 โ€” OCR via pytesseract + PIL
โ”‚   โ””โ”€โ”€ comment_collector.py       # Phase 5 โ€” comments via YouTube Data API v3
โ”‚
โ”œโ”€โ”€ dataset/
โ”‚   โ”œโ”€โ”€ build_dataset.py           # Phase 6 โ€” merges all raw data into CSV
โ”‚   โ””โ”€โ”€ label_dataset.py           # Phase 7 โ€” heuristic + similarity auto-labeling
โ”‚
โ”œโ”€โ”€ preprocessing/
โ”‚   โ””โ”€โ”€ preprocess.py              # Phase 9 โ€” text cleaning pipeline
โ”‚
โ”œโ”€โ”€ embeddings/
โ”‚   โ”œโ”€โ”€ text_embedder.py           # Phase 10 โ€” MiniLM-L6-v2 text embeddings
โ”‚   โ””โ”€โ”€ image_embedder.py          # Phase 11 โ€” CLIP ViT-B/32 image embeddings
โ”‚
โ”œโ”€โ”€ model/
โ”‚   โ”œโ”€โ”€ fusion.py                  # Phase 12 โ€” concatenation fusion + similarity
โ”‚   โ”œโ”€โ”€ claim_verifier.py          # Phase 13 โ€” title vs transcript analysis
โ”‚   โ”œโ”€โ”€ classifier.py              # Phase 14+15 โ€” MLP training + evaluation
โ”‚   โ””โ”€โ”€ train.py                   # Full pipeline entry point
โ”‚
โ”œโ”€โ”€ evaluation/
โ”‚   โ””โ”€โ”€ evaluate.py                # Phase 15 โ€” metrics, confusion matrix, plots
โ”‚
โ”œโ”€โ”€ app/
โ”‚   โ”œโ”€โ”€ app.py                     # Flask dashboard backend
โ”‚   โ”œโ”€โ”€ templates/index.html       # Apple-style UI
โ”‚   โ””โ”€โ”€ static/
โ”‚       โ”œโ”€โ”€ style.css              # Light mode design system
โ”‚       โ””โ”€โ”€ main.js                # Animated result rendering
โ”‚
โ”œโ”€โ”€ requirements.txt
โ””โ”€โ”€ README.md

The 15-Phase Pipeline

Phase 1 โ€” YouTube Metadata Collection

File: collection/youtube_scraper.py

Used the YouTube Data API v3 to search for videos using 25 carefully chosen queries spanning both clickbait-heavy terms ("you won't believe", "shocking", "EXPOSED") and non-clickbait terms ("how to tutorial", "documentary", "lecture university"). Extracted video ID, title, description, thumbnail URL, view count, like count, and tags for each video. Collected 1,177 unique videos after deduplication.

Why: A diverse query set ensures the dataset contains all three label classes rather than being dominated by one type of content.

Phase 2 โ€” Transcript Extraction

File: collection/transcript_extractor.py

Used youtube-transcript-api (v1.2.4) to fetch subtitles for each video. Combined all subtitle segments into a single clean transcript string. Implemented resume support via checkpointing every 50 videos โ€” if the script crashes, it picks up from where it stopped.

Result: 825 transcripts successfully extracted (70.1%). The 30% failure rate is expected โ€” many videos have transcripts disabled or unavailable.

Why: The transcript is the ground truth of what a video actually contains. It's the most powerful signal for detecting whether a title's promise matches the content.

Phase 3 โ€” Thumbnail Download

File: collection/thumbnail_downloader.py

Downloaded all thumbnail images using the URLs collected in Phase 1. Saved as <video_id>.jpg in data/thumbnails/. Used a persistent requests session with a User-Agent header for reliability.

Result: 1,176/1,177 thumbnails downloaded (99.9%).

Why: Thumbnails are a critical clickbait signal โ€” exaggerated facial expressions, bold overlay text, dramatic color palettes, and red arrows are common clickbait patterns that a vision model can detect.

Phase 4 โ€” Thumbnail OCR Text Extraction

File: collection/ocr_extractor.py

Applied Optical Character Recognition (Tesseract via pytesseract) on each thumbnail image to extract any embedded text. Used --psm 3 (fully automatic page segmentation) optimized for bold overlay text common in YouTube thumbnails.

Result: 354 thumbnails contained extractable text (30%). Examples: "SHOCKING", "$3000 HILUX", "WAKEUPLIKEA", "YOU WON'T BELIEVE THIS".

Why: Thumbnail text is an independent signal from the title โ€” many clickbait videos use ALL CAPS text, exclamation marks, and sensational phrases overlaid on the thumbnail image.

Phase 5 โ€” Comment Collection

File: collection/comment_collector.py

Fetched the top 20 most relevant comments per video using the YouTube Comments API, ordered by relevance. Comments are a proxy for viewer sentiment โ€” comments like "clickbait", "misleading", and "waste of time" are strong bad clickbait signals, while "actually delivered" and "underrated" indicate good content.

Result: 1,108/1,177 videos had comments collected (94.1%). 69 videos had comments disabled.

Phase 6 โ€” Dataset Construction

File: dataset/build_dataset.py

Merged all five raw data sources (metadata, transcripts, comments, thumbnail text, thumbnail paths) into a single unified CSV and JSON dataset. Each row represents one video with all collected features plus an empty label column.

Result: 1,177 rows. 787 videos are "fully complete" (have transcript + thumbnail + comments simultaneously).

Phase 7 โ€” Automated Data Labeling

File: dataset/label_dataset.py

Instead of manual labeling (impractical at 1,177 videos), implemented a two-layer automated labeling pipeline:

Layer 1 โ€” Rule-based Heuristics (814 videos)

Fast pattern matching using keyword lists and regex:

  • โ€”Videos with titles matching patterns like "how to", "tutorial", "review", "documentary" โ†’ not_clickbait
  • โ€”Titles containing "you won't believe", "shocking", "i almost died", "exposed" โ†’ bad_clickbait
  • โ€”Titles with >60% uppercase letters โ†’ examined for good/bad clickbait markers
  • โ€”Titles containing "24 hours", "i tried", "vs", "challenge" โ†’ good_clickbait

Layer 2 โ€” Title vs Transcript Semantic Similarity (363 videos)

For videos where heuristics were uncertain, computed cosine similarity between the title embedding and transcript embedding using all-MiniLM-L6-v2:

  • โ€”Similarity โ‰ฅ 0.30 โ†’ title matches content โ†’ not_clickbait or good_clickbait
  • โ€”Similarity < 0.15 โ†’ content diverges from title โ†’ bad_clickbait
  • โ€”Mid-range โ†’ fallback to keyword signals

Label Distribution:

LabelCountPercentage
Not Clickbait70860.2%
Good Clickbait27723.5%
Bad Clickbait19216.3%

Why this approach: Manual labeling of 1,177 videos is time-prohibitive and introduces human fatigue bias. The two-layer approach mirrors industry practice for large-scale dataset construction โ€” heuristics handle obvious cases instantly, semantic similarity handles nuanced ones.

Phase 8 โ€” Dataset Size Planning

Target was 500โ€“1,000 videos per class. With 708/277/192 distribution, all classes exceed the 150-video minimum for meaningful training. The imbalance (not_clickbait dominates) is handled at training time via class weighting.

Phase 9 โ€” Preprocessing

File: preprocessing/preprocess.py

Cleaned each text field separately with a tailored pipeline:

  • โ€”Lowercase conversion
  • โ€”URL removal
  • โ€”HTML tag stripping
  • โ€”Non-ASCII character removal
  • โ€”Punctuation removal (preserving apostrophes for contractions)
  • โ€”Extra whitespace normalization

Also created a text_combined field merging all signals into one string, and converted string labels to integers (0/1/2).

Why separate cleaning per field: The title needs lighter cleaning than the transcript (to preserve its original signals). Thumbnail text needs different handling since OCR introduces noise characters.

Phase 10 โ€” Text Embedding Generation

File: embeddings/text_embedder.py

Encoded all text fields into dense numerical vectors using sentence-transformers/all-MiniLM-L6-v2:

  • โ€”Architecture: 6-layer MiniLM transformer
  • โ€”Output dimension: 384 per embedding
  • โ€”Encoding: Processed in batches of 64 for efficiency

Generated separate embeddings for: title, transcript, thumbnail text, comments, and combined text.

Why MiniLM over BERT: MiniLM-L6-v2 is 5x smaller than BERT-base with only ~2% quality loss on sentence similarity tasks. For 1,177 ร— 5 fields on a local Mac, inference speed matters significantly.

Output shapes:

FieldShape
Title(1177, 384)
Transcript(1177, 384)
Thumbnail text(1177, 384)
Comments(1177, 384)
Combined(1177, 384)

Phase 11 โ€” Image Embedding Generation

File: embeddings/image_embedder.py

Processed all 1,176 thumbnail images through OpenAI's CLIP (Contrastive Language-Image Pretraining) model using the ViT-B/32 (Vision Transformer) backbone. Embeddings were L2-normalized before saving.

  • โ€”Model: ViT-B/32
  • โ€”Output dimension: 512 per image
  • โ€”Device: Apple MPS (Metal Performance Shaders) for GPU acceleration
  • โ€”Missing thumbnails: replaced with zero vectors

Why CLIP over ResNet: CLIP was trained on 400M image-text pairs with contrastive learning, making it particularly good at understanding the kind of dramatic, text-heavy thumbnail compositions common in YouTube videos. Its visual features capture semantic content rather than just pixel statistics.

Output shape: (1177, 512)

Phase 12 โ€” Multimodal Fusion

File: model/fusion.py

Combined all embeddings into a single unified representation per video using feature concatenation:

title(384) + transcript(384) + thumbnail_text(384) + comments(384) + image(512) + similarity(1)
= 2049 dimensions

Also computed the title vs transcript cosine similarity score as a standalone feature โ€” this is the claim verification signal that directly encodes whether the title promise matches the video content.

Why concatenation over attention fusion: For this dataset size (1,177 samples), simple concatenation is more reliable than cross-modal attention which requires significantly more data to learn meaningful cross-modal relationships.

Output shape: (1177, 2049)

Phase 13 โ€” Claim Verification Module

File: model/claim_verifier.py

Analyzed how well the title vs transcript semantic similarity score separates the three classes. Ran threshold analysis to understand at which similarity cutoffs bad clickbait is best detected:

  • โ€”Low similarity โ†’ title doesn't match content โ†’ likely bad clickbait
  • โ€”High similarity โ†’ title matches content โ†’ not clickbait or good clickbait
  • โ€”The similarity score is included as a feature in the fused vector

This module adds interpretability โ€” the similarity score explains why the model made a prediction.

Phase 14 โ€” Classifier Training

File: model/classifier.py

Trained a Multi-Layer Perceptron on the fused 2049-dimensional embeddings:

Architecture:

Input (2049) โ†’ Dense(512, ReLU) โ†’ Dense(256, ReLU) โ†’ Dense(128, ReLU) โ†’ Output(3, Softmax)

Training configuration:

  • โ€”Optimizer: Adam (lr=0.001, adaptive)
  • โ€”Regularization: L2 (ฮฑ=0.001)
  • โ€”Batch size: 64
  • โ€”Early stopping: patience=15 iterations
  • โ€”Validation fraction: 10% of training set
  • โ€”Class weights: balanced (to handle imbalanced distribution)
  • โ€”Train/test split: 80/20 stratified

Class weights (computed automatically): The balanced class weight mode assigns higher weights to minority classes (goodclickbait, badclickbait) so the model doesn't just predict "not_clickbait" for everything.

Phase 15 โ€” Model Evaluation

File: evaluation/evaluate.py

Results on held-out test set (236 videos):

MetricScore
Accuracy80.51%
F1 (Macro)0.705
F1 (Weighted)0.784
Precision (Macro)0.770
Recall (Macro)0.697

Per-class F1:

ClassF1PrecisionRecall
Not Clickbait0.8600.820.91
Good Clickbait0.8470.810.89
Bad Clickbait0.4070.690.29

Confusion Matrix:

Predicted NotPredicted GoodPredicted Bad
Actual Not12985
Actual Good6500
Actual Bad23411

Analysis:

Not Clickbait and Good Clickbait are detected with excellent F1 scores (0.86 and 0.85 respectively). Bad Clickbait has a lower F1 of 0.407 โ€” primarily due to class imbalance (only 192 samples vs 708 not clickbait). The model misclassifies 23 bad clickbait videos as not clickbait, which is the hardest confusion pair since both classes can have plain-sounding titles with dramatically different content alignment.


Flask Dashboard

File: app/app.py

An Apple-style web dashboard that accepts any YouTube URL and runs the complete inference pipeline live:

  1. 1.Fetches video metadata, transcript, comments and thumbnail from YouTube APIs
  2. 2.Encodes all text fields with MiniLM and the thumbnail with CLIP
  3. 3.Fuses into a 2049-dim vector
  4. 4.Scales with the trained StandardScaler
  5. 5.Predicts with the trained MLP classifier
  6. 6.Returns verdict, confidence score, class probabilities, and similarity signal

Run:

bash
cd ~/clickbait-detector && PYTHONPATH=. python app/app.py
# Open http://127.0.0.1:5050

Technology Stack

ComponentTechnologyPurpose
Data collectionYouTube Data API v3Metadata + comments
Transcriptsyoutube-transcript-apiSubtitle extraction
OCRTesseract + pytesseractThumbnail text
Text embeddingsMiniLM-L6-v2 (384-dim)Semantic text encoding
Image embeddingsCLIP ViT-B/32 (512-dim)Visual feature extraction
FusionNumPy concatenationMultimodal representation
ClassifierScikit-learn MLPClassifier3-class prediction
DashboardFlask + vanilla JSLive inference UI
LabelingHeuristics + cosine similarityAutomated annotation

Installation

bash
# Clone
git clone https://github.com/RajanChauhan-07/clickbait-detector
cd clickbait-detector

# Create virtual environment (Python 3.11 required)
python3.11 -m venv .venv311
source .venv311/bin/activate

# Install dependencies
pip install google-api-python-client youtube-transcript-api requests \
    pillow torch torchvision sentence-transformers scikit-learn \
    joblib numpy flask pytesseract
pip install git+https://github.com/openai/CLIP.git

# macOS only โ€” install Tesseract OCR engine
brew install tesseract

# Configure API key
# Edit config/config.py and set YOUTUBE_API_KEY

Running the Full Pipeline

bash
# Phase 1 โ€” Collect metadata
python collection/youtube_scraper.py

# Phase 2 โ€” Extract transcripts
python collection/transcript_extractor.py

# Phase 3 โ€” Download thumbnails
python collection/thumbnail_downloader.py

# Phase 4 โ€” OCR thumbnail text
python collection/ocr_extractor.py

# Phase 5 โ€” Collect comments
python collection/comment_collector.py

# Phase 6 โ€” Build dataset
python dataset/build_dataset.py

# Phase 7 โ€” Auto-label
python dataset/label_dataset.py

# Phase 9 โ€” Preprocess
python preprocessing/preprocess.py

# Phase 10 โ€” Text embeddings
python embeddings/text_embedder.py

# Phase 11 โ€” Image embeddings
python embeddings/image_embedder.py

# Phase 12 โ€” Fuse
python model/fusion.py

# Phase 13 + 14 + 15 โ€” Train and evaluate
python model/claim_verifier.py
python model/classifier.py

# Dashboard
PYTHONPATH=. python app/app.py

CI/CD

This project uses GitHub Actions for CI/CD.

  • โ€”CI runs on pushes and pull requests to main.
  • โ€”CI checks that Python source files compile and required deployment files exist.
  • โ€”CD runs after CI passes on pushes to main.
  • โ€”CD deploys to Hugging Face Spaces by pushing the repository to rajanchauhan/clickbait-detector.
  • โ€”If HF_TOKEN is not configured, the deploy step is skipped with a message.

To enable deployment, add this GitHub repository secret:

SecretPurpose
HF_TOKENHugging Face access token with write permission to the Space

Workflow file: .github/workflows/ci-cd.yml


Dataset Statistics

MetricValue
Total videos collected1,177
Search queries used25
Transcripts available825 (70.1%)
Thumbnails downloaded1,176 (99.9%)
Thumbnails with OCR text354 (30.1%)
Comments collected1,108 (94.1%)
Fully complete entries787
Labeled via heuristics814
Labeled via similarity363
Train set941
Test set236

Key Design Decisions

Why three classes instead of two? Binary clickbait detection misses an important nuance โ€” some videos use dramatic titles but genuinely deliver on their promise. Penalizing these equally with deceptive clickbait would be unfair and inaccurate. The three-class system allows the model to reward good content creators who use engaging titles responsibly.

Why automated labeling? Manual labeling of 1,177 videos would take 6โ€“10 hours with significant fatigue bias. The two-layer automated approach (heuristics + semantic similarity) mirrors industry practice and produces labels that are reasonably consistent and scalable.

Why concatenation fusion? For this dataset size, simple concatenation is more reliable than cross-modal attention or transformer fusion. Attention mechanisms require significantly more training data to learn meaningful cross-modal alignments. Concatenation preserves all information from each modality and lets the MLP learn which signals matter most.

Why MiniLM over larger models? Running inference on a local Mac requires a balance between model quality and speed. MiniLM-L6-v2 achieves ~98% of BERT-base quality on sentence similarity benchmarks at 5x the inference speed with 6x fewer parameters.

Why handle class imbalance with weights instead of resampling? With only 192 bad clickbait samples, SMOTE oversampling would generate synthetic embeddings that may not represent real-world bad clickbait patterns faithfully. Class weighting adjusts the loss function directly without modifying the data distribution.


Limitations and Future Work

Current limitations:

  • โ€”Bad Clickbait F1 of 0.407 due to only 192 training samples in that class
  • โ€”Labels are automatically generated โ€” some may be incorrect, especially for edge cases
  • โ€”Only English-language videos are analyzed
  • โ€”Transcript availability (70.1%) means 30% of videos are classified without content analysis

Potential improvements:

  • โ€”Collect 500+ additional bad clickbait examples to balance the dataset
  • โ€”Use GPT-4 or Claude for higher-quality automated labeling
  • โ€”Fine-tune a RoBERTa or DeBERTa model on the labeled data instead of using frozen embeddings
  • โ€”Add cross-modal attention between text and image embeddings
  • โ€”Deploy to AWS EC2 with Nginx + Gunicorn for production use
  • โ€”Add a feedback mechanism in the dashboard for users to correct predictions

Results Summary

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘           CLICKBAIT DETECTOR โ€” FINAL RESULTS                 โ•‘
โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ
โ•‘  Dataset:        1,177 YouTube videos                        โ•‘
โ•‘  Test set:       236 videos (20% stratified split)           โ•‘
โ•‘                                                              โ•‘
โ•‘  Accuracy:       80.51%                                      โ•‘
โ•‘  F1 Macro:       0.705                                       โ•‘
โ•‘  F1 Weighted:    0.784                                       โ•‘
โ•‘                                                              โ•‘
โ•‘  Not Clickbait F1:   0.860  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ            โ•‘
โ•‘  Good Clickbait F1:  0.847  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ            โ•‘
โ•‘  Bad Clickbait F1:   0.407  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ                        โ•‘
โ•‘                                                              โ•‘
โ•‘  Text model:    MiniLM-L6-v2 (384-dim)                       โ•‘
โ•‘  Image model:   CLIP ViT-B/32 (512-dim)                      โ•‘
โ•‘  Fusion:        Concatenation (2049-dim)                     โ•‘
โ•‘  Classifier:    MLP 2049โ†’512โ†’256โ†’128โ†’3                       โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Repository

GitHub: github.com/RajanChauhan-07/clickbait-detector

Hugging Face: https://huggingface.co/spaces/rajanchauhan/clickbait-detector

Contact: helllorajanchauhan@gmail.com LinkedIn/GitHub: RajanChauhan-07