Case study / NLP classification

"Is this bullying?"
is the wrong question.

A binary bully / not-bully classifier tells a moderator almost nothing useful. The real question is what kind of harm it is, because a racial slur, a gendered insult, and an age-based jab need completely different responses. So I built a model that actually answers that.

RoleSolo build
StackspaCy, TF-IDF, XGBoost
Scope6-class tweet classification
LinksGitHub repo →
Cyberbullying classifier pipeline: raw tweet to category Raw tweet slang, typos Preprocessing spaCy + SymSpell lemmatization TF-IDF features XGBoost (vs. NB / LR / RF) 1 of 6 categories of harm
Cyberbullying classifier pipeline — raw tweet to categorized harm type

The itch

Most cyberbullying-detection demos I looked at during research treat the problem as binary: is this tweet bullying, yes or no. That's a tidy classification problem, but it's close to useless for actual content moderation. A platform doesn't just need to know something is harmful — it needs to know what kind of harmful, because the right response to a racial slur, a gendered insult, and an age-based jab are all different, and routing them to the same "flagged" bucket wastes the one piece of information that would actually help a moderator triage faster.

What already existed

The binary framing is everywhere because it's the easiest version of the problem — more balanced classes, simpler evaluation, cleaner headline accuracy numbers. What I didn't find much of were models evaluated honestly on a multi-class breakdown, where you can actually see whether a model is strong across every category of harm or just coasting on the easiest one to detect and dragging the average up.

A 95% accurate model that's blind to one entire category of harm isn't 95% good. It's failing exactly where it matters most, and the aggregate number is hiding it.

How I actually built it

I framed it as a 6-class problem: age, ethnicity, gender, religion, other, and not-cyberbullying, so a flagged tweet comes with an actual category instead of a flat label.

The preprocessing pipeline ended up mattering more than the model choice. Tweets are noisy — slang, abbreviations, typos, inconsistent casing — and a model trained on badly cleaned text will latch onto noise instead of signal no matter how good it is. I ran lowercasing and regex cleaning, slang normalization, SymSpell for spelling correction, tokenization, stopword removal, and lemmatization through spaCy, specifically before any modeling step, because cleaning up "u r so dumbb" into something a TF-IDF vectorizer can actually use is most of the real work here.

Comparing models honestly

Instead of committing to one algorithm upfront, I trained and compared Naive Bayes, Logistic Regression, Random Forest, and XGBoost on the same TF-IDF features, then tuned the strongest candidates with RandomizedSearchCV. I evaluated every model with class-wise accuracy, not just an aggregate score, specifically to catch a model that looks good overall but is quietly failing on one or two of the six categories.

What it does

  • 6-category classification instead of a flat binary label
  • Preprocessing built specifically for noisy tweet text: slang normalization, spelling correction, lemmatization
  • Four model families compared head-to-head on identical features, not just one algorithm assumed to be best
  • Class-wise evaluation to surface weak categories that an aggregate accuracy score would hide

Why it matters

Content moderation systems that only say "flagged" or "not flagged" push all the actual judgment downstream onto an overworked human moderator. A model that tells you the category gets a platform closer to routing harmful content to the right response automatically — and evaluating it honestly, class by class, is the only way to know if it's actually ready to do that.

FAQ

What does the cyberbullying classifier detect?

It classifies tweets into six categories: age-based, ethnicity-based, gender-based, religion-based, other cyberbullying, and not cyberbullying — instead of a flat bully / not-bully binary label.

Why use six classes instead of a simple bully / not-bully label?

A binary label tells a moderator that something is harmful but not what kind of harm it is. A racial slur, a gendered insult, and an age-based jab need different responses, so a multi-class model gives moderators information they can actually route on.

What preprocessing does the model use on raw tweets?

Lowercasing and regex cleaning, slang normalization, SymSpell spelling correction, tokenization, stopword removal, and lemmatization through spaCy, before TF-IDF vectorization.

Which models did Aishrica Dhiman compare for this classifier?

Naive Bayes, Logistic Regression, Random Forest, and XGBoost, trained on the same TF-IDF features and tuned with RandomizedSearchCV, then evaluated with class-wise accuracy to check performance on every category, not just the average.