Pandas 1.5 数据分析实战:电影评分数据集 3 大统计维度与 2 种分组聚合 Pandas 1.5 电影评分数据分析实战从基础统计到智能洞察1. 数据科学家的电影评分分析工具箱在数据驱动的影视行业掌握Pandas进行电影评分分析已成为数据科学家的核心技能。这个实战教程将带您从零开始使用Pandas 1.5对电影评分数据进行全面剖析揭示用户行为背后的秘密。为什么选择电影评分数据电影评分数据集是练习数据分析的绝佳素材它包含了用户ID、电影ID、评分和时间戳四个核心维度结构简单却蕴含丰富信息。通过分析这些数据我们可以发现用户的评分偏好模式识别高质量电影和潜在爆款优化推荐系统算法预测新上映电影的评分趋势本教程将使用MovieLens数据集的一个子集包含约10万条评分记录涉及1000部电影和600个用户。以下是数据加载和初步观察的代码import pandas as pd # 加载数据集 ratings pd.read_csv(movie_ratings.csv, names[user_id, movie_id, rating, timestamp]) # 查看前5行数据 print(ratings.head()) # 查看数据基本信息 print(ratings.info())2. 三维度基础统计分析2.1 用户维度分析用户是评分系统的核心了解用户行为是数据分析的第一步。我们可以计算以下关键指标# 用户数量统计 num_users ratings[user_id].nunique() print(f总用户数: {num_users}) # 用户评分分布 user_stats ratings.groupby(user_id)[rating].agg([count, mean, std]) print(user_stats.describe())用户评分行为洞察活跃用户与普通用户的评分数量差异用户评分的均值分布是否普遍偏高或偏低用户评分的一致性标准差反映评分波动程度2.2 电影维度分析电影质量直接影响用户评分我们可以通过以下方式评估电影表现# 电影数量统计 num_movies ratings[movie_id].nunique() print(f总电影数: {num_movies}) # 电影评分统计 movie_stats ratings.groupby(movie_id)[rating].agg([count, mean, median]) top_movies movie_stats.sort_values(bymean, ascendingFalse).head(10) print(top_movies)电影评分关键发现评分数量与评分均值的相关性高评分电影的共性特征评分中位数与均值的差异分析2.3 评分维度分析评分本身包含丰富信息深入分析可以揭示用户偏好# 整体评分分布 rating_dist ratings[rating].value_counts().sort_index() print(rating_dist) # 评分随时间变化趋势 ratings[date] pd.to_datetime(ratings[timestamp], units) monthly_avg ratings.resample(M, ondate)[rating].mean() print(monthly_avg.head())评分模式洞察用户是否倾向于给极端评分1分或5分评分标准是否随时间变得宽松或严格是否存在评分通货膨胀现象3. 高级分组聚合技术3.1 用户评分模式分析通过分组聚合我们可以识别不同类型的评分用户# 用户评分习惯分类 user_rating_habits ratings.groupby(user_id)[rating].agg( avg_ratingmean, rating_countcount, rating_stdstd ).reset_index() # 定义用户类型 user_rating_habits[user_type] pd.cut( user_rating_habits[avg_rating], bins[0, 2.5, 3.5, 5], labels[苛刻型, 中立型, 宽容型] ) print(user_rating_habits[user_type].value_counts())用户类型特征苛刻型用户平均评分2.5可能更专业或要求更高中立型用户2.5≤平均评分≤3.5代表大众观点宽容型用户平均评分3.5可能更包容或偏好明确3.2 电影质量评估电影评分不仅反映质量也反映受欢迎程度。我们可以使用加权评分公式平衡两者# 计算电影加权评分(IMDb公式) C movie_stats[mean].mean() m movie_stats[count].quantile(0.9) # 仅考虑评分数量前10%的电影 def weighted_rating(x): v x[count] R x[mean] return (v/(vm) * R) (m/(mv) * C) movie_stats[weighted_score] movie_stats.apply(weighted_rating, axis1) top_weighted movie_stats.sort_values(weighted_score, ascendingFalse).head(10) print(top_weighted)加权评分优势避免少数极端评分影响平衡评分数量和评分均值更准确反映电影的实际质量3.3 时间维度分析评分随时间变化能揭示电影口碑演变# 电影评分随时间变化 movie_time ratings.groupby([movie_id, pd.Grouper(keydate, freqM)])[rating].mean().unstack() # 计算评分稳定性 movie_time[stability] movie_time.std(axis1) stable_movies movie_time.sort_values(stability).head(10) print(stable_movies[[stability]])时间分析价值识别口碑持续优秀的经典电影发现评分波动大的争议性电影分析电影评分衰减速度4. 实战构建电影推荐引擎4.1 基于评分的简单推荐# 获取高评分电影 high_rated movie_stats[movie_stats[count] 100].sort_values(mean, ascendingFalse).head(20) # 获取热门电影 popular movie_stats.sort_values([count, mean], ascending[False, False]).head(20) # 混合推荐 recommendation pd.concat([high_rated, popular]).drop_duplicates() print(recommendation)4.2 基于用户相似度的协同过滤# 创建用户-电影评分矩阵 user_movie_matrix ratings.pivot_table(indexuser_id, columnsmovie_id, valuesrating) # 计算用户相似度 user_similarity user_movie_matrix.T.corr() def get_similar_users(user_id, n5): similar_users user_similarity[user_id].sort_values(ascendingFalse)[1:n1] return similar_users.index.tolist() # 示例为用户1推荐电影 similar_users get_similar_users(1) rec_movies ratings[ratings[user_id].isin(similar_users)] rec_movies rec_movies.groupby(movie_id)[rating].mean().sort_values(ascendingFalse).head(10) print(rec_movies)4.3 评估推荐效果# 划分训练集和测试集 from sklearn.model_selection import train_test_split train, test train_test_split(ratings, test_size0.2, random_state42) # 计算预测准确率 def evaluate(predictions, actual): correct predictions[predictions.index.isin(actual.index)] return len(correct) / len(actual) # 示例评估 train_stats train.groupby(movie_id)[rating].mean() test_ratings test.groupby(movie_id)[rating].mean() top_train train_stats.sort_values(ascendingFalse).head(100) accuracy evaluate(top_train, test_ratings) print(f推荐准确率: {accuracy:.2%})5. 数据分析结果可视化5.1 评分分布热力图import seaborn as sns import matplotlib.pyplot as plt # 用户-电影评分热力图 plt.figure(figsize(12, 8)) sample ratings.sample(1000) # 抽样减少数据量 pivot_sample sample.pivot_table(indexuser_id, columnsmovie_id, valuesrating) sns.heatmap(pivot_sample, cmapYlGnBu, cbar_kws{label: 评分}) plt.title(用户-电影评分分布热力图) plt.xlabel(电影ID) plt.ylabel(用户ID) plt.show()5.2 电影评分随时间变化# 选取特定电影分析评分趋势 movie_id 1 # 以电影ID 1为例 movie_ratings ratings[ratings[movie_id] movie_id].copy() movie_ratings[month] movie_ratings[date].dt.to_period(M) monthly_avg movie_ratings.groupby(month)[rating].mean() plt.figure(figsize(12, 6)) monthly_avg.plot(kindline, markero) plt.title(f电影ID {movie_id} 评分随时间变化) plt.xlabel(月份) plt.ylabel(平均评分) plt.grid(True) plt.show()5.3 用户评分行为雷达图from math import pi # 准备雷达图数据 def prepare_radar_data(user_id): user_data ratings[ratings[user_id] user_id] rating_dist user_data[rating].value_counts().reindex([1, 2, 3, 4, 5], fill_value0) return rating_dist.values # 绘制雷达图 labels [1星, 2星, 3星, 4星, 5星] user1 prepare_radar_data(1) user2 prepare_radar_data(2) angles np.linspace(0, 2 * np.pi, len(labels), endpointFalse).tolist() user1 np.concatenate((user1,[user1[0]])) user2 np.concatenate((user2,[user2[0]])) angles angles[:1] fig, ax plt.subplots(figsize(8, 8), subplot_kwdict(polarTrue)) ax.plot(angles, user1, label用户1) ax.plot(angles, user2, label用户2) ax.fill(angles, user1, alpha0.25) ax.fill(angles, user2, alpha0.25) ax.set_xticks(angles[:-1]) ax.set_xticklabels(labels) ax.set_title(用户评分行为对比雷达图) ax.legend() plt.show()