Machine Learning project 02
Machine Learning Sentiment Analysis Project
Build and evaluate a complete sentiment analysis workflow with reproducible Python code, explicit metrics, and honest limitations.
Explore Machine Learning training in VizagView all project ideas
Dataset and objective
A balanced, labelled set of short positive and negative example reviews embedded in the script.
Skills practised
- Text labels and TF-IDF
- N-gram features
- Stratified splitting
- Classification reports
Requirements
- Python 3.10 or later
- A terminal or command prompt
python -m pip install scikit-learn- About 45-60 minutes to build and review
Machine Learning workflow
- Data: A balanced, labelled set of short positive and negative example reviews embedded in the script.
- Preprocessing: TfidfVectorizer lowercases text and converts unigrams and bigrams into numeric features inside a pipeline.
- Model: LogisticRegression learns a reproducible binary sentiment boundary and provides class probabilities.
- Evaluation: A stratified holdout split and a classification report with precision, recall, F1 score, and accuracy.
Complete Python code
Save the code as ml_sentiment_analysis.py. The random state and data handling are included so the result can be reproduced and reviewed.
"""Train a small TF-IDF sentiment classifier on labelled example reviews."""
from __future__ import annotations
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.feature_extraction.text import TfidfVectorizer
EXAMPLES = [
("The class was clear and the exercises were useful", "positive"),
("I enjoyed the practical examples and patient explanation", "positive"),
("Fast support solved my problem completely", "positive"),
("The interface is simple and pleasant to use", "positive"),
("Excellent value and a smooth learning experience", "positive"),
("The update made the application much better", "positive"),
("Instructions were accurate and easy to follow", "positive"),
("This feature saves me a lot of time", "positive"),
("The project worked exactly as described", "positive"),
("Helpful feedback made the difficult part understandable", "positive"),
("I would happily recommend this course", "positive"),
("Setup was quick and everything ran correctly", "positive"),
("The lesson was confusing and poorly organised", "negative"),
("Support never answered my question", "negative"),
("The application crashes whenever I open it", "negative"),
("The instructions skipped important setup steps", "negative"),
("This was slow frustrating and difficult to use", "negative"),
("The result was incorrect and wasted my time", "negative"),
("I am disappointed with the missing features", "negative"),
("The new update made the experience worse", "negative"),
("Examples failed and the explanation did not help", "negative"),
("The interface is cluttered and unreliable", "negative"),
("I cannot recommend this unfinished product", "negative"),
("Installation failed without a useful error message", "negative"),
]
def train_model(random_state: int = 42):
texts, labels = zip(*EXAMPLES)
x_train, x_test, y_train, y_test = train_test_split(
texts, labels, test_size=0.33, random_state=random_state, stratify=labels
)
model = make_pipeline(
TfidfVectorizer(lowercase=True, ngram_range=(1, 2), min_df=1),
LogisticRegression(max_iter=1000, random_state=random_state),
)
model.fit(x_train, y_train)
predictions = model.predict(x_test)
return model, classification_report(y_test, predictions, zero_division=0)
def main() -> None:
model, report = train_model()
print("Sentiment Analysis Evaluation\n")
print(report)
print("This tiny teaching dataset is not representative of real users or languages.")
text = input("\nWrite a short review to classify (or press Enter to stop): ").strip()
if text:
label = model.predict([text])[0]
probabilities = dict(zip(model.classes_, model.predict_proba([text])[0]))
print(f"Prediction: {label} ({probabilities[label]:.1%})")
if __name__ == "__main__":
main()
How the pipeline works
TfidfVectorizer lowercases text and converts unigrams and bigrams into numeric features inside a pipeline.
LogisticRegression learns a reproducible binary sentiment boundary and provides class probabilities. A stratified holdout split and a classification report with precision, recall, F1 score, and accuracy.
Run the project
- Create and activate a virtual environment.
- Install the dependencies with
python -m pip install scikit-learn. - Run
python ml_sentiment_analysis.py. - Review every printed metric together with the limitation below; a single score never proves deployment readiness.
How to interpret the evaluation
Classification projects report class-aware metrics so majority classes do not hide weak performance. Regression projects report errors in target units and include R-squared or a simple baseline where appropriate. Always verify the split strategy matches how new data will arrive.
Accuracy, ethics, and safety limits
The tiny English-only sample cannot represent real customers, languages, sarcasm, mixed sentiment, or domain-specific meaning. Do not use it to automate decisions about people.
Ways to extend the project
Load a larger reviewed dataset, add neutral and mixed classes, test cross-validation, inspect influential terms, or build an error-analysis table.
Continue learning Machine Learning
Try the next project, return to the Softenant project library, or explore the Machine Learning course in Vizag for guided data preparation, model evaluation, and portfolio feedback.