Built to order

Hate Speech Detection using LSTM

A text classifier that reads a social-media post and sorts it into hate speech, offensive language or neither. It uses a bidirectional LSTM over GloVe Twitter embeddings, trained on the Davidson et al. (2017) dataset of 24,783 labeled tweets — with class weights handling the heavy imbalance (only 5.8% hate speech) and per-class F1 as the honest metric instead of raw accuracy. A demo UI classifies typed or sample posts and highlights which words pushed the decision. Suitable for B.E./B.Tech final-year projects in Computer Science, AI/ML and Data Science.

Hate Speech Detection using LSTM — project thumbnail preview
More project photos (4)

The problem

Every large platform faces the same impossible arithmetic: millions of posts per day, and human moderators who can review only a fraction. Keyword blocklists were the first automation attempt, and they fail exactly where it matters — context. The word "hate" in "I hate Mondays" is harmless; a post with no profanity at all can still target a community. Davidson et al.'s 2017 study made the key distinction the field still uses: hate speech (hostility toward a protected group) is not the same as offensive language (profanity without group targeting), and any useful classifier must separate the two. Their labeled dataset of 24,783 tweets — only 5.8% of it actual hate speech — is the standard teaching benchmark. This project builds the complete NLP workflow on it: tweet preprocessing, GloVe embeddings, a bidirectional LSTM that reads context on both sides of every word, class-weighted training against the imbalance, and an evaluation built on per-class F1 rather than the misleading headline accuracy. It is a moderation-assistance prototype: it triages content for human review, it does not pass judgment.

How it works

  1. Raw tweets are cleaned with tweet-specific preprocessing: URLs, mentions and retweet markers removed, hashtags split into words.
  2. Text is tokenized, mapped to vocabulary indices, padded/truncated to a fixed sequence length, and rare words become an unknown token.
  3. Each token index looks up its 100-dimensional GloVe Twitter embedding vector.
  4. The embedding sequence passes through the bidirectional LSTM, which builds a context-aware representation reading both directions.
  5. Dropout regularizes the representation; a dense layer with softmax outputs probabilities for hate speech, offensive language and neither.
  6. The model trains with class weights and is evaluated with per-class F1 and macro-F1 — metrics that punish the "always predict offensive" shortcut that raw accuracy would reward.

Tech stack:

  • Python 3.10, TensorFlow/Keras (BiLSTM model, class-weighted training)
  • GloVe Twitter embeddings (100-d pretrained vectors)
  • NLTK / tweet-preprocessor style cleaning utilities
  • NumPy, pandas (dataset handling, prediction tables)
  • scikit-learn (per-class precision/recall/F1, confusion matrix)
  • Matplotlib, Seaborn (training curves, confusion heatmap, class-distribution plots)
  • Flask demo app with text-classification UI
  • Jupyter notebook (buyer-run training and evaluation)

Dataset & model

  • Dataset: Davidson et al. (2017), "Automated Hate Speech Detection and the Problem of Offensive Language" (ICWSM 2017) — 24,783 English tweets labeled by CrowdFlower annotators: hate speech 1,430 (5.8%), offensive language 19,190 (77.4%), neither 4,163 (16.8%).
  • Model: embedding (GloVe-Twitter 100-d) → bidirectional LSTM (128 units/direction) → dropout 0.5 → dense softmax over 3 classes.
  • Prediction task: single-label classification of a short social-media text. Metrics: per-class precision/recall/F1, macro-F1, confusion matrix — computed by the notebook on the held-out split during your build. Design target: ~75%+ macro-F1 — a target, not a measured claim.
Parameter Value
Model BiLSTM (128 units/direction) + dropout + 3-way softmax, Keras
Input Raw tweet / short social-media text
Embeddings GloVe Twitter, 100-dimensional, fine-tuned
Dataset Davidson et al. 2017 — 24,783 tweets (5.8% hate / 77.4% offensive / 16.8% neither)
Training Class-weighted cross-entropy against the imbalance
Evaluation Per-class F1, macro-F1, confusion matrix — computed on your split during your build
Output Three class probabilities + word-contribution highlighting
Demo Flask app: text box, sample posts, classification panel

Project features

  • Tweet-specific preprocessing: URL and @mention stripping, hashtag splitting, elongation normalization, lowercasing and tokenization
  • GloVe Twitter embeddings (100-dimensional, pretrained on 2B tweets) as the input representation, with an embedding layer the model fine-tunes
  • Bidirectional LSTM (128 units per direction) that captures left and right context around every word, followed by dropout and a 3-way softmax
  • Class-weighted training that compensates for the 5.8% hate-speech minority so the model cannot ignore it
  • Demo UI: type or pick a sample post, get the three class probabilities plus word-level contribution highlighting
  • Evaluation notebook computing per-class precision, recall and F1, macro-F1 and the confusion matrix on the held-out split
  • Dedicated error analysis of hate-vs-offensive confusions — the dataset's hardest boundary — for the report

What is included

  • Complete source code (preprocessing, embedding pipeline, BiLSTM model, training, evaluation, demo app)
  • Jupyter training and evaluation notebook (buyer-run procedure: prepare the Davidson split, train, evaluate)
  • Project report PDF (moderation background, LSTM theory, imbalance handling, results, error analysis)
  • PPT presentation for final review
  • Viva Q&A preparation document (RNN/LSTM gates, bidirectionality, embeddings, class imbalance, F1 vs accuracy)
  • Setup guide (environment, dataset download, GloVe vectors, training on CPU, running the demo)

