Data is being generated at an unprecedented rate from sources such as social media, financial transactions, and e-commerce platforms. Handling this continuous stream of information is a challenge, but it offers an opportunity to make timely and accurate decisions. Real-time systems, such as financial transactions, voice assistants, and health monitoring systems, rely on continuous data processing in order to provide relevant and up-to-date responses.
Batch learning algorithms such as KNN, SVM, and Decision Trees require the entire dataset to be loaded into memory during training. When working with huge datasets, this becomes increasingly impractical, leading to significant storage and memory issues. These are also inefficient when working with real-time data.
Due to this issue, we require an algorithm that is both efficient and accurate when dealing with huge amounts of data. Passive-Aggressive algorithms set themselves apart in this regard. Unlike batch learning algorithms, they don’t have to be trained on the full dataset to make predictions. Passive-Aggressive algorithms learn from the data on the fly, eliminating the need to store or process the entire dataset into memory.
This article was published as a part of the Data Science Blogathon.
Online learning, also known as incremental learning, is a machine learning paradigm where the model updates incrementally with each new data point rather than being trained on a fixed dataset all at once. This approach allows the model to continuously adapt to new data, making it particularly useful in dynamic environments where data evolves over time. Unlike traditional batch learning methods, online learning enables real-time updates and decision-making by processing new information as it arrives.
Let us look into Batch vs. Online Learning comparison below:
Batch Learning:
Online Learning:
The Passive-Aggressive algorithm was first introduced by Crammer et.al. in 2006 through their paper titled “Online Passive-Aggressive Algorithms”. These algorithms fall under the category of online learning and are primarily used for classification tasks. These are memory efficient because they can learn from each data point incrementally, adjust their parameters, and then discard the data from memory. This makes passive-aggressive algorithms particularly useful when dealing with huge datasets and for real-time applications. Moreover, its ability to adapt quickly allows it to perform well in dynamic environments where data distribution may change over time.
You might be wondering about the unusual name. There is a reason for this. The passive part of the algorithm implies that if the current data point is correctly classified, the model remains unchanged and preserves the knowledge gained from previous data points. The aggressive part, on the other hand, indicates that if a misclassification occurs, the model will significantly adjust its weights to correct the error.
To gain a better understanding of how the PA algorithm works, let’s visualize its behavior in the context of binary classification. Imagine you have a set of data points, each belonging to one of two classes. The PA algorithm aims to find a separating hyperplane that divides the data points into their respective classes. The algorithm starts with an initial guess for the hyperplane. When a new data point is misclassified, the algorithm aggressively updates the current hyperplane to ensure that the new data point is correctly classified. On the other hand, when the data point is correctly classified, then no update to the hyperplane is required.
The Passive-Aggressive algorithm uses hinge loss as its loss function and is one of the key building blocks of the algorithm. That’s why it is crucial to understand the workings of the hinge loss before we delve into the mathematical intuition behind the algorithm.
Hinge loss is widely used in machine learning, particularly for training classifiers such as support vector machines (SVMs).
It is defined as:
Let’s take the case of a binary classification problem where the objective is to differentiate between two data classes. The PA algorithm implicitly aims to maximize the margin between the decision boundary and the data points. The margin is the distance between a data point and the separating line/hyperplane. This is very similar to the workings of the SVM classifier, which also uses the hinge loss as its loss function. A larger margin indicates that the classifier is more confident in its prediction and can accurately distinguish between the two classes. Therefore, the goal is to achieve a margin of at least 1 as often as possible.
Let’s break this down further and see how the equation helps in attaining the maximum margin:
To put it simply, the hinge loss penalizes incorrect classifications as well as correct classifications that are not confident enough. When a data point is correctly classified with at least a unit margin, the loss is zero. Otherwise, if the data point is within the margin or misclassified, the loss increases linearly with the distance from the margin.
The mathematical foundation of the Passive Aggressive Classifier revolves around maintaining a weight vector w that is updated based on the classification error of incoming data points. Here’s a detailed overview of the algorithm:
Given a dataset:
For each data point x_i, if L(w; (x_i, y_i)) > 0 (misclassified or insufficient margin):
The updated weight vector w_t+1 is given as:
If L(w; (x_i, y_i)) = 0 (correctly classified with sufficient margin):
Then the weight vector remains unchanged:
Note that these equations emerge after solving a constrained optimization problem with the objective of obtaining a maximal margin hyperplane between the classes. These are taken from the original research paper and the derivation of these is beyond the scope of this article.
These two update equations are the heart of the Passive-Aggressive algorithm. The significance of these can be understood in simpler terms. On one hand, the update requires the new weight value (w_t+1) to correctly classify the current example with a sufficiently large margin and thus progress is made. On the other hand, it must stay as close as possible to the older weight (w_t) in order to retain the information learned on previous rounds.
The aggressiveness parameter C is the most important hyperparameter in the Passive-Aggressive algorithm. It governs how aggressively the algorithm updates its weights when a misclassification occurs.
A high C value leads to more aggressive updates, potentially resulting in faster learning but also increasing the risk of overfitting. The algorithm might become too sensitive to noise and fluctuations in the data. On the other hand, a low value of C leads to less aggressive updates, making the algorithm more robust to noise and outliers. However, in this case, it is slow to adapt to new information, slowing down the learning process.
We want the algorithm to learn incrementally from each new instance while avoiding overfitting to noisy samples. As a result, we must strive to strike a balance between the two, allowing us to make significant updates while maintaining model stability and preventing overfitting. Most of the time, the optimal value of C depends on the specific dataset and the desired trade-off between learning speed and robustness. In practical scenarios, techniques such as cross-validation are used to arrive at an optimal value of C.
Real-world datasets almost always contain some degree of noise or irregularities. A mislabeled data point may cause the PA algorithm to drastically change its weight vector in the wrong direction. This single mislabeled example can lead to several prediction mistakes on subsequent rounds, impacting the reliability of the model.
To address this, there is one more important hyperparameter that helps in making the algorithm more robust to noise and outliers in the data. It tends to use gentler weight updates in the case of misclassification. This is similar to regularization. The algorithm is divided into two variants based on the regularization parameter, known as PA-I and PA-II.
These differ mainly in the definition of the step size variable τ (also known as the normalized loss). For PA-I the loss is capped to the value of the aggressiveness parameter C.
For PA-II the step size or the normalized loss can be written as:
In the sklearn implementation of the Passive Aggressive classifier, this regularization parameter is regarded as the loss. This can be set to one of two values based on which of the two PA-I and PA-II we want to use. If you want to use the PA-I variant, then the loss should be set to “hinge” otherwise for PA-II, the loss is set to “squared-hinge”.
Again the choice between these two depends on the specific characteristics of your dataset. In practice it is often advisable to experiment with both variants with varying values of C before choosing any one.
Online learning and Passive-Aggressive algorithms have a wide range of applications, from real-time data processing to adaptive systems. Below, we look at some of the most impactful applications of online learning.
Spam filtering is an essential application of text classification where the goal is to distinguish between spam and legitimate emails. The PA algorithm’s ability to learn incrementally is particularly beneficial here, as it can continuously update the model based on new spam trends.
Sentiment analysis involves determining the sentiment expressed in a piece of text, such as a tweet or a product review. The PA algorithm can be used to build models that analyze sentiment in real-time, adapting to new slang, expressions, and sentiment trends as they emerge. This is particularly useful in social media monitoring and customer feedback analysis, where timely insights are crucial.
Hate speech detection is another critical application where the PA algorithm can be extremely useful. By learning incrementally from new instances of hate speech, the model can adapt to evolving language patterns and contexts. This is vital for maintaining the effectiveness of automated moderation tools on platforms like Twitter, Facebook, and Reddit, ensuring a safer and more inclusive online environment.
Financial institutions and online services continuously monitor transactions and user behavior in order to detect fraudulent activity. The PA algorithm’s ability to update its model with each new transaction helps in identifying patterns of fraud as they emerge, providing a strong defense against evolving fraudulent tactics.
Stock prices in financial markets are highly dynamic, requiring models to respond quickly to new information. Online learning algorithms can be used to forecast and analyze stock prices by learning incrementally from new market data, resulting in timely and accurate predictions that benefit traders and investors.
Online learning algorithms can also be used in large-scale recommender systems to dynamically update recommendations based on user interactions. This real-time adaptability ensures that recommendations remain relevant and personalized as user preferences change.
These are some of the areas where online learning algorithms truly shine. However, their capabilities are not limited to these areas. These are also applicable in a variety of other fields, including anomaly detection, medical diagnosis, and robotics.
While online learning and passive-aggressive algorithms offer advantages in dealing with streaming data and adapting to change quickly, they also have drawbacks. Some of the key limitations are:
Social media platforms like Twitter and Reddit generate massive amounts of data on a daily basis, making them ideal for testing our theoretical understanding of online learning algorithms.
In this section, I will demonstrate a practical use case by building a hate speech detection application from scratch using real-time data from Reddit. Reddit is a platform well known for its diverse community. However, it also faces the challenge of toxic comments that can be hurtful and abusive. We will build a system that can identify these toxic comments in real-time using the Reddit API.
In this case, training a model with all of the data at once would be impossible due to the huge volume of data. Furthermore, the data distributions and patterns keep changing with time. Therefore, we require the assistance of passive-aggressive algorithms capable of learning from data on the fly without storing it in memory.
Before we can begin implementing the code, you must first set up your system. To use the Reddit API, you first must create an account on Reddit if you don’t already have one. Then, create a Reddit application and obtain your API keys and other credentials for authentication. After these prerequisite steps are done, we are ready to begin creating our hate speech detection model.
The workflow of the code will look like this:
The first step is to install the required libraries.
pip install praw scikit-learn nltk transformers torch matplotlib seaborn opendatasets
To work with Reddit we need the `praw` library which is the Reddit API wrapper. We also need `nltk` for text processing, `scikit-learn` for machine learning, `matplotlib` and `seaborn` for visualizations, `transformers` and `torch` for creating word embeddings and loading the fine-tuned BERT model and `opendatasets` to load data from Kaggle.
In the next step we import all the necessary libraries and setup a connection to the Reddit API using `praw`. It will help us in streaming comments from subreddits.
import re
import praw
import torch
import nltk
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import opendatasets as od
from nltk.corpus import stopwords
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import PassiveAggressiveClassifier
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
from sklearn.model_selection import train_test_split
from transformers import AutoModel, AutoModelForSequenceClassification, AutoTokenizer
from transformers import BertForSequenceClassification, BertTokenizer, TextClassificationPipeline
# Reddit API credentials
REDDIT_CLIENT_ID = {your_client_id}
REDDIT_CLIENT_SECRET = {your_client_secret}
REDDIT_USER_AGENT = {your_user_agent}
# Set up Reddit API connection
reddit = praw.Reddit(client_id=REDDIT_CLIENT_ID,
client_secret=REDDIT_CLIENT_SECRET,
user_agent=REDDIT_USER_AGENT)
To successfully set up a Reddit instance, simply replace the above placeholders with your credentials and you are good to go.
When dealing with raw text data, it is common to have examples containing symbols, hashtags, slang words, and so on. As these are of no practical use to our model, we must first clean the text in order to remove them.
# Download stopwords
nltk.download('stopwords')
stop_words = set(stopwords.words('english'))
# Clean the text and remove stopwords
def clean_text(text):
text = re.sub(r'http\S+|www\S+|https\S+', '', text, flags=re.MULTILINE)
text = re.sub(r'\@\w+|\#','', text)
text = re.sub(r'\W', ' ', text)
text = re.sub(r'\d', ' ', text)
text = re.sub(r'\s+', ' ', text)
text = text.strip()
text = ' '.join([word for word in text.split() if word.lower() not in stop_words])
return text
The above code defines a helper function that preprocesses the comments by removing unwanted words, special characters, and URLs.
When we are streaming raw comments from Reddit, we don’t have any idea if the comment is toxic or not because it is unlabeled. To use supervised classification, we first need to have labeled data. We must implement a reliable and precise system for labeling incoming raw comments. For this, we would use a BERT model fine-tuned for hate speech detection. This model will accurately classify the comments into the two categories.
model_path = "JungleLee/bert-toxic-comment-classification"
tokenizer = BertTokenizer.from_pretrained(model_path)
model = BertForSequenceClassification.from_pretrained(model_path, num_labels=2)
pipeline = TextClassificationPipeline(model=model, tokenizer=tokenizer)
# Helper function to label the text
def predict_hate_speech(text):
prediction = pipeline(text)[0]['label']
return 1 if prediction == 'toxic' else 0 # 1 for toxic, 0 for non-toxic
Here we use the transformers library to setup the model pipeline. Then we define a helper function to predict whether the given text is toxic or non-toxic using the BERT model. We now have labeled examples to feed into our model.
As our classifier will not work with text inputs, these would need to be converted into a suitable vector representation first. In order to do this, we will use pretrained BERT embeddings, which will convert our text to vectors that can then be fed to the model for training.
# Load the pretrained BERT model and tokenizer for embeddings
model_name = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
bert_model = AutoModel.from_pretrained(model_name)
bert_model.eval()
# Helper function to get BERT embeddings
def get_bert_embedding(text):
inputs = tokenizer(text, return_tensors='pt', truncation=True, padding=True)
with torch.no_grad():
outputs = bert_model(**inputs)
return outputs.last_hidden_state[:, 0, :].squeeze().numpy()
The above code takes a piece of text, tokenizes it using a BERT tokenizer, and then passes it through the BERT model to extract the sentence embeddings. The text has now been converted to vectors.
We are now ready to stream comments in real-time and train our classifier for detecting hate speech.
# Helper function to stream comments from a subreddit
def stream_comments(subreddit_name, batch_size=100):
subreddit = reddit.subreddit(subreddit_name)
comment_stream = subreddit.stream.comments()
batch = []
for comment in comment_stream:
try:
# Clean the incoming text
comment_text = clean_text(comment.body)
# Label the comment using the pretrained BERT model
label = predict_hate_speech(comment_text)
# Add the text and label to the current batch
batch.append((comment_text, label))
if len(batch) >= batch_size:
yield batch
batch = []
except Exception as e:
print(f'Error: {e}')
# Specify the number of training rounds
ROUNDS = 10
# Specify the subreddit
subreddit_name = 'Fitness'
# Initialize the Passive-Aggressive classifier
clf = PassiveAggressiveClassifier(C=0.1, loss='hinge', max_iter=1, random_state=37)
# Stream comments and perform incremental training
for num_rounds, batch in enumerate(stream_comments(subreddit_name, batch_size=100)):
# Train the classifier for a desired number of rounds
if num_rounds == ROUNDS:
break
# Separate the text and labels
batch_texts = [item[0] for item in batch]
batch_labels = [item[1] for item in batch]
# Convert the batch of texts to BERT embeddings
X_train_batch = np.array([get_bert_embedding(text) for text in batch_texts])
y_train_batch = np.array(batch_labels)
# Train the model on the current batch
clf.partial_fit(X_train_batch, y_train_batch, classes=[0, 1])
print(f'Trained on batch of {len(batch_texts)} samples.')
print('Training completed')
In the above code, we first specify the subreddit from which we want to stream comments and then initialize our PA classifier with 10 training rounds. We then stream comments in real time. For each new comment that comes in it first gets cleaned removing unwanted words. Then it is labeled using the pretrained BERT model and added to the current batch.
We initialize our Passive-Aggressive Classifier taking C=0.1 and loss=’hinge’ which corresponds to the PA-I version of the algorithm. For each batch we train our classifier using the `partial_fit()` method. This allows the model to learn incrementally from each training sample rather than storing the whole batch in memory before processing. Thus, enabling the model to constantly adapt to new information, making it ideal for real-time applications.
I will use the Kaggle toxic tweets dataset to evaluate our model. This dataset contains several tweets that are classified as toxic or non-toxic.
# Download data from Kaggle
od.download("https://www.kaggle.com/datasets/ashwiniyer176/toxic-tweets-dataset")
# Load the data
data = pd.read_csv("toxic-tweets-dataset/FinalBalancedDataset.csv", usecols=[1,2])[["tweet", "Toxicity"]]
# Separate the text and labels
test_data = data.sample(n=100)
texts = test_data['tweet'].apply(clean_text)
labels = test_data['Toxicity']
# Convert text to vectors
X_test = np.array([get_bert_embedding(text) for text in texts])
y_test = np.array(labels)
# Make predictions
y_pred = clf.predict(X_test)
# Evaluate the performance of the model
accuracy = accuracy_score(y_test, y_pred)
conf_matrix = confusion_matrix(y_test, y_pred)
print("Classification Report:")
print(classification_report(y_test, y_pred))
# Plot the confusion matrix
plt.figure(figsize=(7, 5))
sns.heatmap(conf_matrix,
annot=True,
fmt='d',
cmap='Blues',
cbar=False,
xticklabels=["Non-Toxic", "Toxic"],
yticklabels=["Non-Toxic", "Toxic"])
plt.xlabel('Predicted Labels')
plt.ylabel('True Labels')
plt.title('Confusion Matrix')
plt.show()
First, we loaded the test set and cleaned it with the `clean_text` method defined earlier. The text is then converted into vectors using BERT embeddings. Finally, we make predictions on the test set and evaluate our model’s performance on different metrics using classification report and confusion matrix.
We explored the power of online learning algorithms, focusing on the passive-aggressive algorithm’s ability to handle large datasets efficiently and adapt to real-time data without requiring complete retraining. And also discussed the role of hinge loss, the aggressiveness hyperparameter ( C ), and how regularization helps manage noise and outliers. We also reviewed real-world applications and limitations before implementing a hate speech detection model for Reddit using the passive-aggressive classifier. Thanks for reading, and I look forward to our next AI tutorial!
A. The fundamental principle behind the passive aggressive algorithm is to aggressively update the weights when a wrong prediction is made and to passively retain the learned weights when a correct prediction is made.
A. When C is high, the algorithm becomes more aggressive, quickly adapting to new data, resulting in faster learning. When C is low, the algorithm becomes less aggressive and makes smaller updates. This reduces the likelihood of overfitting to noisy samples but makes it slower to adapt to new instances.
A. Both aim to maximize the margin between the decision boundary and the data points. Both use hinge loss as their loss function.
A. Online learning algorithms can work with huge datasets, have no storage limitations and easily adapt to rapidly changing data without the need for retraining from scratch.
A. Passive-Aggressive algorithms can be used in a variety of applications, including spam filtering, sentiment analysis, hate speech detection, real-time stock market analysis, and recommender systems.
The media shown in this article is not owned by Analytics Vidhya and is used at the Author’s discretion.