Machine Learning Model for Hate Speech Detection: Practical Approach
AI & Coding • 5 min read

Machine Learning Model for Hate Speech Detection: Practical Approach

Paul Ekung

Author

Learn how to use Python and machine learning to classify tweets into hate speech, offensive speech, and non-offensive content using a Decision Tree classifier.

What Is This All About?

Machine learning models are robust and intelligent to understand data even without explicitly been trained.

Here, we see how a DecisionTreeClassifier Model is been fed with a dataset of tweets from X (formerly Twitter), and it could classify text as either “Hate Speech”, “Offensive Speech”, and “No Hate No Offense”

This three categories can be seen as the model’s decision, or better still called the Target Variables

 How Was It Built?

As earlier noted, it was built by feeding a dataset containing tweets from X into a DecisionTreeClassifier Algorithm which trains the model. Of course, the necessary preprocessing stages like; removal of mentions, punctuations and stopwords were done, tokenization and stemming (PorterStemmer from nltk.stem) were equally done before splitting of the dataset into 20% test and 80% training data.

Demystifying the Magic

Importing all necessary libraries;

import pandas as pd

import numpy as np

import nltk

from sklearn.feature_extraction.text import CountVectorizer

from sklearn.model_selection import train_test_split

from sklearn.tree import DecisionTreeClassifier

from sklearn.metrics import accuracy_score

 

The Natural Language Tool Kit (nltk) and the Regex Expression libraries (re) for preprocessing of data

 

import nltk

nltk.download('stopwords')

import re

from nltk.corpus import stopwords

 

stopword = set(stopwords.words('english'))

stemmer = nltk.SnowballStemmer('english')

 

The dataset is a CSV (comma separated value file) extracted from the open_tweet github repository, and then loaded for cleaning.

 

data_df = pd.read_csv('train.csv')

print(data_df.head())


Exploring the dataset and preprocessing the data;

 

data_df['labels'] = data_df['class'].map({0:'Hate Speech', 1:'Offensive Speech',2:'No Hate No Offense'})

data_df = data_df[['tweet','labels']]

 

data_df.describe()

 

The .describe method on the data frame gives you a typical understanding of the data format.

 

data_df['labels'].unique()

 

User the Seaborn library to visualize the data.

 

import seaborn as sns

sns.set_theme()

sns.countplot(data_df, x ='labels')


Now, the actual tweets can be compared against their actual labels.

 

data_df.head()

data_df.tail()

 

Here is where the heart of the preprocessing stage comes in! Removing stopwords, stemming the data, converting text to lowercase. Any language other than English can be used for stopword filtering.

 

def clean_tweet(text):

    text = text.lower()  # Convert to lowercase

    text = re.sub(r"[^\w\s]", "", text)  # Remove punctuation

   

    #text = re.sub(r"[^A-Za-z0-9]+", "", text)

 

    # Load stopwords (replace 'english' with your desired language)

    stop_words = set(stopwords.words('english'))

 

    # Filter out stopwords (assuming text is tokenized)

    text = [word for word in text.split() if word not in stop_words]

 

    # Import and use a stemmer (replace PorterStemmer with your preferred stemmer)

    from nltk.stem import PorterStemmer

    stemmer = PorterStemmer()

    text = [stemmer.stem(word) for word in text]

 

    return ' '.join(text)

 

data_df['tweet'] = data_df['tweet'].apply(clean_tweet)

print(data_df.head())

Now, the tweets and labels can be stored in an array and tokenize. Tokenize here simply converts the tweets into  a matrix of token counts.

 

x = np.array(data_df['tweet'])

y = np.array(data_df['labels'])

cv = CountVectorizer()

 

Fit it to the text data;

 

x = cv.fit_transform(x)

 

At this stage,  the dataset can be splitted and the algorithm initialized

 

X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=24)

 

model = DecisionTreeClassifier()

 

 

Here is where training the algorithm comes in, by simply fitting the data to the model.

 

model.fit(X_train, y_train)

 

And just like that, a DecisionTreeClassifier model has been trained!!

 

Now, the trained model can be tested to make predictions against the actual data preserved for testing and then check how well it performed (Accuracy)

 

y_pred = model.predict(X_test)

print(accuracy_score(y_test, y_pred))

 

0.871494855759532 in this case was the accuracy score of the model.

This score can be improved to as far as 99%.

 

Now, models mostly perform well on the data they’re trained with. However, they may sometimes perform poorly on external data. Data that has completely different patterns from the initial data used to train them.

So, using data that has a completely different pattern and hidden from them, to test their accuracy strength.

 

i = 'You seem to be a nice person'

i = cv.transform([i]).toarray()

print(model.predict((i)))

 

Output:

['No Hate No Offense']

 

 

Conclusion

By leveraging standard natural language processing techniques and a simple Decision Tree Classifier, one can successfully develop an effective machine learning model to categorize social media text. With an accuracy rate of over 87%, this pipeline demonstrates that powerful content moderation tools can be built efficiently using common Python libraries.

 

Tags:  Python, NLTK, ML, X, Data, Dataset, CSV, Jupyter Notebook, Hate Speech Detection