Portfolio
NLP · Machine Learning 2023

Restaurant Review
Sentiment Analysis

Classifying customer opinions as positive or negative using NLP preprocessing and four ML classifiers — with hyperparameter-tuned accuracy up to 81.5%.

1,000 Reviews
81.5% Best Accuracy
4 Models Tested
1500 Max Features

What this project does

This project applies Natural Language Processing to a dataset of 1,000 restaurant reviews, automatically classifying each as positive or negative. The pipeline covers text preprocessing, feature extraction via Bag-of-Words (CountVectorizer), model training, hyperparameter tuning, and live inference on unseen reviews.

End-to-end workflow

Step 01
Data Ingestion
TSV dataset loaded via pandas from Google Drive in Colab environment.
Step 02
Text Preprocessing
Regex cleaning, lowercasing, stopword removal (NLTK), and Porter stemming applied to all 1,000 reviews.
Step 03
Feature Extraction
CountVectorizer with max_features=1500 transforms corpus into a sparse numeric matrix.
Step 04
Model Training
Four classifiers trained on 80/20 train-test split: Naive Bayes, Logistic Regression, Decision Tree, Random Forest.
Step 05
Hyperparameter Tuning
Grid search over key params (alpha, max_depth) to improve accuracy beyond baseline.
Step 06
Live Inference
predict_sentiment() function classifies arbitrary review text in real-time.

Algorithm comparison

Model Accuracy (Tuned) Precision Recall
Random Forest
81.5%
85.5% 71.0% Best
Decision Tree
80.0%
88.2% 67.0%
Multinomial NB
78.5%
77.8% 81.6%
Logistic Regression
77.5%
77.2% 78.0%

Inference function

A reusable function that preprocesses any raw review string and returns a positive/negative prediction using the trained model.

def predict_sentiment(sample_review):
    # Clean non-alphabetic characters
    sample_review = re.sub(r'[^a-zA-Z]', ' ', sample_review)
    sample_review = sample_review.lower()
    words = sample_review.split()

    # Remove stopwords + apply stemming
    words = [w for w in words
             if w not in set(stopwords.words('english'))]
    final = ' '.join([ps().stem(w) for w in words])

    # Vectorize + predict
    vec = cv.transform([final]).toarray()
    return classifier.predict(vec)  # 1 = Positive, 0 = Negative

Takeaways

Best Accuracy
81.5%
Random Forest (max_depth=14)
Highest Precision
88.2%
Decision Tree (max_depth=30)
Highest Recall
81.6%
Multinomial NB (alpha=0.2)
HPT Gain (NB)
+2.0%
76.5% → 78.5% after tuning

Tools & libraries

Python scikit-learn NLTK pandas NumPy Google Colab CountVectorizer PorterStemmer SMOTE (imbalanced-learn) Multinomial NB Logistic Regression Decision Tree Random Forest

Built by

PG
Priyanka Gandhi A
AI Intern · IBM SkillsBuild via AICTE / Edunet · Aug–Oct 2023
Machine Learning NLP Sentiment Analysis Scikit-Learn Deep Learning Tableau Power BI Kaggle GitHub