Limitations & prerequisites

  • Sarcasm, irony, coded language and reclaimed slurs defeat text-only classifiers routinely — the model sees words, not the speaker's intent, and the report documents these failure cases.
  • Tweets are short, slang-heavy and full of misspellings, so out-of-vocabulary words are constant; character-level handling is documented as an extension, not the base build.
  • Annotation is subjective: annotators themselves disagree on the hate/offensive boundary, and that disagreement becomes the model's performance ceiling.
  • The 5.8% hate-speech minority means the model sees few true hate examples; class weights help but cannot create data that is not there.
  • The dataset is English Twitter from 2017 — other languages, platforms and current slang need fresh labeled data and retraining.
  • This is a moderation-assistance prototype that triages posts for human review; it must never auto-ban or be presented as a final judgment on a person.

Frequently Asked Questions

Which dataset is used?

Davidson et al. (2017), from "Automated Hate Speech Detection and the Problem of Offensive Language" (ICWSM): 24,783 tweets labeled hate speech (1,430), offensive language (19,190) or neither (4,163) by CrowdFlower annotators.

Why an LSTM instead of BERT?

A BiLSTM trains in minutes on a CPU, which fits a student build end to end, and its sequential reading of context is exactly the concept the viva examines. A BERT fine-tuning variant is documented as an optional extension experiment.

Is the accuracy guaranteed?

No — and accuracy would be the wrong number anyway, since always predicting "offensive" scores ~77%. The design target is ~75%+ macro-F1; your build's notebook measures per-class F1 on the held-out split and the report presents those numbers.

Can it detect sarcasm?

Not reliably, and no text classifier in this class honestly claims to. Sarcasm, coded slurs and reclaimed language are listed as known limits with example failure cases in the report's error analysis.

Can it handle Hindi or other languages?

The base build is English-only. Other languages need their own labeled datasets and retraining — the pipeline (preprocessing → embeddings → BiLSTM) transfers directly, which the report notes as future scope.

What can I demonstrate in the viva?

Type any post and watch the three probabilities update with word-level highlighting, then walk the examiner through the confusion matrix — especially the hate-vs-offensive boundary the project is designed around. Suitable for B.E./B.Tech final-year projects in Computer Science, AI/ML and Data Science.

Components & software requirements
  • Python 3.10, TensorFlow/Keras (BiLSTM model, class-weighted training)
  • GloVe Twitter embeddings (100-d pretrained vectors)
  • NLTK / tweet-preprocessor style cleaning utilities
  • NumPy, pandas (dataset handling, prediction tables)
  • scikit-learn (per-class precision/recall/F1, confusion matrix)
  • Matplotlib, Seaborn (training curves, confusion heatmap, class-distribution plots)
  • Flask demo app with text-classification UI
  • Jupyter notebook (buyer-run training and evaluation)

Dataset & model

  • Dataset: Davidson et al. (2017), "Automated Hate Speech Detection and the Problem of Offensive Language" (ICWSM 2017) — 24,783 English tweets labeled by CrowdFlower annotators: hate speech 1,430 (5.8%), offensive language 19,190 (77.4%), neither 4,163 (16.8%).
  • Model: embedding (GloVe-Twitter 100-d) → bidirectional LSTM (128 units/direction) → dropout 0.5 → dense softmax over 3 classes.
  • Prediction task: single-label classification of a short social-media text. Metrics: per-class precision/recall/F1, macro-F1, confusion matrix — computed by the notebook on the held-out split during your build. Design target: ~75%+ macro-F1 — a target, not a measured claim.
Delivery information

Built-to-order project. Delivery timeline is shared after order confirmation based on current queue.

Support terms

Complete documentation, setup guide, and viva preparation included. Support for setup and explanation provided.

Download abstract (PDF)

Related guides

All guides
Blueprint-style technical illustration of multiple decision trees voting together into one final predictionStudents with basic Python and pandas skills who want a reliable first classifier for ML coursework and tabular data projects.

Random Forests Explained: Why Decision Trees Vote Better Together

Decision trees are readable but overfit; random forests fix this by training hundreds of varied trees on bootstrapped data with random feature subsets, then letting them vote. This guide explains Gini impurity, bagging, out-of-bag validation and the four hyperparameters that matter, with a complete scikit-learn workflow, honest feature-importance practices, and the mistakes students keep making.

Read guide
Illustration of object tracking showing video frames with bounding boxes and persistent ID labels following people and vehicles, comparing motion prediction and appearance matching.B.E./B.Tech Computer Science and Electronics students building video analytics projects — people counting, vehicle tracking, sports analysis — who have detection working and need

Object Tracking: DeepSORT and ByteTrack Explained

Detection finds objects per frame; tracking keeps their identities across frames. This guide explains tracking-by-detection, Kalman motion models, DeepSORT's appearance embeddings vs ByteTrack's low-confidence box recovery, tracking metrics (HOTA, IDF1, ID switches), and the tuning parameters that determine real-world quality.

Read guide
Illustration of image segmentation showing U-Net's U-shaped encoder-decoder with skip connections producing pixel masks, alongside Mask R-CNN detecting instances with masks.B.E./B.Tech Computer Science and AI/ML students moving from image classification or detection to pixel-level understanding — medical imaging, defect detection, autonomous driving

Image Segmentation: U-Net and Mask R-CNN

When projects need pixel-level answers, segmentation delivers. This guide explains semantic vs instance vs panoptic segmentation, U-Net's encoder-decoder with skip connections, Mask R-CNN's parallel mask head, Dice and IoU evaluation, paired augmentation, and how to choose the right architecture for your data and question.

Read guide
Get a quotation