import json import matplotlib.pyplot as plt def count_reviews_by_stars_and_average(file_path): star_counts = {} total_stars = 0 total_reviews = 0 total_text_length = 0 short_text_stars = 0 short_text_count = 0 word_frequencies = {} word_count_limit = 100000 star_vote_totals = {stars: {'useful': 0, 'funny': 0, 'cool': 0, 'count': 0} for stars in range(1, 6)} with open(file_path, 'r', encoding='utf-8') as file: for i, line in enumerate(file): record = json.loads(line.strip()) if "stars" in record and isinstance(record["stars"], (int, float)) and "text" in record: stars = record["stars"] text = record["text"] text_length = len(text) if stars not in star_counts: star_counts[stars] = 0 star_counts[stars] += 1 total_stars += stars total_reviews += 1 total_text_length += text_length if text_length < 10: short_text_stars += stars short_text_count += 1 if i < word_count_limit: words = text.lower().split() for word in words: word = ''.join(char for char in word if char.isalnum()) if word: if word not in word_frequencies: word_frequencies[word] = 0 word_frequencies[word] += 1 if "useful" in record and "funny" in record and "cool" in record: star_vote_totals[stars]['useful'] += record["useful"] star_vote_totals[stars]['funny'] += record["funny"] star_vote_totals[stars]['cool'] += record["cool"] star_vote_totals[stars]['count'] += 1 if total_reviews > 0: average_rating = total_stars / total_reviews average_text_length = total_text_length / total_reviews else: average_rating = 0 average_text_length = 0 if short_text_count > 0: average_short_text_rating = short_text_stars / short_text_count else: average_short_text_rating = 0 most_common_word = None most_common_count = 0 for word, count in word_frequencies.items(): if count > most_common_count: most_common_word = word most_common_count = count average_votes_by_star = {} for stars, votes in star_vote_totals.items(): if votes['count'] > 0: average_votes_by_star[stars] = { 'useful': votes['useful'] / votes['count'], 'funny': votes['funny'] / votes['count'], 'cool': votes['cool'] / votes['count'] } return star_counts, average_rating, average_text_length, average_short_text_rating, most_common_word, most_common_count, average_votes_by_star def plot_reviews_and_votes(star_counts, average_votes_by_star): star_ratings = [1, 2, 3, 4, 5] review_counts = [star_counts[star] for star in star_ratings] plt.figure(figsize=(10, 6)) plt.subplot(1, 2, 1) plt.bar(star_ratings, review_counts, color='blue') plt.title('Number of Reviews per Star Rating') plt.xlabel('Star Rating') plt.ylabel('Number of Reviews') useful_votes = [average_votes_by_star[star]['useful'] for star in star_ratings] funny_votes = [average_votes_by_star[star]['funny'] for star in star_ratings] cool_votes = [average_votes_by_star[star]['cool'] for star in star_ratings] plt.subplot(1, 2, 2) width = 0.2 x = [i - width for i in range(len(star_ratings))] plt.bar(x, useful_votes, width, label='Useful', color='green') plt.bar([i + width for i in range(len(star_ratings))], funny_votes, width, label='Funny', color='red') plt.bar([i + 2 * width for i in range(len(star_ratings))], cool_votes, width, label='Cool', color='blue') plt.title('Average Votes per Star Rating') plt.xlabel('Star Rating') plt.ylabel('Average Votes') plt.xticks(range(len(star_ratings)), star_ratings) plt.legend() plt.tight_layout() plt.show() if __name__ == "__main__": file_path = "yelp_academic_dataset_review.json" star_counts, average_rating, average_text_length, average_short_text_rating, most_common_word, most_common_count, average_votes_by_star = count_reviews_by_stars_and_average(file_path) for stars in sorted(star_counts): print(f"{stars} stars: {star_counts[stars]} reviews") print(f"Average rating: {average_rating:.2f}") print(f"Average text length: {average_text_length:.2f} characters") print(f"Average rating for reviews with text length < 10: {average_short_text_rating:.2f}") print(f"Most common word (in first 100,000 reviews): '{most_common_word}' (used {most_common_count} times)") print("Average votes per star rating:") for stars, votes in average_votes_by_star.items(): print(f"{stars} stars - Useful: {votes['useful']:.2f}, Funny: {votes['funny']:.2f}, Cool: {votes['cool']:.2f}") plot_reviews_and_votes(star_counts, average_votes_by_star)