ML-Based Sentiment Analysis Intermediate

Machine learning approaches to sentiment analysis learn patterns from labeled data, achieving higher accuracy than rule-based methods on domain-specific text. This lesson covers the complete pipeline: text preprocessing, feature extraction with TF-IDF, and training classifiers with scikit-learn.

The ML Sentiment Pipeline

  1. Collect labeled data

    Gather text samples with sentiment labels (positive/negative). Common datasets include IMDB reviews, Amazon reviews, and Twitter sentiment.

  2. Preprocess text

    Clean the text: lowercase, remove special characters, handle negation, and optionally stem or lemmatize.

  3. Extract features

    Convert text to numerical features using Bag of Words, TF-IDF, or n-grams.

  4. Train a classifier

    Fit a model (Naive Bayes, Logistic Regression, SVM) on the features.

  5. Evaluate and deploy

    Measure accuracy, precision, recall, and F1 on a held-out test set.

Complete Example with scikit-learn

Python
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
import re

# Load IMDB dataset
df = pd.read_csv("imdb_reviews.csv")

# Text preprocessing
def preprocess(text):
    text = text.lower()
    text = re.sub(r"<br\s*/?>", " ", text)  # Remove HTML
    text = re.sub(r"[^a-z\s]", "", text)      # Keep only letters
    return text

df["clean_text"] = df["review"].apply(preprocess)

# Split data
X_train, X_test, y_train, y_test = train_test_split(
    df["clean_text"], df["sentiment"],
    test_size=0.2, random_state=42
)

# TF-IDF features (unigrams + bigrams)
vectorizer = TfidfVectorizer(
    max_features=50000,
    ngram_range=(1, 2),
    min_df=2
)
X_train_tfidf = vectorizer.fit_transform(X_train)
X_test_tfidf = vectorizer.transform(X_test)

# Train Logistic Regression
model = LogisticRegression(max_iter=1000)
model.fit(X_train_tfidf, y_train)

# Evaluate
y_pred = model.predict(X_test_tfidf)
print(classification_report(y_test, y_pred))

Comparing Classifiers

Python
from sklearn.naive_bayes import MultinomialNB
from sklearn.svm import LinearSVC
from sklearn.ensemble import RandomForestClassifier

classifiers = {
    "Naive Bayes": MultinomialNB(),
    "Logistic Regression": LogisticRegression(max_iter=1000),
    "Linear SVM": LinearSVC(max_iter=1000),
}

for name, clf in classifiers.items():
    clf.fit(X_train_tfidf, y_train)
    accuracy = clf.score(X_test_tfidf, y_test)
    print(f"{name}: {accuracy:.3f}")
Classifier Typical Accuracy (IMDB) Speed Best For
Naive Bayes ~85% Very fast Baseline, small datasets
Logistic Regression ~88% Fast Best overall ML approach
Linear SVM ~88% Fast High-dimensional features

Saving and Loading the Model

Python
import joblib

# Save model and vectorizer
joblib.dump(model, "sentiment_model.pkl")
joblib.dump(vectorizer, "tfidf_vectorizer.pkl")

# Load and predict on new text
model = joblib.load("sentiment_model.pkl")
vectorizer = joblib.load("tfidf_vectorizer.pkl")

new_text = ["This product exceeded my expectations!"]
features = vectorizer.transform(new_text)
prediction = model.predict(features)
print(f"Sentiment: {prediction[0]}")
Feature Engineering Tips: Adding bigrams (ngram_range=(1,2)) typically improves accuracy by 2-3%. Including features like exclamation count, caps ratio, and text length can further boost performance. For the best ML results, combine TF-IDF with hand-crafted features.

Try It Yourself

Download the IMDB dataset from Kaggle, train all three classifiers, and compare their accuracy. Experiment with different TF-IDF settings (max_features, ngram_range).

Next: Deep Learning →

Ready to Go Deeper?

Live instructor-led courses from our partners. Affiliate disclosure.