sentiment-analysis▌
aj-geddes/useful-ai-prompts · updated Apr 8, 2026
Sentiment analysis determines emotional tone and opinions in text, enabling understanding of customer satisfaction, brand perception, and feedback analysis.
Sentiment Analysis
Overview
Sentiment analysis determines emotional tone and opinions in text, enabling understanding of customer satisfaction, brand perception, and feedback analysis.
Approaches
- Lexicon-based: Using sentiment dictionaries
- Machine Learning: Training classifiers on labeled data
- Deep Learning: Neural networks for complex patterns
- Aspect-based: Sentiment about specific features
- Multilingual: Non-English text analysis
Sentiment Types
- Positive: Favorable, satisfied
- Negative: Unfavorable, dissatisfied
- Neutral: Factual, no clear sentiment
- Mixed: Combination of sentiments
Implementation with Python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
import re
from collections import Counter
# Sample review data
reviews_data = [
"This product is amazing! I love it so much.",
"Terrible quality, very disappointed.",
"It's okay, nothing special.",
"Best purchase ever! Highly recommend.",
"Worst product I've ever bought.",
"Pretty good, satisfied with the purchase.",
"Excellent service and fast delivery.",
"Poor quality and bad customer support.",
"Not bad, does what it's supposed to.",
"Absolutely fantastic! Five stars!",
"Mediocre product, expected better.",
"Love everything about this!",
"Complete waste of money.",
"Good value for the price.",
"Very satisfied, will buy again!",
"Horrible experience from start to finish.",
"It works as described.",
"Outstanding quality and design!",
"Disappointed with the results.",
"Perfect! Exactly what I wanted.",
]
sentiments = [
'Positive', 'Negative', 'Neutral', 'Positive', 'Negative',
'Positive', 'Positive', 'Negative', 'Neutral', 'Positive',
'Negative', 'Positive', 'Negative', 'Positive', 'Positive',
'Negative', 'Neutral', 'Positive', 'Negative', 'Positive'
]
df = pd.DataFrame({'review': reviews_data, 'sentiment': sentiments})
print("Sample Reviews:")
print(df.head(10))
# 1. Lexicon-based Sentiment Analysis
from nltk.sentiment import SentimentIntensityAnalyzer
try:
import nltk
nltk.download('vader_lexicon', quiet=True)
sia = SentimentIntensityAnalyzer()
df['vader_scores'] = df['review'].apply(lambda x: sia.polarity_scores(x))
df['vader_compound'] = df['vader_scores'].apply(lambda x: x['compound'])
df['vader_sentiment'] = df['vader_compound'].apply(
lambda x: 'Positive' if x > 0.05 else ('Negative' if x < -0.05 else 'Neutral')
)
print("\n1. VADER Sentiment Scores:")
print(df[['review', 'vader_compound', 'vader_sentiment']].head())
except:
print("NLTK not available, skipping VADER analysis")
# 2. Textblob Sentiment (alternative)
try:
from textblob import TextBlob
df['textblob_polarity'] = df['review'].apply(lambda x: TextBlob(x).sentiment.polarity)
df['textblob_sentiment'] = df['textblob_polarity'].apply(
lambda x: 'Positive' if x > 0.1 else ('Negative' if x < -0.1 else 'Neutral')
)
print("\n2. TextBlob Sentiment Scores:")
print(df[['review', 'textblob_polarity', 'textblob_sentiment']].head())
except:
print("TextBlob not available")
# 3. Feature Extraction for ML
vectorizer = TfidfVectorizer(max_features=100, stop_words='english')
X = vectorizer.fit_transform(df['review'])
y = df['sentiment']
print(f"\n3. Feature Matrix Shape: {X.shape}")
print(f"Features extracted: {len(vectorizer.get_feature_names_out())}")
# 4. Machine Learning Model
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# Naive Bayes classifier
nb_model = MultinomialNB()
nb_model.fit(X_train, y_train)
y_pred = nb_model.predict(X_test)
print("\n4. Machine Learning Results:")
print(f"Accuracy: {accuracy_score(y_test, y_pred):.2f}")
print("\nClassification Report:")
print(classification_report(y_test, y_pred))
# 5. Sentiment Distribution
fig, axes = plt.subplots(2, 2, figsize=(14, 8))
# Distribution of sentiments
sentiment_counts = df['sentiment'].value_counts()
axes[0, 0].bar(sentiment_counts.index, sentiment_counts.values, color=['green', 'red', 'gray'], alpha=0.7, edgecolor='black')
axes[0, 0].set_title('Sentiment Distribution')
axes[0, 0].set_ylabel('Count')
axes[0, 0].grid(True, alpha=0.3, axis='y')
# Pie chart
axes[0, 1].pie(sentiment_counts.values, labels=sentiment_counts.index, autopct='%1.1f%%',
colors=['green', 'red', 'gray'], startangle=90)
axes[0, 1].set_title('Sentiment Proportion')
# VADER compound scores distribution
if 'vader_compound' in df.columns:
axes[1, 0].hist(df['vader_compound'], bins=20, color='steelblue', edgecolor='black', alpha=0.7)
axes[1, 0].axvline(x=0.05, color='green', linestyle='--', label='Positive threshold')
axes[1, 0].axvline(x=-0.05, color='red', linestyle='--', label='Negative threshold')
axes[1, 0].set_xlabel('VADER Compound Score')
axes[1, 0].set_ylabel('Frequency')
axes[1, 0].set_title('VADER Score Distribution')
axes[1, 0].legend()
# Confusion matrix
cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', ax=axes[1, 1],
xticklabels=np.unique(y_test), yticklabels=np.unique(y_test))
axes[1, 1].set_title('Classification Confusion Matrix')
axes[1, 1].set_ylabel('True Label')
axes[1, 1].set_xlabel('Predicted Label')
plt.tight_layout()
plt.show()
# 6. Most Informative Features
feature_names = vectorizer.get_feature_names_out()
# Get feature importance from Naive Bayes
for sentiment_class, idx in enumerate(np.unique(y)):
class_idx = list(np.unique(y)).index(idx)
top_features_idx = np.argsort(nb_model.feature_log_prob_[class_idx])[-5:]
print(f"\nTop features for '{idx}':")
for feature_idx in reversed(top_features_idx):
print(f" {feature_names[feature_idx]}")
# 7. Word frequency analysis
positive_words = ' '.join(df[df['sentiment'] == 'Positive']['review'].values).lower()
negative_words = ' '.join(df[df['sentiment'] == 'Negative']['review'].values).lower()
# Clean and tokenize
def get_words(text):
text = re.sub(r'[^a-z\s]', '', text)
words = text.split()
return [w for w in words if len(w) > 2]
pos_word_freq = Counter(get_words(positive_words))
neg_word_freq = Counter(get_words(negative_words))
# Visualization
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# Positive words
top_pos_words = dict(pos_word_freq.most_common(10))
axes[0].barh(list(top_pos_words.keys()), list(top_pos_words.values()), color='green', alpha=0.7, edgecolor='black')
axes[0].set_xlabel('Frequency')
axes[0].set_title('Top Words in Positive Reviews')
axes[0].invert_yaxis()
# Negative words
top_neg_words = dict(neg_word_freq.most_common(10))
axes[1].barh(list(top_neg_words.keys()), list(top_neg_words.values()), color='red', alpha=0.7, edgecolor='black')
axes[1].set_xlabel('Frequency')
axes[1].set_title('Top Words in Negative Reviews')
axes[1].invert_yaxis()
plt.tight_layout()
plt.show()
# 8. Trend analysis (simulated over time)
dates = pd.date_range('2023-01-01', periods=len(df))
df['date'] = dates
df['rolling_sentiment_score'] = df['vader_compound'].rolling(window=3, center=True).mean()
fig, ax = plt.subplots(figsize=(12, 5))
ax.plot(df['date'], df['rolling_sentiment_score'], marker='o', linewidth=2, label='Rolling Avg (3-day)')
ax.scatter(df['date'], df['vader_compound'], alpha=0.5, s=30, label='Daily Score')
ax.axhline(y=0, color='black', linestyle='--', alpha=0.3)
ax.fill_between(df['date'], df['rolling_sentiment_score'], 0,
where=(df['rolling_sentiment_score'] > 0), alpha=0.3, color='green', label='Positive')
ax.fill_between(df['date'], df['rolling_sentiment_score'], 0,
where=(df['rolling_sentiment_score'] <= 0), alpha=0.3, color='red', label='Negative')
ax.set_xlabel('Date')
ax.set_ylabel('Sentiment Score')
ax.set_title('Sentiment Trend Over Time')
ax.legend()
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# 9. Aspect-based sentiment (simulated)
aspects = ['Quality', 'Price', 'Delivery', 'Customer Service']
aspect_sentiments = []
for aspect in aspects:
keywords = {
'Quality': ['quality', 'product', 'design', 'material'],
'Price': ['price', 'cost', 'expensive', 'value'],
'Delivery': ['delivery', 'fast', 'shipping', 'arrived'],
'Customer Service': ['service', 'support', 'customer', 'help']
}
# Count mentions and associated sentiment
aspect_reviews = df[df['review'].str.contains('|'.join(keywords[aspect]), case=False)]
if len(aspect_reviews) > 0:
avg_sentiment = aspect_reviews['vader_compound'].mean()
aspect_sentiments.append({
'Aspect': aspect,
'Avg Sentiment': avg_sentiment,
'Count': len(aspect_reviews)
})
aspect_df = pd.DataFrame(aspect_sentiments)
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# Aspect sentiment scores
colors_aspect = ['green' if x > 0 else 'red' for x in aspect_df['Avg Sentiment']]
axes[0].barh(aspect_df['Aspect'], aspect_df['Avg Sentiment'], color=colors_aspect, alpha=0.7, edgecolor='black')
axes[0].set_xlabel('Average Sentiment Score')
axes[0].set_title('Sentiment by Aspect')
axes[0].axvline(x=0, color='black', linestyle='-', linewidth=0.8)
axes[0].grid(True, alpha=0.3, axis='x')
# Mention count
axes[1].bar(aspect_df['Aspect'], aspect_df['Count'], color='steelblue', alpha=0.7, edgecolor='black')
axes[1].set_ylabel('Number of Mentions')
axes[1].set_title('Aspect Mention Frequency')
axes[1].grid(True, alpha=0.3, axis='y')
plt.tight_layout()
plt.show()
# 10. Summary report
print("\n" + "="*50)
print("SENTIMENT ANALYSIS SUMMARY")
print("="*50)
print(f"Total Reviews: {len(df)}")
print(f"Positive: {len(df[df['sentiment'] == 'Positive'])} ({len(df[df['sentiment'] == 'Positive'])/len(df)*100:.1f}%)")
print(f"Negative: {len(df[df['sentiment'] == 'Negative'])} ({len(df[df['sentiment'] == 'Negative'])/len(df)*100:.1f}%)")
print(f"Neutral: {len(df[df['sentiment'] == 'Neutral'])} ({len(df[df['sentiment'] == 'Neutral'])/len(df)*100:.1f}%)")
if 'vader_compound' in df.columns:
print(f"\nAverage VADER Score: {df['vader_compound'].mean():.3f}")
print(f"Model Accuracy: {accuracy_score(y_test, y_pred):.2%}")
print("="*50)
Methods Comparison
- Lexicon-based: Fast, interpretable, limited context
- Machine Learning: Requires training data, good accuracy
- Deep Learning: Complex patterns, needs large dataset
- Hybrid: Combines multiple approaches
Applications
- Customer feedback analysis
- Product reviews monitoring
- Social media sentiment
- Brand perception tracking
- Chatbot sentiment detection
Deliverables
- Sentiment distribution analysis
- Classified sentiments for all texts
- Confidence scores
- Feature importance for classification
- Trend analysis visualizations
- Aspect-based sentiment breakdown
- Executive summary with insights
Discussion
Product Hunt–style comments (not star reviews)- No comments yet — start the thread.
Ratings
4.7★★★★★73 reviews- ★★★★★Omar Sethi· Dec 24, 2024
Useful defaults in sentiment-analysis — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
- ★★★★★Benjamin Zhang· Dec 16, 2024
We added sentiment-analysis from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
- ★★★★★Xiao Abebe· Dec 16, 2024
Solid pick for teams standardizing on skills: sentiment-analysis is focused, and the summary matches what you get after install.
- ★★★★★Isabella Johnson· Dec 12, 2024
I recommend sentiment-analysis for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
- ★★★★★Diya Patel· Dec 8, 2024
Keeps context tight: sentiment-analysis is the kind of skill you can hand to a new teammate without a long onboarding doc.
- ★★★★★Nia Agarwal· Dec 4, 2024
sentiment-analysis is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
- ★★★★★Luis Sharma· Nov 27, 2024
Registry listing for sentiment-analysis matched our evaluation — installs cleanly and behaves as described in the markdown.
- ★★★★★Camila Okafor· Nov 23, 2024
sentiment-analysis reduced setup friction for our internal harness; good balance of opinion and flexibility.
- ★★★★★Soo Rahman· Nov 19, 2024
Useful defaults in sentiment-analysis — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
- ★★★★★Ava Khan· Nov 11, 2024
I recommend sentiment-analysis for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
showing 1-10 of 73