
Week 5 content of steam review analyzer
- Aggregate sentiment from multiple reviews
- Create sentiment reports and summaries
- Build a basic Chrome extension structure
We've learned how to analyze individual reviews with VADER. But what about analyzing 100 reviews for a game? How do we summarize the overall sentiment?
This week, we'll learn to:
1. Combine sentiment scores from multiple reviews
2. Generate summary statistics and reports
3. Start building our Chrome extension foundation
By the end, you'll have both the sentiment analysis skills AND the extension structure to bring everything together!
Here's some of the code for this week: https://drive.google.com/file/d/1HSmFAeccx0DSp6ISyp4vuONm9yCK7D8V/view?usp=sharing
Let's start by analyzing a collection of reviews.
from nltk.sentiment import SentimentIntensityAnalyzer
import nltk
nltk.download('vader_lexicon')
sia = SentimentIntensityAnalyzer()
# Sample game reviews
reviews = [
"Amazing game! Love the graphics and gameplay.",
"Pretty good, but has some bugs.",
"Terrible experience. Waste of money.",
"Not bad, could be better.",
"BEST GAME EVER!!! Highly recommended!!!"
]
# Analyze each review
results = []
for review in reviews:
scores = sia.polarity_scores(review)
compound = scores['compound']
* *
if compound >= 0.05:
sentiment = "Positive"
elif compound <= -0.05:
sentiment = "Negative"
else:
sentiment = "Neutral"
* *
results.append({
'text': review,
'compound': compound,
'sentiment': sentiment
})
# Display results
for i, result in enumerate(results, 1):
print(f"Review {i}: {result['text']}")
print(f" Sentiment: {result['sentiment']} (compound: {result['compound']:.3f})")
print()
Now let's combine all the scores to get an overall sentiment.
from nltk.sentiment import SentimentIntensityAnalyzer
sia = SentimentIntensityAnalyzer()
reviews = [
"Amazing game! Love the graphics.",
"Pretty good, but has some bugs.",
"Terrible experience.",
"Not bad, could be better.",
"BEST GAME EVER!!!"
]
# Collect all compound scores
compound_scores = []
for review in reviews:
compound = sia.polarity_scores(review)['compound']
compound_scores.append(compound)
# Calculate average
average_compound = sum(compound_scores) / len(compound_scores)
# Determine overall sentiment
if average_compound >= 0.05:
overall_sentiment = "Positive"
elif average_compound <= -0.05:
overall_sentiment = "Negative"
else:
overall_sentiment = "Mixed/Neutral"
print(f"Total reviews: {len(reviews)}")
print(f"Average compound score: {average_compound:.3f}")
print(f"Overall sentiment: {overall_sentiment}")
Let's count how many reviews are positive, negative, and neutral.
from nltk.sentiment import SentimentIntensityAnalyzer
sia = SentimentIntensityAnalyzer()
reviews = [
"Amazing game! Love it.",
"Pretty good game.",
"Terrible experience.",
"Not bad.",
"BEST GAME EVER!!!",
"Awful game.",
"It's okay.",
"Great graphics!",
"Worst game.",
"Decent game."
]
# Count sentiments
positive_count = 0
negative_count = 0
neutral_count = 0
for review in reviews:
compound = sia.polarity_scores(review)['compound']
* *
if compound >= 0.05:
positive_count += 1
elif compound <= -0.05:
negative_count += 1
else:
neutral_count += 1
# Calculate percentages
total = len(reviews)
positive_pct = (positive_count / total) 100*
negative_pct = (negative_count / total) 100*
neutral_pct = (neutral_count / total) 100*
print("Sentiment Distribution:")
print(f" Positive: {positive_count} ({positive_pct:.1f}%)")
print(f" Negative: {negative_count} ({negative_pct:.1f}%)")
print(f" Neutral: {neutral_count} ({neutral_pct:.1f}%)")
Let's build a function that generates a complete report.
from nltk.sentiment import SentimentIntensityAnalyzer
def generate_sentiment_report(reviews):
"""Generate comprehensive sentiment report"""
* *
sia = SentimentIntensityAnalyzer()
* *
# Analyze each review
all_scores = []
positive_count = 0
negative_count = 0
neutral_count = 0
* *
for review in reviews:
compound = sia.polarity_scores(review)['compound']
all_scores.append(compound)
* *
if compound >= 0.05:
positive_count += 1
elif compound <= -0.05:
negative_count += 1
else:
neutral_count += 1
* *
# Calculate statistics
total = len(reviews)
avg_score = sum(all_scores) / total
max_score = max(all_scores)
min_score = min(all_scores)
* *
# Determine overall sentiment
if avg_score >= 0.05:
overall = "Positive"
elif avg_score <= -0.05:
overall = "Negative"
else:
overall = "Mixed"
* *
return {
'total_reviews': total,
'average_score': round(avg_score, 3),
'overall_sentiment': overall,
'positive_count': positive_count,
'negative_count': negative_count,
'neutral_count': neutral_count,
'positive_percentage': round((positive_count / total) 100, 1),*
'negative_percentage': round((negative_count / total) 100, 1),*
'neutral_percentage': round((neutral_count / total) 100, 1),*
'highest_score': round(max_score, 3),
'lowest_score': round(min_score, 3)
}
# Test with sample reviews
sample_reviews = [
"Amazing game!",
"Pretty good.",
"Terrible.",
"Okay game.",
"LOVE IT!!!",
"Awful.",
"Not bad.",
"Great!",
"Worst ever.",
"Decent."
]
report = generate_sentiment_report(sample_reviews)
print("Sentiment Report:")
print("=" 50)*
for key, value in report.items():
print(f"{key}: {value}")
Let's test our aggregation on the NLTK movie reviews dataset.
from nltk.corpus import movie_reviews
from nltk.sentiment import SentimentIntensityAnalyzer
import nltk
nltk.download('movie_reviews')
sia = SentimentIntensityAnalyzer()
# Analyze first 50 positive reviews
positive_reviews_text = []
for fileid in movie_reviews.fileids('pos')[:50]:
text = movie_reviews.raw(fileid)
positive_reviews_text.append(text)
# Generate report for positive reviews
pos_report = generate_sentiment_report(positive_reviews_text)
print("Analysis of 50 Positive Movie Reviews:")
print(f"Average score: {pos_report['average_score']}")
print(f"Overall sentiment: {pos_report['overall_sentiment']}")
print(f"Correctly identified as positive: {pos_report['positive_percentage']}%")
Now let's start building our Chrome extension structure!
A Chrome extension consists of:
- manifest.json: Configuration file (required)
- content.js: Runs on web pages
- background.js: Handles background tasks
- popup.html: UI when clicking extension icon (optional)
The manifest file tells Chrome about your extension.
manifest.json
{
"manifest_version": 3,
"name": "Steam Review Sentiment Analyzer",
"version": "1.0",
"description": "Analyzes sentiment of Steam game reviews",
* *
"permissions": [
"activeTab"
],
* *
"content_scripts": [
{
"matches": ["https://store.steampowered.com/app/"],*
"js": ["content.js"]
}
],
* *
"background": {
"service_worker": "background.js"
},
* *
"action": {
"default_title": "Steam Review Analyzer"
}
}
What each field means:
- manifest_version: Always use 3 (latest version)
- name, version, description: Basic extension info
- permissions: What the extension can access
- content_scripts: Scripts that run on specific pages
- matches: Which URLs to run on
- background: Script that runs in the background
- action: Extension icon configuration
The content script runs on Steam game pages.
content.js
// Content script - runs on Steam game pages
console.log("Steam Review Analyzer loaded!");
// Detect if we're on a game page
function detectGamePage() {
const url = window.location.href;
* *
// Check if URL contains /app/ (game page)
if (url.includes('/app/')) {
console.log("Game page detected!");
* *
// Extract game ID from URL
const match = url.match(/\/app\/(\d+)/);
if (match) {
const gameId = match[1];
console.log("Game ID:", gameId);
}
}
}
// Run when page loads
detectGamePage();
The background script handles events and long-running tasks.
background.js
// Background script - handles extension events
console.log("Background script loaded");
// Listen for messages from content script
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
console.log("Received message:", request);
* *
if (request.action === "analyzeReviews") {
console.log("Analyzing reviews for game:", request.gameId);
sendResponse({ success: true });
}
* *
return true;
});
Create a folder with these files:
```
steam-review-analyzer/
├── manifest.json
├── content.js
└── background.js
```
Step-by-step instructions:
1. Open Chrome and go to "chrome://extensions/"
2. Enable Developer Mode (toggle in top-right corner)
3. Click "Load unpacked"
4. Select your extension folder (steam-review-analyzer)
5. Your extension should appear in the list!
6. Test it: Visit any Steam game page (e.g., https://store.steampowered.com/app/1174180/)
7. Open DevTools (F12) and check the Console tab
8. You should see: "Steam Review Analyzer loaded!" and "Game page detected!"
Verification checklist:
1. Extension appears in chrome://extensions/
2. No errors shown in extensions page
3. Console logs appear on Steam game pages
4. Game ID is extracted correctly
Let's make content and background scripts communicate.
Updated content.js
console.log("Steam Review Analyzer loaded!");
function detectGamePage() {
const url = window.location.href;
* *
if (url.includes('/app/')) {
const match = url.match(/\/app\/(\d+)/);
* *
if (match) {
const gameId = match[1];
console.log("Sending game ID to background:", gameId);
* *
// Send message to background script
chrome.runtime.sendMessage(
{ action: "analyzeReviews", gameId: gameId },
(response) => {
console.log("Background responded:", response);
}
);
}
}
}
detectGamePage();
Part 1: Sentiment Aggregation
1. Create a list of 10 game reviews (mix of positive, negative, neutral)
2. Use generate_sentiment_report() to analyze them
3. Print the report and verify the percentages add up to 100%
Part 2: Chrome Extension
1. Create the three files (manifest.json, content.js, background.js)
2. Load your extension into Chrome
3. Visit a Steam game page and check the console
4. Verify you can see the game ID being extracted
# Part 1: Your 10 game reviews
my_reviews = [
"Write your reviews here",
# ... 9 more reviews
]
# Generate and print report
my_report = generate_sentiment_report(my_reviews)
print(my_report)
Sentiment Aggregation:
- Average compound scores to get overall sentiment
- Count positive/negative/neutral for distribution
- Generate comprehensive reports with statistics
- Test on real datasets to verify accuracy
Chrome Extensions:
- manifest.json is the required configuration file
- content.js runs on specific web pages
- background.js handles events and background tasks
- Load extensions via chrome://extensions/ in Developer Mode
- Use chrome.runtime.sendMessage() for communication
In Week 6, we'll:
- Integrate VADER sentiment analysis into our Chrome extension
- Fetch real Steam reviews via API
- Display sentiment analysis results on Steam pages
- Create a visual sentiment summary
- Complete the full extension pipeline!
You now have the foundation for both sentiment analysis AND Chrome extensions. Next week, we bring them together!