AS.

YouTube Sentiment Insights

A Chrome extension that reads a YouTube video’s comments and tells you how the audience feels.

  • Ran on EC2, retired
  • Chrome extension · LightGBM · MLflow

View the repo Skip to the lanes

A MacBook with a video page open and the Insights Explorer popup showing a finished analysis: 100 comments, average 0.25, the sentiment pie

Popup recreated from the extension’s code, with sample data. Desktop Chrome only.

One click.

  1. Open a video, click once.

    The popup finds the video ID in the tab’s address and asks the API on EC2 for its comments.

    The popup on a video page: video ID found, step 1, fetching comments
  2. A hundred comments.

    Up to 100 come back, and the model labels each one positive, neutral or negative.

    The popup: step 2, analysing 100 comments
  3. The room, read.

    How many it read, the average from -1 to 1, and the split. Re-analyze runs it again.

    The popup: analysis complete with a Re-analyze button, 100 comments, average 0.25, and the sentiment pie
  4. And what they said.

    The trend by month, the words that come up most, and the comments with their labels.

    The popup scrolled down: the monthly trend, the word cloud and the labelled comment feed
  5. Or it says what went wrong.

    No comments, or no server: the popup says which, and offers Retry.

    The popup: Error, unable to reach analysis server, with a Retry button
The extension on a real YouTube car review: analysis complete, 100 comments, average 0.25, and the pie drawn by the API
The real thing, on a public car review.

Lavender on navy.

  • Deep#0A0A14
  • Card#121225
  • Lavender#A39CF4
  • Slate#6272A4
  • Pink#FF79C6

Insights ExplorerOutfit · headers

The new interior screens look absolutely stunning.Inter · everything else

Under the hood.

A model, a pipeline, a registry, and the three things that broke on the way to EC2.

Three lanes.

Every comment ends up positive, neutral or negative. Pick one and watch the model decide. Two land where you would put them. One doesn’t.

  1. The comment

    The new interior screens look absolutely stunning. Best luxury sedan right now.

  2. What it sees

    • absolutely0.56
    • best0.45
    • new0.43
    • look0.40
    • right0.38
  3. The lane

    • Positive0.999
    • Neutral0.000
    • Negative0.001

Five words it knows, all pointing the same way. Positive, and right.

Learned on Reddit.

It reads YouTube, but it learned from Reddit. One command, dvc repro, runs the five stages.

  1. reddit.csv36,793 labelled Reddit comments.the source
  2. 1 · IngestDrop empty and duplicate rows, split 80 / 20.data/raw
  3. 2 · CleanLower case, stopwords out, lemmas.data/interim
  4. 3 · TrainTF-IDF, then LightGBM: 367 trees.two .pkl files
  5. 4 · EvaluateScores per class, logged to MLflow.experiment_info.json
  6. 5 · RegisterThe model moves to Staging.MLflow registry

The parts.

Tracked by MLflow on EC2

Entry

  • dvc reproruns the stages whose inputs changed

Data

  • reddit.csv36,793 labelled Reddit comments

Work

  • Five stagesclean, TF-IDF, LightGBM, evaluate, register

Model

  • MLflowtracks every run, keeps the model

Reddit comments in, a registered model out. Every run lands in MLflow with its settings and scores.

Run files go to S3 through MLflow.

What broke.

  1. 11 Feb 2026 · Serving

    The registry model said no.

    Serving moved to MLflow’s registry and predictions stopped. The registered model expects a table named by its 1,000 features; the API sent a bare array. A DataFrame with those names fixed it.

    The commit, 984b818
  2. 11 Feb 2026 · Docker

    The image without its vectorizer.

    .gitignore kept tfidf_vectorizer.pkl out of git, so the image built from a fresh checkout never had it, and the API opens it on start. Committing the 37 KB file fixed it.

    The commit, d830565
  3. 11 Feb 2026 · Extension

    One stray character.

    A stray 價 in the popup’s address check meant no URL matched, so every video said “Please open a YouTube video page”.

    The commit, 898d945
  4. 6 Oct 2026 · Security

    The key in the extension.

    The YouTube API key sat in popup.js, so anyone with the extension, or the repo, could read it. Now the API fetches the comments with a key from its own environment, and comments render as text, never HTML.

    The commit, 5a218d0

What I’d do next.

  • Train on YouTube comments, and keep words like “too”. The grille comment shows why.
  • HTTPS and a stable name in front of the API, instead of a raw IP over plain HTTP.
  • Read past the first 100 comments.
  • Tests for the model and the API, and a real lint step. Today CI tests only the comment fetch.

Tech specs.

Extension
Chrome, Manifest V3, with Re-analyze and Retry. Comments come through the API, up to 100
Model
TF-IDF (1 to 3 word phrases, 1,000 features), LightGBM, balanced class weights
Pipeline
DVC, five stages. MLflow tracking and model registry
API
Flask on port 5000; charts drawn with matplotlib
Delivery
A version tag starts GitHub Actions: unit tests, an image to Docker Hub, then a self-hosted runner on the host. Lint is a placeholder
Hosting
One EC2 c7i-flex.large running Docker. Retired.
Origin
Started from a course project. The popup and its design, serving from the registry and the deploy to EC2 are mine.